Example #1
0
def SETNGE(cpu_context, ip, mnem, opvalues):
    """ Set if Not Greater Than or Equal """
    result = int(cpu_context.registers.sf != cpu_context.registers.of)
    cpu_logger.debug("{} 0x{:X} :: Setting {} to {}".format(mnem.upper(), ip, idc.GetOpnd(ip, 0), result))
    set_operand_value(cpu_context, ip, result, idc.GetOpnd(ip, 0), idc.GetOpType(ip, 0))
Example #2
0
def SETNG(cpu_context, ip, mnem, opvalues):
    """ Set if Not Greater """
    result = int(cpu_context.registers.zf or (cpu_context.registers.sf != cpu_context.registers.of))
    cpu_logger.debug("SETNG 0x{:X} :: Setting {} to {}".format(ip, idc.GetOpnd(ip, 0), result))
    set_operand_value(cpu_context, ip, result, idc.GetOpnd(ip, 0), idc.GetOpType(ip, 0))
Example #3
0
def SETPS(cpu_context, ip, mnem, opvalues):
    """ Set if Not??? Parity """
    result = int(cpu_context.registers.sf)
    cpu_logger.debug("SETPS 0x{:X} :: Setting {} to {}".format(ip, idc.GetOpnd(ip, 0), result))
    set_operand_value(cpu_context, ip, result, idc.GetOpnd(ip, 0), idc.GetOpType(ip, 0))
Example #4
0
def SETNO(cpu_context, ip, mnem, opvalues):
    """ Set if Not Overflow """
    result = int(not cpu_context.registers.of)
    cpu_logger.debug("SETNO 0x{:X} :: Setting {} to {}".format(ip, idc.GetOpnd(ip, 0), result))
    set_operand_value(cpu_context, ip, result, idc.GetOpnd(ip, 0), idc.GetOpType(ip, 0))
Example #5
0
def POP(cpu_context, ip, mnem, opvalues):
    """ POP stack value """
    result = utils.struct_unpack(cpu_context.mem_read(cpu_context.reg_read("RSP"), cpu_context._byteness))
    cpu_context.reg_write("RSP", cpu_context.reg_read("RSP") + cpu_context._byteness)
    cpu_logger.debug("POP 0x{:X} :: Popped value {} into {}".format(ip, result, idc.GetOpnd(ip, 0)))
    set_operand_value(cpu_context, ip, result, idc.GetOpnd(ip, 0), idc.GetOpType(ip, 0))
Example #6
0
#获取上一条指令的地址
idc.PrevHead(ea)

#获取下一个地址
idc.NextAddr(ea)

#获取上一个地址
idc.PrevAddr(ea)

#遍历所有的动态调用
for func in idautils.Functions():
    flags = idc.GetFunctionFlags(func)
    if flags & FUNC_LIB or flags & FUNC_THUNK:
        continue
    dism_addr = list(idautils.FuncItems(func))
    for line in dism_addr:
        m = idc.GetMnem(line)
        if m == 'call' or m == 'jmp':
            op = idc.GetOpType(line, 0)
            if op == o_reg:
                print "0x%x %s" % (line, idc.GetDisasm(line))

