None
DLL Proxy MITM Maker
A DLL proxy stands in for, or interfaces to, a normal DLL. In security, these tend to be custom-made DLLs which reimplement key functionality of application or system DLLs. They might do so to enhance games (DirectX overlay), cheat at games (Direct3D proxy), subvert the browser (IE proxy), or just gain execution (Fax Malware). As the interaction between callee and caller, in practice, relies on assembly-level calls; building a DLL proxy tends to be a highly specialized task.

Some folks have generously made publicly available ones though, such as Michael Chourdakis. These make it a lot easier to make a DLL proxy! They don't make it much easier to actually Man-in-the-Middle (MITM) individual calls though. The latter requirement tends to be much more challenging. This DLL proxy generator provides a mirror copy of exports with scaffolding to mitm calls in, and results from, the original DLL.

Usage:
$ python dllproxy.py
usage: dllproxy.py <TargetDLL> <ProxyFileBase> [<TargetFunctions>]
$ python dllproxy.py inetcfg.dll InetProxy InetSetProxy ConfigureSystemForInternet

Source Code
dllproxy.py

DLL Wrappers

What most folks mean by DLL Proxy is actually a DLL Wrapper (as here by floodberry). A DLL wrapper forward all non-implemented function back to the original DLL, while fully intercepting functions the developer cares about. By contrast, a DLL Proxy intentionally inserts itself in all calls between the callee and caller. For example, A DLL Proxy is capable of recording all arguments to, and results from, the original DLL (including modification of those results). A DLL Forwarder may call the original DLL in some instances, but its primary purpose is to hook or interrupt specific calls to fundamentally change the callee's flow of execution.


DLL Exports

DLL exports come in a bewildering array of types, but essentially come down to two characterics:
1) Each export has a name and/or an ordinal (index number).
2) Each export addresses a local function or forwards to a local or remote export

Our goal is to identify each type of export, rebuild the export table, and avoid exposing any changed numbers or names. This is easy for non-forwarding functions; they directly reference functions our scaffolding code generates (trampoline-style or Pre/Post call). Forwarded functions can be trickier though, as the DLL exporting a forward doesn't actually receive execution from such a call. Mimicking it correctly means ensuring the forward continues to the original destination, but that often includes forwarding to a local function (ie, one we're not exporting).


DLL MITM Scaffolding

The MITM scaffolding focuses on three specific instances to MITM:
1) Intercept the call before it happens to record/modify arguments
2) Intercept the call after it occurs to record/modify return values
3) Intercept both before and after to identify interesting queries and modify them

dllproxy.py exposes three functions for the end user:
DllProxyPre( FuncProxyName, .../*Function Arguments*/) // Intercept execution before Original DLL called
DllProxyPost(FuncProxyName, .../*Function Arguments*/) // Intercept execution after Original DLL called
DllProxyBoth(FuncProxyName, .../*Function Arguments*/) // Intercept execution before AND after Original DLL called

...which actually use the following #defines:
#define DllProxyGeneric(A)          extern "C" __declspec(naked) void A()
#define DllProxyFunction(A,...) extern "C" cdecl void A(__VA_ARGS__)

#define DllProxyPreFunction(A,...) DllProxyFunction(intercept_pre_##A, void *ReturnPointer,__VA_ARGS__)
#define DllProxyPostFunction(A,...) DllProxyFunction(intercept_post_##A,void *ReturnValue, __VA_ARGS__)


Example

$ python dllproxy.py inetcfg.dll InetProxy InetSetProxy ConfigureSystemForInternet
$ cat InetProxy.cpp
#include "InetProxy.h"
FARPROC proxyFunctionPointers[58];
HANDLE hThis = NULL; HMODULE hThat = NULL;

BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
hThis = hModule;
lpReserved = NULL;
switch(dwReason)
{
case DLL_PROCESS_ATTACH: return ProxyAttach();
case DLL_PROCESS_DETACH: return ProxyRelease();
default: break;
}
return TRUE;
}

DllProxyPre(ConfigureSystemForInternet /*, add function parameters here */)
{
printf("intercepting ConfigureSystemForInternet\n");
}

DllProxyPre(InetSetProxy /*, add function parameters here */)
{
printf("intercepting InetSetProxy\n");
}



- Kelson (kelson@shysecurity.com)