From 9cb7e326fc2d38915eca88cd91616298fee2a0f1 Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Wed, 22 Sep 2010 21:21:52 +0000 Subject: [PATCH] Add a mechanism for Win32 diversions. --- src/libzzuf/lib-load.h | 14 ++++++++++++ src/libzzuf/lib-stream.c | 8 +++++++ src/libzzuf/sys.c | 47 ++++++++++++++++++++-------------------- 3 files changed, 46 insertions(+), 23 deletions(-) diff --git a/src/libzzuf/lib-load.h b/src/libzzuf/lib-load.h index 03350da..463ab96 100644 --- a/src/libzzuf/lib-load.h +++ b/src/libzzuf/lib-load.h @@ -41,5 +41,19 @@ /* Nothing to do under Windows, everything is done as soon \ * as the process is launched. */ \ } while(0) + +typedef struct +{ + char const *lib, *name; + void **old; + void *new; +} +zzuf_table_t; + +# define DIVERT(x) { "kernel32.dll", #x, &x##_orig, x##_new } +# define DIVERT_END { NULL, NULL, NULL, NULL } + +extern zzuf_table_t table_stream[]; + #endif diff --git a/src/libzzuf/lib-stream.c b/src/libzzuf/lib-stream.c index 973c720..e62f2b2 100644 --- a/src/libzzuf/lib-stream.c +++ b/src/libzzuf/lib-stream.c @@ -1146,3 +1146,11 @@ int NEW(__uflow)(FILE *fp) } #endif +/* Win32 function table */ +zzuf_table_t table_stream[] = +{ + DIVERT(fopen), + DIVERT(fread), + DIVERT(fclose), + DIVERT_END +}; diff --git a/src/libzzuf/sys.c b/src/libzzuf/sys.c index ee0cbe1..2ce8a7e 100644 --- a/src/libzzuf/sys.c +++ b/src/libzzuf/sys.c @@ -33,6 +33,7 @@ #include #include "sys.h" +#include "lib-load.h" #if defined HAVE_WINDOWS_H static void insert_funcs(void *); @@ -90,15 +91,12 @@ void _zz_sys_init(void) #if defined HAVE_WINDOWS_H static void insert_funcs(void *module) { - struct { char const *lib, *name; void **old; void *new; } - diversions[] = + static zzuf_table_t *list[] = { -#define DIVERT(x) { "kernel32.dll", #x, &x##_orig, x##_new } - DIVERT(LoadLibraryA), - DIVERT(AllocConsole), - DIVERT(AttachConsole), + table_stream }; + zzuf_table_t *diversion; unsigned long dummy; import_t import; thunk_t thunk; @@ -110,29 +108,32 @@ static void insert_funcs(void *module) if(!import) return; - for (k = 0; k < sizeof(diversions) / sizeof(*diversions); k++) + for (k = 0; k < sizeof(list) / sizeof(*list); k++) { - void *lib = GetModuleHandleA(diversions[k].lib); - *diversions[k].old = (void *)GetProcAddress(lib, diversions[k].name); - - for(j = 0; import[j].Name; j++) + for (diversion = list[k]; diversion->lib; diversion++) { - char *name = (char *)module + import[j].Name; - if(lstrcmpiA(name, diversions[k].lib) != 0) - continue; + void *lib = GetModuleHandleA(diversion->lib); + *diversion->old = (void *)GetProcAddress(lib, diversion->name); - thunk = (thunk_t)((char *)module + import->FirstThunk); - for(i = 0; thunk[i].u1.Function; i++) + for(j = 0; import[j].Name; j++) { - void **func = (void **)&thunk[i].u1.Function; - if(*func != *diversions[k].old) + char *name = (char *)module + import[j].Name; + if(lstrcmpiA(name, diversion->lib) != 0) continue; - /* FIXME: The StarCraft 2 hack uses two methods for function - * diversion. See HookSsdt() and HookHotPatch(). */ - VirtualProtect(func, sizeof(func), PAGE_EXECUTE_READWRITE, &dummy); - WriteProcessMemory(GetCurrentProcess(), func, &diversions[k].new, - sizeof(diversions[k].new), NULL); + thunk = (thunk_t)((char *)module + import->FirstThunk); + for(i = 0; thunk[i].u1.Function; i++) + { + void **func = (void **)&thunk[i].u1.Function; + if(*func != *diversion->old) + continue; + + /* FIXME: The StarCraft 2 hack uses two methods for function + * diversion. See HookSsdt() and HookHotPatch(). */ + VirtualProtect(func, sizeof(func), PAGE_EXECUTE_READWRITE, &dummy); + WriteProcessMemory(GetCurrentProcess(), func, &diversion->new, + sizeof(diversion->new), NULL); + } } } }