def is_stc_jb(ea): """ like: .text:00401042 stc .text:00401043 jb short loc_401046 .text:00401043 ; --------------------------------------------------------------------------- .text:00401045 db 0B1h ; ± .text:00401046 ; --------------------------------------------------------------------------- .text:00401046 .text:00401046 loc_401046: ; CODE XREF: .text:00401043↑j .text:00401046 mov eax, 0 """ insn = idautils.DecodeInstruction(ea) if insn is None: return False, None if insn.get_canon_mnem() != "stc": return False, None next_ea = insn.ea + insn.size insn = idautils.DecodeInstruction(next_ea) if insn is None: return False, None if insn.get_canon_mnem() != "jb": return False, None if insn.ops[0].addr != insn.ea + insn.size + 1: return False, None return True, 4
def is_clc_jnb(ea): """ like: .text:0040139E clc .text:0040139F jnb short loc_4013A2 .text:0040139F ; --------------------------------------------------------------------------- .text:004013A1 db 0Fh .text:004013A2 ; --------------------------------------------------------------------------- .text:004013A2 .text:004013A2 loc_4013A2: ; CODE XREF: .text:0040139F↑j .text:004013A2 mov eax, 0x0 """ insn = idautils.DecodeInstruction(ea) if insn is None: return False, None if insn.get_canon_mnem() != "clc": return False, None next_ea = insn.ea + insn.size insn = idautils.DecodeInstruction(next_ea) if insn is None: return False, None if insn.get_canon_mnem() != "jnb": return False, None if insn.ops[0].addr != insn.ea + insn.size + 1: return False, None return True, 4
def is_locate_protocol_param(xref): """ Returns True if the xref is the 'Protocol' parameter of this function : typedef EFI_STATUS LocateProtocol ( IN EFI_GUID *Protocol, IN VOID *Registration OPTIONAL, OUT VOID **Interface ); """ inst = idautils.DecodeInstruction(xref) if inst is None: return False # Must be 'lea rcx, gSmtGuid' if inst.get_canon_mnem() != 'lea' or inst.Op1.type != ida_ua.o_reg or \ inst.Op1.reg != ida_idp.str2reg('rcx'): return False # Look up to 5 instructions ahead to find: # call [rax+EFI_BOOT_SERVICES.LocateProtocol] for addr in get_func_items_from_xref(xref)[:5]: inst = idautils.DecodeInstruction(addr) if inst.get_canon_mnem() == 'call': if inst.Op1.type == ida_ua.o_displ and \ get_operand_struct_name(inst, 0) == 'EFI_BOOT_SERVICES' and \ inst.Op1.addr == 0x140: return True else: # Bail out if we hit a call that is not LocateProtocol break return False
def decode(ea=None): if ea == None: ea = idc.ScreenEA() ist = idautils.DecodeInstruction(ea) if ist == None: return None _bytes = map(lambda x: chr(idc.Byte(ea + x)), range(ist.size)) _bytes = ''.join(_bytes) ist = distorm3.Decompose(ea, _bytes)[0] # distorm doesn't decode the operand logical size ie.. byte ptr, so use IDA for that for i in range(len(ist.operands)): idaop = idautils.DecodeInstruction(ist.address)[i] setattr(ist.operands[i], 'op_size', op_size(idaop)) def _get_operand_sym(op): if op.type == 'Immediate': return symath.symbolic(op.value) elif op.type == 'AbsoluteMemoryAddress': return DEREF(op.op_size, op.disp) elif op.type == 'Register': return symath.symbols(distorm3.Registers[op.index].upper()) elif op.type == 'AbsoluteMemory': rv = 0 if op.index != None: rv += symath.symbols( distorm3.Registers[op.index].upper()) * op.scale if op.base != None: rv += symath.symbols(distorm3.Registers[op.base].upper()) if op.disp != None: rv += symath.symbolic(op.disp) return DEREF(op.op_size, rv) else: raise BaseException("Unknown operand type %s (%s)" % (op.type, op)) args = list(map(_get_operand_sym, ist.operands)) if ist.mnemonic.lower() == 'call': spdiff = idc.GetSpDiff(ist.address + ist.size) if spdiff == None: spdiff = 0 try: return Call(args[0], spdiff, ist.address) except Exception as ex: print 'failed to wrap call @%x' % (ist.address) raise ex else: return symath.symbolic(ist.mnemonic.lower())(*args)
def create_vtable_struct(start_address, vtable_name, p_vtable_addr, offset): struct_name = vtable_name + "_struct" struct_id = add_struc(-1, struct_name, 0) if struct_id != idc.BADADDR: add_all_functions_to_struct(start_address, struct_id, p_vtable_addr, offset) idc.op_stroff(idautils.DecodeInstruction(get_pc_value()), 1, struct_id, 0) else: struct_id = ida_struct.get_struc_id(struct_name) # Checks if the struct exists, in this case the function offset will be added to the struct if struct_id != idc.BADADDR: idc.op_stroff(idautils.DecodeInstruction(get_pc_value()), 1, struct_id, 0) else: print ("Failed to create struct: " + struct_name)
def fix_block_link(switch_info, block_info): block_end = block_info.end dispatcher = block_info.dispatcher head = block_info.start br_dispatcher_insn = None while head < block_end + 2: inst = idautils.DecodeInstruction(head) head += 2 if inst is None: continue # 00019C82 PUSH {R0,R1,LR} # 00019C84 LDR R0, =0x16A # 00019C86 LDR R1, loc_19C88 # 00019C88 # 00019C88 loc_19C88 ; CODE XREF: LOAD:0001A262↓j # 00019C88 ; LOAD:0001A97A↓j ... # 00019C88 BL sub_2A584 print('entry block {:08x} {:08x}'.format(inst.ea, dispatcher)) if inst.ea == dispatcher: br_dispatcher_insn = inst.ea - 2 break if inst.itype == idaapi.ARM_bl and inst.Op1.type == o_near and inst.Op1.addr == dispatcher: br_dispatcher_insn = inst.ea break if br_dispatcher_insn: push_insn = find_push(br_dispatcher_insn) patch_pos = push_insn.ea assert push_insn addr = skip_nop(push_insn.ea + push_insn.size) print('skip_nop {:08x}'.format(push_insn.ea)) ldr_insn = idautils.DecodeInstruction(addr) idx = get_ldr_value(ldr_insn) next_block_info = switch_info[idx] asm = 'b.w #%s' % (rel(next_block_info.start - 4, patch_pos)) codes, _ = ks.asm(asm, patch_pos) fill_ops(patch_pos, codes) fill_beg = patch_pos + len(codes) fill_end = block_info.end fill_nop(fill_beg, fill_end - fill_beg) print('link BB: %s ==> %s' % (block_info, switch_info[idx])) else: print('successor not found BB: %s' % block_info)
def _get_constant_ref(self, opnum=0): ''' Return the constant value, if any, reference by the instruction. @author: Peter Silberman @rtype: Mixed @return: Integer value of referenced constant, otherwise None. ''' if idaapi.IDA_SDK_VERSION >= 600: instruction = idaapi.cmd.ea else: instruction = idaapi.get_current_instruction() if not instruction: return None if opnum: if idaapi.IDA_SDK_VERSION >= 600: op0 = idautils.DecodeInstruction(instruction)[opnum] else: op0 = idaapi.get_instruction_operand(instruction, opnum) if op0.value and op0.type == o_imm and GetStringType( self.ea) == None: return op0.value else: if idaapi.IDA_SDK_VERSION >= 600: op0 = idautils.DecodeInstruction(instruction)[0] else: op0 = idaapi.get_instruction_operand(instruction, 0) if op0.value and op0.type == o_imm and GetStringType( self.ea) == None: return op0.value if idaapi.IDA_SDK_VERSION >= 600: op1 = idautils.DecodeInstruction(instruction)[1] else: op1 = idaapi.get_instruction_operand(instruction, 1) if op1.value and op1.type == o_imm and GetStringType( self.ea) == None: return op1.value return None
def get_op(ea, op, stkvars=None): '''ea_t -> int -> opt:{int : tinfo_t} -> op_ret''' cmd = idautils.DecodeInstruction(ea) cmd.Operands = get_operands(cmd) # for mips_op_hack op = mips_op_hack(cmd, op) opd = cmd[op] if opd.type == idaapi.o_reg: # gpr, XXX sorta MIPS-specific return op_ret(op_ty.reg, regs.gpr(opd.reg), 0) elif opd.type == idaapi.o_idpspec1: # fpr, XXX sorta MIPS-specific return op_ret(op_ty.reg, regs.fpr(opd.reg), 0) elif opd.type in [idaapi.o_near, idaapi.o_mem]: return op_ret(op_ty.name, idc.Name(opd.addr), 0) elif idc.isStkvar1(idc.GetFlags(ea)): # IDA seems to set this flag even for operands beyond the second, # i.e. both of these are true for isStkvar1: # .text:10003A84 sd $a1, 0x2E0+var_58($sp) # .text:10003A68 addiu $a1, $sp, 0x2E0+var_2D8 try: func = idaapi.get_func(ea) off = idaapi.calc_stkvar_struc_offset(func, ea, op) (name, ti) = stkvars[off] return op_ret_for_ti(ti, name, off, off) except KeyError: raise OperandUnresolvableError('unable to get operand %u at %s' % (op, idc.atoa(ea))) elif opd.type in [idaapi.o_imm, idaapi.o_displ]: return cpu_ida.ida_current_cpu().data.get_op_addrmode(ea, op, cmd) else: raise OperandUnresolvableError('unable to get operand %u at %s' % (op, idc.atoa(ea)))
def __mark_bbls(self): for thread in self["mem_areas"][0]['threads']: for bbl in thread['bbls']: ea = bbl['start'] for _ in range(bbl['inst']): idaapi.set_item_color(ea, 0x49feaf) ea += idautils.DecodeInstruction(ea).size
def _collect_all(self): """ Calls the attributes' Collect functions, once for attributes in ATTRS_COLLECTED_ONCE and for each instruction in for attributes in ATTR_COLLECTED_ITER. """ collect_args = {"first_addr": self._first_addr} # Attributes that don't need to iterate instructions. for one_attribute in ATTRS_COLLECTED_ONCE.keys(): getattr(self, one_attribute)._collect_data(collect_args) # Attributes which need to iterate instructions. Iterate over # instructions, while each attribute extracts data from it. for i in range(len(self._func_items)): func_item = self._func_items[i] ins = idautils.DecodeInstruction(func_item) ins_type = ins.itype ins_operands = redb_client_utils.collect_operands_data(func_item) collect_args["func_item"] = func_item collect_args["ins_type"] = ins_type collect_args["ins_operands"] = ins_operands for one_attribute in ATTR_COLLECTED_ITER.keys(): getattr(self, one_attribute)._collect_data(collect_args)
def jumps_to(f, t): f_ea = idc.LocByName(f) t_ea = idc.LocByName(t) for start, end in idautils.Chunks(f_ea): ea = start while (ea < end): i = idautils.DecodeInstruction(ea) #Functions have data chunks in them, these are offsets and dwords. skipping 4 ahead seems like a safe choice. if type(i) == type(None): ea += 4 continue #detect if instruction is a jump to t_ea m = idc.GetMnem(ea) if idc.GetMnem(ea) == "LDR" and idc.GetOpnd( ea, 0) == "PC" and t in idc.GetOpnd(ea, 1): return True elif idc.GetMnem(ea) == "BX" and idc.GetOpnd(ea, 0) == t: return True try: ea += i.size except: print "0x%08x" % ea print "DecodeInstruction failed!" print i.size return False
def activate(self, ctx): screen_ea = idaapi.get_screen_ea() gen_xrefs = idautils.XrefsTo(screen_ea, 0) for xx in gen_xrefs: ref_loc = xx.frm print("Creating switch idiom at ea: ", hex(ref_loc)) jmp_loc = ref_loc + 14 print("Jump instruction should be at: ", hex(jmp_loc)) ins = idautils.DecodeInstruction(jmp_loc) name = ins.get_canon_mnem() if name != "jmp": print("Warning found instruction ", name) continue if ins.Op1.type != idaapi.o_reg: print("Warning found non reg as operand") continue reg_num = ins.Op1.reg reg_name = idaapi.get_reg_name(reg_num, 8) print("Jump register is named ", reg_name) s = idaapi.switch_info_t() s.flags |= idaapi.SWI_SIGNED | idaapi.SWI_ELBASE s.elbase = screen_ea s.set_jtable_element_size(4) s.ncases = 6 s.set_expr(reg_num, 7) s.jumps = screen_ea s.startea = jmp_loc idaapi.set_switch_info(jmp_loc, s) idaapi.create_switch_table(jmp_loc, s) return 1
def is_jump_plus_one(ea): """ like: .text:00401089 jmp short loc_40108C .text:00401089 ; --------------------------------------------------------------------------- .text:0040108B db 0BAh ; º .text:0040108C ; --------------------------------------------------------------------------- .text:0040108C .text:0040108C loc_40108C: ; CODE XREF: .text:00401089↑j .text:0040108C mov eax, 1 """ insn = idautils.DecodeInstruction(ea) if insn is None: logger.debug("0x%x: failed to decode instruction", ea) return False, None if insn.get_canon_mnem() != "jmp": return False, None next_ea = insn.ea + insn.size if insn.ops[0].addr != next_ea + 1: return False, None return True, insn.size + 1
def jump_branches(self, ea): """ if this instruction is a jump, yield the destination(s) of the jump, of which there may be more than one. only literal destinations (i.e. addresses without dereferences) are yielded. """ mnem = idc.GetMnem(ea) insn = idautils.DecodeInstruction(ea) if mnem in self.unconditional_jumps: if insn.Op1.type == idaapi.o_near: if insn.Op1.addr > self.signed_limit: dest = -((self.max_int + 1) - op.addr) else: dest = insn.Op1.addr yield dest elif mnem in self.conditional_jumps: dest = insn.Op1.addr yield dest dest = ea + insn.size yield dest return
def activate(self, ctx): # print("ctx.cur_ea : 0x%x" % ctx.cur_ea) # print("ctx.cur_extracted_ea : 0x%x" % ctx.cur_extracted_ea) # Extract selected enum instruction = idc.GetDisasm(ctx.cur_ea) selection = ctx.cur_extracted_ea # correctly parse the selected value as int (hex or decimal) # since ctx.cur_extracted_ea has a bug (IDA always consider # the selected value as hex) if instruction.find("{0:X}h".format(selection)) != -1: # print("hex value found !") selected_value = ctx.cur_extracted_ea elif instruction.find("{0:d}".format(selection)) != -1: # print("int value found !") selected_value = int("%x" % ctx.cur_extracted_ea) else: # print("nothing selected !") return 1 # next power of two for masking selected_value_mask = self.shift_bit_length(selected_value) - 1 # print("selected_value : 0x%X" % selected_value) # print("selected_value mask : 0x%X" % selected_value_mask) # query magnum db url = SearchMagicNumber.MAGNUMDB_QUERY.format( value=selected_value, key=SearchMagicNumber.MAGNUMDB_KEY) answer = urlopen(url) results = json.loads(answer.read()) # Let the user select the best answer c = ChooseMagicNumber(selected_value, results["Items"]) selected_index = c.Show(modal=True) if selected_index < 0: return # Apply the newly found enum selected_item = results["Items"][selected_index] selected_name = selected_item["Title"].encode('ascii') selected_value = int(selected_item["Value"]) # serial is important since several entries can have the same value entryid, serial = self._manager.add_magnumdb_entry( selected_name, selected_value) # locate the operand where to apply the enum insn = idautils.DecodeInstruction(ctx.cur_ea) for op in filter(lambda o: o.type == idaapi.o_imm, insn.Operands): # heuristic : the selected immediate is the first in the instruction with # the same exact value (we are using a mask since IDA loves to set FFFFFFFF to high words) if op.value & selected_value_mask == selected_value: # Apply the enum idc.OpEnumEx(ctx.cur_ea, op.n, idaapi.get_enum("_IDA_MAGNUMDB"), serial) break return 1
def togglejump(self, ea): """ Toggle jump condition """ inst = idautils.DecodeInstruction(ea) mnem = inst.get_canon_mnem() if mnem not in self.JUMPS: return False return self.assemble( ea, [idc.GetDisasm(ea).replace(mnem, self.JUMPS[mnem])])
def decode_instruction(ea): """Read the bytes of an x86/amd64 instruction. This handles things like combining the bytes of an instruction with its prefix. IDA Pro sometimes treats these as separate.""" global _NOT_INST_EAS, _BAD_INSTRUCTION, PREFIX_ITYPES if ea in _NOT_INST_EAS: return _BAD_INSTRUCTION decoded_inst = idautils.DecodeInstruction(ea) if not decoded_inst: _NOT_INST_EAS.add(ea) return _BAD_INSTRUCTION assert decoded_inst.ea == ea end_ea = ea + decoded_inst.size decoded_bytes = read_bytes_slowly(ea, end_ea) # We've got an instruction with a prefix, but the prefix is treated as # independent. if 1 == decoded_inst.size and decoded_inst.itype in PREFIX_ITYPES: decoded_inst, extra_bytes = decode_instruction(end_ea) decoded_bytes += extra_bytes return decoded_inst, decoded_bytes
def stringify(): ea = idc.here() size_data = get_bitness_bytes(ea) f = idaapi.get_func(ea) frsize = idc.GetFrameLvarSize(ea) position = f.startEA size = 0 while position < f.endEA: instr = idautils.DecodeInstruction(position) if instr is None: print("%x: Not and instruction found" % position) break mnem = instr.get_canon_mnem() if mnem == "mov": if instr.Op2.type == idaapi.o_imm and instr.Op1.type == idaapi.o_reg: #this may be string load is_string, size_s = is_this_a_real_string( position + instr.size, instr, size_data) if is_string is True: make_string(instr.Op2.value, size_s) elif mnem == "lea": if instr.Op2.type == idaapi.o_mem and instr.Op1.type == idaapi.o_reg: is_string, size_s = is_this_a_real_string( position + instr.size, instr, size_data) if is_string is True: make_string(instr.Op2.addr, size_s) position += instr.size
def isLikeLoadJmpTable(ea): insn_t = idautils.DecodeInstruction(ea) # 1) mov reg, off[reg*4] if hasDispl(insn_t, 1): base, scale, index, displ = getAddressParts(insn_t, 1) if base == 5 and scale == 2 and idc.isData(idc.GetFlags(displ)): # check if there is a table of valid code pointers ncases = 0 bs = idaapi.get_many_bytes(displ, 4) if bs == None or len(bs) != 4: return False jmpaddress = struct.unpack('<I', bs)[0] while idc.isCode(idc.GetFlags(jmpaddress)): ncases += 1 bs = idaapi.get_many_bytes(displ+ncases*4, 4) if bs == None or len(bs) != 4: break jmpaddress = struct.unpack('<I', bs)[0] if ncases != 0: return True return False
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))
def apply_struct(start, end, reg_name, struct_name): offsets, operands = infer_struct_offsets(start, end, reg_name) sid = get_struct(struct_name) for ea, n in operands: insn = idautils.DecodeInstruction(ea) idc.op_stroff(insn, n, sid, 0)
def code_score(start_ea, end_ea): code_count = 0 total_count = 0 for ea in range(start_ea, end_ea, 4): if idautils.DecodeInstruction(ea): code_count += 1 total_count += 1 return float(code_count) / total_count, total_count
def _instructions_by_count(pc, count): """A generator to iterate over a specified number of instructions.""" for i in xrange(count): insn = idautils.DecodeInstruction(pc) if insn is None: break yield insn pc += insn.size
def __init__(self, ea): self._ea = ea self._insn = idautils.DecodeInstruction(ea) if self._insn is None: raise exceptions.SarkNoInstruction("No Instruction at 0x{:08X}.".format(ea)) self._operands = self._make_operands()
def instruction_data(func_item): """ Returns an integer representing the instruction. """ func_item_size = idautils.DecodeInstruction(func_item).size cmd_data = 0 for i in idaapi.get_many_bytes(func_item, func_item_size): cmd_data = (cmd_data << 8) + ord(i) return cmd_data
def is_jmp_ret(ea): """ like: .text:004010C9 call $+5 .text:004010CE add dword ptr [esp], 6 .text:004010D2 retn .text:004010D2 ; --------------------------------------------------------------------------- .text:004010D3 db 7Dh ; } .text:004010D4 ; --------------------------------------------------------------------------- .text:004010D4 mov eax, 0 """ insn = idautils.DecodeInstruction(ea) if insn is None: return False, None if insn.get_canon_mnem() != "call": return False, None next_ea = insn.ea + insn.size if insn.ops[0].addr != next_ea: return False, None insn = idautils.DecodeInstruction(next_ea) if insn is None: return False, None if insn.get_canon_mnem() != "add": return False, None delta = insn.ops[1].value target = next_ea + delta next_ea = insn.ea + insn.size insn = idautils.DecodeInstruction(next_ea) if insn is None: return False, None if insn.get_canon_mnem() != "retn": return False, None return True, target - ea
def isJmpTable(ea): insn_t = idautils.DecodeInstruction(ea) is_jmp = insn_t.itype in [idaapi.NN_jmp, idaapi.NN_jmpfi, idaapi.NN_jmpni] if not is_jmp: return False if idaapi.get_switch_info_ex(ea): return True return False
def get_operand_expression(self, ea, n): """ return an expression representing the 'n'-th operand of the instruction at 'ea'. """ insn = idautils.DecodeInstruction(ea) op = insn[n] if op.type == idaapi.o_reg: # General Register (al,ax,es,ds...) reg sz = self.get_operand_size(op) expr = regloc_t(op.reg, sz) elif op.type == idaapi.o_mem: # Direct Memory Reference (DATA) addr = self.as_signed(op.addr) if self.has_sib_byte(op): reg = self.get_sib_scaled_index_reg(op) # *(addr+reg*scale) expr = deref_t(add_t(value_t(addr), \ mul_t(regloc_t(reg, self.get_register_size(reg)), \ value_t(self.get_sib_scale(op), 8))), self.get_operand_size(op)) else: expr = deref_t(value_t(addr, self.address_size), self.get_operand_size(op)) elif op.type == idaapi.o_phrase: # Memory Ref [Base Reg + Index Reg] expr = regloc_t(op.reg, self.get_register_size(op.reg)) expr = deref_t(expr, self.get_operand_size(op)) elif op.type == idaapi.o_displ: # Memory Reg [Base Reg + Index Reg + Displacement] phrase+addr addr = self.as_signed(op.addr) expr = regloc_t(op.reg, self.get_register_size(op.reg)) expr = add_t(expr, value_t(addr, self.address_size)) expr = deref_t(expr, self.get_operand_size(op)) elif op.type == idaapi.o_imm: # Immediate Value _value = self.as_signed(op.value) expr = value_t(_value, self.get_operand_size(op)) elif op.type == idaapi.o_near: # Immediate Far Address (CODE) addr = self.as_signed(op.addr) expr = value_t(addr, self.get_operand_size(op)) else: #~ print hex(ea), raise RuntimeError('%x: unhandled operand type: %s %s' % (ea, repr(op.type), repr(idc.GetOpnd(ea, 1)))) return return expr
def is_this_a_real_string(next_pos, instr, size_data): #Common scenario is when we mov offset into register #and after that either fill local string variable or push string as argument #so we just check that we use esp next_instr = idautils.DecodeInstruction(next_pos) if next_instr.get_canon_mnem() == "mov": is_stack_used, ptr_addr = parseOp(next_instr.Op1) if is_stack_used is True: #Check if we really place our offset if next_instr.Op2.type == idaapi.o_reg and next_instr.Op2.reg == instr.Op1.reg: next_pos += next_instr.size next_instr = idautils.DecodeInstruction(next_pos) if next_instr.get_canon_mnem() == "mov": is_stack_used, size_addr = parseOp(next_instr.Op1) #if we filling string or at least smthng looking very similar if is_stack_used is True and (size_addr - ptr_addr == size_data): #for now explicitly set 0x1000 as max string size if next_instr.Op2.type == idaapi.o_imm and next_instr.Op2.value < 0x1000: return True, next_instr.Op2.value return False, 0
def assemble(self, ea, cs, ip, use32, line): line = line.strip() if line == "xor eax, eax": return "\x33\xC0" elif line == "nop": # Decode current instruction to figure out its size cmd = idautils.DecodeInstruction(ea) if cmd: # NOP all the instruction bytes return "\x90" * cmd.size return None