Exemple #1
0
def set_operand_value(cpu_context, ip, value, opnd, optype, width=None):
    """
    Function to set the operand to the specified value.

    :param cpu_context: current context of cpu
    :param ip: instruction pointer
    :param value: value to set operand to
    :param opnd: value returned by idc.GetOpnd()
    :param optype: value returned by idc.GetOpType()
    :param width: byte width of the operand value being set

    """
    if optype == idc.o_reg:
        # Convert the value from string to integer...
        if isinstance(value, str):
            value = utils.struct_unpack(value)

        cpu_context.reg_write(opnd.upper(), value)

    elif optype in [idc.o_phrase, idc.o_displ]:
        # For data written to the frame or memory, this data MUST be in string form so convert it
        if numpy.issubdtype(type(value), numpy.integer):
            value = utils.struct_pack(value, signed=(value < 0), width=width)

        # These need to be handled in the same way even if they don't contain the same types of data.
        try:
            offset = utils.get_stack_offset(cpu_context, ip, 0)

        except ValueError:  # Not a stack variable, calculate the displacement and set it using .memctrlr
            addr = utils.calc_displacement(cpu_context, ip, 0)
            cpu_context.mem_write(addr, value)

        else:
            cpu_context.mem_write(offset, value)

    elif optype == idc.o_mem:
        # FS, GS are identified as memory addresses, rather use them as registers
        if "fs" in opnd:
            cpu_context.reg_write("FS", value)
        elif "gs" in opnd:
            cpu_context.reg_write("GS", value)
        else:
            if numpy.issubdtype(type(value), numpy.integer):
                value = utils.struct_pack(value,
                                          signed=(value < 0),
                                          width=width)

            cpu_context.mem_write(idc.GetOperandValue(ip, 0), value)

    elif optype == idc.o_imm:
        offset = idc.GetOperandValue(ip, 0)
        if idaapi.isLoaded(offset):
            cpu_context.mem_write(offset, value)
Exemple #2
0
def add_xrefs(addr, end=idc.BADADDR):
    """
        https://github.com/xyzz/vita-ida-physdump/blob/master/vita_phys_dump.py
        Searches for MOV / MOVT pair, probably separated by few instructions,
        and adds xrefs to things that look like addresses
    """
    while addr < end and addr != BADADDR:
        addr = idc.NextHead(addr)
        if idc.GetMnem(addr) in ["MOV", "MOVW"]:
            reg = idc.GetOpnd(addr, 0)
            if idc.GetOpnd(addr, 1)[0] != "#":
                continue
            val = idc.GetOperandValue(addr, 1)
            found = False
            next_addr = addr
            for x in range(16):
                next_addr = idc.NextHead(next_addr)
                if idc.GetMnem(next_addr) in ["B", "BX"]:
                    break
                # TODO: we could handle a lot more situations if we follow branches, but it's getting complicated
                # if there's a function call and our register is scratch, it will probably get corrupted, bail out
                if idc.GetMnem(next_addr) in ["BL", "BLX"] and reg in [
                        "R0", "R1", "R2", "R3"
                ]:
                    break
                # if we see a MOVT, do the match!
                if idc.GetMnem(next_addr) in ["MOVT",
                                              "MOVT.W"] and idc.GetOpnd(
                                                  next_addr, 0) == reg:
                    if idc.GetOpnd(next_addr, 1)[0] == "#":
                        found = True
                        val += idc.GetOperandValue(next_addr, 1) * (2**16)
                    break
                # if we see something other than MOVT doing something to the register, bail out
                if idc.GetOpnd(next_addr, 0) == reg or idc.GetOpnd(
                        next_addr, 1) == reg:
                    break
            if val & 0xFFFF0000 == 0:
                continue
            if found:
                # pair of MOV/MOVT
                try:
                    idc.OpOffEx(addr, 1, idc.REF_LOW16, val, 0, 0)
                    idc.OpOffEx(next_addr, 1, idc.REF_HIGH16, val, 0, 0)
                except:
                    print "Failed xref @ %x next_addr %x val %x" % (
                        addr, next_addr, val)
            else:
                # a single MOV instruction
                try:
                    idc.OpOff(addr, 1, 0)
                except:
                    print "Failed xref at addr %x" % (addr)
