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;
}