123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- #include "stdafx.h"
- #include "CWxObject.h"
- #define WX_MAIN_WND_NAME _T("微信")
- #define WX_MAIN_WND_CLASS_NAME _T("WeChatMainWndForPC")
- #define WX_LOGIN_WND_NAME _T("登录")
- #define WX_LOGIN_WND_CLASS_NAME _T("WeChatLoginWndForPC")
- CWxObject::CWxObject()
- :m_dwWxProcId(0)
- , m_hWxProcess(NULL)
- , m_hWxMainWnd(NULL)
- , m_hWxLoginWnd(NULL)
- , m_lpInjectData(NULL)
- , m_lpEjectData(NULL)
- , m_hInjectThread(NULL)
- , m_hEjectThread(NULL)
- , m_dwPathLen(0)
- {
- }
- CWxObject::CWxObject(DWORD dwProcId, LPCTSTR lpDynamicLibraryPath)
- :m_dwWxProcId(dwProcId)
- , m_hWxProcess(NULL)
- , m_hWxMainWnd(NULL)
- , m_hWxLoginWnd(NULL)
- , m_lpInjectData(NULL)
- , m_lpEjectData(NULL)
- , m_hInjectThread(NULL)
- , m_hEjectThread(NULL)
- , m_dwPathLen(0)
- {
- ASSERT(dwProcId != 0);
- ASSERT(lpDynamicLibraryPath != NULL);
- memset(m_szDllPath, 0, sizeof(m_szDllPath));
- _tcscpy_s(m_szDllPath, lpDynamicLibraryPath);
- m_hWxProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, m_dwWxProcId);
- if (m_hWxProcess == NULL)
- {
- WriteTextLog(_T("打开WeChat.exe进程失败"));
- }
- //m_hWxProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, m_dwWxProcId);
- }
- CWxObject::~CWxObject()
- {
- // 卸载dll;
- EjectDynamicLibrary();
- // 释放所有资源;
- if (m_hInjectThread)
- CloseHandle(m_hInjectThread);
- m_hInjectThread = NULL;
- if (m_hEjectThread)
- CloseHandle(m_hEjectThread);
- m_hEjectThread = NULL;
- if (m_lpInjectData)
- VirtualFreeEx(m_hWxProcess, m_lpInjectData, m_dwPathLen, MEM_RELEASE);
- m_lpInjectData = NULL;
- if (m_lpEjectData)
- VirtualFreeEx(m_hWxProcess, m_lpEjectData, m_dwPathLen, MEM_RELEASE);
- m_lpEjectData = NULL;
- if (m_hWxProcess)
- CloseHandle(m_hWxProcess);
- m_hWxProcess = NULL;
- }
- void CWxObject::setInjectionObj(DWORD dwProcId, LPCTSTR lpDynamicLibraryPath)
- {
- ASSERT(dwProcId != 0);
- ASSERT(lpDynamicLibraryPath != NULL);
- memset(m_szDllPath, 0, sizeof(m_szDllPath));
- _tcscpy_s(m_szDllPath, lpDynamicLibraryPath);
- m_dwWxProcId = dwProcId;
- m_hWxProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, m_dwWxProcId);
- if (m_hWxProcess == NULL)
- {
- WriteTextLog(_T("打开WeChat.exe进程失败"));
- }
- //m_hWxProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, m_dwWxProcId);
- }
- BOOL CWxObject::InjectDynamicLibrary()
- {
- ASSERT(m_hWxProcess != NULL);
- m_dwPathLen = _tcslen(m_szDllPath) * sizeof(TCHAR) + 1;
- m_lpInjectData = VirtualAllocEx(m_hWxProcess, NULL, m_dwPathLen, MEM_COMMIT, PAGE_READWRITE);
- if (NULL == m_lpInjectData)
- {
- WriteTextLog(_T("创建WeChat.exe进程虚拟内存失败"));
- return FALSE;
- }
- if (WriteProcessMemory(m_hWxProcess, m_lpInjectData, m_szDllPath, m_dwPathLen, NULL) == 0)
- {
- // 注意:MEM_RELEASE释放时第三参数一定要为0,请查看MSDN;
- VirtualFreeEx(m_hWxProcess, m_lpInjectData, 0, MEM_RELEASE);
- return FALSE;
- }
- HMODULE hk32 = GetModuleHandle(_T("kernel32.dll"));
- // 注意:微信使用的是W版本;
- LPVOID lpAddr = GetProcAddress(hk32, "LoadLibraryW");
- m_hInjectThread = CreateRemoteThread(m_hWxProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpAddr, m_lpInjectData, 0, NULL);
- if (NULL == m_hInjectThread)
- {
- // 注意:MEM_RELEASE释放时第三参数一定要为0,请查看MSDN;
- VirtualFreeEx(m_hWxProcess, m_lpInjectData, 0, MEM_RELEASE);
- return FALSE;
- }
- WaitForSingleObject(m_hInjectThread, INFINITE);
- if (m_hInjectThread)
- CloseHandle(m_hInjectThread);
- m_hInjectThread = NULL;
- /* 注入成功后,不能释放内存否则微信会挂;
- if (m_lpInjectData != NULL)
- VirtualFreeEx(m_hWxProcess, m_lpInjectData, 0, MEM_RELEASE);
- */
- return TRUE;
- }
- BOOL CWxObject::EjectDynamicLibrary()
- {
- if (m_hWxProcess == NULL)
- return TRUE;
- // 获取模块句柄;
- HANDLE hModule = FindModuleEx(m_szDllPath, m_dwWxProcId);
- if (hModule == NULL)
- {
- WriteTextLog(_T("获取WeChat.exe进程模块hook.dll失败"));
- return FALSE;
- }
- LPVOID lpAddr = GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "FreeLibraryAndExitThread");//FreeLibraryAndExitThread//FreeLibrary
- if (lpAddr == NULL)
- {
- WriteTextLog(_T("获取kernel32.dll中的FreeLibraryAndExitThread失败"));
- return FALSE;
- }
- m_hEjectThread = CreateRemoteThread(m_hWxProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpAddr, hModule, 0, NULL);
- if (m_hEjectThread == NULL)
- {
- WriteTextLog(_T("创建WeChat.exe远程线程(FreeLibraryAndExitThread)失败"));
- return FALSE;
- }
- WaitForSingleObject(m_hEjectThread, INFINITE);
- if (m_hEjectThread)
- CloseHandle(m_hEjectThread);
- m_hEjectThread = NULL;
- return TRUE;
- }
- BOOL CWxObject::FindWxMainWnd()
- {
- WNDINFO wnd;
- wnd.hWxWnd = NULL;
- wnd.dwWxProcId = m_dwWxProcId;
- _stprintf_s(wnd.szWndName, WX_MAIN_WND_NAME);
- _stprintf_s(wnd.szClassName, WX_MAIN_WND_CLASS_NAME);
- if (::EnumWindows(&EnumWindowsProc, (LPARAM)&wnd) == FALSE)
- {
- m_hWxMainWnd = wnd.hWxWnd;
- m_rcWnd = wnd.rcWnd;
- return TRUE;
- }
- return FALSE;
- }
- BOOL CWxObject::FindWxLoginWnd()
- {
- WNDINFO wnd;
- wnd.hWxWnd = NULL;
- wnd.dwWxProcId = m_dwWxProcId;
- _stprintf_s(wnd.szWndName, WX_LOGIN_WND_NAME);
- _stprintf_s(wnd.szClassName, WX_LOGIN_WND_CLASS_NAME);
- if (::EnumWindows(&EnumWindowsProc, (LPARAM)&wnd) == FALSE)
- {
- m_hWxLoginWnd = wnd.hWxWnd;
- m_rcWnd = wnd.rcWnd;
- return TRUE;
- }
- return FALSE;
- }
- BOOL CWxObject::EnumWindowsProc(HWND hwnd, LPARAM lParam)
- {
- DWORD dwProcId = 0, dwThreadId;
- TCHAR szWndName[MAX_PATH] = { 0 };
- TCHAR szClassName[MAX_PATH] = { 0 };
- WNDINFO* pWndInfo = (WNDINFO*)lParam;
- dwThreadId = GetWindowThreadProcessId(hwnd, &dwProcId);
- if(dwProcId == pWndInfo->dwWxProcId)
- {
- pWndInfo->hWxWnd = hwnd;
- pWndInfo->dwThreadId = dwThreadId;
- ::GetWindowText(hwnd, szWndName, MAX_PATH);
- ::GetClassName(hwnd, szClassName, MAX_PATH);
- if (_tcscmp(szWndName, pWndInfo->szWndName) == 0 && _tcscmp(szClassName, pWndInfo->szClassName) == 0)
- {
- ::GetWindowRect(hwnd, &pWndInfo->rcWnd);
- return FALSE;
- }
- }
- return TRUE;
- }
|