def mark_instruction(ea):
    ori_commt = idc.GetDisasm(ea)
    if '|' in ori_commt:  # be handled by this python script before
        ori_commt = ori_commt.split('|')[-1]
    elif ';' in ori_commt:
        ori_commt = ori_commt.split(';')[-1]
    else:
        ori_commt = ''

    commt = '(%s, %s), (%s, %s) |%s' % (opertype[idc.GetOpType(
        ea, 0)], idc.GetOperandValue(ea, 0), opertype[idc.GetOpType(
            ea, 1)], idc.GetOperandValue(ea, 1), ori_commt)
    idc.MakeComm(ea, commt)
Exemple #4
0
    def getCallInfo(self, xref_addr, tid):
        result = None
        target = 0
        callee_id = -1
        for thread in self["mem_areas"][0]['threads']:
            if tid == thread['tid']:
                for call in thread['calls']:
                    for xref in call['xrefs']:
                        if xref['addr'] == xref_addr:
                            target = call['target']
                            if len(xref["params"]):
                                if 'count' not in xref:
                                    xref['count'] = 0
                                callee_id = xref['count']
                                xref['count'] += 1
                            if len(call['name']):
                                result = call['name'].encode('ascii')
                            elif 'real_call' in call:
                                result = call['real_call']['name'].encode('ascii')
                                target = call['real_call']['target']
                            else:
                                result = idc.GetFunctionName(target)
                                if len(result) == 0:
                                    opval = idc.GetOperandValue(xref_addr, 0)
                                    if len(idc.get_name(opval)) > 0:
                                        result = idc.get_name(opval)
                                    else:
                                        result = "%x" % target
                            return result, target, callee_id

        return None, None, -1
Exemple #5
0
    def __mark_calls(self):
        for thread in self["mem_areas"][0]['threads']:
            for call in thread['calls']:

                if not call['returns']:
                    continue

                # generate name for the function
                fname = idc.GetFunctionName(call['target'])
                if len(fname) == 0:
                    if len(call["name"]) > 0:
                        fname = call["name"].encode('ascii')
                    else:
                        fname = "0x%x" % call["target"]
                
                # name all indirect calls
                for xref in call['xrefs']:
                    idc.MakeCode(xref['addr'])
                    op = idc.GetOpType(xref['addr'],0)
                    if op == ida_ua.o_mem:
                        val = idc.GetOperandValue(xref['addr'], 0)
                        vname = idc.get_name(val)
                        if val is not None and val > 0 and len(vname) > 0 and 'dword_' in vname:
                            idc.MakeName(val, fname)
                    elif op == ida_ua.o_reg or op == ida_ua.o_displ:
                        idc.MakeComm(xref['addr'], fname)
Exemple #6
0
def find_WdfControlDeviceInitAllocate():
    function_offset = OFFSET_WdfControlDeviceInitAllocate
    call_pfn = None
    try:
        for xref in idautils.XrefsTo(g_vars["_WDFFUNCTIONS"] +
                                     function_offset):
            call_pfn = xref.frm
    except StopIteration:
        # this is case 2 or 3
        pass
    if call_pfn is None:
        call_pfn = find_wdf_callback_through_immediate("call", 0,
                                                       function_offset)
        if call_pfn:
            idc.OpStroffEx(call_pfn, 0, (idaapi.get_struc_id("_WDFFUNCTIONS")),
                           0)

    if call_pfn is None:
        call_pfn = find_wdf_callback_through_immediate("mov", 1,
                                                       function_offset)
        if call_pfn:
            idc.OpStroffEx(call_pfn, 1, (idaapi.get_struc_id("_WDFFUNCTIONS")),
                           0)

    lea_sddl = find_function_arg(call_pfn, "lea", "r8", 0)
    unicode_sddl = idc.GetOperandValue(lea_sddl, 1)
    idc.MakeName(unicode_sddl, 'control_device_sddl')
    assign_struct_to_address(unicode_sddl, "_UNICODE_STRING")
    print("Control Device SDDL at: ", hex(unicode_sddl))
