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))
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))
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))
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))
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))
#获取上一条指令的地址 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))
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("\\", "/")
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))
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]
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)
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, ])
# .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)
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()
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))
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)
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))
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)
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))
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)