Exemplo n.º 1
0
def search_sub_esp_instr(ea):
    func = idaapi.get_func(ea)

    name = idc.GetFunctionName(ea)

    end = func.endEA
    start = func.startEA

    #print('%s - %s: %s()' %(hex(start), hex(end), name))

    #patten = '81 EC'
    #addr = idc.FindBinary(x, SEARCH_DOWN | SEARCH_NEXT, patten)

    bfind_sub_esp = False
    sub_esp_addr = None
    add_esp_addr = None

    x = start
    while x < end:
        asm = idc.GetDisasm(x)
        y = x + idc.ItemSize(x)

        if bfind_sub_esp == False:
            if asm.startswith('sub     esp,') or asm.startswith(
                    'sub     rsp,'):
                #print('%s(): %s => %s' %(name, hex(x), asm))

                #sub     esp, 540h
                t = idc.GetOpType(x, 1)
                if t != idc.o_imm:
                    continue

                bfind_sub_esp = True
                sub_esp_addr = x
                add_esp_asm = asm.replace('sub', 'add')
        else:
            #搜索后续指令应该有leave指令 或   #add     esp, 540h
            if asm.startswith(add_esp_asm):
                add_esp_addr = x
                x = y
                break
            elif asm == 'leave':
                break

        x = y

    if add_esp_addr is not None:
        #搜索后续指令不再对esp操作
        while x < end:
            asm = idc.GetDisasm(x)
            y = x + idc.ItemSize(x)

            if re.search('esp', asm):
                print('why to here')
                pass

            x = y

    return [sub_esp_addr, add_esp_addr]
    def parseArgs(self, ref):

        i = self.trackBackLimit
        argsToParse = self.func.nargs
        argv = []
        ref_p = ref
        while (i and argsToParse):
            insSize, dataSize = self.func.getInstrDataPair(self.func.nargs-argsToParse)
            if (insSize > self.func.ESCAPE_CODE_BEGIN):
                argsToParse -= 1
            else:
                if (dataSize > insSize):
                    self.log(3, "[!!] invalid argument size pair (%d, %d) for arg no: %d" % (insSize, dataSize, self.func.nargs-argsToParse))
                    raise
                ref_p = idc.PrevHead(ref_p, 0)
                if ref_p == BADADDR:
                    break
                disstr = idc.GetDisasm(ref_p)
                if disstr.startswith(self.func.argPassMech) and (idc.ItemSize(ref_p) == insSize):
                    arVal = self.getDataValue(ref_p + insSize - dataSize, dataSize)
                    argv.append(arVal)
                    self.log(4, "Arg found: (0x%x)" % arVal)
                    argsToParse -= 1
                    if not argsToParse:
                        break
                if len(self.getXrefs(ref_p)) == 1:
                    nref = self.getXrefs(ref_p)[0]
                    refins = idc.GetDisasm(nref)
                    if refins.startswith(self.interConnectInstr):
                        ref_p = nref
                i -= 1
        if len(argv) > 0:
            self.log(4, "[-] Adding args for call at 0x%x->%s" % (ref,repr(argv)))
            self.params[ref] = argv
Exemplo n.º 3
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
Exemplo n.º 4
0
def insertRelocatedSymbol(M, D, reloc_dest, offset, seg_offset, new_eas, itemsize=-1):
    pf = idc.GetFlags(reloc_dest)

    DS = D.symbols.add()
    DS.base_address = offset+seg_offset

    itemsize = int(itemsize)
    if itemsize == -1:
        itemsize = int(idc.ItemSize(offset))

    DEBUG("Offset: {0:x}, seg_offset: {1:x}\n".format(offset, seg_offset))
    DEBUG("Reloc Base Address: {0:x}\n".format(DS.base_address))
    DEBUG("Reloc offset: {0:x}\n".format(offset))
    DEBUG("Reloc size: {0:x}\n".format(itemsize))

    if idc.isCode(pf):
        DS.symbol_name = "sub_"+hex(reloc_dest)
        DS.symbol_size = itemsize
        DEBUG("Code Ref: {0:x}!\n".format(reloc_dest))

        if reloc_dest not in RECOVERED_EAS:
            new_eas.add(reloc_dest)

    elif idc.isData(pf):
        reloc_dest = handleDataRelocation(M, reloc_dest, new_eas)
        DS.symbol_name = "dta_"+hex(reloc_dest)
	DS.symbol_size = itemsize
        DEBUG("Data Ref!\n")
    else:
        reloc_dest = handleDataRelocation(M, reloc_dest, new_eas)
        DS.symbol_name = "dta_"+hex(reloc_dest)
	DS.symbol_size = itemsize
        DEBUG("UNKNOWN Ref, assuming data\n")