Exemple #7
0
 def handle_mov(self, state):
     """Updates the state of the stack string finding based on a mov instruction"""
     op1 = tracingutils.get_opnd_replacement(state.ea, POS_FIRST)
     if '[' in op1:
         offset = tracingutils.get_operand_value_replacement(
             state.ea, POS_FIRST, state)
         self.set_stack(offset, state.ea, POS_SECOND, state)
     else:
         reg = tracingutils.get_reg_fam(op1)
         type_ = idc.GetOpType(state.ea, POS_SECOND)
         if reg:
             if type_ != idc.o_phrase and type_ != idc.o_displ:
                 if type_ == idc.o_reg:
                     reg2 = tracingutils.get_reg_fam(
                         tracingutils.get_opnd_replacement(
                             state.ea, POS_SECOND))
                     if reg2 and reg2[0] in state.regs:
                         val = state.regs[reg2[0]][0]
                     else:
                         val = None
                 else:
                     val = idc.GetOperandValue(state.ea, POS_SECOND)
                 if val is not None:
                     state.regs[reg[0]] = (val, state.ea)
             else:
                 offset = tracingutils.get_operand_value_replacement(
                     state.ea, POS_SECOND, state)
                 value = state.stack.get(offset, None)
                 if value is not None:
                     state.regs[reg[0]] = value
                 else:
                     self.clear_reg_if_needed(reg, state.regs)
Exemple #8
0
def set_stack(offset, ea, pos, state):
    '''Sets the stack dictionary, at the given offset, to contain the value at the given position at the given ea,
        performing a lookup in the register dictionary if needed. Used by create_stack
    
        :param offset: offset to set on stack
        :param ea: instruction location
        :param pos: argument position
        :param state: the current TraceState

        :return: None - updates state
    '''
    fill = False
    if idc.GetOpType(ea, pos) == idc.o_imm:
        val = idc.GetOperandValue(ea, pos)
        state.stack[offset] = (val, ea)
        fill = True
    else:
        reg = unsafe_get_reg_fam(get_opnd_replacement(ea, pos))
        if reg and reg[0] in state.regs:
            val = state.regs[reg[0]][0]
            state.stack[offset] = (state.regs[reg[0]][0], ea)
            fill = True
    if fill:
        for i in xrange(0, get_byte_size_of_operand(ea, pos)):
            state.stack[offset + i] = (val & 0xff, ea)
            val /= 256
Exemple #9
0
def find_WdfDeviceCreateDeviceInterface():
    function_offset = OFFSET_WdfDeviceCreateDeviceInterface

    calls_to_pfn_list = []
    try:
        for xref in idautils.XrefsTo(g_vars["_WDFFUNCTIONS"]+function_offset):
            call_pfnWdfDeviceCreateDeviceInterface = xref.frm
            calls_to_pfn_list.append(call_pfnWdfDeviceCreateDeviceInterface)
    except StopIteration:
        # this is case 2 or 3
        pass
    if len(calls_to_pfn_list) == 0:
        call_pfnWdfDeviceCreateDeviceInterface = find_wdf_callback_through_immediate("call", 0, function_offset)
        if call_pfnWdfDeviceCreateDeviceInterface:
            calls_to_pfn_list.append(call_pfnWdfDeviceCreateDeviceInterface)
            idc.OpStroffEx(call_pfnWdfDeviceCreateDeviceInterface,0,(idaapi.get_struc_id("_WDFFUNCTIONS")),0)

    if len(calls_to_pfn_list) == 0:
        call_pfnWdfDeviceCreateDeviceInterface = find_wdf_callback_through_immediate("mov", 1,function_offset)
        if call_pfnWdfDeviceCreateDeviceInterface:
            calls_to_pfn_list.append(call_pfnWdfDeviceCreateDeviceInterface)
            idc.OpStroffEx(call_pfnWdfDeviceCreateDeviceInterface,1,(idaapi.get_struc_id("_WDFFUNCTIONS")),0)

    for k, pfn_call in enumerate(calls_to_pfn_list):
        lea_guid = find_function_arg(pfn_call, "lea", "r8", 0)
        interface_guid = idc.GetOperandValue(lea_guid, 1)
        idc.MakeName(interface_guid, '_InterfaceGUID' + str(k))
        assign_struct_to_address(interface_guid, "GUID")
        g_vars["_InterfaceGUID" + str(k)] = interface_guid
        print("_InterfaceGUID: ", hex(interface_guid))
        guid_bytes = idc.GetManyBytes(interface_guid, 0x10)
        print_guid(guid_bytes)
