core/CrazyDebugger.cpp
author David Anderson <dvander@alliedmods.net>
Thu Aug 09 19:05:34 2007 +0000 (2007-08-09)
changeset 1291 c6d26de53926
parent 1231 17badaf66ce4
child 1330 ab94316bb52b
permissions -rw-r--r--
added amb764, vote delay setting
     1 /**
     2  * vim: set ts=4 :
     3  * ================================================================
     4  * SourceMod
     5  * Copyright (C) 2004-2007 AlliedModders LLC.  All rights reserved.
     6  * ================================================================
     7  *
     8  * This program is free software; you can redistribute it and/or 
     9  * modify it under the terms of the GNU General Public License, 
    10  * version 3.0, as published by the Free Software Foundation.
    11  * 
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    15  * GNU General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    19  *
    20  * As a special exception, AlliedModders LLC gives you permission to 
    21  * link the code of this program (as well as its derivative works) to 
    22  * "Half-Life 2," the "Source Engine," the "SourcePawn JIT," and any 
    23  * Game MODs that run on software by the Valve Corporation.  You must 
    24  * obey the GNU General Public License in all respects for all other 
    25  * code used. Additionally, AlliedModders LLC grants this exception 
    26  * to all derivative works. AlliedModders LLC defines further 
    27  * exceptions, found in LICENSE.txt (as of this writing, version 
    28  * JULY-31-2007), or <http://www.sourcemod.net/license.php>.
    29  *
    30  * Version: $Id$
    31  */
    32 
    33 #if defined CRAZY_DEBUG
    34 #include "sm_globals.h"
    35 #include "sourcemm_api.h"
    36 #include "Tlhelp32.h"
    37 #include "LibrarySys.h"
    38 #include "minidump.h"
    39 
    40 BOOL
    41 WINAPI
    42 MiniDumpWriteDump2(
    43 				  IN HANDLE hProcess,
    44 				  IN DWORD ProcessId,
    45 				  IN HANDLE hFile,
    46 				  IN MINIDUMP_TYPE DumpType,
    47 				  IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL
    48 				  IN CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, OPTIONAL
    49 				  IN CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam OPTIONAL
    50 				  )
    51 {
    52 	DumpType = (MINIDUMP_TYPE)((int)DumpType|MiniDumpWithFullMemory|MiniDumpWithHandleData);
    53 	return MiniDumpWriteDump(hProcess, ProcessId, hFile, DumpType, ExceptionParam, UserStreamParam, CallbackParam);
    54 }
    55 
    56 FARPROC WINAPI GetProcAddress2(HMODULE hModule, LPCSTR lpProcName)
    57 {
    58 	if (strcmp(lpProcName, "MiniDumpWriteDump") == 0)
    59 	{
    60 		return (FARPROC)MiniDumpWriteDump2;
    61 	}
    62 
    63 	return GetProcAddress(hModule, lpProcName);
    64 }
    65 
    66 class CrazyWindowsDebugger : public SMGlobalClass
    67 {
    68 public:
    69 	void OnSourceModAllInitialized()
    70 	{
    71 		HANDLE hModuleList = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
    72 		MODULEENTRY32 me32;
    73 
    74 		me32.dwSize = sizeof(MODULEENTRY32);
    75 
    76 		if (!Module32First(hModuleList, &me32))
    77 		{
    78 			Error("Could not initialize crazy debugger!");
    79 		}
    80 
    81 		bool found = false;
    82 
    83 		do
    84 		{
    85 			if (strcasecmp(me32.szModule, "steam.dll") == 0)
    86 			{
    87 				IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *)me32.modBaseAddr;
    88 				if (dos->e_magic != IMAGE_DOS_SIGNATURE)
    89 				{
    90 					Error("[SM] Could not detect steam.dll with valid DOS signature");
    91 				}
    92 				char *base = (char *)dos;
    93 				IMAGE_NT_HEADERS *nt = (IMAGE_NT_HEADERS *)(base + dos->e_lfanew);
    94 				if (nt->Signature != IMAGE_NT_SIGNATURE)
    95 				{
    96 					Error("[SM] Could not detect steam.dll with valid NT signature");
    97 				}
    98 				IMAGE_IMPORT_DESCRIPTOR *desc = 
    99 					(IMAGE_IMPORT_DESCRIPTOR *)
   100 					(base + nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
   101 				if (base == (char *)desc)
   102 				{
   103 					Error("[SM] Could not find the steam.dll IAT");
   104 				}
   105 				while (desc->Name)
   106 				{
   107 					if (desc->FirstThunk != 0)
   108 					{
   109 						IMAGE_THUNK_DATA *data = (IMAGE_THUNK_DATA *)(base + desc->OriginalFirstThunk);
   110 						DWORD *iat = (DWORD *)(base + desc->FirstThunk);
   111 						while (data->u1.Function)
   112 						{
   113 							if ((data->u1.Ordinal & IMAGE_ORDINAL_FLAG32) != IMAGE_ORDINAL_FLAG32)
   114 							{
   115 								IMAGE_IMPORT_BY_NAME *import = (IMAGE_IMPORT_BY_NAME *)(base + data->u1.AddressOfData);
   116 								if (strcmp((char *)import->Name, "GetProcAddress") == 0)
   117 								{
   118 									DWORD oldprot, oldprot2;
   119 									VirtualProtect(iat, 4, PAGE_READWRITE, &oldprot);
   120 									*iat = (DWORD)GetProcAddress2;
   121 									VirtualProtect(iat, 4, oldprot, &oldprot2);
   122 									found = true;
   123 									goto _end;
   124 								}
   125 							}
   126 							data++;
   127 							iat++;
   128 						}
   129 					}
   130 					desc++;
   131 				}
   132 				break;
   133 			}
   134 		} while  (Module32Next(hModuleList, &me32));
   135 
   136 _end:
   137 
   138 		if (!found)
   139 		{
   140 			Error("Could not find steam.dll's GetProcAddress IAT entry");
   141 		}
   142 
   143 		CloseHandle(hModuleList);
   144 	}
   145 } s_CrazyDebugger;
   146 #endif