Beispiel #1
0
 def __call__(self):
     if self.op == "hex":
         ida_bytes.op_hex(self.ea, self.n)
     if self.op == "bin":
         ida_bytes.op_bin(self.ea, self.n)
     if self.op == "dec":
         ida_bytes.op_dec(self.ea, self.n)
     if self.op == "chr":
         ida_bytes.op_chr(self.ea, self.n)
     if self.op == "oct":
         ida_bytes.op_oct(self.ea, self.n)
     if self.op == "offset":
         ida_idc.op_plain_offset(self.ea, self.n, 0)
     if self.op == "enum":
         id = ida_enum.get_enum(self.extra["ename"])
         ida_bytes.op_enum(self.ea, self.n, id, self.extra["serial"])
     if self.op == "struct":
         path_len = len(self.extra["spath"])
         path = ida_pro.tid_array(path_len)
         for i in range(path_len):
             sname = self.extra["spath"][i]
             path[i] = ida_struct.get_struc_id(sname)
         insn = ida_ua.insn_t()
         ida_ua.decode_insn(insn, self.ea)
         ida_bytes.op_stroff(insn, self.n, path.cast(), path_len,
                             self.extra["delta"])
     if self.op == "stkvar":
         ida_bytes.op_stkvar(self.ea, self.n)
 def __call__(self):
     if self.op == 'hex':
         ida_bytes.op_hex(self.ea, self.n)
     if self.op == 'bin':
         ida_bytes.op_bin(self.ea, self.n)
     if self.op == 'dec':
         ida_bytes.op_dec(self.ea, self.n)
     if self.op == 'chr':
         ida_bytes.op_chr(self.ea, self.n)
     if self.op == 'oct':
         ida_bytes.op_oct(self.ea, self.n)
     if self.op == 'enum':
         id = ida_enum.get_enum(Event.encode(self.extra['ename']))
         ida_bytes.op_enum(self.ea, self.n, id, self.extra['serial'])
     if self.op == 'struct':
         path_len = len(self.extra['spath'])
         path = ida_pro.tid_array(path_len)
         for i in xrange(path_len):
             sname = Event.encode(self.extra['spath'][i])
             path[i] = ida_struct.get_struc_id(sname)
         insn = ida_ua.insn_t()
         ida_ua.decode_insn(insn, self.ea)
         ida_bytes.op_stroff(insn, self.n, path.cast(), path_len,
                             self.extra['delta'])
     if self.op == 'stkvar':
         ida_bytes.op_stkvar(self.ea, self.n)
Beispiel #3
0
 def _on_optypechanged(self, ea, n, op, extra):
     if op == 'hex':
         ida_bytes.op_hex(ea, n)
     if op == 'bin':
         ida_bytes.op_bin(ea, n)
     if op == 'dec':
         ida_bytes.op_dec(ea, n)
     if op == 'chr':
         ida_bytes.op_chr(ea, n)
     if op == 'oct':
         ida_bytes.op_oct(ea, n)
     if op == 'stkvar':
         ida_bytes.op_stkvar(ea, n)
     if op == 'enum':
         enum_id = ida_enum.get_enum(str(extra['ename']))
         ida_bytes.op_enum(ea, n, enum_id, extra['serial'])
     if op == 'struct':
         path_length = len(extra['spath'])
         path = ida_pro.tid_array(path_length)
         for i in range(path_length):
             sname = str(extra['spath'][i])
             path[i] = ida_struct.get_struc_id(sname)
         insn = ida_ua.insn_t()
         ida_ua.decode_insn(insn, ea)
         ida_bytes.op_stroff(insn, n, path.cast(), path_length,
                             extra['delta'])
Beispiel #4
0
def apply_struct_offset(inst, operand_no, struct_name):
    if not import_type(struct_name):
        print "ERROR: Can't import '{}'".format(struct_name)
        return
    path_len = 1
    path = ida_pro.tid_array(path_len)
    path[0] = ida_struct.get_struc_id(struct_name)
    ida_bytes.op_stroff(inst, operand_no, path.cast(), path_len, 0)