Exemple #10
0
def patch_to_call_puts(addr):
    #.text:0000114D E8 DE FE FF FF                          call    _printf
    count = idc.ItemSize(addr)

    #get value
    v = idc.GetOperandValue(addr, 0)

    #要CALL的地址 - 下一条指令地址 = E8 后面的硬编码

    plt_names = idautils.Names()
    for address, name in plt_names:
        if name == '.puts':
            puts_addr = address
        elif name == '.printf':
            printf_addr = address

    op = puts_addr - (addr + count)
    op = op & 0xffffffff

    #print('op: %s' %hex(op))

    idc.PatchDword(addr + 1, op)
    idc.MakeCode(addr)

    print('patch [call _printf] ok, addr: %s' % hex(addr))

    return
def main():
    xrefs = XrefsTo(0xF27B90)
    for xref in xrefs:
        offset = idc.GetOperandValue((xref.frm - 0xF), 0)
        print "%s," % (GetString(offset, -1, ASCSTR_C))

    print "done"
Exemple #12
0
def getMinorDispatchTableAddress(ea):
    """find address of last lea in function"""
    start = idc.GetFunctionAttr(ea, idc.FUNCATTR_START)
    end = idc.PrevHead(idc.GetFunctionAttr(ea, idc.FUNCATTR_END), start)
    res = prevMnemonic(end, 'lea', start)
    assert res != idc.BADADDR
    return idc.GetOperandValue(res, 1)
 def lookForOpArgs(self, start, end):
     for head in idautils.Heads(start, end):
         try:
             for i in range(2):
                 if using_ida7api:
                     t = idc.get_operand_type(head, i)
                 else:
                     t = idc.GetOpType(head, i)
                 if t == idc.o_imm:
                     if using_ida7api:
                         opval = idc.get_operand_value(head, i)
                         insn = idautils.DecodeInstruction(head)
                         opmask = OPERAND_MASK.get(insn.ops[i].dtype)
                         if opmask:
                             opval = opval & opmask
                     else:
                         opval = idc.GetOperandValue(head, i)
                     if self.params.useXORSeed:
                         opval = opval ^ self.params.XORSeed
                     for h in self.params.hashTypes:
                         hits = self.dbstore.getSymbolByTypeHash(
                             h.hashType, opval)
                         for sym in hits:
                             logger.info("0x%08x: %s", head, str(sym))
                             self.addHit(head, sym)
                             self.markupLine(head, sym,
                                             self.params.useDecompiler)
         except Exception as err:
             logger.exception("Exception: %s", str(err))
Exemple #14
0
def get_operand_value_replacement(ea, pos, state):
    """ A replacement for Ida's idc.GetOperandValue that handles displacements more reasonably

        :param ea: memory location
        :param pos: argument location
                    example:
                        add eax, ebx
                        eax is position 0, ebx is position 1
        :param state: the current stack pointer register family (usually sp)

        :return: computes a numerical replacement for an operand
    """
    if is_displ(ea, pos):
        bit_size = 64 if is_64_bit() else 32
        stack_reg = 'rsp' if bit_size == 64 else 'esp'
        idaapi.decode_insn(ea)
        offset = idaapi.cmd.Operands[pos].addr
        # Convert the offset to a signed value
        if offset & (1 << (bit_size - 1)):
            offset -= (1 << bit_size)
        if stack_reg in get_opnd_replacement(ea, pos):
            offset += idc.GetSpd(ea) or 0
        return offset
    else:
        return idc.GetOperandValue(ea, pos)
def norm_func1(head):
    inst = '' + idc.GetMnem(head)
    num_operands = op_count(head)
    for i in range(num_operands):
        type_op = idc.GetOpType(head, i)
        if type_op == idc.o_void:
            break
        elif type_op == idc.o_mem:
            inst += ' [MEM]'
        elif type_op == idc.o_imm:
            val = idc.GetOperandValue(head, i)
            #if -int(5000) <= val <= int(5000):
            if -int(500) <= val <= int(500):
                inst += ' ' + str(hex(val))
            else:
                inst += ' HIMM'
        else:
            inst += ' ' + idc.GetOpnd(head, i)

        if num_operands > 1:
            inst += ','

    if ',' in inst:
        inst = inst[:-1]
    inst = inst.replace(' ', '_')
    return str(inst)
