def add_enums(function): """ Add standard enums from parsed MSDN documentation for all imported library calls and their arguments. Arguments: function -- function object """ enum_count = 0 for argument in function.arguments: # Add standard enums if not argument.enums: g_logger.debug(' No standard constants available for %s' % argument.name) else: for enum in argument.enums: g_logger.debug(' Importing enum %s for argument %s' % (enum, argument.name)) if idc.import_type(-1, enum) != idaapi.BADADDR: g_logger.debug(' ' + enum + ' ' + hex(idc.get_enum(enum)) + ' added successfully') enum_count = enum_count + 1 else: g_logger.debug(' Could not add ' + enum) if not argument.constants: # No constants for this argument continue argument.name = argument.name function.name = function.name # Add constant descriptions for constant in argument.constants: if constant.name == 'NULL': # Create unique name, so we can add descriptive comment to it constant.name = 'NULL_{}_{}'.format(argument.name, function.name) # Add custom enum for NULL values if it does not exist yet enumid = idc.get_enum(NULL_ENUM_NAME) if enumid == idaapi.BADADDR: enumid = idc.add_enum(-1, NULL_ENUM_NAME, idaapi.hex_flag()) idc.add_enum_member(enumid, constant.name, 0, -1) constid = idc.get_enum_member_by_name(constant.name) idc.set_enum_member_cmt(constid, format_comment(constant.description), False) else: constid = idc.get_enum_member_by_name(constant.name) if constid: if idc.set_enum_member_cmt( constid, format_comment(constant.description), False): g_logger.debug(' Description added for %s' % constant.name) else: g_logger.debug(' No description added for %s' % constant.name) return enum_count
def createEnum(self, enum): eid = idc.add_enum(-1, enum[0], 0x1100000) # what is this flag? ida_enum.set_enum_bf(eid, 1) val = 0 mask = 0x1F ida_enum.set_enum_width(eid, 1) for i in enum[1]: idc.add_enum_member(eid, i, val, mask) val += 1
def readStructMacro(path): """ Parses struct macros and updates a corresponding enum with their values :param path: the path to the file containing the macros :return: """ # parse macro file macroFile = open(path) members = [] structName = '' for line in macroFile.readlines(): if line.lstrip().startswith('\struct_entry'): if ', ' in line: name = line[line.index(')')+1 : line.index(',')] size = line[line.index(', ')+2 :].rstrip() if '//' in size: size = size[:size.index('//')].rstrip() if size.startswith('0x'): size = int(size, 16) else: size = int(size) else: name = line[line.index(')')+1 :].rstrip() if '//' in name: name = name[:name.index('//')].rstrip() size = 0 members.append((name, size)) if line.startswith('def_struct_offsets'): structName = line[line.index(', ')+2:].rstrip() print('parsed struct "' + structName + '"') # read into enum enumId = idc.get_enum(structName) if enumId == idaapi.BADADDR: enumId = idc.add_enum(idaapi.BADADDR, structName, idaapi.decflag()) # parse all enum members, needed to know what member to replace offset = 0x00 for member, size in members: enumMember = idc.get_enum_member(enumId, offset, 0, ida_enum.DEFMASK) if enumMember == idaapi.BADADDR: print("why???") idc.add_enum_member(enumId, structName + member, offset, idaapi.BADADDR) elif idc.get_enum_member_name(enumMember) != structName + member: # update member name, if value already exists print('\tupdate %s // 0x%X' % (structName + member, offset)) idc.set_enum_member_name(enumMember, structName + member) offset += size return True
def set_enum_member(name, member, value): ok = idc.add_enum_member(idc.get_enum(str(name)), str(member), int(value), -1) if not ok: if idaapi.get_enum_member_by_name(str(member)) == idaapi.BADADDR: print("Could not add enum member {member} at {name}".format( name=name, member=member))
def create_enums(lib_fpath): lib_fname = lib_fpath.split(os.sep)[-1] lib_name = lib_fname.split('.')[0] enum_ids = {} for hash_name in HASH_TYPES: enum_name = '{}_{}'.format(lib_name, hash_name) enum_ids[enum_name] = idc.add_enum(-1, enum_name, ida_bytes.dec_flag()) f = open(lib_fpath, 'r') while (True): line_csv = f.readline() if not line_csv: break csv_hash_value, csv_func_name, csv_lib_name, csv_hash_name = line_csv.split( ',') csv_hash_name = csv_hash_name[:len(csv_hash_name) - 1] if not csv_hash_name in HASH_TYPES: continue csv_lib_name, _ = os.path.splitext(csv_lib_name) csv_enum_name = '{}_{}'.format(csv_lib_name, csv_hash_name) idc.add_enum_member(enum_ids[csv_enum_name], '{}_{}'.format(csv_hash_name, csv_func_name), int(csv_hash_value, 16), -1) f.close()
def AddConst(enum_id, name, value): return idc.add_enum_member(enum_id, name, value, -1)