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