Exemplo n.º 5
0
    def findCodeCavez(self, segment=".text"):
        start = idc.SegByBase(idc.SegByName(segment))
        if start == idc.BADADDR:
            print "Can't find segment %s" % (segment)
            return

        end = idc.SegEnd(start)

        curr_addr = start
        curr_size = 0
        biggest_addr = idc.BADADDR
        biggest_size = 0
        results = []
        while start < end:
            new_addr = idc.FindText(start + curr_size, idc.SEARCH_DOWN, 0, 0,
                                    "align")
            if start == new_addr:
                break
            curr_size = idc.ItemSize(new_addr)
            if curr_size > biggest_size:
                biggest_addr = new_addr
                biggest_size = curr_size
            start = new_addr
            results.append((new_addr, curr_size))

        return results
        return biggest_addr, biggest_size
Exemplo n.º 6
0
def create_state(endEA, startEA=None):
    '''
        Quick and dirty representation of stack and regs from start of function to this ea.
        
        :param endEA: The EA of which you want to compute the stack up until
        :param startEA: Optional param of the beginning of the function - sometimes necessary
                        if ida can't compute and you can
        
        :return A newly created TraceState
    '''
    if not startEA:
        startEA = idaapi.get_func(endEA).startEA
    state = TraceState()
    ea = startEA
    while ea < endEA:
        mnemonic = idc.GetMnem(ea)
        if 'mov' in mnemonic:
            handle_mov(ea, state)
        elif ('xor' in mnemonic and unsafe_get_reg_fam(get_opnd_replacement(ea, POS_FIRST)) ==
              unsafe_get_reg_fam(get_opnd_replacement(ea, POS_SECOND))) or \
             ('lea' in mnemonic and idc.GetOpnd(ea, POS_SECOND) == '[0]') or \
             ('sub' in mnemonic and get_opnd_replacement(ea, POS_FIRST) ==
              get_opnd_replacement(ea, POS_SECOND)):
            reg = unsafe_get_reg_fam(get_opnd_replacement(ea, POS_FIRST))
            if reg:
                state.regs[reg[0]] = (0, ea)
        elif 'lea' in mnemonic:
            handle_lea(ea, state)
        elif 'push' in mnemonic:
            handle_push(ea, state)
        elif 'pop' in mnemonic:
            handle_pop(ea, state)

        ea += idc.ItemSize(ea)
    return state
Exemplo n.º 7
0
Arquivo: H2o.py Projeto: shmuelyr/H2o
    def DeepSearch(self, function_name, line, max_deep, current_deep=0):

        data = {}
        opcode_offset = 0
        function_start = idc.LocByName(function_name)
        function_end = idc.GetFunctionAttr(function_start, idc.FUNCATTR_END)
        while function_start + opcode_offset < function_end:

            opcode_index = function_start + opcode_offset
            dline = idc.GetDisasm(opcode_index)
            if idc.GetMnem(opcode_index) == "call":
                if current_deep >= max_deep:
                    return
                elif idc.GetOpnd(opcode_index, 0)[:4] == "sub_":
                    deep = self.DeepSearchWithRgx(idc.GetOpnd(opcode_index,
                                                              0), line,
                                                  max_deep, current_deep + 1)
                    if deep:
                        data.update(deep)

            if dline == line:
                data["%x" % opcode_index] = dline

            opcode_offset += idc.ItemSize(opcode_index)

        return data
Exemplo n.º 8
0
def addDataReference(M, I, inst, dref, new_eas):
    if inValidSegment(dref):
        if isExternalReference(dref):
            fn = getFunctionName(dref)

            fn = handleExternalRef(fn)
            if isExternalData(fn):
                I.ext_data_name = fn
                sys.stdout.write(
                    "EXTERNAL DATA REF FROM {0:x} to {1}\n".format(inst, fn))
            else:
                I.ext_call_name = fn
                sys.stdout.write(
                    "EXTERNAL CODE REF FROM {0:x} to {1}\n".format(inst, fn))

        elif isInternalCode(dref):
            I.call_target = dref
            if dref not in RECOVERED_EAS:
                new_eas.add(dref)
        else:
            dref_size = idc.ItemSize(dref)
            DEBUG("\t\tData Ref: {0:x}, size: {1}\n".format(dref, dref_size))
            I.data_offset = handleDataRelocation(M, dref, new_eas)
    else:
        DEBUG("WARNING: Data not in valid segment {0:x}\n".format(dref))
