HomeHome
Stats
border border Dll Proxy Creator border border
Screenshot
DllProxyCreator helps you to create dll proxy automatically.
For that purpose, DllProxyCreator
  • Parses target dll export table
  • Lets you choose which function(s) you want to override, and which you want to let untouched
  • Generates a Visual Studio dll proxy project from project templates
  • For function(s) to override, extracts original dll functions definitions from headers (if available) and create function(s) skeletons
 
Last Update  February 6 2024
Version  1.0.2
Software
Download Software  Download Dll Proxy Creator 64 bits 1.21 Mb
Download Software  Download Dll Proxy Creator 32 bits 1.18 Mb
Compatibility  Windows (Xp, 7, 8, 10, 11)
License  Freeware
Status
 Maintained / Improvements if required Improvement Request 
border border border border

border border User Manual border border
Dll Proxy Creator

Dll Proxy Creator
Summary

DllProxyCreator helps you to create dll proxy automatically.
For that purpose, DllProxyCreator
  • Parses target dll export table
  • Lets you choose which function(s) you want to override, and which you want to let untouched
  • Generates a Visual Studio dll proxy project from project templates
  • For function(s) to override, extracts original dll functions definitions from headers (if available) and create function(s) skeletons

Dll Proxy Creator is a Freeware



Contents
   - What is a dll proxy
   - How it works
   - How to use a dll proxy
       Method 1 (safer --> recommended)
       Method 2 (should be used only when method 1 is not possible)

   - Toolbar

   - Tutorials
       Method 1 Tutorial
       Method 2 Tutorial



What is a dll proxy
A dll proxy is a dll that can
   - Re-implement function without calling the original dll function
   - Check / Change parameters before forwarding the call to the original dll function
   - Change the value returned by the original function call
   - Bypass the call to the original dll function
   - Trace calls to some functions of the original dll



How it works
To understand how dll proxy works, we need to focus first on how dll calls are done.
First a dll is loaded either by the system (for static dll loading), or dynamically by the application (using the LoadLibrary API).
Once loaded, a dll offer a set of functions that can be called.
These callable functions are described in the export address table of the dll.
This export table allow to get addres of exported function code from a name or a number (for ordinal export).
This function code pointer is returned by a call to the GetProcAddress API. Next this function code pointer is used to make the calls.


Standard dll access from a binary
As dll are binaries that are loaded, you can put another binary in place that will handle calls and forward these calls to the original dll or change some functions behaviours
The goal is to be between the application and the original dll.
To achieve that goal, the dll proxy needs to export, at least, the same functions that are exported by the original dll.

Dll proxy




How to use a dll proxy
To put in place a dll proxy, you have two ways
- Rename the original dll and give to your proxy dll the original dll name (Method 1). This is the safer and recommended solution.
Or if not possible
- Patch all the references to the original dll name inside the binaries (Method 2). This method has many cons, so it should be used only when Method 1 is not possible.



Method 1 (safer --> recommended)
Rename the original dll, and give to your proxy dll the original dll name. This is the safer and recommended solution.
By the way if original dll name is "Example.dll" you can rename it to "Example_org.dll" and next rename your proxy dll into "Example_org.dll"
How to use Dll proxy : Method 1

By default, as Dll Proxy Creator doesn't know which name you will give to your original dll, forwarded functions are generated with the original dll name.
So you need to forward functions of your proxy dll to the new name of original dll (aka in this example to "Example_org.dll")

That means you need to replace "Example" by "Example_org" inside the"Forwarded.def" or "Forwarded.cpp" of your dll proxy project source code.

Notice: This is only for Method 1. If you plan to use Method 2, don't do that, as original dll name doesn't change for Method 2.

Renaming original dll implies that all binaries using this dll will be affected by the dll proxy.
So it could be better if dll is in the application folder.



Method 2 (should be used only when method 1 is not possible)
Sometimes you can't rename original dll : always used by the system, shared by many application, with dll path hijacking not possible.
In that case, you have no choice, you need to let the original dll name untouched.
So to force application to use your dll proxy, you need to replace all the references to the original dll by your proxy dll name.
Notice 1: you need to replace the references inside the import addres table (IAT) and the references used by LoadLibrary calls.
Notice 2: the proxy dll name length MUST EXACTLY MATCH the original dll name length.

How to use Dll proxy : Method 2

Method 2 has many cons:
   - Patching will not work on compressed/encoded binaries
   - Patching will not work if dll names are obfuscated/encoded inside the binaries
   - Patching can make your original binary crash
   - If binaries where signed, after patching the signature will be invalid (you will need to sign the binaries again)
   - If you want that the proxy acts for multiple binaries, you need to patch all the targeting binaries
   - You will not catch nested dll calls (If a dll imported by your binary calls original dll internally, the call will not be catched)

How to use Dll proxy for multiple binaries through Method 2: all binaries need to be patched


To help you patching the binaries (for Method 2 only), DllProxyCreator provides a binary patcher that does the dll name replacement automatically.
Notice: All files that need to be patched will be backuped before any change. Backuped files will be in their original directory with the additional ".bak" extension.
It is accessible by the toolbar through the icon

Binary Patcher helper for Method 2



Toolbar
Open the dll for which you want to create a Proxy
Start dll proxy project generation by forwarding unselected functions and creating skeleton for the selected ones
Undecorate C++ functions names in the exported functions list
Binary patcher. Automatically patch files (Needed only for Method 2)
The search done in the results list will be done as a regular expression search (Applies to "String Search" field content)
Do a text search in the exported functions list
Search next matching item in the exported functions list
Search previous matching item in the exported functions list
Show help
Check for software update
Report bug to author
Display about dialog



Tutorials

Method 1 Tutorial
In this tutorial we will show how to override a function belonging to an application dll with a proxy dll.
As a target application we will use the 64 bits version of MagicFileIdentifier and override the function "magic_open" exported by "lib_magic64.dll" ("lib_magic64.dll" is a dll of "MagicFileIdentifier" software)

Notice: to know which function are exported by a dll, you can use All Dlls Dependencies or Helium Hex Editor (with PE tools/Exports). And if you want to search a specific dll exported function name, you can use Dll Export Finder

First Click the Open button and select "lib_magic64.dll" (avaialble inside the folder where you have extracted "MagicFileIdentifier")
The exports of "lib_magic64.dll" are automatically parsed and displayed.

Check "magic_open" as we want to override it

Next select the output directory (where you want the dll proxy project files to be generated).

As you don't have header file, uncheck the "Search for functions definitions inside headers" .

Once done click the Generate button to create your project.

The "Logs" part will show you the progress of the generation.
Once completed, you will get a Visual Studio project ready to create your proxy dll

Project content source files are:

   - DllMain.cpp containing the skeletons of the functions to override : you need to fill these functions code and adjust definition of functions for which header parsing failed (or if no header parsing was done)

   - Forwarded.cpp (or Forwarded.def according to the choosen "Forward way" option) containing forwarded functions definition. For Method 1, as we are going to rename original dll, you must replace the dll original name by the new name. Here, as we are going to rename "lib_magic64.dll" into "lib_magic64_org.dll", we have to replace all occurences of "lib_magic64" by "lib_magic64_org" in Forwarded.cpp (use your favorite editor to do this search and replace operation)

As we didn't provide header definition, we have the following source code in DllMain.cpp
  1. C_DLL_EXPORT ReturnType CALLING_CONVENTION magic_open(Arguments)
  2. {
  3.  
  4. }
At this point you have to fill arguments, return type and calling convention.
If you have absolutely no information, you may need some reverse engenering work to do (out of scope of this tutorial).

For magic_open, the definition is
  1. C_DLL_EXPORT void* __cdecl magic_open(int)
Now we can write our own code and if we want, call the original function.

Here we are going to add a trace MessageBox before calling the original function.

You can call the original function, taking care of doing it by dynamically resolving function address through GetModuleHandle (or LoadLibrary) + GetProcAddress.

