Exemplo n.º 1
0
 def makeInterface(self, offset):
     idc.SetType(offset, "interfaceType")
     ifaceid = ida_struct.get_struc_id("interfaceType")
     meth_offs = idc.get_member_offset(ifaceid, "methods")
     slice_id = ida_struct.get_struc_id("slice")
     size_off = idc.get_member_offset(slice_id, "len")
     size = self.stepper.ptr(offset + meth_offs + size_off)
     if size != 0:
         addr = self.getPtr(slice_id, offset + meth_offs, "data")
         idc.SetType(addr, "imethod")
         sz = ida_struct.get_struc_size(ida_struct.get_struc_id("imethod"))
         self.make_arr(addr, size, sz, "imethod")
         names = self.processIMethods(addr, size)
         # For now only for go1.7
         if names is None:
             return
         name = self.getName(offset)
         while name[0] == "*":
             name = name[1:]
         name = Utils.relaxName(name)
         name = "user_interface_" + name
         # TODO: this is for go1.7 need additional check for other versions
         fields = [("inter", "void *"), ("type", "void *"), ("link", "void *"), ("bad", "__int32"),
                   ("unused", "__int32")]
         for i in names:
             fields.append((i, "void *"))
         itype = [(name, fields)]
         self.settings.structCreator.createTypes(itype)
Exemplo n.º 2
0
 def parseFuncType(self, offset):
     return
     sid = ida_struct.get_struc_id("funcType")
     in_size = idc.Word(offset + idc.get_member_offset(sid, "incount"))
     out_size = idc.Word(offset + idc.get_member_offset(sid, "outcount"))
     sz = ida_struct.get_struc_size(sid)
     for i in xrange(in_size + out_size):
         idc.SetType(offset + sz + i * self.stepper.size, "type *")
Exemplo n.º 3
0
 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.add_struc_member(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.add_struc_member(sid, use_name, -1, i1, i2, i3)
         if new_type is not None:
             offset = idc.get_member_offset(sid, use_name)
             # print "Setting %s as %s" % (i[0], new_type)
             idc.SetType(idc.get_member_id(sid, offset), new_type)
Exemplo n.º 4
0
def _populate_wrapper_struct__slices(sid, classinfo):
    """Fill in the members of the wrapper struct."""
    # First add the vtable pointer.
    offset = 0
    vtable_ptr_type = '{}::vtable *'.format(classinfo.classname)
    ret = idau.struct_add_ptr(sid, 'vtable', offset, type=vtable_ptr_type)
    if ret not in (0, idc.STRUC_ERROR_MEMBER_OFFSET):
        _log(0, 'Could not create {}.vtable: {}', classinfo.classname, ret)
        return False
    # Now add all the ::fields structs.
    offset += idau.WORD_SIZE
    for ci in classinfo.ancestors(inclusive=True):
        # Get the sid of the ::fields struct.
        fields_sid = idau.struct_open(ci.classname + '::fields')
        if fields_sid is None:
            _log(0, 'Could not find {}::fields', ci.classname)
            return False
        # If this is a 0-length struct (no fields), skip it.
        size = ida_struct.get_struc_size(fields_sid)
        if size == 0:
            continue
        # If this is already in the wrapper struct, skip it. This avoids weird
        # STRUC_ERROR_MEMBER_VARLAST errors.
        if idc.get_member_offset(sid, ci.classname) != -1:
            continue
        # Add the ::fields struct to the wrapper.
        ret = idau.struct_add_struct(sid, ci.classname, offset, fields_sid)
        if ret != 0:
            _log(0, 'Could not create {}.{}: {}', classinfo.classname,
                 ci.classname, ret)
            return False
        offset += size
    return True
Exemplo n.º 5
0
 def getName(self, offset):
     sid = ida_struct.get_struc_id("type")
     string_addr = offset + idc.get_member_offset(sid, "string")
     ptr = self.stepper.ptr(string_addr)
     idc.SetType(ptr, "string")
     name = self.stepper.ptr(ptr)
     return idc.GetString(name)
Exemplo n.º 6
0
 def createUserTypeStruct(self, addr, name, size, self_size):
     fields = []
     sid = ida_struct.get_struc_id("structField")
     sz = ida_struct.get_struc_size(sid)
     sid_type = ida_struct.get_struc_id("type")
     fields = []
     curr_offset = 0
     idc.set_cmt(addr, name, 0)
     for i in range(size):
         fieldname = self.nameFromOffset(self.getPtr(sid, addr+i*sz,"Name"))
         type_addr = self.getPtr(sid, addr+i*sz, "typ")
         typename = self.getType(type_addr)
         size = self.getPtr(sid_type, type_addr, "size")
         if fieldname == "" or fieldname is None:
             fieldname = "unused_"+Utils.id_generator()
         offset = self.getStructFieldOffset(sid, addr+i*sz)
         print(f"Get offset: {offset:x}")
         if offset != curr_offset:
             print("Offset missmatch.Got %d expected %d. Adding padding..." % (curr_offset, offset))
             if offset < curr_offset:
                 raise("Too many bytes already")
             while offset != curr_offset:
                 fields.append(("padding", "char"))
                 curr_offset += 1
         curr_offset += size
         if size != 0:
             offset_kind = idc.get_member_offset(sid_type, "kind")
             kind_of_type = self.getKindEnumName(type_addr)
             print(kind_of_type)
             if kind_of_type == "STRUCT_": #Disabled for now
                 name_type = self.getName(type_addr)
                 while name_type[0] == "*":
                     name_type = name_type[1:]
                 name_type = Utils.relaxName(name_type)
                 name_type = "ut_" + name_type
                 #print("setting type %s" % name_type)
                 fields.append((fieldname, name_type))
             elif kind_of_type == "STRING":
                 fields.append((fieldname, "string"))
             elif kind_of_type == "SLICE":
                 fields.append((fieldname, "slice"))
             elif kind_of_type == "INTERFACE":
                 fields.append((fieldname, "__iface"))
             else:
                 fields.append((fieldname, "char [%d]" % size))
     if curr_offset != self_size:
         print("%x: Structure size mismatch: %x" % (addr, curr_offset))
         if self_size < curr_offset:
                 raise("Too many bytes already")
         while self_size != curr_offset:
             fields.append(("padding", "char"))
             curr_offset += 1    
     new_type = [(name, fields)]
     self.settings.structCreator.createTypes(new_type)
     new_type_sid = ida_struct.get_struc_id(name)
     sz = ida_struct.get_struc_size(new_type_sid)
     if sz != self_size:
         print("%x" % addr   )
         raise("Error at creating structure")
Exemplo n.º 7
0
 def getKindEnumName(self, addr):
     try:
         struc_id = ida_struct.get_struc_id("type")
         offset_kind = idc.get_member_offset(struc_id, "kind")
         kind = idc.get_wide_byte(addr + offset_kind) & 0x1F
         return self.settings.typer.standardEnums[0][1][kind]
     except IndexError as e:
         pass
Exemplo n.º 8
0
    def makeStructType(self, offset):
        idc.SetType(offset, "structType")
        sid = ida_struct.get_struc_id("structType")
        slice_id = ida_struct.get_struc_id("slice")
        offset_elem = idc.get_member_offset(sid, "fields")
        inner_offset = idc.get_member_offset(slice_id, "data")
        addr = self.stepper.ptr(offset_elem + offset + inner_offset)

        inner_offset = idc.get_member_offset(slice_id, "len")
        size = self.stepper.ptr(offset+offset_elem+inner_offset)
        if size == 0:
            return
        idc.SetType(addr, "structField")
        sz = ida_struct.get_struc_size(ida_struct.get_struc_id("structField"))
        self.make_arr(addr, size, sz, "structField")
        sid_type = ida_struct.get_struc_id("type")
        size_new_struct = self.getPtr(sid_type, offset, "size")
        for i in xrange(size):
            self.processStructField(addr, i*sz)
        name = self.getName(offset)
        name = Utils.relaxName(name)
        name = "ut_" + name
        self.createUserTypeStruct(addr, name, size, size_new_struct)
Exemplo n.º 9
0
def set_struct_offsets(offsets, sid):
    for offset in offsets:
        try:
            add_struct_member(sid, offset_name(offset), offset.offset,
                              offset.size)
        except exceptions.SarkErrorStructMemberName:
            # Get the offset of the member with the same name
            existing_offset = idc.get_member_offset(sid, offset_name(offset))
            if offset.offset == existing_offset:
                pass
            else:
                raise
        except exceptions.SarkErrorStructMemberOffset:
            # Get the size of the member at the same offset
            if offset.size == idc.get_member_size(sid, offset.offset):
                # If they are the same, all is well.
                pass
Exemplo n.º 10
0
 def getPtrToThis(self, sid, offset):
     memb_offs = idc.get_member_offset(sid, "ptrtothis")
     return idc.get_wide_dword(offset + memb_offs)
Exemplo n.º 11
0
 def getPtr(self, sid, addr, name):
     name_off = idc.get_member_offset(sid, name)
     return self.stepper.ptr(addr+name_off)
Exemplo n.º 12
0
 def getDword(self, sid, addr, name):
     name_off = idc.get_member_offset(sid, name)
     return idc.get_wide_dword(addr+name_off)
Exemplo n.º 13
0
def build_stack_variable(func_ea):
    stack_vars = dict()

    frame = idc.get_func_attr(func_ea, idc.FUNCATTR_FRAME)
    if not frame:
        return stack_vars

    f_name = get_symbol_name(func_ea)
    #grab the offset of the stored frame pointer, so that
    #we can correlate offsets correctly in referent code
    # e.g., EBP+(-0x4) will match up to the -0x4 offset
    delta = idc.get_member_offset(frame, " s")
    if delta == -1:
        delta = 0

    if f_name not in _FUNC_UNSAFE_LIST:
        offset = idc.get_first_member(frame)
        while -1 != _signed_from_unsigned(offset):
            member_name = idc.get_member_name(frame, offset)
            if member_name is None:
                offset = idc.get_next_offset(frame, offset)
                continue
            if (member_name == " r" or member_name == " s"):
                offset = idc.get_next_offset(frame, offset)
                continue

            member_size = idc.get_member_size(frame, offset)
            if offset >= delta:
                offset = idc.get_next_offset(frame, offset)
                continue

            member_flag = idc.get_member_flag(frame, offset)
            flag_str = _get_flags_from_bits(member_flag)
            member_offset = offset - delta
            stack_vars[member_offset] = {
                "name": member_name,
                "size": member_size,
                "flags": flag_str,
                "writes": list(),
                "referent": list(),
                "reads": list(),
                "safe": False
            }

            offset = idc.get_next_offset(frame, offset)
    else:
        offset = idc.get_first_member(frame)
        frame_size = idc.get_func_attr(func_ea, idc.FUNCATTR_FRSIZE)
        flag_str = ""
        member_offset = _signed_from_unsigned(offset) - delta
        stack_vars[member_offset] = {
            "name": f_name,
            "size": frame_size,
            "flags": flag_str,
            "writes": list(),
            "referent": list(),
            "reads": list(),
            "safe": False
        }

    return stack_vars
Exemplo n.º 14
0
 def __getitem__(self, item):
     if type(item) is str:
         return StructureMember(get_member_offset(self.__sid, item))
     raise NotImplementedError