Exemple #16
0
 def find_interesting_xors(self):
     next_xor = idc.FindText(idc.MinEA(), idc.SEARCH_DOWN | idc.SEARCH_NEXT,
                             0, 0, "xor")
     while next_xor != idc.BADADDR:
         if idc.GetOpnd(next_xor, 0) != idc.GetOpnd(next_xor, 1):
             entry = {
                 "func": "",
                 "addr": next_xor,
                 "loop": False,
                 "disasm": idc.GetDisasm(next_xor)
             }
             func = idaapi.get_func(next_xor)
             if func:
                 entry["func"] = idaapi.get_name(idc.BADADDR, func.startEA)
                 heads = idautils.Heads(next_xor, func.endEA)
                 lxors = []
                 for head in heads:
                     if idc.GetMnem(head).startswith('j'):
                         jmp_addr = idc.GetOperandValue(head, 0)
                         if jmp_addr < next_xor and jmp_addr > func.startEA:
                             entry["loop"] = True
                             break
             self._interesting_xors.append(entry)
         next_xor = idc.FindText(idc.NextHead(next_xor),
                                 idc.SEARCH_DOWN | idc.SEARCH_NEXT, 0, 0,
                                 "xor")
Exemple #17
0
def get_operand_value_replacement(ea, pos, state):
    ''' A replacement for Ida's idc.GetOperandValue that handles displacements more reasonably
        
        :param ea: memory location
        :param pos: argument location
                    example:
                        add eax, ebx
                        eax is position 0, ebx is position 1
        :param state: the current stack pointer register family (usually sp)
                        
        :return: computes a numerical replacement for an operand
    '''
    if is_displ(ea, pos):
        idaapi.decode_insn(ea)
        offset = idaapi.cmd.Operands[pos].addr
        flipped = (offset ^
                   (0xffffffffffffffff if is_64_bit(ea) else 0xffffffff)) + 1
        # Use reg_fam[2] here as opposed to reg_fam[0] like usual because we need to mach the reg name string
        if any(reg_fam[2] in get_opnd_replacement(ea, pos)
               for reg_fam in state.stack_pointer_reg_fams):
            adjustment = idc.GetSpd(ea)
        else:
            adjustment = 0
        if not adjustment:
            adjustment = 0
        if flipped < offset:
            return -flipped + adjustment
        else:
            return offset + adjustment
    else:
        return idc.GetOperandValue(ea, pos)
Exemple #18
0
def patch_64_rsp(addr, sub_value, is_sub_rsp):
    count = idc.ItemSize(addr)

    #get value
    v = idc.GetOperandValue(addr, 1)
    #print(hex(v))

    if v == -1:
        print('get value error')
        return

    if count == 4:
        #.text:000055BBF4127FD9 48 83 EC 10                             sub     rsp, 10h
        off = 0xff - v

        if sub_value < off:
            idc.PatchByte(addr + 3, v + sub_value)
        else:
            idc.PatchByte(addr + 3, 0xff)

        idc.MakeCode(addr)
    else:
        #.text:00007EFEA44A5310 48 81 EC 20 01 00 00                    sub     rsp, 120h
        idc.PatchDword(addr + 3, v + sub_value)
        idc.MakeCode(addr)

    if is_sub_rsp != 0:
        print('patch [sub rsp, %s] ok, addr: %s' % (hex(v), hex(addr)))
    else:
        print('patch [add rsp, %s] ok, addr: %s' % (hex(v), hex(addr)))

    return
