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