www.pudn.com > remote_thread.zip > spec_apis.cpp


/*  Remote Run Library 
    Copyright (C) 2001, Sting Feng(冯越) 
 
    This program is free software; you can redistribute it and/or modify 
    it under the terms of the GNU General Public License as published by 
    the Free Software Foundation; either version 2 of the License, or 
    (at your option) any later version. 
 
    This program is distributed in the hope that it will be useful, 
    but WITHOUT ANY WARRANTY; without even the implied warranty of 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    GNU General Public License for more details. 
 
    You should have received a copy of the GNU General Public License 
    along with this program; if not, write to the Free Software 
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 
	The author of this program may be contacted at fenny@163.net. */ 
 
 
#include  
#include  
#include "ntthread.h" 
#include "RemoteRunLib.h" 
#include "spec_apis.h" 
#include "log.h" 
 
 
#ifdef _DEBUG 
#define TRACE(s) ::OutputDebugString(s); 
#define EXIT_TIME_OUT	5000//INFINITE 
#else 
#define TRACE(s) 
#define EXIT_TIME_OUT	3000 
#endif // _DEBUG 
 
 
 
//----------------------------------------------------- 
// 对这些API做特殊处理 
//----------------------------------------------------- 
DETOUR_TRAMPOLINE(VOID		WINAPI Real_ExitProcess(UINT uExitCode),ExitProcess); 
DETOUR_TRAMPOLINE(HANDLE	WINAPI Real_CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,DWORD dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId),CreateThread); 
DETOUR_TRAMPOLINE(VOID		WINAPI Real_ExitThread(DWORD dwExitCode),ExitThread); 
DETOUR_TRAMPOLINE(LONG		WINAPI Real_UnhandledExceptionFilter(_EXCEPTION_POINTERS *ExceptionInfo),UnhandledExceptionFilter); 
 
 
DETOUR_TRAMPOLINE(HMODULE	WINAPI Real_LoadLibraryExW(LPCWSTR lpFileName,HANDLE hFile,DWORD dwFlags),LoadLibraryExW); 
DETOUR_TRAMPOLINE(BOOL		WINAPI Real_FreeLibrary(HMODULE hModule),FreeLibrary); 
 
DETOUR_TRAMPOLINE(HMODULE	WINAPI Real_GetModuleHandleA(LPCSTR lpModuleName), GetModuleHandleA); 
DETOUR_TRAMPOLINE(HMODULE	WINAPI Real_GetModuleHandleW(LPCWSTR lpModuleName), GetModuleHandleW); 
 
DETOUR_TRAMPOLINE(HGLOBAL	WINAPI Real_LoadResource(HMODULE hModule,HRSRC hResInfo), LoadResource); 
 
DETOUR_TRAMPOLINE(HRSRC		WINAPI Real_FindResourceExA(HMODULE hModule,LPCSTR lpType,LPCSTR lpName,WORD wLanguage),FindResourceExA); 
DETOUR_TRAMPOLINE(HRSRC		WINAPI Real_FindResourceExW(HMODULE hModule,LPCWSTR lpType,LPCWSTR lpName,WORD wLanguage),FindResourceExW); 
 
DETOUR_TRAMPOLINE(BOOL		WINAPI Real_EnumResourceLanguagesA(HMODULE hModule,LPCSTR lpType,LPCSTR lpName,ENUMRESLANGPROCA lpEnumFunc,LONG_PTR lParam),EnumResourceLanguagesA); 
DETOUR_TRAMPOLINE(BOOL		WINAPI Real_EnumResourceLanguagesW(HMODULE hModule,LPCWSTR lpType,LPCWSTR lpName,ENUMRESLANGPROCW lpEnumFunc,LONG_PTR lParam),EnumResourceLanguagesW); 
 
DETOUR_TRAMPOLINE(BOOL		WINAPI Real_EnumResourceNamesA(HMODULE hModule,LPCSTR lpszType,ENUMRESNAMEPROCA lpEnumFunc,LONG_PTR lParam),EnumResourceNamesA); 
DETOUR_TRAMPOLINE(BOOL		WINAPI Real_EnumResourceNamesW(HMODULE hModule,LPCWSTR lpszType,ENUMRESNAMEPROCW lpEnumFunc,LONG_PTR lParam),EnumResourceNamesW); 
 
