Skip to content

Commit acf8986

Browse files
committed
Fix IndexError raised for single operand IMUL instruction
1 parent 78fba75 commit acf8986

2 files changed

Lines changed: 25 additions & 1 deletion

File tree

reccmp/compare/asm/fixes.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,11 @@ def patch_mov_commutative(orig: list[str], recomp: list[str]) -> set[int]:
155155
orig_ops = _split_operands(orig[inst_index])
156156
recomp_ops = _split_operands(recomp[inst_index])
157157

158-
if len(orig_mov_ops) < 2 or len(recomp_mov_ops) < 2:
158+
# We expect these instructions to all have two operands.
159+
if any(
160+
len(operands) != 2
161+
for operands in (orig_mov_ops, recomp_mov_ops, orig_ops, recomp_ops)
162+
):
159163
return set()
160164

161165
# MOV destination must be the same register in both versions.

tests/test_fixes.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,26 @@ def test_fix_mov_imul_swap_valid():
256256
assert is_effective is True
257257

258258

259+
def test_fix_mov_imul_single_operand_imul():
260+
"""Should not crash with IndexError if single operand IMUL is used.
261+
The desination is presumed to be EAX/AX/AL, so this example could be considered a match.
262+
"""
263+
264+
orig_asm = [
265+
"mov ax, word ptr [ebp - 0x4]",
266+
"imul word ptr [ebp - 0x8]",
267+
]
268+
recomp_asm = [
269+
"mov ax, word ptr [ebp - 0x8]",
270+
"imul word ptr [ebp - 0x4]",
271+
]
272+
273+
diff = difflib.SequenceMatcher(None, orig_asm, recomp_asm)
274+
is_effective = find_effective_match(diff.get_opcodes(), orig_asm, recomp_asm)
275+
276+
assert is_effective is False
277+
278+
259279
def test_fix_mov_add_swap_valid():
260280

261281
orig_asm = [

0 commit comments

Comments
 (0)