Browse Source

完成微信登录窗口、微信聊天主窗口的嵌入功能。

Jeff 6 years ago
parent
commit
9306eed45f

+ 58 - 13
source/hook/WeChats/CWxObject.cpp

@@ -2,9 +2,17 @@
 #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)
@@ -17,6 +25,8 @@ CWxObject::CWxObject()
 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)
@@ -64,7 +74,6 @@ CWxObject::~CWxObject()
 	m_hWxProcess = NULL;
 }
 
-
 void CWxObject::setInjectionObj(DWORD dwProcId, LPCTSTR lpDynamicLibraryPath)
 {
 	ASSERT(dwProcId != 0);
@@ -160,24 +169,60 @@ BOOL CWxObject::EjectDynamicLibrary()
 	return TRUE;
 }
 
-BOOL CWxObject::FindWxWnd()
+BOOL CWxObject::FindWxMainWnd()
 {
-	while(true)
+	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)
 	{
-		::EnumWindows(&EnumWindowsProc, processInfo.dwThreadId);//Iterate all windows
-		if(NULL != m_hWxWnd)
-			break;
+		m_hWxMainWnd = wnd.hWxWnd;
+		m_rcWnd = wnd.rcWnd;
+		return TRUE;
 	}
+
+	return FALSE;
 }
 
-int CWxObject::EnumWindowsProc(HWND hwnd, LPARAM lParam)
+BOOL CWxObject::FindWxLoginWnd()
 {
-    DWORD pID;
-    DWORD tpID = GetWindowThreadProcessId(hwnd,&pID);
-    if(tpID == (DWORD)lParam)
+	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)
     {
-        apphWnd = hwnd;
-        return false;
+		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;
+
+    return TRUE;
 }

+ 29 - 6
source/hook/WeChats/CWxObject.h

@@ -3,7 +3,21 @@
 
 #pragma once
 
-//#include "Injection.h"
+typedef struct _WNDINFO_
+{
+	// 返回的窗口句柄;
+	HWND	hWxWnd;
+	// 要遍历的进程id;
+	DWORD	dwWxProcId;
+	// 返回的窗口线程id;
+	DWORD	dwThreadId;
+	// 窗口名称;
+	TCHAR	szWndName[MAX_PATH];
+	// 窗口类名;
+	TCHAR	szClassName[MAX_PATH];
+	// 窗口原始大小;
+	CRect	rcWnd;
+}WNDINFO, *pWNDINFO;
 
 class CWxObject
 {
@@ -12,13 +26,18 @@ public:
 	explicit CWxObject(DWORD dwProcId, LPCTSTR lpDynamicLibraryPath);
 	~CWxObject();
 
-protected:
+public:
 	// 进程id;
 	DWORD			m_dwWxProcId;
 	// 进程句柄;
 	HANDLE			m_hWxProcess;
 	// 进程窗口句柄;
-	HWND			m_hWxWnd;
+	HWND			m_hWxMainWnd;
+	HWND			m_hWxLoginWnd;
+	// 窗口大小;
+	CRect			m_rcWnd;
+
+private:
 	// 动态库路径;
 	TCHAR			m_szDllPath[MAX_PATH];
 	// 路径分配的内存;
@@ -32,13 +51,17 @@ protected:
 	HANDLE			m_hEjectThread;
 
 public:
-	inline DWORD GetProcId() { return m_dwWxProcId; };
+	inline DWORD GetWxProcId() { return m_dwWxProcId; }
+	inline HWND GetWxMainWnd() { return m_hWxMainWnd; }
+	inline HWND GetWxLoginWnd() { return m_hWxLoginWnd; }
 	// dll路径和要注入的进程id;
 	void setInjectionObj(DWORD dwProcId, LPCTSTR lpDynamicLibraryPath);
 	BOOL InjectDynamicLibrary();
 	BOOL EjectDynamicLibrary();
-	BOOL FindWxWnd();
-	static int CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam);
+	BOOL FindWxMainWnd();
+	BOOL FindWxLoginWnd();
+
+	static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam);
 };
 
 #endif //__WX_OBJECT__