DETOUR_TRAMPOLINE(BOOL		WINAPI Real_EnumResourceTypesA(HMODULE hModule,ENUMRESTYPEPROCA lpEnumFunc,LONG_PTR lParam),EnumResourceTypesA); 
DETOUR_TRAMPOLINE(BOOL		WINAPI Real_EnumResourceTypesW(HMODULE hModule,ENUMRESTYPEPROCW lpEnumFunc,LONG_PTR lParam),EnumResourceTypesW); 
 
DETOUR_TRAMPOLINE(DWORD		WINAPI Real_GetModuleFileNameA(HMODULE hModule,LPSTR lpFilename,DWORD nSize),GetModuleFileNameA); 
DETOUR_TRAMPOLINE(DWORD		WINAPI Real_GetModuleFileNameW(HMODULE hModule,LPWSTR lpFilename,DWORD nSize),GetModuleFileNameW); 
 
 
void WINAPI RmRaiseException() 
{ 
	::RaiseException( SE_KILLTHREAD, 0, 0, NULL ); 
} 
 
void SafeKillThread( DWORD tid, BOOL fPostQuitMsg ) 
{ 
	if( tid == ::GetCurrentThreadId() ) 
		return; 
 
	HANDLE h = NtThread::NtOpenThread( THREAD_ALL_ACCESS, FALSE, tid, ::GetCurrentProcessId() ); 
	if( h != NULL ) 
	{ 
		//------------------------------- 
		// 试图让线程自己退出,如果不行, 
		// 让线程抛出异常 
		//------------------------------- 
		if( fPostQuitMsg ) 
		{ 
			::PostThreadMessage( tid, WM_QUIT, 0, 0 ); 
			if( ::WaitForSingleObject( h, EXIT_TIME_OUT ) != WAIT_TIMEOUT ) 
			{ 
				::CloseHandle( h ); 
				return; 
			} 
		} 
 
		//------------------------------- 
		// 抛出异常 
		//------------------------------- 
		SuspendThread( h ); 
 
		CONTEXT context; 
		context.ContextFlags = CONTEXT_CONTROL; 
		GetThreadContext( h, &context ); 
 
		//----------------------------------------------- 
		// 让主线程调用ExitProcess,这样主线程会终止属于 
		// 该exe的所有子线程 
		//----------------------------------------------- 
		context.Eip = (DWORD)RmRaiseException; 
		SetThreadContext( h, &context ); 
 
		ResumeThread( h ); 
		WaitForSingleObject( h, INFINITE ); 
		CloseHandle( h ); 
	} 
} 
 
 
//----------------------------------------------------- 
// 不让exe把我们的异常(SE_KILLTHREAD),当成未处理异常, 
// 这个异常将被RealRun捕获 
//----------------------------------------------------- 
static LONG WINAPI Mine_UnhandledExceptionFilter(_EXCEPTION_POINTERS *ExceptionInfo) 
{ 
	if( ExceptionInfo->ExceptionRecord->ExceptionCode == SE_KILLTHREAD ) 
		return EXCEPTION_CONTINUE_SEARCH; 
	return Real_UnhandledExceptionFilter( ExceptionInfo ); 
} 
 
 
static DWORD KillAllChildThread( DWORD tid ) 
{ 
	int i, c; 
	CRemoteRunLib *lib = CRemoteRunLib::Instance(); 
	 
	int index = lib->FindEXEIndex( tid ); 
	if( index == -1 ) 
		return 0; 
 
	lib->Lock(); 
 
	vector& threadList = lib->GetEXEInfoByIndex( index )->ThreadList; 
 
	//-------------------------------------------- 
	// 遍历线程列表,如果还有线程活着,终止他 
	// 除了本线程和exe的主线程 
	//-------------------------------------------- 
	DWORD pid = ::GetCurrentProcessId(); 
 
	c = threadList.size(); 
 
	//--------------------- 
	// 保留exe的主线程 
	//--------------------- 
	DWORD dwMainThreadId = threadList[0]; 
 
	 
	for( i = 1; i < c; i++) 
	{ 
		if( threadList[i] != 0 && threadList[i] != tid ) 
		{ 
			HANDLE h = NtThread::NtOpenThread( SYNCHRONIZE | THREAD_TERMINATE, 
												FALSE, 
												threadList[i], 
												pid ); 
 
			if( h != NULL ) 
			{ 
				//------------------------------------------------ 
				// 试图让线程自己终止自己,如果不行就强行终止 
				//------------------------------------------------ 
				::PostThreadMessage( threadList[i], WM_QUIT, 0, 0 ); 
				if( ::WaitForSingleObject( h, 1000 ) == WAIT_TIMEOUT ) 
					::TerminateThread( h, -1 ); 
				 
				::CloseHandle( h ); 
			} 
		} 
	} 
 
	//------------------------------------------------ 
	// 从模块信息列表中删除该exe信息 
	//------------------------------------------------ 
	CRemoteRunLib::UnregisterEXE( index ); 
 
	lib->Unlock(); 
 
	return dwMainThreadId; 
} 
 
