def _lift_op(il: LowLevelILFunction, insn: SHInsn, op: Oper, sign_ext=False): il_op = None if op.type == OpType.REG: if op.reg == "PC": il_op = il.const(RSIZE, insn.addr) else: il_op = il.reg(RSIZE, op.reg) elif op.type == OpType.IMM or op.type == OpType.DISP: assert op.size != 0, f"Invalid instruction at: 0x{insn.addr:x}" if op.type == OpType.DISP and op.is_ref and op.is_pair: # Fetch the next part of the pair next_op = None for i, cur_op in enumerate(insn.opcode["args"]): if cur_op.is_pair: next_op = insn.opcode["args"][i + 1] break assert next_op is not None, f"Invalid instruction at: 0x{insn.addr:x}" assert next_op.type == OpType.REG, f"Invalid instruction at: 0x{insn.addr:x}" if next_op.reg == "PC": cur_il = il.shift_left( RSIZE, il.const(RSIZE, op.val), il.const(RSIZE, int(insn.opcode['width'] / 2))) if insn.opcode["width"] == 4: next_il = il.and_expr(RSIZE, il.const(RSIZE, insn.addr), il.const(RSIZE, 0xFFFFFFFC)) else: next_il = il.const(RSIZE, insn.addr) next_il = il.add(RSIZE, next_il, il.const(RSIZE, 4)) else: cur_il = il.const(op.size, op.val) next_il = il.reg(RSIZE, next_op.reg) il_op = il.add(RSIZE, cur_il, next_il) else: il_op = il.const(op.size, op.val) if sign_ext: il_op = il.sign_extend(RSIZE, il_op) return il_op
def lift_movi20s(il: LowLevelILFunction, insn: SHInsn): assert len(insn.opcode["args"] ) == 2, f"Invalid instruction at: 0x{insn.addr:x}" op_1 = insn.opcode["args"][0] op_2 = insn.opcode["args"][1] assert op_1.type == OpType.IMM, f"Invalid instruction at: 0x{insn.addr:x}" assert op_1.size != 0, f"Invalid instruction at: 0x{insn.addr:x}" il.append( il.set_reg( RSIZE, op_2.reg, il.sign_extend( RSIZE, il.shift_left(op_1.size, il.const(op_1.size, op_1.val), il.const(1, 8)))))