+ 2 - 1
source/hook/WeChats/Resource.h

@@ -13,6 +13,7 @@
 #define IDC_BUTTON1                     1000
 #define BTN_OPEN_WX                     1000
 #define TX_ACCOUNT                      1001
+#define WX_RECT                         1001
 #define TX_PASSWROD                     1002
 #define ST_ACCOUNT                      1035
 #define ST_PASSWORD                     1036
@@ -23,7 +24,7 @@
 #ifndef APSTUDIO_READONLY_SYMBOLS
 #define _APS_NEXT_RESOURCE_VALUE        135
 #define _APS_NEXT_COMMAND_VALUE         32771
-#define _APS_NEXT_CONTROL_VALUE         1001
+#define _APS_NEXT_CONTROL_VALUE         1002
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif

+ 3 - 0
source/hook/WeChats/WeChats.cpp

@@ -198,6 +198,7 @@ BOOL CWeChatsApp::InitInstance()
 	{
 		return FALSE;
 	}
+
 // 	HANDLE hObject = CreateMutex(NULL, FALSE, _T("CYLGLAppXiao"));
 // 	if (GetLastError() == ERROR_ALREADY_EXISTS)
 // 	{
@@ -213,6 +214,7 @@ BOOL CWeChatsApp::InitInstance()
 // 		OpenWeChat();
 
 
+#if 0
 	TCHAR szDllPath[MAX_PATH];
 	ZeroMemory(szDllPath,MAX_PATH);
 	DWORD ss = sizeof(szDllPath);
@@ -231,6 +233,7 @@ BOOL CWeChatsApp::InitInstance()
 			inject.EjectDynamicLibrary();
 		}
 	}
+#endif
 	// 标准初始化
 	// 如果未使用这些功能并希望减小
 	// 最终可执行文件的大小,则应移除下列

+ 6 - 6
source/hook/WeChats/WeChats.rc

@@ -87,16 +87,16 @@ BEGIN
     DEFPUSHBUTTON   "确定",IDOK,113,41,50,14,WS_GROUP
 END
 
-IDD_WECHATS_DIALOG DIALOGEX 0, 0, 543, 306
-STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+IDD_WECHATS_DIALOG DIALOGEX 0, 0, 774, 431
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
 EXSTYLE WS_EX_APPWINDOW
 CAPTION "WeChats"
 FONT 9, "MS Shell Dlg", 0, 0, 0x1
 BEGIN
     DEFPUSHBUTTON   "确定",IDOK,7,264,50,14
-    PUSHBUTTON      "取消",IDCANCEL,7,285,50,14
+    PUSHBUTTON      "取消",IDCANCEL,7,410,50,14
     PUSHBUTTON      "启动微信",BTN_OPEN_WX,7,244,50,14
-    CONTROL         "",IDC_STATIC,"Static",SS_BLACKRECT,63,7,473,292
+    CONTROL         "",WX_RECT,"Static",SS_BLACKRECT,68,7,699,417
 END
 
 IDD_DLG_LOGIN DIALOGEX 0, 0, 287, 153
@@ -179,9 +179,9 @@ BEGIN
     IDD_WECHATS_DIALOG, DIALOG
     BEGIN
         LEFTMARGIN, 7
-        RIGHTMARGIN, 536
+        RIGHTMARGIN, 767
         TOPMARGIN, 7
-        BOTTOMMARGIN, 299
+        BOTTOMMARGIN, 424
     END
 
     IDD_DLG_LOGIN, DIALOG

+ 62 - 1
source/hook/WeChats/WeChatsDlg.cpp

@@ -5,6 +5,7 @@
 #include "stdafx.h"
 #include "WeChats.h"
 #include "WeChatsDlg.h"
+#include "CWxObject.h"
 
 #ifdef _DEBUG
 #define new DEBUG_NEW
@@ -44,7 +45,7 @@ END_MESSAGE_MAP()
 
 // CWeChatsDlg 对话框
 
-
+HWND g_hWxWnd = NULL;
 
 
 CWeChatsDlg::CWeChatsDlg(CWnd* pParent /*=NULL*/)
