@@ -127,12 +127,25 @@ def is_valid_insert_point(self, addr: int) -> bool:
127
127
128
128
def is_movable_instruction (self , addr : int ) -> bool :
129
129
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 ]
132
134
# 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" ])
134
136
tokens = list (filter (None , tokens ))
135
137
if list (set (self .p .archinfo .pc_reg_names ) & set (tokens )):
136
138
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
+ disassembled = self .p .disassembler .to_asm_string (disassembled )
140
+ for addr in [0x0 , 0x7F00000 , 0xFE000000 ]:
141
+ re_assembled = self .p .assembler .assemble (
142
+ disassembled , addr , is_thumb = is_thumb
143
+ )
144
+ re_disassembled = self .p .disassembler .disassemble (
145
+ re_assembled , addr , is_thumb = is_thumb
146
+ )[0 ]
147
+ re_disassembled = self .p .disassembler .to_asm_string (re_disassembled )
148
+ if re_disassembled != disassembled :
149
+ return False
150
+ # TODO: this assumes that keystone always gives abs addr when disassembling, but it might not be true
138
151
return True
0 commit comments