Exemple #19
0
def patch_32_esp(addr, sub_value, is_sub_esp):
    count = idc.ItemSize(addr)

    #get value
    v = idc.GetOperandValue(addr, 1)
    #print(hex(v))

    if v == -1:
        print('get value error')
        return

    if count == 3:
        #.text:0804867C 83 EC 18                                sub     esp, 18h
        off = 0xff - v
        if sub_value < off:
            idc.PatchByte(addr + 2, v + sub_value)
        else:
            idc.PatchByte(addr + 2, 0xff)

        idc.MakeCode(addr)
    else:
        #.text:0804875B 81 EC 30 02 00 00                       sub     esp, 230h
        idc.PatchDword(addr + 2, v + sub_value)
        idc.MakeCode(addr)

    if is_sub_esp != 0:
        print('patch [sub esp, %s] ok, addr: %s' % (hex(v), hex(addr)))
    else:
        print('patch [add esp, %s] ok, addr: %s' % (hex(v), hex(addr)))

    return
Exemple #20
0
def get_first_function(ea):
    """ see above, but returns the first pushed value """
    maybe_start = idc.get_func_attr(ea, idc.FUNCATTR_START)
    limit = 0
    if maybe_start == idc.BADADDR:
        limit = 10

    cur_ea = ea
    limit_count = 0
    while cur_ea != idc.BADADDR:
        # are we over limit or up to the func start?
        limit_count += 1
        limit_exceeded = (limit > 0 and limit_count > limit)
        too_far = (maybe_start != idc.BADADDR and cur_ea < maybe_start)
        if limit_exceeded or too_far:
            LOG.error(
                "Failed to find string walking backwards from {:08X}".format(
                    ea))
            return None

        prev_ins = idautils.DecodePreviousInstruction(cur_ea)
        prev_ea = prev_ins.ea

        # did we find it?
        if idc.GetMnem(prev_ea) == 'push':
            if idc.get_operand_type(prev_ea, 0) in [idc.o_mem, idc.o_imm]:
                # push offset found!
                pushed_addr = idc.GetOperandValue(prev_ea, 0)
                # it's not data, then probably good
                if idc.isCode(idc.GetFlags(pushed_addr)):
                    return pushed_addr

        cur_ea = prev_ea
Exemple #21
0
    def isCall(self, xref, tid):
        if xref in self._call_lut:
            return True
        elif idc.GetMnem(xref) == 'jmp':
            curf = idc.GetFunctionName(xref)
            if curf is not None:
                val = idc.GetOperandValue(xref, 0)
                if val is not None and val > 0:
                    tarf = idc.GetFunctionName(val)
                    if tarf is not None and tarf != curf:
                        self._call_lut.add(xref)
                        for thread in self["mem_areas"][0]['threads']:
                            if thread['tid'] == tid:
                                thread['calls'].append({
                                    "execs":
                                    1,
                                    "name":
                                    "",
                                    "target":
                                    val,
                                    "xrefs": [{
                                        "addr": xref,
                                        "execs": 1,
                                        "params": []
                                    }]
                                })
                        return True

        return False
Exemple #22
0
def get_goversion():
    global GOVER

    func_goroot = find_func_by_name("runtime_schedinit")
    if func_goroot is None:
        _error("Failed to find func runtime_schedinit")
        return

    schedinit_flowchart = idaapi.FlowChart(f=func_goroot)
    _debug("Flowchart number of runtime_schedinit: %d" %
           schedinit_flowchart.size)

    for fc_idx in xrange(schedinit_flowchart.size):
        fc = schedinit_flowchart[fc_idx]
        _debug("Current flowchart start addr: 0x%x" % fc.startEA)
        # mov     dword_AD744C, 7 ; dword_AD744C stores length of Go Version string
        if idc.GetMnem(fc.startEA) == "mov" and idc.GetOpType(fc.startEA, 0) == 2 \
            and str(idc.GetOperandValue(fc.startEA, 1)) == "7":
            _debug("Find length of go version string @ 0x%x" % fc.startEA)
            possible_goversion_len_addr = idc.GetOperandValue(fc.startEA, 0)
            _debug("Possible go version string len addr: 0x%x" %
                   possible_goversion_len_addr)
            possible_goversion_str_ptr_addr = possible_goversion_len_addr - ADDR_SZ
            possible_goversion_str_addr = read_mem(
                possible_goversion_str_ptr_addr)
            _debug("Possible go version string addr: 0x%x" %
                   possible_goversion_str_addr)
            possible_goversion_len = read_mem(possible_goversion_len_addr)
            _debug("Real go version string len: %d" % possible_goversion_len)
            if possible_goversion_len >= 5 and possible_goversion_len < 10:
                if idc.MakeStr(
                        possible_goversion_str_addr,
                        possible_goversion_str_addr + possible_goversion_len):
                    idaapi.autoWait()
                    goversion_str = str(
                        idc.GetManyBytes(possible_goversion_str_addr,
                                         possible_goversion_len))
                    _debug(goversion_str)
                    if goversion_str.startswith("go"):
                        GOVER = goversion_str[2:]
                        _info("\nGo version: %s\n" % GOVER)
                    else:
                        _debug("Invalid go string")
                else:
                    _debug("Failed to create go version string")
            else:
                _debug("Invalid go version len")