@@ -64,6 +65,7 @@ BEGIN_MESSAGE_MAP(CWeChatsDlg, CDialog)
 	ON_WM_QUERYDRAGICON()
 	//}}AFX_MSG_MAP
 	ON_BN_CLICKED(BTN_OPEN_WX, &CWeChatsDlg::OnBnClickedOpenWx)
+	ON_WM_CTLCOLOR()
 END_MESSAGE_MAP()
 
 
@@ -141,6 +143,8 @@ void CWeChatsDlg::OnPaint()
 	}
 	else
 	{
+		if (g_hWxWnd)
+			::UpdateWindow(g_hWxWnd);
 		CDialog::OnPaint();
 	}
 }
@@ -157,4 +161,61 @@ HCURSOR CWeChatsDlg::OnQueryDragIcon()
 void CWeChatsDlg::OnBnClickedOpenWx()
 {
 	// TODO: 在此添加控件通知处理程序代码
+
+#ifdef _DEBUG
+	//vector<DWORD> vtPID = FindAllProcess(_T("lyfzServer.exe"));
+	vector<DWORD> vtPID = FindAllProcess(WECHAT);
+	//vector<DWORD> vtPID = FindAllProcess(_T("cheatengine-x86_64.exe"));
+	//vector<DWORD> vtPID = FindAllProcess(_T("AliIM.exe"));
+	//vector<DWORD> vtPID = FindAllProcess(_T("AliIM.exe"));
+	if (vtPID.size() != 0)
+	{
+		CWxObject wxobj(*vtPID.begin(), _T("E:\\bin\\WeChats2017\\hook.dll"));
+		//if (wxobj.FindWxMainWnd())
+		if (wxobj.FindWxLoginWnd())
+		{
+			//g_hWxWnd = wxobj.GetWxMainWnd();
+			g_hWxWnd = wxobj.GetWxLoginWnd();
+			if (g_hWxWnd != NULL)
+			{
+				// 获取微信窗口的样式;
+				DWORD dwStyle = ::GetWindowLong(g_hWxWnd, GWL_STYLE);
+				// WS_CLIPSIBLINGS告诉父窗口不要绘制子窗口出现的区域;
+				dwStyle |= WS_CLIPSIBLINGS; 
+				// 重新设置窗口样式 ;
+				::SetWindowLong(g_hWxWnd, GWL_STYLE, dwStyle);
+
+				CRect rect;
+				GetDlgItem(WX_RECT)->GetWindowRect(&rect);
+				// 设置背景透明;
+				::SetParent(g_hWxWnd, GetDlgItem(WX_RECT)->m_hWnd);//set parent of ms paint to our dialog.
+				//::SetParent(hWxWnd, m_hWnd);
+				// 擦除背景;
+				//SetWindowLong(hWxWnd, GWL_STYLE, WS_VISIBLE);//eraze title of ms paint window.
+				//Positioning ms paint.
+				ScreenToClient(wxobj.m_rcWnd);
+				::MoveWindow(g_hWxWnd, wxobj.m_rcWnd.left, wxobj.m_rcWnd.top, wxobj.m_rcWnd.right, wxobj.m_rcWnd.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(g_hWxWnd);
+				::ShowWindow(g_hWxWnd, SW_SHOW);
+			}
+		}
+	}
+#endif
+}
+
+
+HBRUSH CWeChatsDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
+{
+	HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
+
+	// TODO:  在此更改 DC 的任何特性
+	//pDC->SetBkMode(TRANSPARENT);
+
+	// TODO:  如果默认的不是所需画笔,则返回另一个画笔
+	return hbr;
 }

+ 2 - 0
source/hook/WeChats/WeChatsDlg.h

@@ -4,6 +4,7 @@
 
 #pragma once
 
+#include "CWxObject.h"
 
 // CWeChatsDlg ¶Ô»°¿ò
 class CWeChatsDlg : public CDialog
@@ -31,4 +32,5 @@ protected:
 	DECLARE_MESSAGE_MAP()
 public:
 	afx_msg void OnBnClickedOpenWx();
+	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
 };