def createEnumeration(self, element): """ Convert CastXML XML element into a Ghidra EnumDataType. Args: element (ElementTree): XML element Returns (EnumDataType): Ghidra EnumDataType """ enumName = element.attrib['name'] if enumName == "": enumName = "anon_enum" + element.attrib['id'] print("Enum: {0}".format(enumName)) enumBitSize = int(element.attrib['size']) enumByteSize = enumBitSize / 8 filePath = self.getFileFromId(element.attrib['file']) categoryPath = self.getCategoryPathFromFile(filePath) enumDataType = EnumDataType(categoryPath, enumName, enumByteSize) for enumValue in element: name = enumValue.attrib['name'] bitSize = int(element.attrib['size']) init = int(enumValue.attrib['init']) #print("{0} = {1}".format(name, init)) # Convert to signed integer as Java cannot coerce large unsigned numbers init = init & ((1 << bitSize) - 1) init = init | (-(init & (1 << (bitSize - 1)))) enumDataType.add(name, init) self.recordTypeForId(element.attrib['id'], enumDataType) return enumDataType
0x21: "Global Common symbol", 0x40: "Local Symbols", 0x41: "Global Symbols" } # Init data type ptr_data_type = PointerDataType() byte_data_type = ByteDataType() char_data_type = CharDataType() void_data_type = VoidDataType() unsigned_int_type = UnsignedIntegerDataType() short_data_type = ShortDataType() char_ptr_type = ptr_data_type.getPointer(char_data_type, 4) void_ptr_type = ptr_data_type.getPointer(void_data_type, 4) # Prepare VxWorks symbol types vx_5_sym_enum = EnumDataType("Vx5symType", 1) for flag in vx_5_symbol_type_enum: vx_5_sym_enum.add(vx_5_symbol_type_enum[flag], flag) vx_6_sym_enum = EnumDataType("Vx6symType", 1) for flag in vx_6_symbol_type_enum: vx_6_sym_enum.add(vx_6_symbol_type_enum[flag], flag) # Init VxWorks symbol table structs vx_5_symtbl_dt = StructureDataType("VX_5_SYMBOL_IN_TBL", 0x10) vx_5_symtbl_dt.replaceAtOffset(0, unsigned_int_type, 4, "symHashNode", "") vx_5_symtbl_dt.replaceAtOffset(4, char_ptr_type, 4, "symNamePtr", "") vx_5_symtbl_dt.replaceAtOffset(8, void_ptr_type, 4, "symPrt", "") vx_5_symtbl_dt.replaceAtOffset(0x0c, short_data_type, 4, "symGroup", "") vx_5_symtbl_dt.replaceAtOffset(0x0e, vx_5_sym_enum, 1, "symType", "") vx_5_symtbl_dt.replaceAtOffset(0x0f, byte_data_type, 1, "End", "")
accu = (tmp + accu * 0x1003f) % 2**32 hash = accu ^ xor_value libs.update({hash: dll_name}) def get_lib(hash): dll_name = libs.get(hash) if dll_name is None: print "ERROR: Could not find dll name for hash " + str(hash) return "Unknown" return dll_name init_libs(currentAddress) enum = EnumDataType('emotet_lib_hash', 4) for lib in libs: enum.add(libs[lib], lib) dtm = currentProgram.getDataTypeManager() dtm.addDataType(enum, None) refs = getReferencesTo(currentAddress) for r in refs: callee = r.getFromAddress() inst = inst_ = getInstructionAt(callee) i = 0 # TODO: use pcode and reaching definition while not inst.toString().startswith('MOV ECX,0x'): inst = getInstructionBefore(inst) i += 1
def syncEnums(): if not enumNames: scanEnums() # sync all the stuff up n = 0 for key, enum in enumInfo.iteritems(): if key not in enumTypeMap: if isEnumSafe(enum['choices']): # gotta throw this one in! name = 'Enum' + key dt = EnumDataType(enumCatPath, name, 4, dtManager) dt.description = 'hash ' + key for i, choice in enumerate(enum['choices']): try: dt.add(choice, i) except: dt.add(choice + ('__%d'%i), i) dtManager.addDataType(dt, handler) enumTypeMap[key] = dt enumNames[key] = name else: print('{} is not safe'.format(enum)) if key in enumTypeMap and 'needsU16Variant' in enum: name = enumNames[key] + '_u16' if key not in enumTypeMapU16: dt = EnumDataType(enumCatPath, name, 2, dtManager) dt.description = 'hashU16 ' + key for i, choice in enumerate(enum['choices']): try: dt.add(choice, i) except: dt.add(choice + ('__%d'%i), i) dtManager.addDataType(dt, handler) enumTypeMapU16[key] = dt else: if enumTypeMapU16[key].name != name: enumTypeMapU16[key].name = name # poke the enum's text array for i, addrValue in enumerate(enum['locations']): addr = toAddr(addrValue) sym = getSymbolAt(addr) # is there a name we can pull, for data-type-less enums? if key not in enumNames and not sym.dynamic and sym.parentNamespace == enumNS: enumNames[key] = sym.name # if not, make sure we have one if key not in enumNames: enumNames[key] = 'Enum' + key # either way, give this enum the name it needs nameToUse = enumNames[key] if i > 0: nameToUse += '_%d' % i if sym.parentNamespace != enumNS or sym.name != nameToUse: sym.setNameAndNamespace(nameToUse, enumNS, SourceType.DEFAULT) # poke the enum's getters for i, addrValue in enumerate(enum['getters']): addr = toAddr(addrValue) sym = getSymbolAt(addr) fn = getFunctionAt(addr) # it's easier here, as we've already picked a canonical name nameToUse = enumNames[key] if nameToUse.startswith('e'): nameToUse = nameToUse[1:] nameToUse = 'get' + nameToUse if sym.name != nameToUse: sym.setNameAndNamespace(nameToUse, enumNS, SourceType.DEFAULT) # give the function the correct signature too if fn.returnType.name == 'undefined': fn.setReturnType(charPtrPtrDT, SourceType.DEFAULT) fn.setCallingConvention('__cdecl') n += 1
tmp = ord(c) accu = (tmp + accu * 0x1003f)%2**32; hash = accu ^ xor_value funcs.update({hash:func_name}) def get_func(hash): func_name = funcs.get(hash) if func_name is None: print "ERROR: Could not find function name for hash " + hex(hash) return "Unknown" return func_name init_funcs(currentAddress) enum = EnumDataType('emotet_func_hash',4) for func in funcs: enum.add(funcs[func], func) dtm = currentProgram.getDataTypeManager() dtm.addDataType(enum,None) refs = getReferencesTo(currentAddress) for r in refs: callee = r.getFromAddress() inst = inst_ = getInstructionAt(callee) i = 0 # TODO: use pcode and reaching definition while not inst.toString().startswith('MOV EDX,0x'): inst = getInstructionBefore(inst) i += 1