www.pudn.com > remote_thread.zip > RemoteRunLib.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  
#include "spec_apis.h" 
#include "pedef.h" 
#include "decimage.h" 
#include "RemoteRunLib.h" 
 
 
CRemoteRunLib* CRemoteRunLib::_singleton_lib = NULL; 
 
 
CRemoteRunLib::CRemoteRunLib() 
			:m_nRefCount(0) 
			,m_hMainInstance(NULL) 
			,m_hLibInstance(NULL) 
			,m_isDebugMode(FALSE) 
			,m_isExitProcess(FALSE) 
{ 
	::InitializeCriticalSection( &m_cs ); 
} 
 
CRemoteRunLib::~CRemoteRunLib() 
{ 
	::DeleteCriticalSection( &m_cs ); 
} 
 
inline CRemoteRunLib* CRemoteRunLib::Instance() 
{ 
	if( _singleton_lib == NULL ) 
		_singleton_lib = new CRemoteRunLib; 
	return _singleton_lib; 
} 
 
long CRemoteRunLib::AddRef() 
{ 
	return InterlockedIncrement( &_singleton_lib->m_nRefCount ); 
} 
 
long CRemoteRunLib::Release() 
{ 
	long count = InterlockedDecrement( &_singleton_lib->m_nRefCount ); 
	if( count == 0 ) 
	{ 
		//-------------------------------------- 
		// remote.dll将被销毁 
		//-------------------------------------- 
 
#ifdef _DEBUG 
		::OutputDebugString( _T("warning: remote library will be unload now.\n") ); 
#endif // _DEBUG 
 
		//-------------------------------------- 
		// 恢复所有被截获的APIs 
		//-------------------------------------- 
		UninitializeHookAPIs(); 
 
		 
		HMODULE hLibInstance = _singleton_lib->m_hLibInstance; 
		BOOL isDebugMode = _singleton_lib->m_isDebugMode; 
		BOOL isExitProcess = _singleton_lib->m_isExitProcess; 
 
		delete _singleton_lib; 
		_singleton_lib = NULL; 
 
 
		//-------------------------------------- 
		// 卸载remote.dll,退出线程 
		//-------------------------------------- 
		UnloadLibrary( hLibInstance, isDebugMode, isExitProcess ); 
	} 
 
	return count; 
} 
 
BOOL CRemoteRunLib::InitializeOnce( HMODULE hLibInstance, HMODULE hMainInstance, BOOL isDebugMode ) 
{ 
	CRemoteRunLib* lib = Instance(); 
 
	//-------------------------------------- 
	// 如果创建失败,remote.dll应立即退出, 
	// 不应再继续运行 
	//-------------------------------------- 
	if( lib == NULL ) 
		return FALSE; 
 
	lib->m_hLibInstance = hLibInstance; 
	lib->m_hMainInstance = hMainInstance; 
	lib->m_isDebugMode = isDebugMode; 
	lib->m_nRefCount = 1; 
 
 
	//--------------------------- 
	// remote.dll被Load了两次, 
	// 先减掉一次 
	//--------------------------- 
	FreeLibrary( hLibInstance ); 
	 
	 
	//---------------------------- 
	// 调试模式不用隐藏remote.dll 
	//---------------------------- 
	if( !isDebugMode ) 
		lib->HideLibrary(); 
 
	 
	 
	//-------------------------------------- 
	// 截获一些必要的APIs 
	//-------------------------------------- 
	InitializeHookAPIs(); 
	 
 
	return TRUE; 
} 
 
BOOL CRemoteRunLib::AddThread(DWORD tid) 
{ 
	BOOL fAdded; 
	DWORD* location; 
	int i, c; 
 
	//------------------------------------- 
	// curThreadId是调用CreateThread的线程 
	//------------------------------------- 
	DWORD curThreadId = ::GetCurrentThreadId(); 
 
	Lock(); 
 
	//--------------------------------------------------- 
	// 搜索模块列表,看看调用CreateThread的线程是否在其中 
	//--------------------------------------------------- 
	c = m_exeList.size(); 
	for( i = 0; i < c; i++) 
	{ 
		fAdded = find( m_exeList[i].ThreadList.begin(), m_exeList[i].ThreadList.end(), curThreadId ) 
				!= m_exeList[i].ThreadList.end(); 
		if( fAdded ) 
		{ 
			//---------------------------------- 
			// 把tid加入列表 
			//---------------------------------- 
 
 
			//--------------------------------- 
			// find a blank slot to fill tid 
			//--------------------------------- 
			location = find( m_exeList[i].ThreadList.begin(), m_exeList[i].ThreadList.end(), 0 ); 
			if( location != m_exeList[i].ThreadList.end() ) 
				*location = tid; 
			else 
				m_exeList[i].ThreadList.push_back( tid ); // append 
 
			break; 
		} 
	} 
 
	Unlock(); 
 
	return fAdded; 
} 
 
