|
@@ -8,6 +8,25 @@
|
|
|
#define WX_LOGIN_WND_NAME _T("登录")
|
|
|
#define WX_LOGIN_WND_CLASS_NAME _T("WeChatLoginWndForPC")
|
|
|
|
|
|
+BOOL ASCII2UNICODE(IN LPCCH lpASCIIStr, OUT PWCH pUNICODEStr, IN CONST INT& nUNICODEStrLen)
|
|
|
+{
|
|
|
+ if (lpASCIIStr == NULL)
|
|
|
+ return FALSE;
|
|
|
+
|
|
|
+ // 获取宽字符字节数;
|
|
|
+ int cchWideChar = MultiByteToWideChar(CP_ACP, 0, lpASCIIStr, -1, NULL, 0);
|
|
|
+ if (cchWideChar == 0 || cchWideChar >= nUNICODEStrLen)
|
|
|
+ return FALSE;
|
|
|
+
|
|
|
+ // 转换成宽字符串;
|
|
|
+ memset(pUNICODEStr, 0, sizeof(WCHAR)*nUNICODEStrLen);
|
|
|
+ int nWriteNum = MultiByteToWideChar(CP_ACP, 0, lpASCIIStr, -1, pUNICODEStr, cchWideChar);
|
|
|
+ if (nWriteNum != cchWideChar)
|
|
|
+ return FALSE;
|
|
|
+
|
|
|
+ return TRUE;
|
|
|
+}
|
|
|
+
|
|
|
CWxObject::CWxObject()
|
|
|
:m_dwWxProcId(0)
|
|
|
, m_hWxProcess(NULL)
|
|
@@ -18,6 +37,7 @@ CWxObject::CWxObject()
|
|
|
, m_hInjectThread(NULL)
|
|
|
, m_hEjectThread(NULL)
|
|
|
, m_dwPathLen(0)
|
|
|
+ , m_bAttached(FALSE)
|
|
|
{
|
|
|
|
|
|
}
|
|
@@ -32,19 +52,9 @@ CWxObject::CWxObject(DWORD dwProcId, LPCTSTR lpDynamicLibraryPath)
|
|
|
, m_hInjectThread(NULL)
|
|
|
, m_hEjectThread(NULL)
|
|
|
, m_dwPathLen(0)
|
|
|
+ , m_bAttached(FALSE)
|
|
|
{
|
|
|
- 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);
|
|
|
+ setInjectionObj(dwProcId, lpDynamicLibraryPath);
|
|
|
}
|
|
|
|
|
|
CWxObject::~CWxObject()
|
|
@@ -79,22 +89,28 @@ void CWxObject::setInjectionObj(DWORD dwProcId, LPCTSTR lpDynamicLibraryPath)
|
|
|
ASSERT(dwProcId != 0);
|
|
|
ASSERT(lpDynamicLibraryPath != NULL);
|
|
|
|
|
|
+ m_dwWxProcId = dwProcId;
|
|
|
memset(m_szDllPath, 0, sizeof(m_szDllPath));
|
|
|
+ memset(m_wszDllPath, 0, sizeof(m_wszDllPath));
|
|
|
+#ifdef UNICODE
|
|
|
_tcscpy_s(m_szDllPath, lpDynamicLibraryPath);
|
|
|
- m_dwWxProcId = dwProcId;
|
|
|
- m_hWxProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, m_dwWxProcId);
|
|
|
+#else
|
|
|
+ _tcscpy_s(m_szDllPath, lpDynamicLibraryPath);
|
|
|
+ ASCII2UNICODE(lpDynamicLibraryPath, m_wszDllPath, MAX_PATH);
|
|
|
+#endif
|
|
|
+
|
|
|
+ //m_hWxProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, m_dwWxProcId);
|
|
|
+ m_hWxProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, 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_dwPathLen = wcslen(m_wszDllPath) * sizeof(WCHAR) + 1;
|
|
|
m_lpInjectData = VirtualAllocEx(m_hWxProcess, NULL, m_dwPathLen, MEM_COMMIT, PAGE_READWRITE);
|
|
|
if (NULL == m_lpInjectData)
|
|
|
{
|
|
@@ -102,7 +118,7 @@ BOOL CWxObject::InjectDynamicLibrary()
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
- if (WriteProcessMemory(m_hWxProcess, m_lpInjectData, m_szDllPath, m_dwPathLen, NULL) == 0)
|
|
|
+ if (WriteProcessMemory(m_hWxProcess, m_lpInjectData, m_wszDllPath, m_dwPathLen, NULL) == 0)
|
|
|
{
|
|
|
// 注意:MEM_RELEASE释放时第三参数一定要为0,请查看MSDN;
|
|
|
VirtualFreeEx(m_hWxProcess, m_lpInjectData, 0, MEM_RELEASE);
|
|
@@ -112,7 +128,6 @@ BOOL CWxObject::InjectDynamicLibrary()
|
|
|
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)
|
|
|
{
|
|
@@ -179,7 +194,7 @@ BOOL CWxObject::FindWxMainWnd()
|
|
|
if (::EnumWindows(&EnumWindowsProc, (LPARAM)&wnd) == FALSE)
|
|
|
{
|
|
|
m_hWxMainWnd = wnd.hWxWnd;
|
|
|
- m_rcWnd = wnd.rcWnd;
|
|
|
+ m_rcWxWnd = wnd.rcWnd;
|
|
|
return TRUE;
|
|
|
}
|
|
|
|
|
@@ -196,13 +211,61 @@ BOOL CWxObject::FindWxLoginWnd()
|
|
|
if (::EnumWindows(&EnumWindowsProc, (LPARAM)&wnd) == FALSE)
|
|
|
{
|
|
|
m_hWxLoginWnd = wnd.hWxWnd;
|
|
|
- m_rcWnd = wnd.rcWnd;
|
|
|
+ m_rcWxWnd = wnd.rcWnd;
|
|
|
return TRUE;
|
|
|
}
|
|
|
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
+BOOL CWxObject::Attach2MainWnd(CWnd *pMainWnd, BOOL bLoginWnd )
|
|
|
+{
|
|
|
+ HWND hWxWnd = bLoginWnd ? m_hWxLoginWnd : m_hWxMainWnd;
|
|
|
+ if (hWxWnd != NULL)
|
|
|
+ {
|
|
|
+ // 获取微信窗口的样式;
|
|
|
+ DWORD dwStyle = ::GetWindowLong(hWxWnd, GWL_STYLE);
|
|
|
+ // WS_CLIPSIBLINGS告诉父窗口不要绘制子窗口出现的区域;
|
|
|
+ dwStyle |= WS_CLIPSIBLINGS;
|
|
|
+ // 如果窗口隐藏的,显示出来;
|
|
|
+ dwStyle |= WS_VISIBLE;
|
|
|
+ // 重新设置窗口样式 ;
|
|
|
+ ::SetWindowLong(hWxWnd, GWL_STYLE, dwStyle);
|
|
|
+
|
|
|
+ CRect rect;
|
|
|
+ pMainWnd->GetWindowRect(&rect);
|
|
|
+ // 设置背景透明;
|
|
|
+ ::SetParent(hWxWnd, pMainWnd->m_hWnd);//set parent of ms paint to our dialog.
|
|
|
+ // 擦除背景;
|
|
|
+ //SetWindowLong(hWxWnd, GWL_STYLE, WS_VISIBLE);//eraze title of ms paint window.
|
|
|
+ //Positioning ms paint.
|
|
|
+ pMainWnd->ScreenToClient(&m_rcWxWnd);
|
|
|
+ ::MoveWindow(hWxWnd, m_rcWxWnd.left, m_rcWxWnd.top, m_rcWxWnd.right, m_rcWxWnd.bottom, true);
|
|
|
+ //ClientToScreen(&rect);
|
|
|
+ //ScreenToClient(&rect);
|
|
|
+ //::SetWindowPos(hWxWnd, NULL, rect.left, rect.top, rect.right, rect.bottom, SWP_SHOWWINDOW | SWP_HIDEWINDOW);
|
|
|
+ //窗口重绘,(因创建exe时,设置为SW_HIDE,导致exe窗口会被父窗口覆盖一部分)
|
|
|
+ //Invalidate();
|
|
|
+ ::UpdateWindow(hWxWnd);
|
|
|
+ ::ShowWindow(hWxWnd, SW_SHOW);
|
|
|
+
|
|
|
+ m_bAttached = TRUE;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+BOOL CWxObject::DetachWxWnd()
|
|
|
+{
|
|
|
+ if (m_hWxMainWnd)
|
|
|
+ ::SetParent(m_hWxMainWnd, NULL);
|
|
|
+
|
|
|
+ if (m_hWxLoginWnd)
|
|
|
+ ::SetParent(m_hWxLoginWnd, NULL);
|
|
|
+
|
|
|
+ m_bAttached = FALSE;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
BOOL CWxObject::EnumWindowsProc(HWND hwnd, LPARAM lParam)
|
|
|
{
|
|
|
DWORD dwProcId = 0, dwThreadId;
|