//------------------------------------------------- 
// 进程即将结束,释放所有资源 
//------------------------------------------------- 
static VOID WINAPI Mine_ExitProcess(UINT uExitCode) 
{ 
	PrintLog( "Process exiting...\n" ); 
 
	int i, c; 
	DWORD tid = ::GetCurrentThreadId(); 
	DWORD dwMainThreadId = 0; 
 
	CRemoteRunLib *lib = CRemoteRunLib::Instance(); 
 
 
	lib->Lock(); 
 
	int index = lib->FindEXEIndex( tid ); 
 
	//---------------------------------------------------- 
	// 如果这是加载remote.dll的线程或者这是进程的主线程, 
	// 则先让exe的主线程退出 
	//---------------------------------------------------- 
	if( index == -1 ) 
	{ 
		//---------------------------------------- 
		// 增加remote.dll使用计数,禁止卸载 
		//---------------------------------------- 
		CRemoteRunLib::AddRef(); 
 
		//--------------------------------------- 
		// 先保存一份主线程ID列表 
		// 确保加载remote.dll的线程最后退出 
		//--------------------------------------- 
		vector mainThreadList; 
 
		lib->GetMainThreadList( mainThreadList ); 
 
 
 
		//---------------------------------------- 
		// 先解锁,让其他线程处理 
		//---------------------------------------- 
		lib->Unlock(); 
 
 
 
		//--------------------------------------- 
		// 依次在主线程中抛出异常 
		//--------------------------------------- 
		c = mainThreadList.size(); 
		for( i = c-1; i >= 0; i-- ) 
		{ 
//			KillAllChildThread( mainThreadList[i] ); 
			SafeKillThread( mainThreadList[i], TRUE ); 
		} 
 
 
		//--------------------------------------- 
		// 让CRemoteRunLib::UnloadLibrary调用 
		// ExitProcess退出进程 
		//--------------------------------------- 
		lib->SetExitProcessFlag(); 
 
		//--------------------------------------- 
		// 释放资源 
		//--------------------------------------- 
		CRemoteRunLib::Release(); 
 
		//--------------------------------------------- 
		// 退出进程。事实上程序永远不会执行到这里 
		//--------------------------------------------- 
		Real_ExitProcess(uExitCode); 
		return; // 程序不会走到这里了 
	} 
 
 
	//----------------------------------------------------- 
	// 终止列表中所有线程,并从exe信息列表中删除该exe信息 
	//----------------------------------------------------- 
 
	 
	dwMainThreadId = KillAllChildThread( tid ); 
 
	 
	lib->Unlock(); 
 
 
	if( dwMainThreadId == tid ) 
	{ 
		//------------------------------------------------ 
		// 抛出一个异常。这个异常会被RealRun捕捉 
		//------------------------------------------------ 
		RmRaiseException(); 
	} 
	else 
	{ 
		//-------------------------------------------- 
		// 优雅的终止主线程 
		//-------------------------------------------- 
		SafeKillThread( dwMainThreadId, FALSE ); 
 
 
		//-------------------------------------------- 
		// 退出线程 
		//-------------------------------------------- 
		Real_ExitThread( -1 ); 
	} 
} 
 
 
static HANDLE WINAPI Mine_CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,DWORD dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId) 
{ 
	DWORD tid; 
	HANDLE hThread = Real_CreateThread(lpThreadAttributes,dwStackSize,lpStartAddress,lpParameter,dwCreationFlags,&tid); 
	if( hThread != NULL ) 
	{ 
		PrintLog( "Thread Created:%d\n", tid ); 
 
		if( lpThreadId != NULL ) *lpThreadId = tid; 
 
 
		//------------------------------ 
		// 把新线程加入到列表 
		//------------------------------ 
		CRemoteRunLib::Instance()->AddThread( tid ); 
	} 
	return hThread; 
} 
 
 
static VOID WINAPI Mine_ExitThread(DWORD dwExitCode) 
{ 
	DWORD tid = ::GetCurrentThreadId(); 
	PrintLog( "Thread Removed:%d\n", tid ); 
 
 
	//---------------------------------- 
	// 从列表中删除该线程 
	//---------------------------------- 
	CRemoteRunLib::Instance()->RemoveThread( tid ); 
	 
	Real_ExitThread(dwExitCode); 
} 
 
 
//---------------------------------------------------------------- 
// 在以下函数中,如果以缺省参数调用,我们要做特殊处理 
//---------------------------------------------------------------- 
static HMODULE WINAPI Mine_GetModuleHandleA(LPCSTR lpModuleName) 
{ 
	HMODULE hInstance; 
	if( lpModuleName == NULL && 
		(hInstance = CRemoteRunLib::Instance()->FindEXEHandle( ::GetCurrentThreadId() ) ) != NULL ) 
		return hInstance; 
	return Real_GetModuleHandleA(lpModuleName); 
} 
 