ea = here()
print hex(ea), idc.GetDisasm(ea)
next_instr = idc.NextHead(ea)
print hex(next_instr), idc.GetDisasm(next_instr)
prev_instr = idc.PrevAddr(ea)
print hex(prev_instr), idc.GetDisasm(prev_instr)
print hex(idc.NextAddr(ea))
print hex(idc.PrevAddr(ea))
Example #7
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):

        (1). goroot string length as ptr
        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

        (2). goroot string length as instant number
        lea     rax, unk_7220B5
        mov     [rsp+28h+arg_0], rax
        mov     [rsp+28h+arg_8], 0Dh
        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_len = 0
            goroot_path_addr = 0

            curr_addr = goroot_flowchart[cb_idx].startEA
            goroot_path_addr_val = idc.GetOperandValue(curr_addr, 1)

            end_addr = goroot_flowchart[cb_idx].endEA
            curr_addr = idc.FindCode(curr_addr, idaapi.SEARCH_DOWN)
            # find goroot path length and OpType of length(instant len number or addr of len)
            while curr_addr <= end_addr:
                len_optype = idc.GetOpType(curr_addr, 1)
                if len_optype == 2:
                    # addr of len
                    # mov     rcx, cs:qword_D9AB58
                    goroot_path_addr = read_mem(goroot_path_addr_val)
                    goroot_path_len = read_mem(goroot_path_addr_val + ADDR_SZ)
                    break
                elif len_optype == 5:
                    # instant number as len
                    # mov     [rsp+28h+arg_8], 0Dh
                    goroot_path_addr = goroot_path_addr_val
                    goroot_path_len = idc.GetOperandValue(curr_addr, 1)
                    break

                curr_addr = idc.FindCode(curr_addr, idaapi.SEARCH_DOWN)

            if goroot_path_len == 0 or goroot_path_addr == 0:
                raise Exception("Invalid GOROOT Address ang Length")

            goroot_path_str = str(
                idc.GetManyBytes(goroot_path_addr, goroot_path_len))
            if goroot_path_str is None or len(goroot_path_str) == 0:
                raise Exception("Invalid GOROOT")
            idc.MakeStr(goroot_path_addr, goroot_path_addr + goroot_path_len)
            idaapi.autoWait()
            break

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

    return goroot_path_str.replace("\\", "/")
Example #8
0
def _movsx(cpu_context, ip, mnem, opvalues):
    """ Move with Sign Extend """
    opvalue2 = opvalues[1].value
    cpu_logger.debug("MOVSX 0x{:X} :: Sign-extend {} into {}".format(ip, opvalue2, idc.GetOpnd(ip, 0)))
    size = utils.sign_extend(opvalue2, opvalues[1].width, opvalues[0].width)
    set_operand_value(cpu_context, ip, size, idc.GetOpnd(ip, 0), idc.GetOpType(ip, 0))
Example #9
0
    symbol = (int(linesplit[0], 16), symbolstr)
    symbols.append(symbol)

symbols = sorted(symbols, key=lambda symbols: symbols[0])

for seg_ea in Segments():

    for ea in range(seg_ea, SegEnd(seg_ea)):

        vop1 = None
        vop2 = None

        bIsCode = isCode(GetFlags(ea))

        if bIsCode:
            op1type = idc.GetOpType(ea, 0)
            op2type = idc.GetOpType(ea, 1)
            if op1type == 5 or op1type == 6 or op1type == 7:
                vop1 = GetOperandValue(ea, 0)
            if op2type == 5 or op2type == 6 or op2type == 7:
                vop2 = GetOperandValue(ea, 1)

        v = Dword(ea)

        isymbol = binarySearch(symbols, v)
        if vop1 and not isymbol[0]: isymbol = binarySearch(symbols, vop1)
        if vop2 and not isymbol[0]: isymbol = binarySearch(symbols, vop2)

        if isymbol[0]:

            i = isymbol[1]
