def get_instruction_low_level_il(self, data, addr, il: LowLevelILFunction): try: (nmemonic, inst_length, inst_operand, inst_type, mode, value) = M6800._decode_instruction(data, addr) except LookupError as error: log_error(error.__str__()) return None # Figure out what the instruction uses load_size = 2 if nmemonic in BIGGER_LOADS else 1 operand, second_operand = None, None # if this is a conditional branch, handle that separately if inst_type == InstructionType.CONDITIONAL_BRANCH: M6800._handle_branch(il, nmemonic, inst_length, value) return inst_length # if this is an unconditional branch, handle that separately if inst_type == InstructionType.UNCONDITIONAL_BRANCH: M6800._handle_jump(il, value) return inst_length if mode == AddressMode.ACCUMULATOR: # handle the case where we need the name, not the reg, for pop operand = inst_operand if nmemonic == 'PUL' else il.reg( 1, inst_operand) elif mode == AddressMode.INDEXED: # set the destination variable for the memory store operations destination = il.add(2, il.reg(2, 'IX'), il.const(1, value)) operand = il.load(load_size, destination) elif mode in [AddressMode.DIRECT, AddressMode.EXTENDED]: # set the destination variable for the memory store operations destination = il.const(inst_length - 1, value) operand = il.load(load_size, destination) elif mode == AddressMode.IMMEDIATE: operand = il.const(inst_length - 1, value) elif mode == AddressMode.RELATIVE: # we have already calculated the absolute address # set the destination variable for the memory store operations destination = il.const(2, value) operand = il.load(load_size, destination) # if we are dual mode, we have to handle things special if inst_type == InstructionType.DUAL: second_operand = inst_operand # calculate the base LLIL operation = LLIL_OPERATIONS[nmemonic](il, operand, second_operand) # if the instruction has different destinations, set them appropriately if nmemonic in REGISTER_OR_MEMORY_DESTINATIONS: if mode == AddressMode.ACCUMULATOR: operation = il.set_reg(1, inst_operand, operation) else: operation = il.store(1, destination, operation) # Finally, calculate and append the instruction(s) il.append(operation) return inst_length
def lift_mov_b(il: LowLevelILFunction, insn: SHInsn): assert len(insn.opcode["args"] ) > 1, f"Invalid instruction at: 0x{insn.addr:x}" op_1 = insn.opcode["args"][0] if op_1.is_pair: op_2 = insn.opcode["args"][2] else: op_2 = insn.opcode["args"][1] extra_op = None if op_1.is_ref: il_op = il.set_reg( RSIZE, op_2.reg, il.load(insn.opcode["width"], Lifter._lift_op(il, insn, op_1))) if op_1.mod_reg != 0: if op_1.type == OpType.REG and op_2.type == OpType.REG and op_1.mod_reg > 0: extra_op = None else: extra_op = il.set_reg( RSIZE, op_1.reg, il.add(RSIZE, il.reg(RSIZE, op_1.reg), il.const(RSIZE, op_1.mod_reg))) elif op_2.is_ref: il_op = il.store(insn.opcode["width"], Lifter._lift_op(il, insn, op_2), Lifter._lift_op(il, insn, op_1)) if op_2.mod_reg != 0: extra_op = il.set_reg( RSIZE, op_2.reg, il.add(RSIZE, il.reg(RSIZE, op_2.reg), il.const(RSIZE, op_2.mod_reg))) else: assert False, f"Invalid instruction at: 0x{insn.addr:x}" il.append(il_op) if extra_op is not None: il.append(extra_op)