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