Example #10
0
    def get_stack_strings(self, functions):
        """
        Finds all the stack strings it can in the given functions.

        Parameters set globally:
            STRING_GAP_TOLERANCE - the gap allowed between string characters.
            MAX_CHARACTER_WIDTH  - the maximum character size, in bytes
            ASCII                - Whether character values must be 0-127
        """
        stack_strings = []
        for func in functions:
            state = tracingutils.BranchingTraceState(func.startEA)
            state.strs = set()
            states = [state]
            func_eas = []
            ea = state.ea
            while ea < func.endEA:
                func_eas.append(ea)
                ea += idc.ItemSize(ea)
            while states:
                state = states.pop()
                while state.ea < func.endEA:
                    try:
                        func_eas.remove(state.ea)
                    except:
                        pass
                    state.visited_eas.append(state.ea)
                    mnemonic = idc.GetMnem(state.ea)
                    if mnemonic in IGNORED_MNEMONICS:
                        pass
                    elif 'pop' in mnemonic:
                        reg = tracingutils.get_reg_fam(
                            tracingutils.get_opnd_replacement(
                                state.ea, POS_FIRST))
                        if reg:
                            value = state.stack.get(idc.GetSpd(state.ea), None)
                            if value is not None:
                                state.regs[reg[0]] = value
                            else:
                                self.clear_reg_if_needed(reg, state.regs)
                    elif 'push' in mnemonic:
                        pass  # bug where idc.GetSpd was not correctly tracking the pointer, this case also hasn't really been seen often as part of a stack string
                        # self.set_stack(idc.GetSpd(ea), ea, POS_FIRST, regs, stack)
                    elif 'mov' in mnemonic:
                        self.handle_mov(state)
                    elif ('xor' in mnemonic and tracingutils.get_reg_fam(
                            tracingutils.get_opnd_replacement(state.ea, POS_FIRST)) ==
                          tracingutils.get_reg_fam(tracingutils.get_opnd_replacement(state.ea, POS_SECOND))) or \
                            ('lea' in mnemonic and idc.GetOpnd(state.ea, POS_SECOND) == '[0]') or \
                            ('sub' in mnemonic and tracingutils.get_opnd_replacement(state.ea, POS_FIRST) ==
                             tracingutils.get_opnd_replacement(state.ea, POS_SECOND)):
                        reg = tracingutils.get_reg_fam(
                            tracingutils.get_opnd_replacement(
                                state.ea, POS_FIRST))
                        if reg:
                            state.regs[reg[0]] = (0, state.ea)
                    elif 'loop' in mnemonic or 'movsb' in mnemonic:
                        state.regs['rcx'] = (0, state.ea)
                    elif mnemonic in JUMPS:
                        try:
                            target = idautils.CodeRefsFrom(state.ea, 0).next()
                        except StopIteration:
                            target = None
                        if target and target not in state.visited_eas:
                            if func.endEA > target >= func.startEA:
                                state.visited_eas.append(target)
                                new_state = tracingutils.BranchingTraceState(
                                    target, state)
                                new_state.strs = state.strs
                                states.append(new_state)
                            else:
                                self.report_strings(state.strs, state.stack)
                        # Always follow an unconditional jump
                        if mnemonic == 'jmp':
                            break
                    elif 'rep' in idc.GetDisasm(state.ea).split(' ')[0] and 'scas' not in \
                            idc.GetDisasm(state.ea).split(' ')[1]:
                        self.report_strings(state.strs, state.stack)
                    elif 'lea' in mnemonic:
                        self.handle_lea(state)
                    elif 'call' in mnemonic:
                        self.handle_call(state)
                    elif 'ret' in mnemonic:
                        break
                    elif idc.GetOpType(
                            state.ea, POS_FIRST
                    ) == idc.o_reg:  # If we find a target register we were tracking, stop tracking it.
                        self.clear_reg_if_needed(
                            tracingutils.get_reg_fam(
                                tracingutils.get_opnd_replacement(
                                    state.ea, POS_FIRST)), state.regs)
                    state.ea += idc.ItemSize(state.ea)
                self.report_strings(state.strs, state.stack)
                if not states and func_eas:
                    new_state = tracingutils.BranchingTraceState(func_eas[0])
                    new_state.strs = set()
                    states.append(new_state)
                stack_strings.extend(state.strs)
        self.strings.update(stack_strings)
