Skip to content

Instantly share code, notes, and snippets.

@ess7
Last active August 19, 2024 12:42
Show Gist options
  • Save ess7/1934e2242ee2e008658686251c155973 to your computer and use it in GitHub Desktop.
Save ess7/1934e2242ee2e008658686251c155973 to your computer and use it in GitHub Desktop.
Calling a thiscall DLL function in Python ctypes (x86)
import ctypes
kernel32 = ctypes.windll.kernel32
# __declspec(dllexport) __thiscall int add3(int a, int b, int c) {
# return a + b + c;
# }
_add3 = ctypes.cdll.lib.add3
buf = kernel32.VirtualAlloc(0, 4096, 0x3000, 0x40)
# Stack: ret addr, func addr, arg1, arg2, arg3, ...
# [esp] [esp+4] ...
code = "\x8b\x4c\x24\x08" # mov ecx, dword ptr [esp+8]
code += "\x8f\x44\x24\x04" # pop dword ptr [esp+4]
# Stack: func addr, ret addr, arg2, arg3, ...
code += "\xc3" # ret
ctypes.memmove(buf, code, len(code))
add3 = lambda a, b, c: ctypes.WINFUNCTYPE(
ctypes.c_int, # return
ctypes.c_void_p, # address of function
ctypes.c_int, # arg1
ctypes.c_int, # arg2
ctypes.c_int # arg3
)(buf)(_add3, a, b, c)
print(add3(1, 2, 3))
@diorcety
Copy link

Thanks for this gist !
I made few updates:

  • Python 3
  • Allow callback with this call
  • Wrap all this in THISCALLFUNCTYPE like CFUNCTYPE/WINFUNCTYPE

https://gist.github.com/diorcety/756db868180672e6b37566a659f5b567

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment