Wrap DLL
A tool to automatically generate cpp/asm codes for wrapping a dynamic-link library.
Features
- All the wrapper functions perform a
jmp
instruction that jumps to the real function. - A CMake project is generated under the directory with the same name as the DLL.
- If the signature of any of the functions is known, the user can replace the default implementation with a custom function that performs API hooking / code injection.
- Both
x64
orWin32
DLLs are supported. - The original real DLL is prefixed with
real_
and copied to the project directory. - C++ functions are demangled, a C function name is created in the generated project but it is exported as the original mangled symbol.
__stdcall
,__fastcall
symbols are undecorated, but exported as the original symbol. The user is responsible to ensure the overriding function has the same calling convention.
Install
No installation is necessary, but you need python>=3.7
to run it, and want to install the dependencies through
pip install -r requirements.txt
currently there's only jinja2
for rendering the code templates.
Make sure you installed Visual Studio, the script by default assumes the dumpbin.exe
and undname.exe
tools are available in the PATH
. Mine is located at C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\bin\Hostx64\x64\
, so add it to your path. Otherwise pass the --dumpbin
and --undname
arguments.
Example
x64 DLL
python3 wrap_dll.py C:\Windows\System32\AudioSes.dll
cd AudioSes
cmake -f CMakeLists.txt
x86 DLL
python3 wrap_dll.py C:\Windows\SysWOW64\AudioSes.dll
cd AudioSes
cmake -f CMakeLists.txt
Override some of the exported functions
To override some of the functions, provide a hook.h
file.
Say if we wrap abc_dll.dll
with the function int abc(const char* a, int b, float c)
, override it in the hook.h
with
/*
* content of file: hook.h
*/
#include "hook_macro.h"
/*
* define a variable that is uppercase of the function name that you want to override.
* which notifies the generated code that a override of the function is provided.
*/
#define ABC
/*
* Arguments of the FAKE macro is (return_type, call_convention, function_name, arg_type1 arg1, arg_type2 arg2, ...).
*/
FAKE(int, __cdecl, abc, const char* a, int b, float c) { // currently, the parsing code only support __cdecl functions.
b = 0; // custom code before calling the real function.
int ret = abc_real(a, b, c); // call the real function, FAKE macro prepares abc_real for you, which can be called directly.
ret += 1; // custom code after calling the real function.
return ret;
}
Now generate the wrapper with
python3 wrap_dll.py --hook hook.h abc_dll.dll
cd abc_dll
cmake -f CMakeLists.txt
PS
This tool seems to be useful for some people, as I saw a few forks recently. Therefore I performed a major refactor to make the code more professional.
Changes:
- Remove the
dumpbin.exe
included, the user can specify their owndumpbin.exe
that comes with their visual studio installation. e.g. Mine is located atC:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\bin\Hostx64\x64\dumpbin.exe
. The script by default assumesdumpbin.exe
is available in the user'sPATH
. - Use
cmake
to generate visual studio solution file. - Use
jinja2
to separate thec++/asm
code into independent template files. - Support
--dry
flag to perform dry run, which only prints all the files to be generated.