Beispiel #5
0
    def op_type_changed(self, ea, n):
        self._plugin.logger.debug("op_type_changed(ea = %x, n = %d)" % (ea, n))

        def gather_enum_info(ea, n):
            id = ida_bytes.get_enum_id(ea, n)[0]
            serial = ida_enum.get_enum_idx(id)
            return id, serial

        extra = {}
        mask = ida_bytes.MS_0TYPE if not n else ida_bytes.MS_1TYPE
        flags = ida_bytes.get_full_flags(ea)
        self._plugin.logger.debug("op_type_changed: flags = 0x%X)" % flags)

        def is_flag(type):
            return flags & mask == mask & type

        if is_flag(ida_bytes.hex_flag()):
            op = "hex"
        elif is_flag(ida_bytes.dec_flag()):
            op = "dec"
        elif is_flag(ida_bytes.char_flag()):
            op = "chr"
        elif is_flag(ida_bytes.bin_flag()):
            op = "bin"
        elif is_flag(ida_bytes.oct_flag()):
            op = "oct"
        elif is_flag(ida_bytes.off_flag()):
            op = "offset"
        elif is_flag(ida_bytes.enum_flag()):
            op = "enum"
            id, serial = gather_enum_info(ea, n)
            ename = ida_enum.get_enum_name(id)
            extra["ename"] = Event.decode(ename)
            extra["serial"] = serial
        elif flags & ida_bytes.stroff_flag():
            op = "struct"
            path = ida_pro.tid_array(1)
            delta = ida_pro.sval_pointer()
            path_len = ida_bytes.get_stroff_path(path.cast(), delta.cast(), ea,
                                                 n)
            spath = []
            for i in range(path_len):
                sname = ida_struct.get_struc_name(path[i])
                spath.append(Event.decode(sname))
            extra["delta"] = delta.value()
            extra["spath"] = spath
        elif is_flag(ida_bytes.stkvar_flag()):
            op = "stkvar"
        # FIXME: No hooks are called when inverting sign
        # elif ida_bytes.is_invsign(ea, flags, n):
        #     op = 'invert_sign'
        else:
            return 0  # FIXME: Find a better way to do this
        self._send_packet(evt.OpTypeChangedEvent(ea, n, op, extra))
        return 0
Beispiel #6
0
    def op_type_changed(self, ea, n):
        def gather_enum_info(ea, n):
            id = ida_bytes.get_enum_id(ea, n)[0]
            serial = ida_enum.get_enum_idx(id)
            return id, serial

        extra = {}
        mask = ida_bytes.MS_0TYPE if not n else ida_bytes.MS_1TYPE
        flags = ida_bytes.get_full_flags(ea) & mask

        def is_flag(type):
            return flags == mask & type

        if is_flag(ida_bytes.hex_flag()):
            op = 'hex'
        elif is_flag(ida_bytes.dec_flag()):
            op = 'dec'
        elif is_flag(ida_bytes.char_flag()):
            op = 'chr'
        elif is_flag(ida_bytes.bin_flag()):
            op = 'bin'
        elif is_flag(ida_bytes.oct_flag()):
            op = 'oct'
        elif is_flag(ida_bytes.enum_flag()):
            op = 'enum'
            id, serial = gather_enum_info(ea, n)
            ename = ida_enum.get_enum_name(id)
            extra['ename'] = Event.decode(ename)
            extra['serial'] = serial
        elif is_flag(flags & ida_bytes.stroff_flag()):
            op = 'struct'
            path = ida_pro.tid_array(1)
            delta = ida_pro.sval_pointer()
            path_len = ida_bytes.get_stroff_path(path.cast(), delta.cast(), ea,
                                                 n)
            spath = []
            for i in range(path_len):
                sname = ida_struct.get_struc_name(path[i])
                spath.append(Event.decode(sname))
            extra['delta'] = delta.value()
            extra['spath'] = spath
        elif is_flag(ida_bytes.stkvar_flag()):
            op = 'stkvar'
        # IDA hooks for is_invsign seems broken
        # Inverting sign don't trigger the hook
        # elif ida_bytes.is_invsign(ea, flags, n):
        #     op = 'invert_sign'
        else:
            return 0  # FIXME: Find a better way
        self._send_event(OpTypeChangedEvent(ea, n, op, extra))
        return 0
Beispiel #7
0
    def op_type_changed(self, ea, n):
        extra = {}
        mask = ida_bytes.MS_0TYPE if not n else ida_bytes.MS_1TYPE
        flags = ida_bytes.get_full_flags(ea) & mask

        if flags == mask & ida_bytes.hex_flag():
            op = 'hex'
        elif flags == mask & ida_bytes.dec_flag():
            op = 'dec'
        elif flags == mask & ida_bytes.char_flag():
            op = 'chr'
        elif flags == mask & ida_bytes.bin_flag():
            op = 'bin'
        elif flags == mask & ida_bytes.oct_flag():
            op = 'oct'
        elif flags == mask & ida_bytes.enum_flag():
            op = 'enum'
            enum_id = ida_bytes.get_enum_id(ea, n)[0]
            enum_serial = ida_enum.get_enum_idx(enum_id)
            ename = ida_enum.get_enum_name(enum_id)
            extra['ename'] = Unicoder.decode(ename)
            extra['serial'] = enum_serial
        elif flags == mask & ida_bytes.stroff_flag():
            op = 'struct'
            path = ida_pro.tid_array(1)
            delta = ida_pro.sval_pointer()
            path_len = ida_bytes.get_stroff_path(path.cast(), delta.cast(), ea,
                                                 n)
            spath = []
            for i in range(path_len):
                sname = ida_struct.get_struc_name(path[i])
                spath.append(Unicoder.decode(sname))
            extra['delta'] = delta.value()
            extra['spath'] = spath
        elif flags == mask & ida_bytes.stkvar_flag():
            op = 'stkvar'
        else:
            return 0
        self._network.send_event(
            EventType.OPTYPECHANGED,
            ea=ea,
            n=n,
            op=Unicoder.decode(op),
            extra=extra,
        )
        return 0