static HMODULE WINAPI Mine_GetModuleHandleW(LPCWSTR lpModuleName) 
{ 
	HMODULE hInstance; 
	if( lpModuleName == NULL && 
		(hInstance = CRemoteRunLib::Instance()->FindEXEHandle( ::GetCurrentThreadId() ) ) != NULL ) 
		return hInstance; 
	return Real_GetModuleHandleW(lpModuleName); 
} 
 
static inline HMODULE GetRealHandle( HMODULE hModule ) 
{ 
	CRemoteRunLib *lib = CRemoteRunLib::Instance(); 
	if( hModule == lib->GetMainEXEHandle() || hModule == NULL ) 
	{ 
		return lib->FindEXEHandle( ::GetCurrentThreadId() ); 
	} 
	return hModule; 
} 
 
static HGLOBAL WINAPI Mine_LoadResource(HMODULE hModule,HRSRC hResInfo) 
{ 
	return Real_LoadResource( GetRealHandle(hModule), hResInfo ); 
} 
 
static HRSRC WINAPI Mine_FindResourceExA(HMODULE hModule,LPCSTR lpType,LPCSTR lpName,WORD wLanguage) 
{ 
	return Real_FindResourceExA( GetRealHandle(hModule), lpType, lpName, wLanguage); 
} 
static HRSRC WINAPI Mine_FindResourceExW(HMODULE hModule,LPCWSTR lpType,LPCWSTR lpName,WORD wLanguage) 
{ 
	return Real_FindResourceExW( GetRealHandle(hModule), lpType, lpName, wLanguage); 
} 
 
static BOOL WINAPI Mine_EnumResourceLanguagesA(HMODULE hModule,LPCSTR lpType,LPCSTR lpName,ENUMRESLANGPROCA lpEnumFunc,LONG_PTR lParam) 
{ 
	return Real_EnumResourceLanguagesA(GetRealHandle(hModule),lpType,lpName,lpEnumFunc,lParam); 
} 
static BOOL WINAPI Mine_EnumResourceLanguagesW(HMODULE hModule,LPCWSTR lpType,LPCWSTR lpName,ENUMRESLANGPROCW lpEnumFunc,LONG_PTR lParam) 
{ 
	return Real_EnumResourceLanguagesW(GetRealHandle(hModule),lpType,lpName,lpEnumFunc,lParam); 
} 
 