Exemple #23
0
def handle_mov(ea, state):
    '''Updates the stack based on a mov instruction. Used by create_stack
    
        :param ea: instruction location
        :param state: the current TraceState
        
        :return: None - updates stack or regs
    '''
    op1 = get_opnd_replacement(ea, POS_FIRST)
    if '[' in op1:
        offset = get_operand_value_replacement(ea, POS_FIRST, state)
        set_stack(offset, ea, POS_SECOND, state)
    else:
        reg = unsafe_get_reg_fam(op1)
        type_ = idc.GetOpType(ea, POS_SECOND)
        if reg:
            if type_ != idc.o_phrase and type_ != idc.o_displ:
                val = None
                if type_ == idc.o_reg:
                    reg2 = unsafe_get_reg_fam(
                        get_opnd_replacement(ea, POS_SECOND))
                    if reg2 and reg2[0] in state.regs:
                        val = state.regs[reg2[0]][0]
                        if reg2 in state.stack_pointer_reg_fams:
                            state.stack_pointer_reg_fams.remove(reg2)
                    else:
                        if reg2 in state.stack_pointer_reg_fams:
                            state.stack_pointer_reg_fams.append(reg2)
                        else:
                            val = None
                elif type_ == idc.o_mem:
                    bytes = idc.GetManyBytes(
                        idc.GetOperandValue(ea, POS_SECOND),
                        get_byte_size_of_operand(ea, 1))
                    val = 0
                    if bytes:
                        for x in range(len(bytes)):
                            val += ord(bytes[x]) << x
                else:
                    val = idc.GetOperandValue(ea, POS_SECOND)
                if val is not None:
                    state.regs[reg[0]] = (val, ea)
            else:
                offset = get_operand_value_replacement(ea, POS_SECOND, state)
                value = state.stack.get(offset, None)
                if value is not None:
                    state.regs[reg[0]] = value
Exemple #24
0
def get_goroot():
    goroot_path_str = ""
    '''
    Get GOROOT path string
    '''
    func_goroot = find_func_by_name("runtime_GOROOT")
    if func_goroot is None:
        _error("Failed to find func contains goroot")
        return goroot_path_str

    goroot_flowchart = idaapi.FlowChart(f=func_goroot)
    ret_cbs = find_ret_cb(goroot_flowchart)
    '''
    runtime.GOROOT() normally has 2 return code blocks:
    1. False return
        mov     [rsp+28h+arg_0], rax
        mov     [rsp+28h+arg_8], rcx
        mov     rbp, [rsp+28h+var_8]
        add     rsp, 28h
        retn

    2. True return(Which we needed):
        mov     rax, cs:runtime_internal_sys_DefaultGoroot
        mov     rcx, cs:qword_D9AB58
        mov     [rsp+28h+arg_0], rax
        mov     [rsp+28h+arg_8], rcx
        mov     rbp, [rsp+28h+var_8]
        add     rsp, 28h
        retn
    '''
    for cb_idx in ret_cbs:
        if idc.GetOpType(goroot_flowchart[cb_idx].startEA, 0) == 1:
            # e.g.: mov     rax, cs:runtime_internal_sys_DefaultGoroot
            '''
            Op Types refer: https://www.hex-rays.com/products/ida/support/sdkdoc/ua_8hpp.html#aaf9da6ae7e8b201108fc225adf13b4d9
                o_void  =      0  # No Operand               
                o_reg  =       1  # General Register (al,ax,es,ds...)    reg
                o_mem  =       2  # Direct Memory Reference  (DATA)      addr
                o_phrase  =    3  # Memory Ref [Base Reg + Index Reg]    phrase
                o_displ  =     4  # Memory Reg [Base Reg + Index Reg + Displacement] phrase+addr
                o_imm  =       5  # Immediate Value                      value
                o_far  =       6  # Immediate Far Address  (CODE)        addr
                o_near  =      7  # Immediate Near Address (CODE)        addr
                ......
            '''
            goroot_path_str_addr = read_mem(
                idc.GetOperandValue(goroot_flowchart[cb_idx].startEA, 1))
            goroot_path_str = idc.GetString(goroot_path_str_addr)
            if goroot_path_str is None or len(goroot_path_str) == 0:
                raise Exception("Invalid GOROOT")
            idc.MakeStr(goroot_path_str_addr,
                        goroot_path_str_addr + len(goroot_path_str) + 1)
            idaapi.autoWait()
            break

    if len(goroot_path_str) > 0:
        _info("Go ROOT Path: %s\n" % goroot_path_str)

    return goroot_path_str.replace("\\", "/")
