CWxObject.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. #include "stdafx.h"
  2. #include "CWxObject.h"
  3. #define WX_MAIN_WND_NAME _T("微信")
  4. #define WX_MAIN_WND_CLASS_NAME _T("WeChatMainWndForPC")
  5. #define WX_LOGIN_WND_NAME _T("登录")
  6. #define WX_LOGIN_WND_CLASS_NAME _T("WeChatLoginWndForPC")
  7. CWxObject::CWxObject()
  8. :m_dwWxProcId(0)
  9. , m_hWxProcess(NULL)
  10. , m_hWxMainWnd(NULL)
  11. , m_hWxLoginWnd(NULL)
  12. , m_lpInjectData(NULL)
  13. , m_lpEjectData(NULL)
  14. , m_hInjectThread(NULL)
  15. , m_hEjectThread(NULL)
  16. , m_dwPathLen(0)
  17. {
  18. }
  19. CWxObject::CWxObject(DWORD dwProcId, LPCTSTR lpDynamicLibraryPath)
  20. :m_dwWxProcId(dwProcId)
  21. , m_hWxProcess(NULL)
  22. , m_hWxMainWnd(NULL)
  23. , m_hWxLoginWnd(NULL)
  24. , m_lpInjectData(NULL)
  25. , m_lpEjectData(NULL)
  26. , m_hInjectThread(NULL)
  27. , m_hEjectThread(NULL)
  28. , m_dwPathLen(0)
  29. {
  30. ASSERT(dwProcId != 0);
  31. ASSERT(lpDynamicLibraryPath != NULL);
  32. memset(m_szDllPath, 0, sizeof(m_szDllPath));
  33. _tcscpy_s(m_szDllPath, lpDynamicLibraryPath);
  34. m_hWxProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, m_dwWxProcId);
  35. if (m_hWxProcess == NULL)
  36. {
  37. WriteTextLog(_T("打开WeChat.exe进程失败"));
  38. }
  39. //m_hWxProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, m_dwWxProcId);
  40. }
  41. CWxObject::~CWxObject()
  42. {
  43. // 卸载dll;
  44. EjectDynamicLibrary();
  45. // 释放所有资源;
  46. if (m_hInjectThread)
  47. CloseHandle(m_hInjectThread);
  48. m_hInjectThread = NULL;
  49. if (m_hEjectThread)
  50. CloseHandle(m_hEjectThread);
  51. m_hEjectThread = NULL;
  52. if (m_lpInjectData)
  53. VirtualFreeEx(m_hWxProcess, m_lpInjectData, m_dwPathLen, MEM_RELEASE);
  54. m_lpInjectData = NULL;
  55. if (m_lpEjectData)
  56. VirtualFreeEx(m_hWxProcess, m_lpEjectData, m_dwPathLen, MEM_RELEASE);
  57. m_lpEjectData = NULL;
  58. if (m_hWxProcess)
  59. CloseHandle(m_hWxProcess);
  60. m_hWxProcess = NULL;
  61. }
  62. void CWxObject::setInjectionObj(DWORD dwProcId, LPCTSTR lpDynamicLibraryPath)
  63. {
  64. ASSERT(dwProcId != 0);
  65. ASSERT(lpDynamicLibraryPath != NULL);
  66. memset(m_szDllPath, 0, sizeof(m_szDllPath));
  67. _tcscpy_s(m_szDllPath, lpDynamicLibraryPath);
  68. m_dwWxProcId = dwProcId;
  69. m_hWxProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, m_dwWxProcId);
  70. if (m_hWxProcess == NULL)
  71. {
  72. WriteTextLog(_T("打开WeChat.exe进程失败"));
  73. }
  74. //m_hWxProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, m_dwWxProcId);
  75. }
  76. BOOL CWxObject::InjectDynamicLibrary()
  77. {
  78. ASSERT(m_hWxProcess != NULL);
  79. m_dwPathLen = _tcslen(m_szDllPath) * sizeof(TCHAR) + 1;
  80. m_lpInjectData = VirtualAllocEx(m_hWxProcess, NULL, m_dwPathLen, MEM_COMMIT, PAGE_READWRITE);
  81. if (NULL == m_lpInjectData)
  82. {
  83. WriteTextLog(_T("创建WeChat.exe进程虚拟内存失败"));
  84. return FALSE;
  85. }
  86. if (WriteProcessMemory(m_hWxProcess, m_lpInjectData, m_szDllPath, m_dwPathLen, NULL) == 0)
  87. {
  88. // 注意:MEM_RELEASE释放时第三参数一定要为0,请查看MSDN;
  89. VirtualFreeEx(m_hWxProcess, m_lpInjectData, 0, MEM_RELEASE);
  90. return FALSE;
  91. }
  92. HMODULE hk32 = GetModuleHandle(_T("kernel32.dll"));
  93. // 注意:微信使用的是W版本;
  94. LPVOID lpAddr = GetProcAddress(hk32, "LoadLibraryW");
  95. m_hInjectThread = CreateRemoteThread(m_hWxProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpAddr, m_lpInjectData, 0, NULL);
  96. if (NULL == m_hInjectThread)
  97. {
  98. // 注意:MEM_RELEASE释放时第三参数一定要为0,请查看MSDN;
  99. VirtualFreeEx(m_hWxProcess, m_lpInjectData, 0, MEM_RELEASE);
  100. return FALSE;
  101. }
  102. WaitForSingleObject(m_hInjectThread, INFINITE);
  103. if (m_hInjectThread)
  104. CloseHandle(m_hInjectThread);
  105. m_hInjectThread = NULL;
  106. /* 注入成功后,不能释放内存否则微信会挂;
  107. if (m_lpInjectData != NULL)
  108. VirtualFreeEx(m_hWxProcess, m_lpInjectData, 0, MEM_RELEASE);
  109. */
  110. return TRUE;
  111. }
  112. BOOL CWxObject::EjectDynamicLibrary()
  113. {
  114. if (m_hWxProcess == NULL)
  115. return TRUE;
  116. // 获取模块句柄;
  117. HANDLE hModule = FindModuleEx(m_szDllPath, m_dwWxProcId);
  118. if (hModule == NULL)
  119. {
  120. WriteTextLog(_T("获取WeChat.exe进程模块hook.dll失败"));
  121. return FALSE;
  122. }
  123. LPVOID lpAddr = GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "FreeLibraryAndExitThread");//FreeLibraryAndExitThread//FreeLibrary
  124. if (lpAddr == NULL)
  125. {
  126. WriteTextLog(_T("获取kernel32.dll中的FreeLibraryAndExitThread失败"));
  127. return FALSE;
  128. }
  129. m_hEjectThread = CreateRemoteThread(m_hWxProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpAddr, hModule, 0, NULL);
  130. if (m_hEjectThread == NULL)
  131. {
  132. WriteTextLog(_T("创建WeChat.exe远程线程(FreeLibraryAndExitThread)失败"));
  133. return FALSE;
  134. }
  135. WaitForSingleObject(m_hEjectThread, INFINITE);
  136. if (m_hEjectThread)
  137. CloseHandle(m_hEjectThread);
  138. m_hEjectThread = NULL;
  139. return TRUE;
  140. }
  141. BOOL CWxObject::FindWxMainWnd()
  142. {
  143. WNDINFO wnd;
  144. wnd.hWxWnd = NULL;
  145. wnd.dwWxProcId = m_dwWxProcId;
  146. _stprintf_s(wnd.szWndName, WX_MAIN_WND_NAME);
  147. _stprintf_s(wnd.szClassName, WX_MAIN_WND_CLASS_NAME);
  148. if (::EnumWindows(&EnumWindowsProc, (LPARAM)&wnd) == FALSE)
  149. {
  150. m_hWxMainWnd = wnd.hWxWnd;
  151. m_rcWnd = wnd.rcWnd;
  152. return TRUE;
  153. }
  154. return FALSE;
  155. }
  156. BOOL CWxObject::FindWxLoginWnd()
  157. {
  158. WNDINFO wnd;
  159. wnd.hWxWnd = NULL;
  160. wnd.dwWxProcId = m_dwWxProcId;
  161. _stprintf_s(wnd.szWndName, WX_LOGIN_WND_NAME);
  162. _stprintf_s(wnd.szClassName, WX_LOGIN_WND_CLASS_NAME);
  163. if (::EnumWindows(&EnumWindowsProc, (LPARAM)&wnd) == FALSE)
  164. {
  165. m_hWxLoginWnd = wnd.hWxWnd;
  166. m_rcWnd = wnd.rcWnd;
  167. return TRUE;
  168. }
  169. return FALSE;
  170. }
  171. BOOL CWxObject::EnumWindowsProc(HWND hwnd, LPARAM lParam)
  172. {
  173. DWORD dwProcId = 0, dwThreadId;
  174. TCHAR szWndName[MAX_PATH] = { 0 };
  175. TCHAR szClassName[MAX_PATH] = { 0 };
  176. WNDINFO* pWndInfo = (WNDINFO*)lParam;
  177. dwThreadId = GetWindowThreadProcessId(hwnd, &dwProcId);
  178. if(dwProcId == pWndInfo->dwWxProcId)
  179. {
  180. pWndInfo->hWxWnd = hwnd;
  181. pWndInfo->dwThreadId = dwThreadId;
  182. ::GetWindowText(hwnd, szWndName, MAX_PATH);
  183. ::GetClassName(hwnd, szClassName, MAX_PATH);
  184. if (_tcscmp(szWndName, pWndInfo->szWndName) == 0 && _tcscmp(szClassName, pWndInfo->szClassName) == 0)
  185. {
  186. ::GetWindowRect(hwnd, &pWndInfo->rcWnd);
  187. return FALSE;
  188. }
  189. }
  190. return TRUE;
  191. }