Example #11
0
    def createRegisterChain(self, p, ea):
        f = idaapi.FlowChart(idaapi.get_func(ea))

        functionName = idaapi.get_func_name(ea)
        client = MongoClient('localhost', 27017)
        db = client.BinAuthor
        collection = db.Choice18

        if idaapi.get_func_name(ea) not in self.functionRegisterChains.keys():
            self.functionRegisterChains[idaapi.get_func_name(ea)] = {}
        for block in f:
            if p:
                registerChain = {}
                for address in Heads(block.startEA, block.endEA):
                    if idc.GetOpType(address,
                                     0) == 1 and idc.GetOpnd(address, 0) != "":
                        if idc.GetOpnd(address,
                                       0) not in self.functionRegisterChains[
                                           idaapi.get_func_name(ea)].keys():
                            self.functionRegisterChains[idaapi.get_func_name(
                                ea)][idc.GetOpnd(address,
                                                 0)] = [GetMnem(address)]
                        else:
                            self.functionRegisterChains[idaapi.get_func_name(
                                ea)][idc.GetOpnd(address,
                                                 0)].append(GetMnem(address))

                        if idc.GetOpnd(address, 0) not in registerChain.keys():
                            registerChain[idc.GetOpnd(address,
                                                      0)] = [GetMnem(address)]
                        else:
                            registerChain[idc.GetOpnd(address, 0)].append(
                                GetMnem(address))
                    if idc.GetOpType(address,
                                     1) == 1 and idc.GetOpnd(address, 1) != "":
                        if idc.GetOpnd(address,
                                       1) not in self.functionRegisterChains[
                                           idaapi.get_func_name(ea)].keys():
                            self.functionRegisterChains[idaapi.get_func_name(
                                ea)][idc.GetOpnd(address,
                                                 1)] = [GetMnem(address)]
                        else:
                            self.functionRegisterChains[idaapi.get_func_name(
                                ea)][idc.GetOpnd(address,
                                                 1)].append(GetMnem(address))

                        if idc.GetOpnd(address, 1) not in registerChain.keys():
                            registerChain[idc.GetOpnd(address,
                                                      1)] = [GetMnem(address)]
                        else:
                            registerChain[idc.GetOpnd(address, 1)].append(
                                GetMnem(address))
                for register in registerChain.keys():
                    fingerPrint = str(register)
                    functionMinhashes = {}
                    functionMinhashes["FunctionName"] = functionName
                    functionMinhashes["FileName"] = self.fileName
                    functionMinhashes["FileMD5"] = self.fileMD5
                    functionMinhashes["Author Name"] = self.authorName
                    functionMinhashes["BlockStartEA"] = block.startEA
                    functionMinhashes["register"] = register
                    functionMinhashes["registerChain"] = registerChain[
                        register]
                    counter = 0
                    for instruction in registerChain[register]:
                        fingerPrint += " " + str(instruction)
                        counter += 1

                    functionMinhashes["SimHashSignature"] = str(
                        simhash.Simhash(fingerPrint).value)

                    self.simhashList.append(
                        [counter, simhash.Simhash(fingerPrint).value])
                    if len(fingerPrint.split(" ")) >= 6:
                        self.registerChainMinhash.append([
                            fingerPrint,
                            minhash.minHash(
                                minhash.createShingles(fingerPrint))
                        ])
                        functionMinhashes[
                            "MinHashSignature"] = minhash.minHash(
                                minhash.createShingles(fingerPrint))
                        collection.insert(functionMinhashes)
                    else:
                        self.registerChainMinhash.append([
                            fingerPrint,
                        ])
Example #12
0
# .text:00401000 ; Input SHA256 : 852C530DF2EF78E3662F8282640DEDABE10D808C94F7188885C8A2CB4E7A9F84
# .text:00401000 ; Input MD5    : 3C78A494DF37F707AB013360BA4CFBF6
# .text:00401000 ; Input CRC32  : 30F64FC5

opcodes = []

if GetInputMD5() == "DC4F692AAA7A9AEF5EE2D2A3F00C690B":
    # sub_49CF7D
    EA = 0x49CF7D

    opcode_num = 0
    opcode_name = ""

    for e in list(idautils.FuncItems(EA)):
        if idc.GetMnem(e) == "push":
            if idc.GetOpType(e, 0) == o_imm:
                val = idc.GetOperandValue(e, 0)
                if val < 0x100:
                    opcode_num = val
                else:
                    opcode_name = idc.GetString(val)
        elif idc.GetMnem(e) == "call":
            if idc.GetOpType(e, 0) == o_near:
                if idc.GetOperandValue(e, 0) == 0x48A93E:
                    if opcode_num != 0 and opcode_name != "":
                        opcodes.append((opcode_num, opcode_name))
                        opcode_num = 0
                        opcode_name = ""
                    else:
                        print "WTF"
                        exit(0)