As you use Method 1, ensure to use the original module handle (that means the renamed dll name, aka GetModuleHandle("lib_magic64_org.dll" for this example)
Take care when calling original API to not write an infinite loop

This is the incorrect way, producing an infinite loop
  1. C_DLL_EXPORT void* __cdecl magic_open(int i)
  2. {
  3. ::MessageBoxW(NULL,L"magic_open trace",L"Dll Proxy",MB_ICONINFORMATION);
  4. return magic_open(i);
  5. }

This is the correct way: you have to do an explicit function address resolving
  1. typedef void* (__cdecl *pfmagic_open)(int i);
  2. C_DLL_EXPORT void* __cdecl magic_open(int i)
  3. {
  4. ::MessageBoxW(NULL,L"magic_open trace",L"Dll Proxy",MB_ICONINFORMATION);
  5.  
  6. // 1) get the original dll handle (WARNING the new name of the original dll)
  7. HMODULE hModule = ::GetModuleHandle(TEXT("lib_magic64_org.dll"));
  8.  
  9. // 2) get function address inside the original dll
  10. pfmagic_open pmagic_open = (pfmagic_open)::GetProcAddress(hModule,"magic_open");
  11.  
  12. // 3) call original function
  13. if (pmagic_open)
  14. return pmagic_open(i);
  15. else
  16. return NULL;
  17. }
Notice: GetModuleHandle is enough if your proxy dll has at least a forwarded export to the original dll. That means you will need a LoadLibrary call only if you override all the exported functions of the original dll

Once done, build the dll proxy project with Visual Studio.

Take care of generating 64 bits dll for a 64 bits application, or a 32 bits dll for a 32 bits application
Rename original dll "lib_magic64.dll" into "lib_magic64_org.dll" and copy the generated dll in the same folder.

Finaly rename the generated proxy dll into "lib_magic64.dll".
Now all is in place, it's time to check your proxy dll.

Launch MagicFileIdentifier from Windows explorer.

As "magic_open" function is called at startup, you should see your tracing MessageBox appear




Method 2 Tutorial
In this tutorial we will show how to override the function MessageBoxW of the library user32.dll with a proxy dll
As a target application we will use the 64 bits version of MagicFileIdentifier
Notice 1: If you have already completed "Method 1 Tutorial" you can continue to use it with the Method 1 proxy dll

First Click the Open button and select user32.dll (under C:\Windows\System32\)
The exports of user32.dll are automatically parsed and displayed.
Notice : To quickly locate the MessageBoxW function, you can use the search bar at the bottom of the list
Once the MessageBoxW export has been found, check it as you want to override it

Next select the output directory (where you want the dll proxy project files to be generated).

As we are going to re-write a function which is defined in windows SDK header, we can ask Dll Proxy Creator to find and extract definition for us.

So if you have Windows SDK install, click the "Add" button inside the "Function Definition Search" part and select your SDK include directory.

Check the "Search for functions definitions inside headers".

Once done click the Generate button to create your project.


The "Logs" part will show you the progress of the generation.
Once completed, you will get a Visual Studio project ready to create your proxy dll

Project content source files are:

   - DllMain.cpp containing the skeletons of the functions to override : you need to fill these functions code (and potentially adjust definition of functions for which header parsing failed)

   - Forwarded.cpp (or Forwarded.def according to the choosen "Forward way" option) containing forwarded functions definition : you don't need to edit this file for Method 2


As we only checked MessageBoxW, we only have a function code to write inside DllMain.cpp.

You can call the original function, taking care of doing it by dynamically resolving function address through GetModuleHandle (or LoadLibrary) + GetProcAddress.

Here we are using Method 2 (original dll name will not be renamed), and the original code will still reside in the user32.dll file, so we need to use the user32.dll module handle to do a call to original function.
Take care when calling original API to not write an infinite loop

This is the incorrect way, producing an infinite loop
  1. C_DLL_EXPORT int WINAPI MessageBoxW(_In_opt_ HWND hWnd,_In_opt_ LPCWSTR lpText,_In_opt_ LPCWSTR lpCaption,_In_ UINT uType)
  2. {
  3. // this will do a nice infinite loop as your local function will be called instead of the user32 one
  4. return MessageBoxW(hWnd,L"MyText",L"MyCaption",uType);
  5. }

This is the correct way: you have to do an explicit function address resolving
  1. typedef int (WINAPI *pfMessageBoxW)(_In_opt_ HWND hWnd,_In_opt_ LPCWSTR lpText,_In_opt_ LPCWSTR lpCaption,_In_ UINT uType);
  2. C_DLL_EXPORT int WINAPI MessageBoxW(_In_opt_ HWND hWnd,_In_opt_ LPCWSTR lpText,_In_opt_ LPCWSTR lpCaption,_In_ UINT uType)
  3. {
  4. // 1) get the original dll handle
  5. HMODULE hModule = ::GetModuleHandle(TEXT("user32.dll"));
  6.  
  7. // 2) get function address inside the original dll
  8. pfMessageBoxW pMessageBoxW = (pfMessageBoxW)::GetProcAddress(hModule,"MessageBoxW");
  9.  
  10. // 3) call original function
  11. if (pMessageBoxW)
  12. return pMessageBoxW(hWnd,L"MyText",L"MyCaption",uType);
  13. else
  14. return IDCANCEL;
  15. }
Notice: GetModuleHandle is enough if your proxy dll has at least a forwarded export to the original dll. That means you will need a LoadLibrary call only if you override all the exported functions of the original dll

Once done, build the dll proxy project with Visual Studio.

Take care of generating 64 bits dll for a 64 bits application, or a 32 bits dll for a 32 bits application

Here we use Method 2, so we have an extra step to do: patch the application (and optionnally some application dll) loading "user32.dll".
Click on Binary Patcher on the toolbar and select the targeted application

Enter the path of the targeted application "MagicFileIdentifier64.exe"
Notice: For those who have already completed Method 1 tutorial, you can also select your previous proxy dll, to make previous proxy dll MessageBoxW calls to be redirected too

Inside "Imported Dll Renaming" part,

   - In the "Original Dll File Name" field, enter "user32.dll".

   - In the "Proxy Dll File Name" field, enter the dll name you want to use for the proxy dll name.

In this example we will use "_ser32.dll" for the proxy dll name

Notice 1: Ensure the new name has the same length as the original dll name.
Notice 2: Also ensure that the extension is .dll (if extension is not dll, forwarded exports could fail)



Once done click the "Patch" button.

Wait patch completion...

The application will now get references to "_ser32.dll" instead of "user32.dll".
Inside Windows explorer, rename the just build proxy dll into "_ser32.dll", and copy it into the application folder.

You can check inside binary folder that the patched file has been backuped

Now all is in place, it's time to check your proxy dll.

Launch the patched version of MagicFileIdentifier from Windows explorer.

Searching an empty motif inside MagicFileIdentifier will call MessageBoxW function, so let the search field empty and click on the search button.


Your version of MessageBoxW is called !
Top
border border border border

border border Known Troubles border border
Report new bug
  - None Yet
Top
border border border border
DllProxyCreator : DllProxyCreator: DllProxyCreator allows to simply create Dll proxy