def decode_instr(eip): MakeCode(eip) mnem = idaapi.ua_mnem(eip) sz = idaapi.decode_insn(eip) x = dict(nextip=[],inst=mnem, ops=[]) if not idaapi.cmd.itype in (idaapi.NN_jmp, idaapi.NN_retn): x['nextip'].append(eip+sz) for n, op in enumerate(idaapi.cmd.Operands): if op.type == 0: break ty = op.type text = idaapi.tag_remove(idaapi.ua_outop2(eip, n)) if op.dtyp == 0: bits = 8 elif op.dtyp == 1: bits = 16 elif op.dtyp == 2: bits = 32 if ty == idc.o_reg: x['ops'].append(IR.Var(text, bits)) elif ty == idc.o_mem: x['ops'].append(IR.Mem(IR.Const(op.addr),bits)) elif ty in (idc.o_phrase, idc.o_displ): x['ops'].append(IR.Mem(parse_mem(op),bits)) elif ty == idc.o_imm: x['ops'].append(IR.Const(op.value,bits)) elif ty == idc.o_near: x['ops'].append(IR.Const(op.addr)) x['nextip'].append(op.addr) else: raise UnknownError return x
def decode_instr(eip): MakeCode(eip) mnem = idaapi.ua_mnem(eip) sz = idaapi.decode_insn(eip) x = dict(nextip=[], inst=mnem, ops=[]) if not idaapi.cmd.itype in (idaapi.NN_jmp, idaapi.NN_retn): x['nextip'].append(eip + sz) for n, op in enumerate(idaapi.cmd.Operands): if op.type == 0: break ty = op.type text = idaapi.tag_remove(idaapi.ua_outop2(eip, n)) if op.dtyp == 0: bits = 8 elif op.dtyp == 1: bits = 16 elif op.dtyp == 2: bits = 32 if ty == idc.o_reg: x['ops'].append(IR.Var(text, bits)) elif ty == idc.o_mem: x['ops'].append(IR.Mem(IR.Const(op.addr), bits)) elif ty in (idc.o_phrase, idc.o_displ): x['ops'].append(IR.Mem(parse_mem(op), bits)) elif ty == idc.o_imm: x['ops'].append(IR.Const(op.value, bits)) elif ty == idc.o_near: x['ops'].append(IR.Const(op.addr)) x['nextip'].append(op.addr) else: raise UnknownError return x
def decoder(self,from_loc,to_loc,key): self.GlobalCounter += 1 for loc in range(from_loc, to_loc+1): temp = idc.Byte(loc) ^ key idc.PatchByte(loc,temp) SetColor(loc, CIC_ITEM, 0x208020) next_inst = from_loc ready = False xor_check = False jmp_dword = False idc.MakeUnkn(from_loc,1) idc.MakeCode(from_loc) while next_inst <= to_loc: #idc.MakeCode(next_inst) idaapi.decode_insn(next_inst) inst = idc.GetDisasm(next_inst) print "inst %s next_inst %x" % (inst, next_inst) opndValue = idc.GetOperandValue(next_inst,1) if ready and xor_check and jmp_dword: self.flag.append(format(key,'x')) print '[{0:d}] decoder(0x{1:x},0x{2:x},0x{3:x})'.format(self.GlobalCounter,from_loc,to_loc,key) if self.GlobalCounter >= 10: print ''.join([chr(int(i,16)) for i in self.flag]).strip() return self.decoder(from_loc,to_loc,key) elif "xor" in inst: #key = hex(opndValue) #print idaapi.cmd.Operands[1].value xor_check = True key = idc.GetOperandValue(next_inst,1) print key elif "mov" in inst or format(idaapi.get_byte(next_inst),'x') == "BA": print idaapi.cmd.Operands[1].value to_loc = idaapi.cmd.Operands[1].value elif format(idaapi.get_byte(next_inst),'x') == "81" or "cmp" in inst: print idaapi.cmd.Operands[1].value from_loc = idaapi.cmd.Operands[1].value ready = True elif format(idaapi.get_byte(next_inst),'x') == "e9" or "jmp" in inst: print 'jmp_dword hitted' jmp_dword = True if idaapi.cmd.Operands[0].type == o_near and "dword" in GetOpnd(next_inst,0): offset = int(idaapi.tag_remove(idaapi.ua_outop2(next_inst, 0))[24:-1],16) address = GetOperandValue(next_inst,0) dword_adr = address - offset idc.MakeUnkn(dword_adr,DOUNK_SIMPLE) idc.MakeCode(address) next_inst = idc.NextHead(next_inst) #next_inst += idaapi.decode_insn(next_inst) print "out of loop"
def ops_repr(ea): '''Returns the repr of each operand of an instruction''' insn = at(ea) res = (idaapi.ua_outop2(insn.ea, n) for n in range(ops_count(insn.ea))) return [idaapi.tag_remove(res) if res else None for res in res]
def AnalyzeRange( self, startEA, endEA ): CurrentAddress = startEA CurrentBlockAddress = CurrentAddress NewBlockStart = True last_op_code = '' while CurrentAddress < endEA: if idaapi.isCode( idaapi.get_flags_novalue( CurrentAddress ) ): idaapi.decode_insn( CurrentAddress ) op_code = idaapi.ua_mnem( CurrentAddress ) operands=[] disasm_line = op_code + ' ' for i in range(0, 6, 1): operand = idaapi.ua_outop2( CurrentAddress, i ) if not operand: break; operand = idaapi.tag_remove( operand ) operands.append( operand ) if i != 0: disasm_line += ',' disasm_line += operand #disasm_line = idaapi.tag_remove( idaapi.generate_disasm_line( CurrentAddress ) ) xref = idaapi.xrefblk_t() ret = xref.first_to( CurrentAddress, idaapi.XREF_FAR ) while ret: ret = xref.next_to() NewBlockStart = True if NewBlockStart and last_op_code[0:3] != 'ret' and last_op_code != 'new block': self.AddToMap( CurrentBlockAddress, CurrentAddress, None, 'link') if NewBlockStart: CurrentBlockAddress = CurrentAddress self.BlockData[CurrentBlockAddress]=[] if self.DebugLevel > 2: print '='*80 if self.DebugLevel > 2: print hex(CurrentAddress), disasm_line self.BlockData[CurrentBlockAddress].append( ( CurrentAddress, disasm_line ) ) NewBlockStart = False CallIsResolved = False ret = xref.first_from( CurrentAddress, idaapi.XREF_FAR ) while ret: if xref.iscode: if op_code == 'jmp' and xref.to == CurrentAddress + idaapi.cvar.cmd.size: NewBlockStart = True elif op_code == 'call': CallIsResolved = True self.AddToMap( CurrentBlockAddress,xref.to, operands[0], 'call') else: if len(operands) > 0 : self.AddToMap( CurrentBlockAddress,xref.to, operands[0], 'from') NewBlockStart = True ret = xref.next_from() if ( op_code == 'call' or op_code =='' ) and not CallIsResolved: self.AddToMap( CurrentBlockAddress, operands[0], operands[0], 'call') if NewBlockStart and op_code != 'jmp': self.AddToMap( CurrentBlockAddress, CurrentAddress + idaapi.cvar.cmd.size, '', 'link') if op_code[0:3] == 'ret': NewBlockStart = True last_op_code = op_code CurrentAddress += idaapi.cvar.cmd.size else: CurrentAddress += 1
def to_masm(self): s = idaapi.tag_remove(idaapi.ua_outop2(self.ea, self.idx)) s = do_special_op_replacements(s) return qualify_stack_struct_references(s, self.struct_vars)
#跳过库函数和简单的跳转函数 if flags & FUNC_LIB or flags & FUNC_THUNK: continue dism_addr = list(idautils.FuncItems(func)) for curr_addr in dism_addr: op = None index = None #另一种访问类型的方式,跟idc.GetOpType类似 idaapi.decode_insn(curr_addr) if idaapi.cmd.Op1.type == idaapi.o_displ: op = 1 if idaapi.cmd.Op2.type == idaapi.o_displ: op = 2 if op == None: continue if "bp" in idaapi.tag_remove(idaapi.ua_outop2( curr_addr, 0)) or "bp" in idaapi.tag_remove( idaapi.ua_outop2(curr_addr, 1)): # bp/ebp/rbp将返回一个负数 if op == 1: index = (~(int(idaapi.cmd.Op1.addr) - 1) & 0xFFFFFFFF) else: index = (~(int(idaapi.cmd.Op2.addr) - 1) & 0xFFFFFFFF) else: if op == 1: index = int(idaapi.cmd.Op1.addr) else: index = int(idaapi.cmd.Op2.addr) if index: if displace.has_key(index) == False: displace[index] = [] displace[index].append(curr_addr)
def AnalyzeRange(self, startEA, endEA): CurrentAddress = startEA CurrentBlockAddress = CurrentAddress NewBlockStart = True last_op_code = '' while CurrentAddress < endEA: if idaapi.isCode(idaapi.get_flags_novalue(CurrentAddress)): idaapi.decode_insn(CurrentAddress) op_code = idaapi.ua_mnem(CurrentAddress) operands = [] disasm_line = op_code + ' ' for i in range(0, 6, 1): operand = idaapi.ua_outop2(CurrentAddress, i) if not operand: break operand = idaapi.tag_remove(operand) operands.append(operand) if i != 0: disasm_line += ',' disasm_line += operand #disasm_line = idaapi.tag_remove( idaapi.generate_disasm_line( CurrentAddress ) ) xref = idaapi.xrefblk_t() ret = xref.first_to(CurrentAddress, idaapi.XREF_FAR) while ret: ret = xref.next_to() NewBlockStart = True if NewBlockStart and last_op_code[ 0:3] != 'ret' and last_op_code != 'new block': self.AddToMap(CurrentBlockAddress, CurrentAddress, None, 'link') if NewBlockStart: CurrentBlockAddress = CurrentAddress self.BlockData[CurrentBlockAddress] = [] if self.DebugLevel > 2: print '=' * 80 if self.DebugLevel > 2: print hex(CurrentAddress), disasm_line self.BlockData[CurrentBlockAddress].append( (CurrentAddress, disasm_line)) NewBlockStart = False CallIsResolved = False ret = xref.first_from(CurrentAddress, idaapi.XREF_FAR) while ret: if xref.iscode: if op_code == 'jmp' and xref.to == CurrentAddress + idaapi.cvar.cmd.size: NewBlockStart = True elif op_code == 'call': CallIsResolved = True self.AddToMap(CurrentBlockAddress, xref.to, operands[0], 'call') else: if len(operands) > 0: self.AddToMap(CurrentBlockAddress, xref.to, operands[0], 'from') NewBlockStart = True ret = xref.next_from() if (op_code == 'call' or op_code == '') and not CallIsResolved: self.AddToMap(CurrentBlockAddress, operands[0], operands[0], 'call') if NewBlockStart and op_code != 'jmp': self.AddToMap(CurrentBlockAddress, CurrentAddress + idaapi.cvar.cmd.size, '', 'link') if op_code[0:3] == 'ret': NewBlockStart = True last_op_code = op_code CurrentAddress += idaapi.cvar.cmd.size else: CurrentAddress += 1