Example #13
0
    def __init__(self, bb_id, startEA, endEA, pred_blocks, succ_blocks):
        self.bid = bb_id
        self.start_ea = startEA
        self.end_ea = endEA
        self.pred_blocks = pred_blocks
        self.succ_blocks = succ_blocks
        self.addr_inst_map = {}
        self.addr_inst_abs_map = {}
        self.inst_str = ""
        self.inst_abs_str = ""

        for head in idautils.Heads(self.start_ea, self.end_ea):
            idc.OpHex(head, -1)  # print everything in Hex
            addr = "%08X" % head
            mnem = idc.GetMnem(head)

            if mnem.startswith("j"):
                continue  # WARNING: experimental feature to filter jmp's at the end of blocks

            op1 = idc.GetOpnd(head, 0)
            op1_type = idc.GetOpType(head, 0)
            # op1_val = idc.GetOperandValue(head, 0)
            op2 = idc.GetOpnd(head, 1)
            op2_type = idc.GetOpType(head, 1)
            # op2_val = idc.GetOperandValue(head, 1)

            if op1_type == idc.o_far or op1_type == idc.o_near:
                op1 = "addr"
            if op2_type == idc.o_far or op2_type == idc.o_near:
                op2 = "addr"

            self.inst_str += mnem + op1 + op2
            self.addr_inst_map[addr] = [mnem, op1, op2]

            if op1_type == idc.o_void:  # 0
                op1 = ""
            elif op1_type == idc.o_reg:  # 1
                op1 = "reg"
            elif op1_type == idc.o_mem:  # 2
                op1 = "mem"
            elif op1_type == idc.o_phrase:  # 3
                op1 = "phr"
            elif op1_type == idc.o_displ:  # 4
                op1 = "dis"
            elif op1_type == idc.o_imm:  # 5
                op1 = "val"
            elif op1_type == idc.o_far or op1_type == idc.o_near:  # 6 7
                op1 = "addr"

            if op2_type == idc.o_void:
                op2 = ""
            elif op2_type == idc.o_reg:
                op2 = "reg"
            elif op2_type == idc.o_mem:
                op2 = "mem"
            elif op2_type == idc.o_phrase:
                op2 = "phr"
            elif op2_type == idc.o_displ:
                op2 = "dis"
            elif op2_type == idc.o_imm:
                op2 = "val"
            elif op2_type == idc.o_far or op2_type == idc.o_near:
                op2 = "addr"

            self.inst_abs_str += mnem + op1 + op2
            self.addr_inst_abs_map[addr] = [mnem, op1, op2]

        self.inst_hash = hashlib.md5(self.inst_str).hexdigest()
        self.inst_abs_hash = hashlib.md5(self.inst_abs_str).hexdigest()
Example #14
0
def SETNC(cpu_context, ip, mnem, opvalues):
    """ Set if Not Carry """
    result = int(not cpu_context.registers.cf)
    cpu_logger.debug("{} 0x{:X} :: Setting {} to {}".format(mnem.upper(), ip, idc.GetOpnd(ip, 0), result))
    set_operand_value(cpu_context, ip, result, idc.GetOpnd(ip, 0), idc.GetOpType(ip, 0))
