1.1 --- a/core/CrazyDebugger.cpp Fri Jul 11 06:51:21 2008 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,199 +0,0 @@
1.4 -/**
1.5 - * vim: set ts=4 :
1.6 - * =============================================================================
1.7 - * SourceMod
1.8 - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
1.9 - * =============================================================================
1.10 - *
1.11 - * This program is free software; you can redistribute it and/or modify it under
1.12 - * the terms of the GNU General Public License, version 3.0, as published by the
1.13 - * Free Software Foundation.
1.14 - *
1.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
1.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1.18 - * details.
1.19 - *
1.20 - * You should have received a copy of the GNU General Public License along with
1.21 - * this program. If not, see <http://www.gnu.org/licenses/>.
1.22 - *
1.23 - * As a special exception, AlliedModders LLC gives you permission to link the
1.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
1.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
1.26 - * by the Valve Corporation. You must obey the GNU General Public License in
1.27 - * all respects for all other code used. Additionally, AlliedModders LLC grants
1.28 - * this exception to all derivative works. AlliedModders LLC defines further
1.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
1.30 - * or <http://www.sourcemod.net/license.php>.
1.31 - *
1.32 - * Version: $Id$
1.33 - */
1.34 -
1.35 -#include "sm_globals.h"
1.36 -#include "sourcemm_api.h"
1.37 -#include "Tlhelp32.h"
1.38 -#include "LibrarySys.h"
1.39 -#include "minidump.h"
1.40 -#include "sm_stringutil.h"
1.41 -
1.42 -bool HookImportAddrTable(BYTE *base, const char *func, DWORD hookfunc, char *err, size_t maxlength)
1.43 -{
1.44 - IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *)base;
1.45 - if (dos->e_magic != IMAGE_DOS_SIGNATURE)
1.46 - {
1.47 - UTIL_Format(err, maxlength, "%s", "Could not detect valid DOS signature");
1.48 - return false;
1.49 - }
1.50 -
1.51 - IMAGE_NT_HEADERS *nt = (IMAGE_NT_HEADERS *)(base + dos->e_lfanew);
1.52 - if (nt->Signature != IMAGE_NT_SIGNATURE)
1.53 - {
1.54 - UTIL_Format(err, maxlength, "%s", "Could not detect valid NT signature");
1.55 - return false;
1.56 - }
1.57 -
1.58 - IMAGE_IMPORT_DESCRIPTOR *desc =
1.59 - (IMAGE_IMPORT_DESCRIPTOR *)
1.60 - (base + nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
1.61 - if (base == (BYTE *)desc)
1.62 - {
1.63 - UTIL_Format(err, maxlength, "%s", "Could not find IAT");
1.64 - return false;
1.65 - }
1.66 -
1.67 - bool entryFound = false;
1.68 - while (desc->Name)
1.69 - {
1.70 - if (desc->FirstThunk != 0)
1.71 - {
1.72 - IMAGE_THUNK_DATA *data = (IMAGE_THUNK_DATA *)(base + desc->OriginalFirstThunk);
1.73 - DWORD *iat = (DWORD *)(base + desc->FirstThunk);
1.74 - while (data->u1.Function)
1.75 - {
1.76 - if ((data->u1.Ordinal & IMAGE_ORDINAL_FLAG32) != IMAGE_ORDINAL_FLAG32)
1.77 - {
1.78 - IMAGE_IMPORT_BY_NAME *import = (IMAGE_IMPORT_BY_NAME *)(base + data->u1.AddressOfData);
1.79 - if (strcmp((char *)import->Name, func) == 0)
1.80 - {
1.81 - DWORD oldprot, oldprot2;
1.82 - VirtualProtect(iat, 4, PAGE_READWRITE, &oldprot);
1.83 - *iat = hookfunc;
1.84 - VirtualProtect(iat, 4, oldprot, &oldprot2);
1.85 - entryFound = true;
1.86 - }
1.87 - }
1.88 - data++;
1.89 - iat++;
1.90 - }
1.91 - }
1.92 - desc++;
1.93 - }
1.94 -
1.95 - if (!entryFound)
1.96 - {
1.97 - UTIL_Format(err, maxlength, "Could not find IAT entry for %s", func);
1.98 - return false;
1.99 - }
1.100 -
1.101 - return true;
1.102 -}
1.103 -
1.104 -BOOL
1.105 -WINAPI
1.106 -MiniDumpWriteDump2(
1.107 - IN HANDLE hProcess,
1.108 - IN DWORD ProcessId,
1.109 - IN HANDLE hFile,
1.110 - IN MINIDUMP_TYPE DumpType,
1.111 - IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL
1.112 - IN CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, OPTIONAL
1.113 - IN CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam OPTIONAL
1.114 - )
1.115 -{
1.116 - DumpType = (MINIDUMP_TYPE)((int)DumpType|MiniDumpWithFullMemory|MiniDumpWithHandleData);
1.117 - return MiniDumpWriteDump(hProcess, ProcessId, hFile, DumpType, ExceptionParam, UserStreamParam, CallbackParam);
1.118 -}
1.119 -
1.120 -FARPROC WINAPI GetProcAddress2(HMODULE hModule, LPCSTR lpProcName)
1.121 -{
1.122 - if (strcmp(lpProcName, "MiniDumpWriteDump") == 0)
1.123 - {
1.124 - return (FARPROC)MiniDumpWriteDump2;
1.125 - }
1.126 -
1.127 - return GetProcAddress(hModule, lpProcName);
1.128 -}
1.129 -
1.130 -HMODULE WINAPI LoadLibraryEx2(LPCTSTR lpFileName, HANDLE hFile, DWORD dwFlags)
1.131 -{
1.132 - HMODULE lib = LoadLibraryEx(lpFileName, hFile, dwFlags);
1.133 -
1.134 - /* Steam.dll seems to get loaded using an abs path, thus the use of stristr() */
1.135 - if (stristr(lpFileName, "steam.dll"))
1.136 - {
1.137 - char err[64];
1.138 - if (!HookImportAddrTable((BYTE *)lib, "GetProcAddress", (DWORD)GetProcAddress2, err, sizeof(err)))
1.139 - {
1.140 - Error("[SM] %s in steam.dll\n", err);
1.141 - return NULL;
1.142 - }
1.143 - }
1.144 -
1.145 - return lib;
1.146 -}
1.147 -
1.148 -class CrazyWindowsDebugger : public SMGlobalClass
1.149 -{
1.150 -public:
1.151 - void OnSourceModAllInitialized()
1.152 - {
1.153 - HANDLE hModuleList = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
1.154 - MODULEENTRY32 me32;
1.155 - BYTE *engine = NULL;
1.156 - BYTE *steam = NULL;
1.157 - char err[64];
1.158 -
1.159 - me32.dwSize = sizeof(MODULEENTRY32);
1.160 -
1.161 - if (!Module32First(hModuleList, &me32))
1.162 - {
1.163 - Error("Could not initialize crazy debugger!");
1.164 - }
1.165 -
1.166 - do
1.167 - {
1.168 - if (strcasecmp(me32.szModule, "engine.dll") == 0)
1.169 - {
1.170 - engine = me32.modBaseAddr;
1.171 - }
1.172 - else if (strcasecmp(me32.szModule, "steam.dll") == 0)
1.173 - {
1.174 - steam = me32.modBaseAddr;
1.175 - }
1.176 - } while (Module32Next(hModuleList, &me32));
1.177 -
1.178 - CloseHandle(hModuleList);
1.179 -
1.180 - /* This really should not happen, but ... */
1.181 - if (!engine)
1.182 - {
1.183 - Error("[SM] Could not find engine.dll\n");
1.184 - }
1.185 -
1.186 - /* Steam.dll isn't loaded yet */
1.187 - if (!steam)
1.188 - {
1.189 - if (!HookImportAddrTable(engine, "LoadLibraryExA", (DWORD)LoadLibraryEx2, err, sizeof(err)))
1.190 - {
1.191 - Error("[SM] %s in engine.dll)\n", err);
1.192 - }
1.193 - }
1.194 - else
1.195 - {
1.196 - if (!HookImportAddrTable(steam, "GetProcAddress", (DWORD)GetProcAddress2, err, sizeof(err)))
1.197 - {
1.198 - Error("[SM] %s in steam.dll)\n", err);
1.199 - }
1.200 - }
1.201 - }
1.202 -} s_CrazyDebugger;