static BOOL WINAPI Mine_EnumResourceNamesA(HMODULE hModule,LPCSTR lpszType,ENUMRESNAMEPROCA lpEnumFunc,LONG_PTR lParam) 
{ 
	return Real_EnumResourceNamesA(GetRealHandle(hModule),lpszType,lpEnumFunc,lParam); 
} 
static BOOL WINAPI Mine_EnumResourceNamesW(HMODULE hModule,LPCWSTR lpszType,ENUMRESNAMEPROCW lpEnumFunc,LONG_PTR lParam) 
{ 
	return Real_EnumResourceNamesW(GetRealHandle(hModule),lpszType,lpEnumFunc,lParam); 
} 
 
static BOOL WINAPI Mine_EnumResourceTypesA(HMODULE hModule,ENUMRESTYPEPROCA lpEnumFunc,LONG_PTR lParam) 
{ 
	return Real_EnumResourceTypesA(GetRealHandle(hModule),lpEnumFunc,lParam); 
} 
static BOOL WINAPI Mine_EnumResourceTypesW(HMODULE hModule,ENUMRESTYPEPROCW lpEnumFunc,LONG_PTR lParam) 
{ 
	return Real_EnumResourceTypesW(GetRealHandle(hModule),lpEnumFunc,lParam); 
} 
 
static DWORD WINAPI Mine_GetModuleFileNameA(HMODULE hModule,LPSTR lpFilename,DWORD nSize) 
{ 
	return Real_GetModuleFileNameA(GetRealHandle(hModule),lpFilename,nSize); 
} 
 
static DWORD WINAPI Mine_GetModuleFileNameW(HMODULE hModule,LPWSTR lpFilename,DWORD nSize) 
{ 
	DWORD tid; 
 
	CRemoteRunLib *lib = CRemoteRunLib::Instance(); 
	 
	//-------------------------------------------------------------- 
	// 是不是后加载的remote.dll在寻找我们? 
	//-------------------------------------------------------------- 
	if( hModule == (HMODULE)-1 && lpFilename == NULL && nSize == 0 ) 
		return (DWORD)lib->GetLibHandle(); 
 
 
	//------------------------------------------- 
	// 不是,照常处理 
	//------------------------------------------- 
	tid = ::GetCurrentThreadId(); 
	CRemoteRunLib::PEXEINFO pExeInfo = lib->GetEXEInfoByIndex( lib->FindEXEIndex( tid ) ); 
	if( pExeInfo != NULL ) 
	{ 
		if( hModule == NULL || hModule == pExeInfo->hInstance ) 
		{ 
			//----------------------------- 
			// 找到!!! 
			//----------------------------- 
			return ::MultiByteToWideChar( CP_ACP, 0, 
				pExeInfo->strExePath.c_str(), -1, 
				lpFilename, nSize ); 
		} 
	} 
 
	return Real_GetModuleFileNameW(hModule,lpFilename,nSize); 
} 
 
 
//--------------------------------------------------------------------- 
// LoadLibrary和FreeLibrary只在Debug时处理,打印一些模块加载/卸载信息 
//--------------------------------------------------------------------- 
static HMODULE WINAPI Mine_LoadLibraryExW(LPCWSTR lpFileName,HANDLE hFile,DWORD dwFlags) 
{ 
 
#ifdef _DEBUG 
	if( lpFileName != NULL ) 
	{ 
		WCHAR szInfo[MAX_PATH+100]; 
		wsprintfW( szInfo, L"Load Library: %s\n", lpFileName ); 
		::OutputDebugStringW( szInfo ); 
	} 
#endif // _DEBUG 
 
	return Real_LoadLibraryExW(lpFileName,hFile,dwFlags); 
} 
 
static BOOL	WINAPI Mine_FreeLibrary(HMODULE hModule) 
{ 
#ifdef _DEBUG 
	WCHAR szLibPath[MAX_PATH]; 
	if( Mine_GetModuleFileNameW( hModule, szLibPath, MAX_PATH ) != 0 ) 
	{ 
		WCHAR szInfo[MAX_PATH+100]; 
		wsprintfW( szInfo, L"Free Library: %s\n", szLibPath ); 
		::OutputDebugStringW( szInfo ); 
	} 
#endif // _DEBUG 
 
	return Real_FreeLibrary(hModule); 
} 
 
 
 
//---------------------------------------------------------- 
// 截获这些函数 
//---------------------------------------------------------- 
static BOOL CALLBACK DetoursFunctions() 
{ 
 
	PrintLog( "Detouring some functions...\n" ); 
 
	DetourFunctionWithTrampoline((PBYTE)Real_ExitProcess, (PBYTE)Mine_ExitProcess); 
	DetourFunctionWithTrampoline((PBYTE)Real_CreateThread, (PBYTE)Mine_CreateThread); 
	DetourFunctionWithTrampoline((PBYTE)Real_ExitThread, (PBYTE)Mine_ExitThread); 
	DetourFunctionWithTrampoline((PBYTE)Real_UnhandledExceptionFilter, (PBYTE)Mine_UnhandledExceptionFilter); 
	 
 
//	DetourFunctionWithTrampoline((PBYTE)Real_LoadLibraryExW, (PBYTE)Mine_LoadLibraryExW); 
//	DetourFunctionWithTrampoline((PBYTE)Real_FreeLibrary, (PBYTE)Mine_FreeLibrary); 
 
	DetourFunctionWithTrampoline((PBYTE)Real_GetModuleHandleA, (PBYTE)Mine_GetModuleHandleA); 
	DetourFunctionWithTrampoline((PBYTE)Real_GetModuleHandleW, (PBYTE)Mine_GetModuleHandleW); 
 
	DetourFunctionWithTrampoline((PBYTE)Real_LoadResource, (PBYTE)Mine_LoadResource); 
 
	DetourFunctionWithTrampoline((PBYTE)Real_FindResourceExA, (PBYTE)Mine_FindResourceExA); 
	DetourFunctionWithTrampoline((PBYTE)Real_FindResourceExW, (PBYTE)Mine_FindResourceExW); 
 
	DetourFunctionWithTrampoline((PBYTE)Real_EnumResourceLanguagesA, (PBYTE)Mine_EnumResourceLanguagesA); 
	DetourFunctionWithTrampoline((PBYTE)Real_EnumResourceLanguagesW, (PBYTE)Mine_EnumResourceLanguagesW); 
 
	DetourFunctionWithTrampoline((PBYTE)Real_EnumResourceNamesA, (PBYTE)Mine_EnumResourceNamesA); 
	DetourFunctionWithTrampoline((PBYTE)Real_EnumResourceNamesW, (PBYTE)Mine_EnumResourceNamesW); 
 
	DetourFunctionWithTrampoline((PBYTE)Real_EnumResourceTypesA, (PBYTE)Mine_EnumResourceTypesA); 
	DetourFunctionWithTrampoline((PBYTE)Real_EnumResourceTypesW, (PBYTE)Mine_EnumResourceTypesW); 
 
	DetourFunctionWithTrampoline((PBYTE)Real_GetModuleFileNameA, (PBYTE)Mine_GetModuleFileNameA); 
	DetourFunctionWithTrampoline((PBYTE)Real_GetModuleFileNameW, (PBYTE)Mine_GetModuleFileNameW); 
 
	return TRUE; 
} 
 
