Skip to content

Instantly share code, notes, and snippets.

@hewittc
Last active November 22, 2024 22:22
Show Gist options
  • Save hewittc/abe9901ea394f1246ff03118e32d7c9b to your computer and use it in GitHub Desktop.
Save hewittc/abe9901ea394f1246ff03118e32d7c9b to your computer and use it in GitHub Desktop.
Python ctypes automatically uses RTLD_NOW despite supplied flags. Here's something for fun.
#!/usr/bin/env python3
'''
test.c - clang -o test.so -fPIC -shared test.c
----------------------------------------------
extern int baz();
int foo() {
return 42;
}
int bar() {
return baz();
}
'''
import ctypes
import sys
import os
so = b'./test.so'
def test(mode):
if mode is os.RTLD_LAZY:
print('testing RTLD_LAZY\n-----------------')
else:
print('\ntesting RTLD_NOW\n----------------')
FUNKY = ctypes.CFUNCTYPE(ctypes.c_int)
parent = ctypes.CDLL(None)
dlopen = parent.dlopen
dlopen.restype = ctypes.c_void_p
dlsym = parent.dlsym
dlsym.restype = ctypes.c_void_p
lib = dlopen(so, mode)
if not lib:
print('error: could not load {}'.format(so.decode('utf-8')))
if mode is os.RTLD_NOW:
print('error: missing an undefined function?')
sys.exit(-1)
foo = parent.dlsym(lib, b'foo')
bar = parent.dlsym(lib, b'bar')
baz = parent.dlsym(lib, b'baz')
print('foo: {}'.format(hex(foo) if foo else '0x0'))
print('bar: {}'.format(hex(bar) if bar else '0x0'))
print('baz: {}'.format(hex(baz) if baz else '0x0'))
print('calling foo(): {}'.format(FUNKY(foo)()))
#print('calling bar(): {}'.format(FUNKY(bar)()))
parent.dlclose(lib)
if __name__ == '__main__':
for mode in (os.RTLD_LAZY, os.RTLD_NOW):
test(mode)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment