core/CrazyDebugger.cpp
changeset 1111 003e822e8a46
child 1231 17badaf66ce4
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/core/CrazyDebugger.cpp	Sat Jul 14 17:36:11 2007 +0000
     1.3 @@ -0,0 +1,127 @@
     1.4 +/**
     1.5 + * vim: set ts=4 :
     1.6 + * ===============================================================
     1.7 + * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
     1.8 + * ===============================================================
     1.9 + *
    1.10 + * This file is not open source and may not be copied without explicit
    1.11 + * written permission of AlliedModders LLC.  This file may not be redistributed 
    1.12 + * in whole or significant part.
    1.13 + * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
    1.14 + *
    1.15 + * Version: $Id$
    1.16 + */
    1.17 +#if defined CRAZY_DEBUG
    1.18 +#include "sm_globals.h"
    1.19 +#include "sourcemm_api.h"
    1.20 +#include "Tlhelp32.h"
    1.21 +#include "LibrarySys.h"
    1.22 +#include "minidump.h"
    1.23 +
    1.24 +BOOL
    1.25 +WINAPI
    1.26 +MiniDumpWriteDump2(
    1.27 +				  IN HANDLE hProcess,
    1.28 +				  IN DWORD ProcessId,
    1.29 +				  IN HANDLE hFile,
    1.30 +				  IN MINIDUMP_TYPE DumpType,
    1.31 +				  IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL
    1.32 +				  IN CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, OPTIONAL
    1.33 +				  IN CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam OPTIONAL
    1.34 +				  )
    1.35 +{
    1.36 +	DumpType = (MINIDUMP_TYPE)((int)DumpType|MiniDumpWithFullMemory|MiniDumpWithHandleData);
    1.37 +	return MiniDumpWriteDump(hProcess, ProcessId, hFile, DumpType, ExceptionParam, UserStreamParam, CallbackParam);
    1.38 +}
    1.39 +
    1.40 +FARPROC WINAPI GetProcAddress2(HMODULE hModule, LPCSTR lpProcName)
    1.41 +{
    1.42 +	if (strcmp(lpProcName, "MiniDumpWriteDump") == 0)
    1.43 +	{
    1.44 +		return (FARPROC)MiniDumpWriteDump2;
    1.45 +	}
    1.46 +
    1.47 +	return GetProcAddress(hModule, lpProcName);
    1.48 +}
    1.49 +
    1.50 +class CrazyWindowsDebugger : public SMGlobalClass
    1.51 +{
    1.52 +public:
    1.53 +	void OnSourceModAllInitialized()
    1.54 +	{
    1.55 +		HANDLE hModuleList = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
    1.56 +		MODULEENTRY32 me32;
    1.57 +
    1.58 +		me32.dwSize = sizeof(MODULEENTRY32);
    1.59 +
    1.60 +		if (!Module32First(hModuleList, &me32))
    1.61 +		{
    1.62 +			Error("Could not initialize crazy debugger!");
    1.63 +		}
    1.64 +
    1.65 +		bool found = false;
    1.66 +
    1.67 +		do
    1.68 +		{
    1.69 +			if (strcasecmp(me32.szModule, "steam.dll") == 0)
    1.70 +			{
    1.71 +				IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *)me32.modBaseAddr;
    1.72 +				if (dos->e_magic != IMAGE_DOS_SIGNATURE)
    1.73 +				{
    1.74 +					Error("[SM] Could not detect steam.dll with valid DOS signature");
    1.75 +				}
    1.76 +				char *base = (char *)dos;
    1.77 +				IMAGE_NT_HEADERS *nt = (IMAGE_NT_HEADERS *)(base + dos->e_lfanew);
    1.78 +				if (nt->Signature != IMAGE_NT_SIGNATURE)
    1.79 +				{
    1.80 +					Error("[SM] Could not detect steam.dll with valid NT signature");
    1.81 +				}
    1.82 +				IMAGE_IMPORT_DESCRIPTOR *desc = 
    1.83 +					(IMAGE_IMPORT_DESCRIPTOR *)
    1.84 +					(base + nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
    1.85 +				if (base == (char *)desc)
    1.86 +				{
    1.87 +					Error("[SM] Could not find the steam.dll IAT");
    1.88 +				}
    1.89 +				while (desc->Name)
    1.90 +				{
    1.91 +					if (desc->FirstThunk != 0)
    1.92 +					{
    1.93 +						IMAGE_THUNK_DATA *data = (IMAGE_THUNK_DATA *)(base + desc->OriginalFirstThunk);
    1.94 +						DWORD *iat = (DWORD *)(base + desc->FirstThunk);
    1.95 +						while (data->u1.Function)
    1.96 +						{
    1.97 +							if ((data->u1.Ordinal & IMAGE_ORDINAL_FLAG32) != IMAGE_ORDINAL_FLAG32)
    1.98 +							{
    1.99 +								IMAGE_IMPORT_BY_NAME *import = (IMAGE_IMPORT_BY_NAME *)(base + data->u1.AddressOfData);
   1.100 +								if (strcmp((char *)import->Name, "GetProcAddress") == 0)
   1.101 +								{
   1.102 +									DWORD oldprot, oldprot2;
   1.103 +									VirtualProtect(iat, 4, PAGE_READWRITE, &oldprot);
   1.104 +									*iat = (DWORD)GetProcAddress2;
   1.105 +									VirtualProtect(iat, 4, oldprot, &oldprot2);
   1.106 +									found = true;
   1.107 +									goto _end;
   1.108 +								}
   1.109 +							}
   1.110 +							data++;
   1.111 +							iat++;
   1.112 +						}
   1.113 +					}
   1.114 +					desc++;
   1.115 +				}
   1.116 +				break;
   1.117 +			}
   1.118 +		} while  (Module32Next(hModuleList, &me32));
   1.119 +
   1.120 +_end:
   1.121 +
   1.122 +		if (!found)
   1.123 +		{
   1.124 +			Error("Could not find steam.dll's GetProcAddress IAT entry");
   1.125 +		}
   1.126 +
   1.127 +		CloseHandle(hModuleList);
   1.128 +	}
   1.129 +} s_CrazyDebugger;
   1.130 +#endif