Beispiel #8
0
    def analyze_function_frame(self, function: Function) -> None:
        """
        inspect the given function to determine the frame layout and set references appropriately.

        args:
          function (Function): function instance.
        """
        # given a function prologue like the following:
        #
        #     23 80 80 80 80 00       get_global          $global0
        #     21 04                   set_local           $local4
        #     41 20                   i32.const           0x20
        #     21 05                   set_local           $local5
        #     20 04                   get_local           $local4
        #     20 05                   get_local           $local5
        #     6B                      i32.sub
        #     21 06                   set_local           $local6
        #
        # recognize that the function frame is 0x20 bytes.

        if not self.has_llvm_prologue(function):
            return

        bc = self.get_prologue_bc(function['offset'])
        if len(bc) == 0:
            return

        global_frame_pointer = bc[0].imm.global_index
        frame_size = bc[2].imm.value
        local_frame_pointer = bc[7].imm.local_index

        # add a frame structure to the function
        f = ida_funcs.get_func(function['offset'])
        ida_frame.add_frame(f, 0x0, 0x0, frame_size)
        ida_struct.set_struc_name(f.frame, 'frame%d' % function['index'])

        # ensure global variable $frame_stack is named appropriately
        ida_name.set_name(self.proc.globals[global_frame_pointer]['offset'],
                          '$frame_stack')

        # re-map local variable to $frame_pointer
        ida_frame.add_regvar(f, function['offset'],
                             function['offset'] + function['size'],
                             '$local%d' % local_frame_pointer,
                             '$frame_pointer', '')

        # define the frame structure layout by scanning for references within this function
        frame_references = self.find_function_frame_references(
            function, local_frame_pointer)
        for frame_offset, refs in frame_references.items():

            member_name = 'field_%x' % frame_offset
            for ref in refs:
                if 'parameter' in ref:
                    member_name = 'param%d' % (ref['parameter'])

            # pick largest element size for the element type
            flags = 0
            size = 0
            for ref in refs:
                fl = {
                    'i8': ida_bytes.FF_BYTE | ida_bytes.FF_DATA,
                    'i16': ida_bytes.FF_WORD | ida_bytes.FF_DATA,
                    'i32': ida_bytes.FF_DWORD | ida_bytes.FF_DATA,
                    'i64': ida_bytes.FF_QWORD | ida_bytes.FF_DATA,
                    'f32': ida_bytes.FF_FLOAT | ida_bytes.FF_DATA,
                    'f64': ida_bytes.FF_DOUBLE | ida_bytes.FF_DATA,
                }[ref['element_size']]

                s = {
                    'i8': 1,
                    'i16': 2,
                    'i32': 4,
                    'i64': 8,
                    'f32': 4,
                    'f64': 8,
                }[ref['element_size']]

                # by luck, FF_BYTE < FF_WORD < FF_DWORD < FF_QWORD,
                # so we can order flag values.
                if fl > flags:
                    flags = fl
                    size = s

            logger.debug('adding frame member %s to function %d', member_name,
                         function['index'])
            ida_struct.add_struc_member(ida_struct.get_struc(f.frame),
                                        member_name, frame_offset,
                                        flags & 0xFFFFFFFF, None, size)

        # mark struct references
        for refs in frame_references.values():
            for ref in refs:
                # set type of operand 0 to function frame structure offset
                # ref: https://github.com/idapython/src/blob/a3855ab969fd16758b3de007525feeba3a920344/tools/inject_pydoc/bytes.py#L5
                insn = ida_ua.insn_t()
                if not ida_ua.decode_insn(insn, ref['offset']):
                    continue

                path = ida_pro.tid_array(1)
                path[0] = f.frame
                ida_bytes.op_stroff(insn, 0, path.cast(), 1, 0)
Beispiel #9
0
def get_operand_struct_name(inst, op_no):
    path_len = 1
    path = ida_pro.tid_array(path_len)
    if ida_bytes.get_stroff_path(path.cast(), None, inst.ea, op_no):
        return ida_struct.get_struc_name(path[0])
    return ''