JonathanSalwan/ROPgadget

Incorrect handling of movsxd instruction

sleirsgoevy opened this issue · 6 comments

ROPgadget output is incorrect for the following code:

main:
movsxd rax, edi
ret

ROPgadget reports the movsxd rax, edi ; ret gadget at main+1, while it is actually at main.

EDIT: #56 seems to be related. Probably that is another symptom of the same off-by-1 error.

According to capstone in your example movsxd rax, edi ; ret gadget does exist at main+0x1 (_start+0x1 in example below).

$ cat test.s
_start:
  movsxd rax, edi
  ret
$ objdump -d -M intel test
0000000000401000 <_start>:
  401000:	48 63 c7             	movsxd rax,edi
  401003:	c3                   	ret
$ cstool x64 4863c7
 0  48 63 c7                                         movsxd	rax, edi
$ cstool x64 63c7
 0  63 c7                                            movsxd	rax, edi

Then it is probably a bug in capstone itself. The instruction without the leading byte does not actually work as movsxd rax, edi.

Yes, it is a capstone bug. I checked that this bug kind of fixed in capstone upcoming 5 release (next branch). So I think you can install fresh capstone to avoid this bug.

However, I am not sure that they correctly fix this instruction decoding. According to fresh capstone

$ cstool x64 63c7
ERROR: invalid assembly code

But e.g. gdb disassembles this bytes as movsxd eax,edi.

A quick'n'dirty workaround is to use the --dump flag to verify that the first byte is indeed 48 (that's the REX.W prefix, so it will be the same for other registers). If it is not, the address probably needs to be decremented.

You can upgrade Capstone or use --all option to display all gadgets.