def create_cmdref(): sid = ida_struct.add_struc(0, "cmd_ref") idc.AddStrucMember(sid, "name", -1, offflag() | FF_DATA | FF_DWRD, -1, 4) idc.AddStrucMember(sid, "id", -1, idc.FF_DWRD, -1, 4) idc.AddStrucMember(sid, "id2", -1, idc.FF_DWRD, -1, 4) idc.AddStrucMember(sid, "id3", -1, idc.FF_DWRD, -1, 4) return sid
def fillStruct(self, sid, data): for i in data: new_type = None #(i1, i2, i3) = self.stepper.parseField(i[1]) name = i[1] if name[0] == "*": name = name[1:] if i[1] != "uintptr": i1, i2, i3 = (idc.FF_BYTE | idc.FF_DATA, -1, 1) else: i1, i2, i3 = self.uintptr if name == i[1]: new_type = i[1] else: new_type = name + " *" res = idc.AddStrucMember(sid, i[0], -1, i1, i2, i3) use_name = i[0] if res == -1: #Bad name #print "Bad name %s for struct member" % i[0] use_name = i[0] + "_autogen_" + id_generator() idc.AddStrucMember(sid, use_name, -1, i1, i2, i3) if new_type is not None: offset = idc.GetMemberOffset(sid, use_name) #print "Setting %s as %s" % (i[0], new_type) idc.SetType(idc.GetMemberId(sid, offset), new_type)
def create_struc_from_skeleton(name, skeleton, default_type=idaapi.FF_DWRD): sorted_data_types = sorted(data_types.items(), key=lambda x: x[1], reverse=True) sid = idc.GetStrucIdByName(name) if sid != idaapi.BADADDR: idc.DelStruc(sid) idx = idc.AddStrucEx(idaapi.BADADDR, name, False) i = 0 size = skeleton[-1][SKELETON_OFFSET] + data_types[skeleton[-1] [SKELETON_TYPE]] while i < size: if i < skeleton[0][SKELETON_OFFSET]: if i + data_types[default_type] <= skeleton[0][SKELETON_OFFSET]: idc.AddStrucMember(idx, 'field_{0}'.format(hex(i)), i, default_type | idaapi.FF_DATA, -1, data_types[default_type]) i += data_types[default_type] else: for data_type in sorted_data_types: if skeleton[0][SKELETON_OFFSET] - i >= data_type[1]: idc.AddStrucMember(idx, 'field_{0}'.format(hex(i)), i, data_type[0] | idaapi.FF_DATA, -1, data_type[1]) i += data_type[1] break elif i == skeleton[0][SKELETON_OFFSET]: idc.AddStrucMember(idx, skeleton[0][SKELETON_NAME], skeleton[0][SKELETON_OFFSET], skeleton[0][SKELETON_TYPE] | idaapi.FF_DATA, -1, data_types[skeleton[0][SKELETON_TYPE]]) i += data_types[skeleton[0][SKELETON_TYPE]] skeleton.pop(0) else: skeleton.pop(0)
def create_CFLString_struct(): sid = find_or_create_struct("CFLString") print idc.AddStrucMember(sid, "magic", -1, idc.FF_DWRD, -1, 4) print idc.AddStrucMember(sid, "unk4", -1, idc.FF_DWRD, -1, 4) print idc.AddStrucMember(sid, "cstr", -1, idc.FF_BYTE, -1, 0) return sid
def yatest_create_sub(self): for offset, count in create_sub: name = 'substruct_' + hhex(offset) + '_' + hhex(count) sida = idc.AddStrucEx(-1, name + '_sub1', 0) self.assertNotEqual(sida, -1) sidb = idc.AddStrucEx(-1, name + '_sub2', 0) self.assertNotEqual(sidb, -1) for i in xrange(0, 16): self.assertEqual(idc.AddStrucMember(sidb, 'sub_' + hhex(i), i, idaapi.FF_BYTE | idaapi.FF_DATA, -1, 1), 0) self.assertEqual(idc.AddStrucMember(sida, 'sub_struc', offset, idaapi.FF_STRU | idaapi.FF_DATA, sidb, count * 16), 0)
def yatest_apply_struct(self): addrs = [] # -1: struct, n: union for k in range(-1, 4): # find an integer operand in any function addr = self.find_operand_addr() addrs.append(addr) # create struct sid = idc.AddStrucEx(-1, 'apply_struct_%x' % (k + 1), 0) self.assertNotEqual(sid, -1) ftype = idaapi.FF_BYTE | idaapi.FF_DATA # apply struct only if k == -1: # add struct fields for x in xrange(0, 0x60): self.assertEqual( idc.AddStrucMember(sid, 'field_%x' % x, -1, ftype, -1, 1), 0) path = idaapi.tid_array(1) path[0] = sid self.assertNotEqual( self.custom_op_stroff(addr, path.cast(), 1), idaapi.BADADDR) continue # create union uid = idc.AddStrucEx(-1, 'apply_union_%x' % (k + 1), 1) self.assertNotEqual(uid, -1) for x in xrange(1, 0x10): self.assertEqual( idc.AddStrucMember(uid, 'union_%x' % x, -1, ftype, -1, 1), 0) # add struct fields for x in xrange(0, 0x60): self.assertEqual( idc.AddStrucMember(sid, 'field_%x' % x, -1, idaapi.struflag(), uid, 1), 0) # apply selected union field fid = idc.GetMemberId(uid, k) self.assertNotEqual(fid, -1) path = idaapi.tid_array(2) path[0] = sid path[1] = fid self.assertNotEqual(self.custom_op_stroff(addr, path.cast(), 2), idaapi.BADADDR) yaunit.save('apply_struct', addrs)
def register_struct(objname, s): """Registers a ctypes.Structure structure and returns Structure Type ID""" tid = idc.AddStruc(-1, objname) if tid < 0: raise Exception('ida_add_structure error %d' % tid) for name, typ in s._fields_: # normal type if typ in _ctypes_table: typ, size = _ctypes_table[typ] typeid = -1 # embedded struct type elif typ in _registered_structures: _, typeid, size = _registered_structures[typ] typ = idc.FF_STRU # pointer to a predefined structure else: typ = idc.FF_0OFF | idc.FF_DWRD typeid, size = 0, 4 ret = idc.AddStrucMember(tid, name, -1, typ, typeid, size) if ret < 0: raise Exception('ida_add_structure_member %s: %d' % (name, ret)) # add this structure identifier to the global list _registered_structures[s] = objname, tid, ctypes.sizeof(s) return tid
def _create_class_structs__slices(classinfo, endmarkers=True): """Create the IDA structs for a C++ class.""" classname = classinfo.classname # Open or create the structs. sidf = idau.struct_open(classname + '::fields', create=True) sid = idau.struct_open(classname, create=True) if sid is None or sidf is None: _log(0, 'Could not create class structs for {}', classname) return None assert all(not idc.IsUnion(s) for s in (sidf, sid)) # Calculate the size of the ::fields struct. if classinfo.superclass: # If we have a superclass, our fields start after our superclass's fields end. fields_start = classinfo.superclass.class_size else: # If we don't have a superclass, our fields start after our vtable. fields_start = idau.WORD_SIZE fields_size = classinfo.class_size - fields_start # Add an ::end member to the fields struct if requested. if endmarkers: ret = idc.AddStrucMember(sidf, classname + '::end', fields_size, idc.FF_UNK, -1, 0) if ret not in (0, idc.STRUC_ERROR_MEMBER_NAME, idc.STRUC_ERROR_MEMBER_OFFSET): # If that didn't work that's too bad, but continue anyway. _log(0, 'Could not create {}::end', classname) return sid, sidf, fields_start
def struct_add_word(sid, name, offset, size, count=1): """Add a word (integer) to a structure. If sid is a union, offset must be -1. """ return idc.AddStrucMember(sid, name, offset, idc.FF_DATA | word_flag(size), -1, size * count)
def build_struct(self): ''' Creates an IDA structure for this Type. ''' if self.struct is not None: return for p in self.parents: p.build_struct() self.struct = idc.AddStrucEx(-1, self.name, 0) if as_signed(self.struct, TARGET_ADDRESS_SIZE) == -1: raise RuntimeError("Unable to make struct `{}`".format(self.name)) else: #TODO: either come up with another way of showing this, or # sync it with the actual function names cmt = "constructors: " for c in self.constructors(): cmt += "{}(0x{:02x}), ".format(idc.Name(c), c) cmt = cmt.strip(", ") idaapi.set_struc_cmt(self.struct, cmt, False) if TARGET_ADDRESS_SIZE == 8: mask = idc.FF_QWRD else: mask = idc.FF_DWRD # Only bases get the magic _vptr member if len(self.parents) == 0: idc.AddStrucMember(self.struct, "_vptr", 0, idc.FF_DATA | mask, -1, TARGET_ADDRESS_SIZE) idc.SetType(idc.GetMemberId(self.struct, 0), "_vfunc**") for i, parent in enumerate(self.parents): try: #TODO: for non-itanium ABI, this may not be available # when RTTI is disabled offset = self.tablegroup.tables[i].offset_to_top except: break idc.AddStrucMember(self.struct, "parent_{}".format(i), -offset, idc.FF_DATA, -1, idc.GetStrucSize(parent.struct)) idc.SetType(idc.GetMemberId(self.struct, -offset), parent.name)
def yatest_set_field_prototype(self): for field_type, name, prototype in set_field_prototype: sid = idc.AddStrucEx(-1, name, 0) self.assertNotEqual(sid, -1) self.assertEqual(idc.AddStrucMember(sid, 'field', 0, field_type | idaapi.FF_DATA, -1, get_size(field_type, -1)), 0) mid = idc.GetMemberId(sid, 0) self.assertNotEqual(mid, -1) self.assertTrue(idc.SetType(mid, prototype))
def struct_add_struct(sid, name, offset, msid, count=1): """Add a structure member to a structure. If sid is a union, offset must be -1. """ size = idc.GetStrucSize(msid) return idc.AddStrucMember(sid, name, offset, idc.FF_DATA | idc.FF_STRU, msid, size * count)
def create_field(self, sid, offset, name, ftype, strid, count): if ftype is None or name is None: return name = 'field_%.04X_%s' % (offset, name) size = get_size(ftype, strid) if ftype is not None else 1 self.assertEqual( idc.AddStrucMember(sid, name, offset, ftype | idaapi.FF_DATA, strid, size * count), 0)
def find_WdfDriverCreate(): function_offset = OFFSET_WdfDriverCreate # If the XREF to wdfFunctions + function_offset exists.. then we're in case 1! try: call_pfnWdfDriverCreate = idautils.XrefsTo(g_vars["_WDFFUNCTIONS"]+function_offset).next().frm except StopIteration: # this is case 2! call_pfnWdfDriverCreate = find_wdf_callback_through_immediate("mov", 1,function_offset) if call_pfnWdfDriverCreate != None: idc.OpStroffEx(call_pfnWdfDriverCreate,1,(idaapi.get_struc_id("_WDFFUNCTIONS")),0) else: call_pfnWdfDriverCreate = find_wdf_callback_through_immediate("call", 0, function_offset) idc.OpStroffEx(call_pfnWdfDriverCreate,0,(idaapi.get_struc_id("_WDFFUNCTIONS")),0) if call_pfnWdfDriverCreate != None: # First identify the RealDriverEntry :) current_func = idaapi.get_func(call_pfnWdfDriverCreate) idc.MakeName(current_func.startEA, "_DriverEntry_") argument_DriverConfig_addr = find_function_arg_with_operand_value(call_pfnWdfDriverCreate, "mov", "rsp", 0x20, 0) register_DriverConfig = idc.GetOpnd(argument_DriverConfig_addr, 1) lea_DriverConfig_addr = find_function_arg(argument_DriverConfig_addr, "lea", register_DriverConfig, 0) # Get stack and the stack operand offset current_func = idaapi.get_func(lea_DriverConfig_addr) stack_id = idc.GetFrame(current_func) opnd = idc.GetOpnd(lea_DriverConfig_addr, 1) if "rsp" in opnd: stack_member_offset = idc.GetOperandValue(lea_DriverConfig_addr, 1) elif "rbp" in opnd: var_x = opnd.split("+")[-1][:-1] # [rbp+57h+var_80] -> var_80 members, _ = retrieve_stack_members(current_func) inverted_members = {v:k for k, v in members.items()} try: stack_member_offset = inverted_members[var_x] except KeyError as msg: print msg return else: print("+] WdfDriverCreate() Unidentified register stack layout") return #idc.SetMemberName(stack_id, stack_member_offset, "_DriverConfig") struct_id = idaapi.get_struc_id("_WDF_DRIVER_CONFIG") struct_size = idc.GetStrucSize(struct_id) # First check if we have already touch this function stack before #if function_stack_erased(current_func): # need to take care of the already defined structs # pass #else: delete_all_function_stack_members(current_func, force=True) idc.AddStrucMember(stack_id, "driver_config", stack_member_offset, idc.FF_BYTE|idc.FF_DATA, -1, struct_size) idc.SetMemberType(stack_id, stack_member_offset, idc.FF_STRU|idc.FF_DATA, struct_id, 1)
def create_DISPFUNC_struct(name): sid = find_or_create_struct(name) idc.AddStrucMember(sid, "FuncName", 0, idc.FF_DWRD | FF_0OFF, -1, 4) idc.AddStrucMember(sid, "DISPID", 4, idc.FF_DWRD, -1, 4) idc.AddStrucMember(sid, "vtsParam", 8, idc.FF_DWRD, -1, 4) idc.AddStrucMember(sid, "vtRetVal", 0xC, idc.FF_DWRD, -1, 4) idc.AddStrucMember(sid, "pfnMember", 0x10, idc.FF_DWRD | FF_0OFF, -1, 4) idc.AddStrucMember(sid, "pfn", 0x14, idc.FF_DWRD | FF_0OFF, -1, 4) idc.AddStrucMember(sid, "filed18", 0x18, idc.FF_DWRD, -1, 4) idc.AddStrucMember(sid, "afxDispCustom", 0x1C, idc.FF_DWRD, -1, 4) return sid
def checkVtblStruct(self, descr): if not descr.get('vtblid'): descr['vtblnm'] = descr['name'] + 'Vtbl' descr['vtblid'] = idc.AddStrucEx(-1, descr['vtblnm'], 0) idc.AddStrucMember(descr['vtblid'], "queryi", 0, idc.FF_QWRD, -1, 8) if not descr.get('id'): descr['id'] = idc.AddStrucEx(-1, descr['name'], 0) self.setStrucPntr(descr['id'], 0, 'vtbl', descr['vtblnm'] + '*') return descr
def yatest_create_struct_field(self): for offset, count, field_type, string_type, comment, repeatable in create_field: size = count * get_size(field_type, string_type) name = get_name(field_type, string_type, offset, size) sid = idc.AddStrucEx(0, 'struct_' + name, 0) self.assertNotEqual(sid, -1) err = idc.AddStrucMember(sid, 'field_' + name, offset, field_type | idaapi.FF_DATA, string_type, size) self.assertEqual(err, 0) if comment is not None: self.assertNotEqual(idc.SetMemberComment(sid, offset, comment, repeatable), 0)
def yatest_reference_loop(self): mids = [] for k in range(0, 2): sid = idc.AddStrucEx(-1, 'refloop' + str(k), 0) self.assertNotEqual(sid, -1) self.assertEqual(idc.AddStrucMember(sid, 'refloop_field' + str(k), 0, idaapi.FF_DWRD, -1, 4), 0) mid = idc.GetMemberId(sid, 0) self.assertNotEqual(mid, -1) mids.append(mid) for k in range(0, 2): self.assertTrue(idc.SetType(mids[k], 'refloop' + str(1 - k) + ' *'))
def create_struc(name, size, default_type=idaapi.FF_DWRD): sid = idc.GetStrucIdByName(name) if sid != idaapi.BADADDR: idc.DelStruc(sid) idx = idc.AddStrucEx(idaapi.BADADDR, name, False) i = 0 while i < size: idc.AddStrucMember(idx, 'field_{0}'.format(hex(i)), i, default_type | idaapi.FF_DATA, -1, data_types[default_type]) i += data_types[default_type]
def makeStructFromHits(self, count, startHitIdx, endHitIdx): structName = 'sc%d' % count self.logger.debug("Making struct %d:", count) structId = idc.AddStrucEx(0xffffffff, structName, 0) if structId == 0xffffffff: raise ValueError("Struct %s already exists!" % structName) subRange = self.hits[startHitIdx:endHitIdx] for i in range(len(subRange)): hit = subRange[i] self.logger.debug("%02x: %08x: %08x %s" , i*self.PTR_SIZE, hit.ea, hit.symHash.hashVal, hit.symHash.symbolName) idc.AddStrucMember(structId, str(hit.symHash.symbolName), i*self.PTR_SIZE, idc.FF_DATA|idc.FF_DWRD, -1, 4)
def find_WdfIoQueueCreate(): function_offset = OFFSET_WdfIoQueueCreate calls_to_pfn_list = [] try: for xref in idautils.XrefsTo(g_vars["_WDFFUNCTIONS"] + function_offset): call_pfnWdfIoQueueCreate = xref.frm calls_to_pfn_list.append(call_pfnWdfIoQueueCreate) except StopIteration: # this is case 2 or 3 pass if len(calls_to_pfn_list) == 0: call_pfnWdfIoQueueCreate = find_wdf_callback_through_immediate( "call", 0, function_offset) if call_pfnWdfIoQueueCreate: calls_to_pfn_list.append(call_pfnWdfIoQueueCreate) idc.OpStroffEx(call_pfnWdfIoQueueCreate, 0, (idaapi.get_struc_id("_WDFFUNCTIONS")), 0) if len(calls_to_pfn_list) == 0: call_pfnWdfIoQueueCreate = find_wdf_callback_through_immediate( "mov", 1, function_offset) if call_pfnWdfIoQueueCreate: calls_to_pfn_list.append(call_pfnWdfIoQueueCreate) idc.OpStroffEx(call_pfnWdfIoQueueCreate, 1, (idaapi.get_struc_id("_WDFFUNCTIONS")), 0) for pfn_call in calls_to_pfn_list: lea_argument_addr = find_function_arg(pfn_call, "lea", "r8", 0) # Get stack and the stack operand offset current_func = idaapi.get_func(lea_argument_addr) stack_id = idc.GetFrame(current_func) stack_member_offset = idc.get_operand_value(lea_argument_addr, 1) struct_id = idaapi.get_struc_id("_WDF_IO_QUEUE_CONFIG") struct_size = idc.GetStrucSize(struct_id) # First check if we have already touch this function stack before if function_stack_erased(current_func): # need to take care of the already defined structs # If the arguments collide then this will fail pass else: delete_all_function_stack_members(current_func) print("Erased the stack members") idc.AddStrucMember(stack_id, "queue_config", stack_member_offset, idc.FF_BYTE | idc.FF_DATA, -1, struct_size) idc.SetMemberType(stack_id, stack_member_offset, idc.FF_STRU | idc.FF_DATA, struct_id, 1) print("IOQueue Creation at: " + hex(pfn_call))
def struct_add_ptr(sid, name, offset, count=1, type=None): """Add a pointer to a structure. If sid is a union, offset must be -1. """ ptr_flag = idc.FF_DATA | word_flag(WORD_SIZE) | idaapi.offflag() ret = idc.AddStrucMember(sid, name, offset, ptr_flag, 0, WORD_SIZE) if ret == 0 and type is not None: if offset == -1: offset = struct_member_offset(sid, name) assert offset is not None mid = idc.GetMemberId(sid, offset) idc.SetType(mid, type) return ret
def setStrucPntr(self, sid, ofs, name, tp=None): vnm = idc.GetMemberName(sid, ofs) if not vnm or vnm in (idc.BADADDR, -1): idc.AddStrucMember(sid, name, ofs, idc.FF_QWRD, -1, 8) vnm = name if vnm != name: idc.SetMemberName(sid, ofs, name) sz = idc.GetMemberSize(sid, ofs) if sz != 8: idc.SetMemberType(sid, ofs, idc.FF_QWRD, -1, 1) mid = idc.GetMemberId(sid, ofs) t = idc.GetType(mid) or '' if tp and t.replace(' ', '') != tp.replace(' ', ''): idc.SetType(mid, tp + ';')
def new_struct(name, nb_field, field_size, is_union=False): type_by_size = { 1: idc.FF_BYTE, 2: idc.FF_WORD, 4: idc.FF_DWRD, 8: idc.FF_QWRD } if field_size not in type_by_size: raise ValueError("field size muste be {0}".format(list(type_by_size))) sid = idc.AddStrucEx(-1, name, is_union) if sid == -1: # handle if name is already taken ? raise ValueError('bad name <{0}> for struct name'.format(name)) for i in range(nb_field): idc.AddStrucMember(sid, 'field_{0}'.format(i), i * field_size, idc.FF_DATA | type_by_size[field_size], -1, field_size) return sid
def makeStructFromHits(self, count, startHitIdx, endHitIdx): structName = 'sc%d' % count logger.debug("Making struct %d:", count) if using_ida7api: structId = idc.add_struc(0xffffffff, structName, 0) else: structId = idc.AddStrucEx(0xffffffff, structName, 0) if structId == 0xffffffff: raise ValueError("Struct %s already exists!" % structName) subRange = self.hits[startHitIdx:endHitIdx] for i in range(len(subRange)): hit = subRange[i] logger.debug("%02x: %08x: %08x %s" , i*self.ptrSize, hit.ea, hit.symHash.hashVal, hit.symHash.symbolName) if using_ida7api: idc.add_struc_member(structId, str(hit.symHash.symbolName), i*self.ptrSize, idc.FF_DATA|idc.FF_DWORD, -1, 4) else: idc.AddStrucMember(structId, str(hit.symHash.symbolName), i*self.ptrSize, idc.FF_DATA|idc.FF_DWRD, -1, 4)
def make_struc(self, object_version, address): name = object_version.get_name() object_id = object_version.get_id() size = object_version.get_size() struc_id = idc.GetStrucIdByName(name) if struc_id == idc.BADADDR: try: is_union = object_version.get_object_flags() except KeyError: is_union = 0 struc_id = idc.AddStrucEx(0, name, is_union) # add a dummy field. # This is necessary to avoid an error is idc.SetType(struc*) is used on another struc # member # TODO not for empty strucs if is_union: idc.AddStrucMember(struc_id, "yaco_filler", 0, idc.FF_BYTE, 0, 1) else: is_union = idc.IsUnion(struc_id) # if(is_union): # pass # else: # self.clear_struc_fields(struc_id, object_version['xrefs'], is_union) if not is_union or is_union == 0: self.clear_struc_fields( struc_id, size, object_version.get_xrefed_id_map().iterkeys(), False) else: self.union_ids.add(struc_id) if DEBUG_EXPORTER: logger.debug( "adding struc id %s : '0x%.016X' (%s)" % (self.hash_provider.hash_to_string(object_id), struc_id, name)) self.struc_ids[object_id] = struc_id _yatools_ida_exporter.set_struct_id(object_id, struc_id) self.hash_provider.put_hash_struc_or_enum(struc_id, object_id)
def create_vtable_struct(class_name, functions): struct_name = 'vtable_' + class_name sid = idc.GetStrucIdByName(struct_name) if sid != BADADDR: print("vtable already exists for " + class_name) return 0 sid = idc.AddStrucEx(-1, struct_name, 0) idc.Til2Idb(-1, struct_name) offset = 0 for fn in functions: func_name = fn[0] func_name = func_name.replace('~', 'destr_') func_type = fn[1] idc.AddStrucMember(sid, func_name, -1, idc.FF_QWRD, -1, 8) if func_type != '': if func_type.find("__cdecl(") > -1: func_type = func_type.replace("__cdecl", "(__cdecl *%s)" % func_name) elif func_type.find("__stdcall(") > -1: func_type = func_type.replace("__stdcall", "(__stdcall *%s)" % func_name) elif func_type.find("__fastcall(") > -1: func_type = func_type.replace("__fastcall", "(__fastcall *%s)" % func_name) elif func_type.find("__thiscall(") > -1: func_type = func_type.replace("__thiscall", "(__thiscall *%s)" % func_name) elif func_type.find("__usercall(") > -1: func_type = func_type.replace("__usercall", "(__usercall *%s)" % func_name) elif func_type.find("__userpurge(") > -1: func_type = func_type.replace("__userpurge", "(__userpurge *%s)" % func_name) SetType(GetMemberId(sid, offset), func_type) # MakeComm(GetMemberId(sid, offset), func_name) # "__int64 (__fastcall *)(ClassName *this)"); offset += 8 print(fn) return 1
def makeStruct(strname=""): ''' Función para crear la estructura de Gustavo en IDA con idc. @param strname: nombre de la estructura @return: 0-todo bien, -1-caca ''' sid = idc.GetStrucIdByName(strname) if sid == idc.BADADDR: sid = idc.AddStrucEx(-1, strname, 0) else: print "[-] Error. Structure %s already exists." % strname return -1 print idc.AddStrucMember(sid, "instructionType", -1, idc.FF_BYTE, -1, 1) print idc.AddStrucMember(sid, "hashSha", -1, idc.FF_BYTE, -1, 20) print idc.AddStrucMember(sid, "instructionSize", -1, idc.FF_BYTE, -1, 1) print idc.AddStrucMember(sid, "branchHash", -1, idc.FF_BYTE, -1, 20) print idc.AddStrucMember(sid, "nextHash", -1, idc.FF_BYTE, -1, 20) print idc.AddStrucMember(sid, "salt", -1, idc.FF_DWRD, -1, 4) return 0
def add_struct_member(sid, name, offset, size): failure = idc.AddStrucMember(sid, name, offset, size_to_flags(size), -1, size) if failure: raise struct_member_error(failure, sid, name, offset, size)
def make_struc_member(self, object_version, address, member_type=ya.OBJECT_TYPE_STRUCT_MEMBER): struc_object_id = object_version.get_parent_object_id() struc_id = 0 try: struc_id = self.struc_ids[struc_object_id] except: return is_union = struc_id in self.union_ids offset = address if is_union: last_offset = idc.GetLastMember(struc_id) if last_offset == idc.BADADDR: last_offset = -1 if last_offset < offset: for i in xrange(last_offset + 1, offset + 1): idc.AddStrucMember(struc_id, "yaco_filler_%d" % i, 0, idc.FF_BYTE | idc.FF_DATA, -1, 1) # ensure that 'offset' fields are present member_size = object_version.get_size() member_name = object_version.get_name() flags = object_version.get_object_flags() if idc.isStruct(flags): # if the sub field is a struct, it must have a single Xref field with the struct object id try: sub_struc_object_id = object_version.getXRefIdsAt(0, 0)[0] sub_struc_id = self.struc_ids[sub_struc_object_id] # logger.debug("%20s: adding sub member at offset 0x%08X, # size=0x%08X (sub=0x%.016X, size=0x%08X) with name %s" % # ( # idc.GetStrucName(struc_id), offset, member_size, sub_struc_id, # idc.GetStrucSize(sub_struc_id), object_version.get_name() # )) sub_struc_size = idc.GetStrucSize(sub_struc_id) if sub_struc_size == 0: logger.error( "%20s: adding sub member at offset 0x%08X, size=0x%08X " "(sub=0x%.016X, size=0x%08X) with name %s : sub struc size is ZERO" % (idc.GetStrucName(struc_id), offset, member_size, sub_struc_id, idc.GetStrucSize(sub_struc_id), object_version.get_name())) else: nitems = member_size / sub_struc_size YaToolIDATools.SetStrucmember(struc_id, member_name, offset, flags, sub_struc_id, nitems) except KeyError: logger.error( "Error while looking for sub struc in struc %s, offset 0x%08X (field name='%s')" % (self.hash_provider.hash_to_string(struc_object_id), offset, object_version.get_name())) traceback.print_exc() elif idc.isEnum0(flags): # an enum is applied here try: sub_enum_object_id = object_version.getXRefIdsAt(0, 0)[0] sub_enum_id = self.enum_ids[sub_enum_object_id] name_ok = idc.SetMemberName(struc_id, offset, member_name) if name_ok is not True: logger.debug( "Error while setting member name (enum) : " "(struc=%s, member=%s, offset=0x%08X, mflags=%d, msize=%d, tid=0x%016X" % (name_ok, idc.GetStrucName(struc_id), member_name, offset, flags, member_size, sub_struc_id)) else: sub_enum_size = idc.GetEnumWidth(sub_enum_id) if sub_enum_size == 0: sub_enum_size = member_size nitems = member_size / sub_enum_size ret = idc.SetMemberType(struc_id, offset, flags, sub_enum_id, nitems) if ret == 0: logger.debug( "Error while setting member type (enum) : " "(struc=%s, member=%s, offset=0x%08X, mflags=%d, msize=%d, tid=0x%016X" % (ret, idc.GetStrucName(struc_id), member_name, offset, flags, member_size, sub_struc_id)) except KeyError: logger.error( "Error while looking for sub enum in struc %s, offset 0x%08X (field name='%s')" % (struc_object_id, offset, member_name)) traceback.print_exc() else: # logger.debug("%20s: adding member at offset 0x%08X, size=0x%08X with name %s" % # ( # idc.GetStrucName(struc_id), offset, member_size, object_version.get_name() # )) tid = -1 if idc.isASCII(flags): logger.debug( "object: %s : %s" % (self.hash_provider.hash_to_string( object_version.get_id()), object_version.get_name())) try: tid = object_version.get_string_type() except KeyError: tid = idc.ASCSTR_C name_ok = idc.SetMemberName(struc_id, offset, member_name) if name_ok is not True: logger.debug( "Error while setting member name :" + " (struc_id=0x%08X, struc=%s, member=%s, offset=0x%08X, mflags=%d, msize=%d)" % (struc_id, idc.GetStrucName(struc_id), member_name, offset, flags, member_size)) else: item_size = YaToolIDATools.get_field_size(flags, tid) nitems = member_size / item_size # IDA BUG : 4-byte chars are stored as 2 double words, thus me must # multiply nitem by 2! ret = idc.SetMemberType(struc_id, offset, flags, tid, nitems) if ret == 0: logger.debug( "Error while setting member type :" + " (struc=%s, member=%s, offset=0x%08X, mflags=%d, msize=%d)" % (idc.GetStrucName(struc_id), member_name, offset, flags, member_size)) try: repeatable_headercomment = self.sanitize_comment_to_ascii( object_version.get_header_comment(True)) idc.SetMemberComment(struc_id, offset, repeatable_headercomment, 1) except KeyError: pass try: nonrepeatable_headercomment = self.sanitize_comment_to_ascii( object_version.get_header_comment(False)) idc.SetMemberComment(struc_id, offset, nonrepeatable_headercomment, 0) except KeyError: pass member_id = idc.GetMemberId(struc_id, offset) self.set_struct_member_type(object_version, member_id) if object_version.get_type() == ya.OBJECT_TYPE_STRUCT_MEMBER: self.strucmember_ids[object_version.get_id()] = member_id