Skip to content

Commit a8caba2

Browse files
committed
better movable instr check
1 parent 9959816 commit a8caba2

File tree

1 file changed

+17
-4
lines changed

1 file changed

+17
-4
lines changed

src/patcherex2/components/utils/utils.py

+17-4
Original file line numberDiff line numberDiff line change
@@ -127,12 +127,25 @@ def is_valid_insert_point(self, addr: int) -> bool:
127127

128128
def is_movable_instruction(self, addr: int) -> bool:
129129
is_thumb = self.p.binary_analyzer.is_thumb(addr)
130-
insn = self.p.binary_analyzer.get_instr_bytes_at(addr)
131-
asm = self.p.disassembler.disassemble(insn, addr, is_thumb=is_thumb)[0]
130+
insn_bytes = self.p.binary_analyzer.get_instr_bytes_at(addr)
131+
disassembled = self.p.disassembler.disassemble(
132+
insn_bytes, addr, is_thumb=is_thumb
133+
)[0]
132134
# if instruction use PC as a base register, it's not movable
133-
tokens = re.split(r"\s|,|\[|\]", asm["op_str"])
135+
tokens = re.split(r"\s|,|\[|\]", disassembled["op_str"])
134136
tokens = list(filter(None, tokens))
135137
if list(set(self.p.archinfo.pc_reg_names) & set(tokens)):
136138
return False
137-
# TODO: is it safe to assume that the instruction is movable if it's not using PC as a base register?
139+
# TODO: this assumes that keystone always gives abs addr when disassembling, but it might not be true
140+
disassembled = self.p.disassembler.to_asm_string(disassembled)
141+
for test_addr in [addr - 0x10000, addr + 0x10000]:
142+
re_assembled = self.p.assembler.assemble(
143+
disassembled, test_addr, is_thumb=is_thumb
144+
)
145+
re_disassembled = self.p.disassembler.disassemble(
146+
re_assembled, test_addr, is_thumb=is_thumb
147+
)[0]
148+
re_disassembled = self.p.disassembler.to_asm_string(re_disassembled)
149+
if re_disassembled != disassembled:
150+
return False
138151
return True

0 commit comments

Comments
 (0)