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 @@
+
+
+