-
-
Save pydemo/ac848dd8319139b25a538b7d67496ad2 to your computer and use it in GitHub Desktop.
Shim DLL Generation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Code originally found on http://www.hulver.com/scoop/story/2006/2/18/125521/185 | |
// Created by Rogerborg | |
#include <stdio.h> | |
#include <windows.h> | |
#include <list> | |
using namespace std; | |
// Change this to the name of the DLL that you want to clone | |
#define CLONE_DLL "WS2_32" | |
// Define this to insert basic fprintf debug into the cloned DLL | |
#define INSERT_DEBUG_OUTPUT 1 | |
typedef struct | |
{ | |
int ordinal; | |
char name[64]; | |
} Symbol; | |
static list<Symbol> gs_symbols; | |
main() | |
{ | |
char originalDLL[256]; | |
(void)GetSystemDirectory(originalDLL, sizeof(originalDLL) - 1); | |
strcat(originalDLL, "\\" CLONE_DLL ".dll"); | |
char exportFile[256]; | |
(void)GetTempPath(sizeof(exportFile), exportFile); | |
strcat(exportFile, "exports.txt"); | |
char dumpbin[512]; | |
sprintf(dumpbin, "dumpbin /exports %s > %s", originalDLL, exportFile); | |
(void)system(dumpbin); | |
FILE * exports = fopen(exportFile, "r"); | |
FILE * cpp = fopen(CLONE_DLL ".cpp", "w"); | |
FILE * def = fopen(CLONE_DLL ".def", "w"); | |
while(!feof(exports)) | |
{ | |
char line[256]; | |
Symbol newSymbol; | |
if(fgets(line, sizeof(line) - 1, exports)) | |
if(2 == sscanf(line, "%d %*x %*x %s", | |
&newSymbol.ordinal, | |
newSymbol.name)) | |
gs_symbols.push_back(newSymbol); | |
} | |
fprintf(def, "LIBRARY " CLONE_DLL "\n\nEXPORTS\n"); | |
for(list<Symbol>::iterator symbol = gs_symbols.begin(); | |
symbol != gs_symbols.end(); | |
++symbol) | |
fprintf(def, "\t%s = _I_%s @%d\n", | |
symbol->name, | |
symbol->name, | |
symbol->ordinal); | |
fprintf(cpp, "#include <stdio.h>\n"); | |
fprintf(cpp, "#include <windows.h>\n"); | |
fprintf(cpp, "static HINSTANCE gs_hDLL = 0;\n\n"); | |
#if INSERT_DEBUG_OUTPUT | |
fprintf(cpp, "#if defined (_DEBUG)\n"); | |
fprintf(cpp, "static FILE * debug;\n"); | |
fprintf(cpp, "#define DEBUG(x) fprintf x\n"); | |
fprintf(cpp, "#else // DEBUG\n"); | |
fprintf(cpp, "#define DEBUG(x)\n"); | |
fprintf(cpp, "#endif // _DEBUG\n\n"); | |
#endif // INSERT_DEBUG_OUTPUT | |
for(symbol = gs_symbols.begin(); | |
symbol != gs_symbols.end(); | |
++symbol) | |
{ | |
fprintf(cpp, "int (__stdcall * _O_%s)();\n", symbol->name); | |
fprintf(cpp, "extern \"C\" void __declspec(naked) __stdcall _I_%s()\n", symbol->name); | |
fprintf(cpp, "{\n"); | |
#if INSERT_DEBUG_OUTPUT | |
fprintf(cpp, "\tDEBUG((debug, \"%s\\n\"));\n", symbol->name); | |
#endif // INSERT_DEBUG_OUTPUT | |
fprintf(cpp, "\t__asm { jmp _O_%s }\n", symbol->name); | |
fprintf(cpp, "}\n\n"); | |
} | |
fprintf(cpp, "BOOL WINAPI DllMain(HINSTANCE hI, DWORD reason, LPVOID notUsed)\n"); | |
fprintf(cpp, "{\n"); | |
fprintf(cpp, " if (reason == DLL_PROCESS_ATTACH)\n"); | |
fprintf(cpp, " {\n"); | |
#if INSERT_DEBUG_OUTPUT | |
fprintf(cpp, "#if defined(_DEBUG)\n"); | |
fprintf(cpp, " if(!debug)\n"); | |
fprintf(cpp, " debug = fopen(\"debug.txt\", \"w\");\n"); | |
fprintf(cpp, "#endif // DEBUG\n"); | |
fprintf(cpp, " DEBUG((debug, \"DllMain\\n\"));\n\n"); | |
#endif // INSERT_DEBUG_OUTPUT | |
fprintf(cpp, " char realDLL[MAX_PATH];\n"); | |
fprintf(cpp, " (void)GetSystemDirectory(realDLL, sizeof(realDLL) - 1);\n"); | |
fprintf(cpp, " strcat(realDLL, \"\\\\" CLONE_DLL ".dll\");\n"); | |
fprintf(cpp, " gs_hDLL = LoadLibrary(realDLL);\n"); | |
fprintf(cpp, " if (!gs_hDLL)\n"); | |
fprintf(cpp, " return FALSE;\n\n"); | |
for(symbol = gs_symbols.begin(); | |
symbol != gs_symbols.end(); | |
++symbol) | |
{ | |
fprintf(cpp, " _O_%s = GetProcAddress(gs_hDLL, \"%s\");\n", | |
symbol->name, symbol->name); | |
} | |
fprintf(cpp, "\n return TRUE;\n"); | |
fprintf(cpp, " }\n"); | |
fprintf(cpp, " else if (reason == DLL_PROCESS_DETACH)\n"); | |
fprintf(cpp, " {\n"); | |
#if INSERT_DEBUG_OUTPUT | |
fprintf(cpp, "#if defined(_DEBUG)\n"); | |
fprintf(cpp, " if(debug)\n"); | |
fprintf(cpp, " fclose(debug);\n"); | |
fprintf(cpp, "#endif // DEBUG\n\n"); | |
#endif // INSERT_DEBUG_OUTPUT | |
fprintf(cpp, " FreeLibrary(gs_hDLL);\n\n"); | |
fprintf(cpp, " }\n"); | |
fprintf(cpp, " return TRUE;\n"); | |
fprintf(cpp, "}\n\n"); | |
fclose(exports); | |
fclose(cpp); | |
fclose(def); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment