This project shows how to proxy and wrap functions in a .pyd
file to intercept and view their behavior without altering the main
application.
.pyd
is python code compiled using Cython (translated to C/C++ code) <- this make reverse engineering on.pyd
is hard.
showcase.mp4
In this proof-of-concept, we are working with a number guessing game where the answer is generated by two functions, thinking_number()
and select_number()
, located in brain.cp310-win_amd64.pyd
. The game's challenge is to guess the correct answer number generated by these functions. To reveal this number, we will proxy and wrap these functions to observe their behavior.
-
Rename Exported Functions
- The
brain.cp310-win_amd64.pyd
file exports a function namedPyInit_brain
that allows it to be imported asbrain
. - Rename
brain.cp310-win_amd64.pyd
toxxxxx.pyd
and update the exported function name toPyInit_xxxxx
.
- The
-
Create a Proxy Module
- Create
brain.py
which will act as a proxy. It will importxxxxx.pyd
and forward calls to it while allowing us to intercept function calls.
- Create
-
Implement Wrappers
- In
brain.py
, wrap the functionsthinking_number()
andselect_number()
to capture their return values. This will allow us to see the generated answer number and win the game.
- In
For further details on how to set up the proxy and wrap functions, refer to the
2-original-build-with-proxy/brain.py
file.
-
0-original-code
- Contains the original source code of
main.py
(number guessing game),brain.py
before compilation andsetup.py
script to compilebrain.py
to.pyd
- Contains the original source code of
-
1-original-build
- Includes the
main.py
(assume it compiled asmain.exe
) andbrain.cp310-win_amd64.pyd
- Includes the
-
2-original-build-with-proxy
- Contains the renamed
.pyd
file (xxxxx.pyd
),brain.py
with the proxy implementation, andexported_renamer.py
script to rename PyInit exported function.
- Contains the renamed