BOOL CRemoteRunLib::RemoveThread(DWORD tid) 
{ 
	BOOL fRemoved = FALSE; 
	DWORD* location; 
	int i, c; 
 
	Lock(); 
 
	//------------------------------------- 
	// 在列表中搜索tid 
	//------------------------------------- 
	c = m_exeList.size(); 
	for( i = 0; i < c; i++) 
	{ 
		location = find( m_exeList[i].ThreadList.begin(), m_exeList[i].ThreadList.end(), tid ); 
		fRemoved = location != m_exeList[i].ThreadList.end(); 
		if( fRemoved ) 
		{ 
			//------------------------ 
			// 把他干掉 
			//------------------------ 
			*location = 0; 
 
			break; 
		} 
	} 
 
	Unlock(); 
 
	return fRemoved; 
} 
 
 
int CRemoteRunLib::FindEXEIndex(DWORD tid) 
{ 
	int index = -1; 
	int i, c; 
 
	Lock(); 
 
	//--------------------------------------------- 
	// 以tid为关键字搜索列表 
	//--------------------------------------------- 
	c = m_exeList.size(); 
	for( i = 0; i < c; i++) 
	{ 
		if( find( m_exeList[i].ThreadList.begin(), m_exeList[i].ThreadList.end(), tid ) != m_exeList[i].ThreadList.end() ) 
		{ 
			index = i; 
			break; 
		} 
	} 
 
	Unlock(); 
	 
	return index; 
} 
 
//-------------------------------------------- 
// 找出tid所属的exe模块句柄 
//-------------------------------------------- 
HMODULE CRemoteRunLib::FindEXEHandle(DWORD tid) 
{ 
	HMODULE hInstance = NULL; 
 
	Lock(); 
 
	int index = FindEXEIndex( tid ); 
	if( index != -1 ) 
		hInstance = m_exeList[index].hInstance; 
 
	Unlock(); 
 
	return hInstance; 
} 
 
const CRemoteRunLib::PEXEINFO CRemoteRunLib::GetEXEInfoByIndex(int i) 
{ 
	if( i < 0 || i >= m_exeList.size() ) 
		return NULL; 
	return &m_exeList[i]; 
} 
 
 
//------------------------------------------------------------ 
// 把新的exe信息加入列表 
//------------------------------------------------------------ 
BOOL CRemoteRunLib::RegisterEXE(HMODULE hEXEHandle, LPCSTR pszAppPath) 
{ 
	EXEINFO ei; 
	 
	ei.hInstance = hEXEHandle; 
	ei.strExePath = pszAppPath; 
	ei.ThreadList.push_back( ::GetCurrentThreadId() ); 
	 
	CRemoteRunLib *lib = CRemoteRunLib::Instance(); 
 
	lib->Lock(); 
	lib->m_exeList.push_back( ei ); 
	lib->Unlock(); 
 
	return TRUE; 
} 
 
BOOL CRemoteRunLib::UnregisterEXE(int index) 
{ 
	BOOL retval = FALSE; 
	CRemoteRunLib *lib = CRemoteRunLib::Instance(); 
 
	lib->Lock(); 
 
	if( index >= 0 && index < lib->m_exeList.size() ) 
	{ 
		lib->m_exeList.erase( lib->m_exeList.begin()+index ); 
		retval = TRUE; 
	} 
 
	lib->Unlock(); 
 
	return TRUE; 
} 
 