Exemple #25
0
def ret_operand(ea, index):
    opType = idc.GetOpType(ea, index)
    if opType == 0:  # o_void
        return "void"
    elif opType == 1:  # o_reg
        return idc.GetOpnd(ea, index)
    elif opType == 2:  # o_mem
        return idc.GetOperandValue(ea, index)
    elif opType == 3:  # o_phrase [X20,X8]
        return idc.GetOpnd(ea, index).strip('[]').split(',')
    elif opType == 4:  # o_displ [SP,#0x80+var_80]; [SP+0xC0+var_C0],#0x60;[X8]
        op = idc.GetOpnd(ea, index)
        ops = []
        for pat in patterns:
            m = pat.match(op)
            if m:
                ops.append(m.groupdict()['register'])
                if 'offset' in m.groupdict():
                    ops.append(idc.GetOperandValue(ea, index))
        return ops
    elif opType == 5:  # o_imm
        return idc.GetOperandValue(ea, index)
    elif opType == 6:  # o_far
        return idc.GetOperandValue(ea, index)
    elif opType == 7:  # o_near
        return idc.GetOperandValue(ea, index)
    else:
        return idc.GetOpnd(ea, index)


# funcs = Functions()
# for f in funcs:
#     name = Name(f)
#     end = GetFunctionAttr(f, FUNCATTR_END)
#     locals = GetFunctionAttr(f, FUNCATTR_FRSIZE)
#     frame = GetFrame(f)
#     if frame is None:
#         continue

# for struct in idautils.Structs():
#     index = struct[0]
#     sid = struct[1]
#     name = struct[2]
#     size = idc.GetStrucSize(sid)

# idc.NextNotTail(ea)
Exemple #26
0
def main():
	xrefs = XrefsTo(0x13070FC)
	for xref in xrefs:
		packetHeader = idc.NextNotTail(xref.frm)
		opCode1 = idc.GetOperandValue(packetHeader, 1)

		if opCode1 > 10 and opCode1 < 16655:
			print "%08x -> %2x" % (packetHeader, opCode1)
Exemple #27
0
def get_opnd_replacement(ea, pos):
    """ A replacement for IDA's idc.GetOpnd that can de-alias register names"""
    # TODO: Support renames in other operand types
    if idc.GetOpType(ea, pos) == idc.o_reg:
        return idaapi.get_reg_name(idc.GetOperandValue(ea, pos),
                                   get_byte_size_of_operand(ea, pos))
    else:
        return idc.GetOpnd(ea, pos)
Exemple #28
0
def getDispatchCode(ea):
    # get dispatch code out of an instruction
    first, second = (idc.GetOpnd(ea, 0), idc.GetOperandValue(ea, 1))
    if first == 'eax':
        return second
    raise ValueError(
        "Search resulted in address %08x, but instruction '%s' does fulfill requested constraints"
        % (ea, idc.GetMnem(ea)))
Exemple #29
0
 def run(self, arg=0):
     print("running")
     ea = idc.get_screen_ea()
     if idc.GetOpType(ea, 1) != 5:   # Immediate
         return
     value = idc.GetOperandValue(ea, 1) & 0xffffffff
     ida_bytes.set_cmt(ea, windows_ioctl_decode(value), 1)
     return
Exemple #30
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)