keystone-engine / keystone

Keystone assembler framework: Core (Arm, Arm64, Hexagon, Mips, PowerPC, Sparc, SystemZ & X86) + bindings
http://www.keystone-engine.org
GNU General Public License v2.0
2.25k stars 450 forks source link

Inconsistent behavior with push/pop #506

Open russdill opened 3 years ago

russdill commented 3 years ago

pop with register memory addresses is not working at all for me. In some failures, no exception is thrown, it just returns an empty result. push seems to work as expected. Example below:

>>> import keystone
>>> keystone.debug()
'python--arm-arm64-evm-hexagon-mips-ppc-sparc-systemz-x86-c0.9-b0.9'
>>> ks = keystone.Ks(keystone.KS_ARCH_X86, keystone.KS_MODE_32)
>>> ks.asm('push dword [edx]')
([255, 50], 1)
>>> ks.asm('pop dword [edx]')
(None, 0)
>>> ks.asm('push [edx]')
([255, 50], 1)
>>> ks.asm('pop [edx]')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/russ/.local/lib/python3.9/site-packages/keystone/keystone.py", line 213, in asm
    raise KsError(errno, stat_count.value)
keystone.keystone.KsError: Invalid operand (KS_ERR_ASM_INVALIDOPERAND)
russdill commented 3 years ago

There seems to be an additional bug when it comes to immediates. Pushing an 8-bit immediate in 32-bit mode without specifying dword works as expected. But supplying the dword specifier is treated as if the word specifier was applied.

>>> import keystone
>>> keystone.debug()
'python--arm-arm64-evm-hexagon-mips-ppc-sparc-systemz-x86-c0.9-b0.9'
>>> ks = keystone.Ks(keystone.KS_ARCH_X86, keystone.KS_MODE_32)
>>> ks.asm('push 0x78')
([106, 120], 1)
>>> ks.asm('push dword 0x78')
([102, 106, 120], 1)
>>> ks.asm('push word 0x78')
([102, 106, 120], 1)