Example #15
0
    def choice2(self):
        client = MongoClient('localhost', 27017)
        db = client.BinAuthor
        collection = db.Choice2

        numOfInstructions = 0
        printfNewline = [0, 0]
        mainEA = 0
        #fileName = idc.ARGV[1]

        self.getAllStrings()
        for name in Names():
            if (str(name[1]).find("main") != -1) and (len(str(name[1])) <= 5):
                mainEA = name[0]

        numberOfImports = idaapi.get_import_module_qty()

        for counter in xrange(0, numberOfImports):
            idaapi.enum_import_names(counter, self.getImportedFunctions)

        for address in Heads(mainEA, FindFuncEnd(mainEA)):
            numOfInstructions += 1

        currentInstruction = 0
        currentStackValue = ''
        numberOfCalls = 0
        previousInstructionEA = 0
        for address in Heads(mainEA, FindFuncEnd(mainEA)):
            currentInstruction += 1
            if GetMnem(address) == "push":
                previousInstructionEA = address
                currentStackValue = idc.GetOpnd(address, 0)
            elif GetMnem(address) == "pop":
                currentStackValue = ''
            elif GetMnem(address) == "mov":
                if idc.GetOpnd(address, 0) in self.standardRegisters.keys():
                    self.standardRegisters[idc.GetOpnd(
                        address, 0)] = idc.GetOperandValue(address, 1)

            distanceFromEndOfFunction = int(numOfInstructions * (3 / float(4)))
            if idc.GetOpType(address, 0) == 1 and idc.GetOpnd(
                    address, 0) in self.standardRegisters.keys():
                libraryInstruction = self.standardRegisters[idc.GetOpnd(
                    address, 0)]
            else:
                libraryInstruction = idc.GetOperandValue(address, 0)

            for string in self.subStrings:
                if string in idc.GetOpnd(
                        address,
                        1) and currentInstruction >= distanceFromEndOfFunction:
                    self.libraryFunctionNamesDict[string][1] += 1

            if GetMnem(
                    address
            ) == "call" and currentInstruction >= distanceFromEndOfFunction:
                numberOfCalls += 1

            if GetMnem(address) in self.returns.keys(
            ) and currentInstruction >= distanceFromEndOfFunction:
                self.returns[GetMnem(address)] += 1

            if GetMnem(
                    address
            ) == "call" and libraryInstruction in self.libraryFunctionNameEADict.keys(
            ) and currentInstruction >= distanceFromEndOfFunction:
                if self.libraryFunctionNameEADict[
                        libraryInstruction] == "exit":
                    if currentStackValue == "1":
                        self.libraryFunctionNamesDict[
                            self.libraryFunctionNameEADict[
                                libraryInstruction]][1] += 1
                else:
                    if "printf" in self.libraryFunctionNameEADict[
                            libraryInstruction] and GetMnem(
                                previousInstructionEA) == "push":
                        locationOfPushValue = idc.GetOperandValue(
                            previousInstructionEA, 0)

                        if locationOfPushValue in self.allStrings.keys():
                            if "\n" in self.allStrings[locationOfPushValue]:
                                printfNewline[0] += 1
                            else:
                                printfNewline[1] += 1

                    self.libraryFunctionNamesDict[
                        self.
                        libraryFunctionNameEADict[libraryInstruction]][1] += 1

        output = {"LibraryFunctions": {}}
        for libraryFunction in self.libraryFunctionNamesDict.keys():
            output["LibraryFunctions"][
                libraryFunction] = self.libraryFunctionNamesDict[
                    libraryFunction][1]

        output["calls"] = numberOfCalls

        output["returns"] = self.returns
        output["printf with newline"] = printfNewline[0]
        output["printf without newline"] = printfNewline[1]
        output["FileName"] = self.fileName
        output["FileMD5"] = self.fileMD5
        output["Author Name"] = self.authorName
        collection.insert(output)
Example #16
0
def SETNBE(cpu_context, ip, mnem, opvalues):
    """ Set if Not Below or Equal """
    result = int(not (cpu_context.registers.cf | cpu_context.registers.zf))
    cpu_logger.debug("SETNBE 0x{:X} :: Setting {} to {}".format(ip, idc.GetOpnd(ip, 0), result))
    set_operand_value(cpu_context, ip, result, idc.GetOpnd(ip, 0), idc.GetOpType(ip, 0))
Example #17
0
    def find_byte_strings(self):
        for f in idautils.Functions():
            func = idaapi.get_func(f)
            chr_vals = {}
            eightbit = {}
            for head in idautils.Heads(func.startEA, func.endEA):
                if idc.GetMnem(head) == "mov":
                    if re.match('[abcd]l', idc.GetOpnd(
                            head,
                            0)) and idc.GetOpType(head, 1) == idc.o_imm and (
                                (idc.GetOperandValue(head, 1) >= 0x20
                                 and idc.GetOperandValue(head, 1) <= 0x7f)
                                or idc.GetOperandValue(head, 1) in [0xd, 0xa]):
                        eightbit[idc.GetOpnd(head, 0)] = idc.GetOperandValue(
                            head, 1)
                    if (idc.GetOpnd(head, 0).startswith('byte ptr')
                            or idc.GetOpnd(head, 0).startswith('[e')
                        ) and idc.GetOpType(head, 1) == idc.o_imm and (
                            (idc.GetOperandValue(head, 1) >= 0x20
                             and idc.GetOperandValue(head, 1) <= 0x7f)
                            or idc.GetOperandValue(head, 1) in [0xd, 0xa]):
                        reg = idc.GetOpnd(head, 0)
                        reg = reg[reg.find('['):]
                        if reg.count('+') == 0: offset = 0
                        else:
                            ops = reg.split('+')
                            reg = reg[:reg.find('+')] + ']'
                            offset = ctypes.c_int32(
                                idc.GetOperandValue(head, 0)).value
                            reg_base = 0
                            if len(ops) > 2 and ops[1].endswith('h'):
                                reg_base = int(ops[1][:-1], 16)
                            offset -= reg_base
                        if reg not in chr_vals: chr_vals[reg] = {}
                        chr_vals[reg][offset] = (head,
                                                 chr(
                                                     idc.GetOperandValue(
                                                         head, 1)))
                    elif (idc.GetOpnd(head, 0).startswith('byte ptr')
                          or idc.GetOpnd(
                              head, 0).startswith('[e')) and idc.GetOpType(
                                  head, 1) == idc.o_reg and idc.GetOpnd(
                                      head, 1) in eightbit:
                        reg = idc.GetOpnd(head, 0)
                        reg = reg[reg.find('['):]
                        if reg.count('+') == 0:
                            offset = 0
                        else:
                            ops = reg.split('+')
                            reg = reg[:reg.find('+')] + ']'
                            offset = ctypes.c_int32(
                                idc.GetOperandValue(head, 0)).value
                            reg_base = 0
                            if len(ops) > 2 and ops[1].endswith('h'):
                                reg_base = int(ops[1][:-1], 16)
                            offset -= reg_base

                        if reg not in chr_vals:
                            chr_vals[reg] = {}
                        chr_vals[reg][offset] = (head,
                                                 chr(eightbit[idc.GetOpnd(
                                                     head, 1)]))
            for reg, c_v in chr_vals.items():
                keys = c_v.keys()
                keys.sort()
                last = None
                s = ""
                offset = 0
                for o in keys:
                    if last is None:
                        addr = c_v[o][0]
                        offset = o
                        s = c_v[o][1]
                    elif last + 1 == o and c_v[o] != '\x00':
                        s += c_v[o][1]
                    else:
                        if s != "" and len(s) > 3:
                            self.byte_strings["0x%X" % addr] = s
                            func = idaapi.get_func(addr)
                            if offset > 0:
                                s = ""
                                continue

                        s = c_v[o][1]
                        offset = o
                        addr = c_v[o][0]
                    last = o
                if s != "" and len(s) > 1:
                    self.byte_strings["0x%X" % addr] = s
                    func = idaapi.get_func(addr)
Example #18
0
def MOVQ(cpu_context, ip, mnem, opvalues):
    """ Move Quadword """
    opvalue2 = opvalues[1].value & 0xFFFFFFFFFFFFFFFF
    cpu_logger.debug("{} 0x{:X} :: Copy {} into {}".format(mnem, ip, opvalue2, idc.GetOpnd(ip, 0)))
    set_operand_value(cpu_context, ip, opvalue2, idc.GetOpnd(ip, 0), idc.GetOpType(ip, 0))
    def run(self):
        logger.debug('Starting up')
        try:
            here = idc.here()
            logger.info('Using ea: 0x%08x', here)
            if using_ida7api:
                mnem = idc.print_insn_mnem(here)
            else:
                mnem = idc.GetMnem(here)
            if not mnem.startswith('call'):
                logger.info(
                    'Not running at a call instruction. Bailing out now')
                return

            if using_ida7api:
                optype = idc.get_operand_type(here, 0)
            else:
                optype = idc.GetOpType(here, 0)
            if optype == idc.o_near:
                logger.info(
                    "Cannot (or shouldn't) run when call optype is o_near")
                return

            dlg = ApplyCalleeTypeWidget()
            oldTo = idaapi.set_script_timeout(0)
            res = dlg.exec_()
            idaapi.set_script_timeout(oldTo)

            if res == QtWidgets.QDialog.Accepted:
                logger.debug('Dialog accepted. Input type: %d', dlg.inputType)
            else:
                logger.debug('Dialog rejected')
                return

            tinfo = None
            #check user input type
            if dlg.inputType == dlg.USER_TYPE:
                decl = self.convertUserType(str(dlg.getUserText()))
                tinfo = self.getUserDeclType(decl)
            elif dlg.inputType == dlg.STANDARD_TYPE:
                tinfo = self.getBuiltinGlobalType()
            elif dlg.inputType == dlg.LOCAL_TYPE:
                tinfo = self.getLocalType()
            else:
                logger.info('Bad user input type')
                return
            if tinfo is None:
                logger.debug('Bailing due to null tinfo')
                return
            #logger.info('Deserialize result: %r', ret)
            #not 100% sure if i need to explicitly convert from func to funcptr - seemed
            # to pretty much work without this, but doing it just to be sure
            if not tinfo.is_funcptr():
                logger.debug('Converting to func pointer')
                tinfo.create_ptr(tinfo)
            typename = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, tinfo,
                                          '', '')
            logger.info('Applying tinfo: "%s"', str(typename))
            #both applying callee type & setting op type -> not sure if both are needed?
            # set op type causes change in hexrays decompilation
            # apply callee type updates ida's stack analysis
            ret = idaapi.apply_callee_tinfo(here, tinfo)
            if using_ida7api:
                ret = idaapi.set_op_tinfo(here, 0, tinfo)
            else:
                ret = idaapi.set_op_tinfo2(here, 0, tinfo)
            logger.debug('set_op_tinfo2 result: %r', ret)

        except Exception, err:
            logger.exception("Exception caught: %s", str(err))
Example #20
0
def SETNA(cpu_context, ip, mnem, opvalues):
    """ Set if Not Above """
    result = int(cpu_context.registers.zf or cpu_context.registers.cf)
    cpu_logger.debug("SETNA 0x{:X} :: Setting {} to {}".format(ip, idc.GetOpnd(ip, 0), result))
    set_operand_value(cpu_context, ip, result, idc.GetOpnd(ip, 0), idc.GetOpType(ip, 0))
        next_val = int(seq[:n], 16)
        if next_val != 0:
            my_str = chr(next_val) + my_str
        seq = seq[n:]
    return my_str


def hex_to_str(op_val):
    if not is_hex_val(op_val):
        return ""
    op_val = op_val[:len(op_val) - 1]  #remove the 'h' at the end
    #if the number of chars is not even, pad it with zero:
    if (len(op_val) % 2) == 1:
        op_val = '0' + op_val
    my_str = split_and_convert(op_val)
    return my_str


for seg_ea in idautils.Segments():
    for head in idautils.Heads(seg_ea, idc.SegEnd(seg_ea)):
        if idc.isCode(idc.GetFlags(head)):
            mnem = idc.GetMnem(head)
            op_type1 = idc.GetOpType(head, 0)
            op_type2 = idc.GetOpType(head, 1)
            if mnem == 'mov' and op_type1 == 4 and op_type2 == 5:
                op_val = idc.GetOpnd(head, 1)
                ostr = hex_to_str(op_val)
                if len(ostr) > 0:
                    MakeRptCmt(head, ostr)
                    print "%08x : %s" % (head, ostr)