void CRemoteRunLib::UnloadLibrary( HMODULE hLibInstance, BOOL isDebugMode, BOOL isExitProcess ) 
{ 
	FARPROC fnExitProc = isExitProcess ? (FARPROC)ExitProcess : (FARPROC)ExitThread; 
	if( isDebugMode ) 
	{ 
		//------------------------------------------------- 
		// 调试模式 
		//------------------------------------------------- 
 
 
		//------------------------------------------------- 
		// FreeLibrary( hLibInstance ); 
		// ExitThread/ExitProcess( 0 ); 
		//------------------------------------------------- 
		__asm { 
			push 0;				// parameter of ExitThread/ExitProcess 
			push 0;				// return address of ExitThread/ExitProcess 
			push hLibInstance;	// parameter of FreeLibrary 
			push fnExitProc;	// return address of FreeLibrary 
			push FreeLibrary; 
			ret;				// call FreeLibrary 
		} 
 
	} 
	else 
	{ 
		//------------------------------------------------- 
		// 隐藏模式 
		//------------------------------------------------- 
 
		PIMAGE_OPTIONAL_HEADER poh; 
		poh=(PIMAGE_OPTIONAL_HEADER) OPTHDROFFSET(hLibInstance); 
 
		typedef BOOL (WINAPI *PFN_DllMain)( HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved ); 
 
		//--------------------------------------------------- 
		// 获取remote.dll入口点 
		//--------------------------------------------------- 
		PFN_DllMain fnDllMain = (PFN_DllMain)((DWORD)hLibInstance+poh->AddressOfEntryPoint); 
 
		//--------------------------------------------------- 
		// 让remtoe.dll释放资源 
		//--------------------------------------------------- 
		fnDllMain( hLibInstance, DLL_PROCESS_DETACH, NULL ); 
 
 
		//----------------------------------------------------- 
		// 释放remote.dll占用的内存空间,并结束线程 
		// VirtualFree( hLibInstance, 0, MEM_RELEASE ); 
		// ExitThread/ExitProcess( 0 ); 
		//----------------------------------------------------- 
		__asm { 
			push 0;				// parameter of ExitThread/ExitProcess 
			push 0;				// return address of ExitThread/ExitProcess 
			push MEM_RELEASE;	// parameter of VirtualFree 
			push 0;				// parameter of VirtualFree 
			push hLibInstance;	// parameter of VirtualFree 
			push fnExitProc;	// return address of VirtualFree 
			push VirtualFree; 
			ret;				// call VirtualFree 
		} 
	} 
} 
 
 
//-------------------------------------------------------- 
// 在隐藏remote.dll模块时,我们不能让OS调用真正的DllMain, 
// 否则他会把所有在remote.dll中申请的资源释放掉,而这些 
// 资源我们以后还要使用。用这个冒牌货把他换掉。 
//-------------------------------------------------------- 
static BOOL APIENTRY PseudoDllMain( HMODULE hModule, DWORD  dwReason, LPVOID lpReserved ) 
{ 
	return TRUE; 
} 
 
BOOL CRemoteRunLib::HideLibrary() 
{ 
	//---------------------------------- 
	// 用户要求我们隐藏remote.dll 
	//---------------------------------- 
	PIMAGE_OPTIONAL_HEADER poh; 
	poh=(PIMAGE_OPTIONAL_HEADER) OPTHDROFFSET(m_hLibInstance); 
 
	 
	BYTE abTrampoline[DETOUR_TRAMPOLINE_SIZE]; 
	// initialize with NOP 
	memset( abTrampoline, 0x90, sizeof(abTrampoline) ); 
	 
	//----------------------------------------------- 
	// 用PseudoDllMain替换掉真正的remote.dll的入口, 
	// 因为我们不希望他把资源释放掉。 
	// 我们只是想隐藏自己而已。 
	//----------------------------------------------- 
	DetourFunctionWithEmptyTrampoline( abTrampoline, 
		(PBYTE)((DWORD)m_hLibInstance+poh->AddressOfEntryPoint), 
		(PBYTE)PseudoDllMain ); 
 
 
	//--------------------------- 
	// 来吧,让我们把自己藏起来, 
	// 谁都别想找到我。 
	//--------------------------- 
	DecorticateImage( m_hLibInstance, UNLOAD_MODULE, FreeLibrary ); 
 
	//------------------------------------------------ 
	// 好了这个冒牌的DllMain已经没用了,干掉他。 
	//------------------------------------------------ 
	DetourRemove( abTrampoline, (PBYTE)PseudoDllMain ); 
 
	return TRUE; 
} 
 
BOOL CRemoteRunLib::GetMainThreadList( vector& mainThreadList ) 
{ 
	int i, c; 
 
	Lock(); 
 
	c = m_exeList.size(); 
	for( i = 0; i < c; i++ ) 
		mainThreadList.push_back( m_exeList[i].ThreadList[0] ); 
 
	Unlock(); 
 
	return TRUE; 
}