- Decorator API - simple
import il
import ctypes
@il.asm
def add_ints(rdi=ctypes.c_int32, rsi=ctypes.c_int32):
"""
# return sum of two 32-bit integers
# 64-bit Linux/MacOS call convention
#
.intel_syntax noprefix
mov rax, 0
mov eax, edi
add eax, esi
ret
"""
return ctypes.c_int32
print(add_ints(43, -1))
- Function API - powerful
add_ints = il.def_asm(
name="add_ints",
prototype=ctypes.CFUNCTYPE(ctypes.c_int32, # return value (eax)
ctypes.c_int32, # 1st param (edi)
ctypes.c_int32), # 2nd param (esi)
code="""
.intel_syntax noprefix
mov rax, 0
mov eax, edi
add eax, esi
ret
""")
print(add_ints(43, -1))
-
If object code is available: no dependencies outside Python standard library.
ctypes
from the standard library is needed for loading and running object code. -
If object code is not available:
as
andobjcopy
(frombinutils
) are required for compiling assembly.
From PyPI:
$ pip3 install il
From source tree:
$ sudo python3 setup.py install
$ python3 -c 'import il; help(il)'
-
Assume that
mylib.py
contains inlined assembly. By default,il
looks for object code frommylib.py.il
. If found, that code will be executed when inlined functions are called. -
If object code is not found,
il
uses binutils:as
(assembler) andobjcopy
to compile the assembly on-the-fly and extract object code from the result. Object code is saved tomylib.py.il
for later use. -
Note:
il
does not link object code before running it. -
You can view contents of
mylib.py.il
usingil
:$ python3 -c 'import il; print(il.dump_lib("mylib.py.il", disasm=False))'
(Use
disasm=True
to disassemble the code in the dump. Requiresobjdump
.)
-
Import the library, print the pid of the Python process and the address of the function that you want to debug:
>>> import mylib >>> import os >>> os.getpid() 12345 >>> print(mylib.myfunc.il_addr) 21954560
-
Attach GDB to the Python process, set a breakpoint to the address and let the Python process continue.
$ gdb -p 12345 (gdb) layout asm (gdb) break *21954560 (gdb) cont
-
Call the function in Python
>>> mylib.myfunc()
-
Now you can step assembly instructions and see register values in GDB:
(gdb) ni (gdb) info registers