static BOOL CALLBACK UndetoursFunctions() 
{ 
	PrintLog( "Undetouring some functions...\n" ); 
 
	DetourRemove((PBYTE)Real_ExitProcess, (PBYTE)Mine_ExitProcess); 
	DetourRemove((PBYTE)Real_CreateThread, (PBYTE)Mine_CreateThread); 
	DetourRemove((PBYTE)Real_ExitThread, (PBYTE)Mine_ExitThread); 
	DetourRemove((PBYTE)Real_UnhandledExceptionFilter, (PBYTE)Mine_UnhandledExceptionFilter); 
 
//	DetourRemove((PBYTE)Real_LoadLibraryExW, (PBYTE)Mine_LoadLibraryExW); 
//	DetourRemove((PBYTE)Real_FreeLibrary, (PBYTE)Mine_FreeLibrary); 
 
	DetourRemove((PBYTE)Real_GetModuleHandleA, (PBYTE)Mine_GetModuleHandleA); 
	DetourRemove((PBYTE)Real_GetModuleHandleW, (PBYTE)Mine_GetModuleHandleW); 
 
	DetourRemove((PBYTE)Real_LoadResource, (PBYTE)Mine_LoadResource); 
 
	DetourRemove((PBYTE)Real_FindResourceExA, (PBYTE)Mine_FindResourceExA); 
	DetourRemove((PBYTE)Real_FindResourceExW, (PBYTE)Mine_FindResourceExW); 
 
	DetourRemove((PBYTE)Real_EnumResourceLanguagesA, (PBYTE)Mine_EnumResourceLanguagesA); 
	DetourRemove((PBYTE)Real_EnumResourceLanguagesW, (PBYTE)Mine_EnumResourceLanguagesW); 
 
	DetourRemove((PBYTE)Real_EnumResourceNamesA, (PBYTE)Mine_EnumResourceNamesA); 
	DetourRemove((PBYTE)Real_EnumResourceNamesW, (PBYTE)Mine_EnumResourceNamesW); 
 
	DetourRemove((PBYTE)Real_EnumResourceTypesA, (PBYTE)Mine_EnumResourceTypesA); 
	DetourRemove((PBYTE)Real_EnumResourceTypesW, (PBYTE)Mine_EnumResourceTypesW); 
 
	DetourRemove((PBYTE)Real_GetModuleFileNameA, (PBYTE)Mine_GetModuleFileNameA); 
	DetourRemove((PBYTE)Real_GetModuleFileNameW, (PBYTE)Mine_GetModuleFileNameW); 
	 
	 
	return TRUE; 
} 
 
 
//-------------------------------------------------------------------- 
// 在截获函数前,应该挂起其他线程,防止访问冲突 
// 里面用到了两个未公开接口:NtOpenThread和NtQuerySystemInformation 
//-------------------------------------------------------------------- 
static void SafeProcessAPIs( BOOL (WINAPI *fnCallBack)() ) 
{ 
	DWORD i, count, processId, threadId; 
 
	if( fnCallBack == NULL ) 
		return; 
 
	//----------------------------------------------------------------------- 
	// 假定进程里的线程不会超过1024个,这样处理比较简单。:) 
	//----------------------------------------------------------------------- 
	DWORD tid[1024]; 
	 
	HANDLE hThread[1024]; 
	count = 1024; 
 
	processId = ::GetCurrentProcessId(); 
	threadId = ::GetCurrentThreadId(); 
	ZeroMemory( hThread, sizeof(hThread) ); 
 
	__try { 
 
		//----------------------------------------- 
		// 枚举进程中所有线程ID 
		//----------------------------------------- 
		if( NtThread::EnumThread( processId, tid, &count ) ) 
		{ 
			//--------------------------------- 
			// 挂起所有线程,当然,除了自己。 
			//--------------------------------- 
			for( i = 0; i < count; i++) 
			{ 
				if( threadId != tid[i] ) 
					hThread[i] = NtThread::NtOpenThread( THREAD_SUSPEND_RESUME, FALSE, tid[i], processId ); 
				if( hThread[i] != NULL ) 
					::SuspendThread( hThread[i] ); 
			} 
 
			//--------------------------------- 
			// 截获必要的API 
			// Detours some functions 
			//--------------------------------- 
			fnCallBack(); 
		} 
	}__finally { 
 
		//---------------------------------- 
		// 确保完事后激活所有线程 
		//---------------------------------- 
		for( i = 0; i < count; i++) 
		{ 
			if( hThread[i] != NULL ) 
				::ResumeThread( hThread[i] ); 
		} 
	} 
} 
 
BOOL InitializeHookAPIs() 
{ 
	//---------------------------------------------- 
	// 对一些API做特殊处理 
	//---------------------------------------------- 
	SafeProcessAPIs( DetoursFunctions ); 
	return TRUE; 
} 
 
BOOL UninitializeHookAPIs() 
{ 
	SafeProcessAPIs( UndetoursFunctions ); 
	return TRUE; 
}