diff --git a/core/CrazyDebugger.cpp b/core/CrazyDebugger.cpp index 3bada64f..c2fb88ba 100644 --- a/core/CrazyDebugger.cpp +++ b/core/CrazyDebugger.cpp @@ -29,12 +29,74 @@ * Version: $Id$ */ -#if 0 #include "sm_globals.h" #include "sourcemm_api.h" #include "Tlhelp32.h" #include "LibrarySys.h" #include "minidump.h" +#include "sm_stringutil.h" + +bool HookImportAddrTable(BYTE *base, const char *func, DWORD hookfunc, char *err, size_t maxlength) +{ + IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *)base; + if (dos->e_magic != IMAGE_DOS_SIGNATURE) + { + UTIL_Format(err, maxlength, "%s", "Could not detect valid DOS signature"); + return (err == NULL) ? true : false; + } + + IMAGE_NT_HEADERS *nt = (IMAGE_NT_HEADERS *)(base + dos->e_lfanew); + if (nt->Signature != IMAGE_NT_SIGNATURE) + { + UTIL_Format(err, maxlength, "%s", "Could not detect valid NT signature"); + return false; + } + + IMAGE_IMPORT_DESCRIPTOR *desc = + (IMAGE_IMPORT_DESCRIPTOR *) + (base + nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); + if (base == (BYTE *)desc) + { + UTIL_Format(err, maxlength, "%s", "Could not find IAT"); + return false; + } + + bool entryFound = false; + while (desc->Name) + { + if (desc->FirstThunk != 0) + { + IMAGE_THUNK_DATA *data = (IMAGE_THUNK_DATA *)(base + desc->OriginalFirstThunk); + DWORD *iat = (DWORD *)(base + desc->FirstThunk); + while (data->u1.Function) + { + if ((data->u1.Ordinal & IMAGE_ORDINAL_FLAG32) != IMAGE_ORDINAL_FLAG32) + { + IMAGE_IMPORT_BY_NAME *import = (IMAGE_IMPORT_BY_NAME *)(base + data->u1.AddressOfData); + if (strcmp((char *)import->Name, func) == 0) + { + DWORD oldprot, oldprot2; + VirtualProtect(iat, 4, PAGE_READWRITE, &oldprot); + *iat = hookfunc; + VirtualProtect(iat, 4, oldprot, &oldprot2); + entryFound = true; + } + } + data++; + iat++; + } + } + desc++; + } + + if (!entryFound) + { + UTIL_Format(err, maxlength, "Could not find IAT entry for %s", func); + return false; + } + + return true; +} BOOL WINAPI @@ -62,6 +124,24 @@ FARPROC WINAPI GetProcAddress2(HMODULE hModule, LPCSTR lpProcName) return GetProcAddress(hModule, lpProcName); } +HMODULE WINAPI LoadLibraryEx2(LPCTSTR lpFileName, HANDLE hFile, DWORD dwFlags) +{ + HMODULE lib = LoadLibraryEx(lpFileName, hFile, dwFlags); + + /* Steam.dll seems to get loaded using an abs path, thus the use of stristr() */ + if (stristr(lpFileName, "steam.dll")) + { + char err[64]; + if (!HookImportAddrTable((BYTE *)lib, "GetProcAddress", (DWORD)GetProcAddress2, err, sizeof(err))) + { + Error("[SM] %s in steam.dll\n", err); + return NULL; + } + } + + return lib; +} + class CrazyWindowsDebugger : public SMGlobalClass { public: @@ -69,6 +149,9 @@ public: { HANDLE hModuleList = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId()); MODULEENTRY32 me32; + BYTE *engine = NULL; + BYTE *steam = NULL; + char err[64]; me32.dwSize = sizeof(MODULEENTRY32); @@ -77,69 +160,42 @@ public: Error("Could not initialize crazy debugger!"); } - bool found = false; - do { - if (strcasecmp(me32.szModule, "steam.dll") == 0) + if (strcasecmp(me32.szModule, "engine.dll") == 0) { - IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *)me32.modBaseAddr; - if (dos->e_magic != IMAGE_DOS_SIGNATURE) - { - Error("[SM] Could not detect steam.dll with valid DOS signature"); - } - char *base = (char *)dos; - IMAGE_NT_HEADERS *nt = (IMAGE_NT_HEADERS *)(base + dos->e_lfanew); - if (nt->Signature != IMAGE_NT_SIGNATURE) - { - Error("[SM] Could not detect steam.dll with valid NT signature"); - } - IMAGE_IMPORT_DESCRIPTOR *desc = - (IMAGE_IMPORT_DESCRIPTOR *) - (base + nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); - if (base == (char *)desc) - { - Error("[SM] Could not find the steam.dll IAT"); - } - while (desc->Name) - { - if (desc->FirstThunk != 0) - { - IMAGE_THUNK_DATA *data = (IMAGE_THUNK_DATA *)(base + desc->OriginalFirstThunk); - DWORD *iat = (DWORD *)(base + desc->FirstThunk); - while (data->u1.Function) - { - if ((data->u1.Ordinal & IMAGE_ORDINAL_FLAG32) != IMAGE_ORDINAL_FLAG32) - { - IMAGE_IMPORT_BY_NAME *import = (IMAGE_IMPORT_BY_NAME *)(base + data->u1.AddressOfData); - if (strcmp((char *)import->Name, "GetProcAddress") == 0) - { - DWORD oldprot, oldprot2; - VirtualProtect(iat, 4, PAGE_READWRITE, &oldprot); - *iat = (DWORD)GetProcAddress2; - VirtualProtect(iat, 4, oldprot, &oldprot2); - found = true; - goto _end; - } - } - data++; - iat++; - } - } - desc++; - } + engine = me32.modBaseAddr; + } + else if (strcasecmp(me32.szModule, "steam.dll") == 0) + { + /* Steam.dll is loaded by engine.dll, so we can exit the loop here */ + steam = me32.modBaseAddr; break; } } while (Module32Next(hModuleList, &me32)); -_end: + CloseHandle(hModuleList); - if (!found) + /* This really should not happen, but ... */ + if (!engine) { - Error("Could not find steam.dll's GetProcAddress IAT entry"); + Error("[SM] Could not find engine.dll\n"); } - CloseHandle(hModuleList); + /* Steam.dll isn't loaded yet */ + if (!steam) + { + if (!HookImportAddrTable(engine, "LoadLibraryExA", (DWORD)LoadLibraryEx2, err, sizeof(err))) + { + Error("[SM] %s in engine.dll)\n", err); + } + } + else + { + if (!HookImportAddrTable(steam, "GetProcAddress", (DWORD)GetProcAddress2, err, sizeof(err))) + { + Error("[SM] %s in steam.dll)\n", err); + } + } } } s_CrazyDebugger; -#endif diff --git a/core/msvc8/sourcemod_mm.sln b/core/msvc8/sourcemod_mm.sln index 780f496a..27d206cc 100644 --- a/core/msvc8/sourcemod_mm.sln +++ b/core/msvc8/sourcemod_mm.sln @@ -5,7 +5,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sourcemod_mm", "sourcemod_m EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - CrazyDebug|Win32 = CrazyDebug|Win32 + CrazyDebug - Episode 1|Win32 = CrazyDebug - Episode 1|Win32 + CrazyDebug - Old Metamod|Win32 = CrazyDebug - Old Metamod|Win32 + CrazyDebug - Orange Box|Win32 = CrazyDebug - Orange Box|Win32 Debug - Episode 1|Win32 = Debug - Episode 1|Win32 Debug - Old Metamod|Win32 = Debug - Old Metamod|Win32 Debug - Orange Box|Win32 = Debug - Orange Box|Win32 @@ -14,8 +16,12 @@ Global Release - Orange Box|Win32 = Release - Orange Box|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {E39527CD-7CAB-4420-97CC-DA1B93B260BC}.CrazyDebug|Win32.ActiveCfg = CrazyDebug|Win32 - {E39527CD-7CAB-4420-97CC-DA1B93B260BC}.CrazyDebug|Win32.Build.0 = CrazyDebug|Win32 + {E39527CD-7CAB-4420-97CC-DA1B93B260BC}.CrazyDebug - Episode 1|Win32.ActiveCfg = CrazyDebug - Episode 1|Win32 + {E39527CD-7CAB-4420-97CC-DA1B93B260BC}.CrazyDebug - Episode 1|Win32.Build.0 = CrazyDebug - Episode 1|Win32 + {E39527CD-7CAB-4420-97CC-DA1B93B260BC}.CrazyDebug - Old Metamod|Win32.ActiveCfg = CrazyDebug - Old Metamod|Win32 + {E39527CD-7CAB-4420-97CC-DA1B93B260BC}.CrazyDebug - Old Metamod|Win32.Build.0 = CrazyDebug - Old Metamod|Win32 + {E39527CD-7CAB-4420-97CC-DA1B93B260BC}.CrazyDebug - Orange Box|Win32.ActiveCfg = CrazyDebug - Orange Box|Win32 + {E39527CD-7CAB-4420-97CC-DA1B93B260BC}.CrazyDebug - Orange Box|Win32.Build.0 = CrazyDebug - Orange Box|Win32 {E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Debug - Episode 1|Win32.ActiveCfg = Debug - Episode 1|Win32 {E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Debug - Episode 1|Win32.Build.0 = Debug - Episode 1|Win32 {E39527CD-7CAB-4420-97CC-DA1B93B260BC}.Debug - Old Metamod|Win32.ActiveCfg = Debug - Old Metamod|Win32 diff --git a/core/msvc8/sourcemod_mm.vcproj b/core/msvc8/sourcemod_mm.vcproj index b2b47154..a6921478 100644 --- a/core/msvc8/sourcemod_mm.vcproj +++ b/core/msvc8/sourcemod_mm.vcproj @@ -15,6 +15,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - @@ -633,47 +800,59 @@ - - + + + + + + + + + - - - + + @@ -1165,6 +1344,14 @@ + + +