Exemplo n.º 9
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
Exemplo n.º 10
0
def ExecuteSymbolicSingleStep(addr, state=INIT_REG):
    size = idc.ItemSize(addr)
    code = idc.GetManyBytes(addr, size)
    loc_db = LocationDB()

    base = addr
    try:
        ins = mn_x86.dis(bin_stream_str(code, base_address=base), 64, base)
    except:
        return state.copy()

    ira = machine.ira(loc_db)
    ircfg = ira.new_ircfg()
    try:
        ira.add_instr_to_ircfg(ins, ircfg)
        sb = SymbolicExecutionEngine(ira, state)
        symbolic_pc = sb.run_at(ircfg, base)
    except:
        return state.copy()
    ret = state.copy()
    for key, value in sb.modified():
        if isinstance(value, ExprOp) and value.op == "call_func_ret":
            value = ExprInt(0, 64)
        ret[key] = value
    return ret
Exemplo n.º 11
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
Exemplo n.º 12
0
 def _execution_tree_onClickItem(self, item):
     address = int(item.text(1), 16)
     is_api = int(item.text(5), 16)
     tid = int(item.text(6), 16)
     target = int(item.text(3), 16)
     callee_id = int(item.text(7), 16)
     if is_api > 0:
         for thread in self._maze['process']['threads']:
             if tid == thread['tid']:
                 for i in range(len(thread['api_parameters'])):
                     if thread['api_parameters'][i][
                             'target'] == target and thread[
                                 'api_parameters'][i]['id'] == callee_id:
                         if thread['api_parameters'][i]['xref'] == (
                                 address + idc.ItemSize(address)):
                             if 'parameters' in thread['api_parameters'][i]:
                                 cmt = item.text(0).encode('ascii') + "\n"
                                 for param in thread['api_parameters'][i][
                                         'parameters']:
                                     cmt += (param['name'] + " : " +
                                             str(param['data']) +
                                             "\n").encode('ascii')
                                 idc.MakeComm(address, cmt)
                                 break
     idc.Jump(address)
Exemplo n.º 13
0
def createBasicBlockXRefsTo(startAddress, endAddress,
                            minSegAddress, maxSegAddress, func=None):
    function_xrefs = {}
    data_xrefs = {}
    comments = {}
    strucs = {}
    stackframe = {}
    operand_view = {}
    hidden_areas = {}
    references = {}
    enums = {}

    ea = startAddress
    while ea < endAddress:
        get_function_xrefs_at_ea(startAddress, ea, function_xrefs, minSegAddress, maxSegAddress)
        get_data_xrefs_at_ea(startAddress, ea, data_xrefs, function_xrefs, minSegAddress, maxSegAddress)
        add_comments_at_ea(startAddress, ea, comments)
        get_hidden_area_at_ea(startAddress, ea, hidden_areas)
        get_struc_enum_xrefs_at_ea(startAddress, ea, strucs, enums, stackframe, func)
        get_reference_xrefs_at_ea(startAddress, ea, references)

        #
        # OPERAND VIEW
        #
        operand_view[ea - startAddress] = getOperandView(ea)

        # next instruction
        # (a, size) = getInvariantsBytes(ea, ida_function_bytes_cache[ea - startAddress:])
        ea += idc.ItemSize(ea)

    return (function_xrefs, data_xrefs, comments, strucs, enums, operand_view, hidden_areas, stackframe, references)
Exemplo n.º 14
0
def GetItemContaining(ea):
    previous_item = idc.PrevHead(ea)
    if previous_item is not idc.BADADDR:
        previous_item_size = idc.ItemSize(previous_item)
        if previous_item_size > 0 and ea < previous_item + previous_item_size:
            return previous_item
    return ea
Exemplo n.º 15
0
def extractCode():
	printAvd()
	
	start = idc.SelStart()
	end = idc.SelEnd()
	codeSize = end - start
	ea = start
	#print hex(ea)
	result=""

	for i in range(codeSize):
		op1 = idc.GetOpType(ea,0)
		op2 = idc.GetOpType(ea,1)
		instructionSize=idc.ItemSize(ea) 
	
		if op1 == idc.o_reg and (op2 ==idc.o_reg or op2 == idc.o_void or op2 == idc.o_phrase):
			for b in range(0,instructionSize):
				result += formatByte(ea+b)
		elif (op1 == idc.o_reg and op2 == idc.o_displ) or (op1 == idc.o_displ and op2 == idc.o_reg) or (op1 == idc.o_displ and op2 == idc.o_imm):
			result += formatByte(ea) + formatByte(ea+1)
			for b in range(2,instructionSize):
				result=result+"*"
		elif op1 == idc.o_phrase and op2 == idc.o_reg:
			for b in range(0,instructionSize):
				result+=formatByte(ea+b)
		else:
			result+=calcStr(ea,instructionSize)

		ea = ea + instructionSize
		if ea >= (start + codeSize):
			break
	print ("%s  Offset:%s") % (idc.GetFunctionName(start),hex(start - idc.GetFunctionAttr(start,0)))
	print result
	return result
 def handle_call(self, state):
     '''Updates the state of the stack string finding based on a call instruction'''
     stack_pointer = idc.GetSpd(state.ea)
     next_ea = state.ea + idc.ItemSize(state.ea)
     stack_pointer_delta = idc.GetSpDiff(next_ea)
     if stack_pointer is not None and stack_pointer_delta is not None:
         next_reg = tracingutils.get_reg_fam(idc.GetOpnd(
             next_ea, POS_FIRST))
         # Caller cleanup handling, vulnerable to instruction reordering though.
         if next_reg and 'esp' in next_reg and "add" in idc.GetMnem(
                 next_ea).lower():
             stack_pointer_delta += idc.GetSpDiff(next_ea +
                                                  idc.ItemSize(next_ea))
         for index in xrange(stack_pointer,
                             stack_pointer + stack_pointer_delta):
             if index in state.stack:
                 del state.stack[index]
Exemplo n.º 17
0
    def is_end_of_flow(self, instruction):
        """Return whether the last instruction processed end the flow."""

        next_addr = instruction.ip + idc.ItemSize(instruction.ip)
        next_addr_flags = idc.GetFlags(next_addr)
        if idc.isCode(next_addr_flags) and idc.isFlow(next_addr_flags):
            return False

        return True
Exemplo n.º 18
0
 def data(self):
   h = self.keleven
   for ea in idautils.FuncItems(self.offset):
     h = self._cycle(h, idc.Byte(ea))
     # skip additional bytes of any instruction that contains an offset in it
     if idautils.CodeRefsFrom(ea, False) or idautils.DataRefsFrom(ea):
       continue
     for i in range(ea + 1, ea + idc.ItemSize(ea)):
       h = self._cycle(h, idc.Byte(i))
   return h
Exemplo n.º 19
0
    def _scan_block(self, block, fname):
        current_bb_start = block.startEA
        instructions = idautils.Heads(block.startEA, block.endEA)
        last_instruction = None
        last_instruction_size = None
        call_instructions = []
        next_instruction = None

        for i in instructions:
            last_instruction = i
            last_instruction_size = idc.ItemSize(i)
            mnem = idc.GetMnem(i)
            is_call = mnem == "call"
            is_int = mnem == "int"

            if (is_call or is_int) and i != block.endEA:
                if not ida_graph:
                    next_instruction = i + last_instruction_size
                    bb_size = next_instruction - current_bb_start
                    ct = []
                    if is_call:
                        call_instructions = [(i, next_instruction)]
                        ct = self._get_call_target(call_instructions)
                    self._invoke_cbs(current_bb_start, i, bb_size, ct,
                                     [next_instruction], fname)

                    # start a new translation block
                    current_bb_start = idc.NextHead(i, block.endEA + 1)
                else:
                    next_instruction = i + last_instruction_size
                    call_instructions.append((i, next_instruction))

        if current_bb_start == idc.BADADDR:
            current_inst = last_instruction + last_instruction_size
            self._invoke_cbs(current_inst, idc.BADADDR, 0, [], [], fname)
            # the call instruction probably doesn't return.
            return

        if current_bb_start < block.endEA:
            bb_size = block.endEA - current_bb_start
            ct = []
            succs = []
            for succ_block in block.succs():
                succs.append(succ_block.startEA)

            if not ida_graph and mnem == "call":
                call_instructions = [(last_instruction, succs[0])]
            ct = self._get_call_target(call_instructions)

            if not ida_graph:
                self._invoke_cbs(current_bb_start, last_instruction, bb_size,
                                 ct, succs, fname)
            else:
                self._invoke_cbs(current_bb_start, i, bb_size, ct, succs,
                                 fname)