瀏覽代碼

1、窗口布局。
2、继续CWxMgr类的实现

Jeff 6 年之前
父節點
當前提交
bcf1c05e7a

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

@@ -15,6 +15,9 @@
 #define TX_ACCOUNT                      1001
 #define WX_RECT                         1001
 #define TX_PASSWROD                     1002
+#define BTN_ATTACH_WX                   1002
+#define RECT_WECHAT                     1003
+#define RECT_WXLIST                     1004
 #define ST_ACCOUNT                      1035
 #define ST_PASSWORD                     1036
 
@@ -24,7 +27,7 @@
 #ifndef APSTUDIO_READONLY_SYMBOLS
 #define _APS_NEXT_RESOURCE_VALUE        135
 #define _APS_NEXT_COMMAND_VALUE         32771
-#define _APS_NEXT_CONTROL_VALUE         1002
+#define _APS_NEXT_CONTROL_VALUE         1005
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif

+ 8 - 144
source/hook/WeChats/WeChats.cpp

@@ -7,6 +7,7 @@
 #include "WeChatsDlg.h"
 #include "Injection.h"
 #include "CDLG_Login.h"
+#include "WxMgr.h"
 
 #ifdef _DEBUG
 #define new DEBUG_NEW
@@ -36,143 +37,6 @@ CWeChatsApp theApp;
 
 // CWeChatsApp 初始化
 
-//////////////////////////////////////////////////////////////////////////
-// BEGIN
-// killWeChatMutex函数用到的未公开的声明;
-
-typedef ULONG   PPS_POST_PROCESS_INIT_ROUTINE;  
-
-
-// 以下声明,都是系统未公开的定义;
-//
-typedef enum {
-	ProcessBasicInformation = 0,
-	ProcessDebugPort = 7,
-	ProcessWow64Information = 26,
-	ProcessImageFileName = 27,
-	ProcessBreakOnTermination = 29,
-	ProcessProtectionInformation = 61,
-}PROCESSINFOCLASS;
-
-typedef struct _PEB_LDR_DATA {
-	BYTE       Reserved1[8];
-	PVOID      Reserved2[3];
-	LIST_ENTRY InMemoryOrderModuleList;
-} PEB_LDR_DATA, *PPEB_LDR_DATA;
-
-typedef struct _LDR_DATA_TABLE_ENTRY {
-	PVOID Reserved1[2];
-	LIST_ENTRY InMemoryOrderLinks;
-	PVOID Reserved2[2];
-	PVOID DllBase;
-	PVOID EntryPoint;
-	PVOID Reserved3;
-	UNICODE_STRING FullDllName;
-	BYTE Reserved4[8];
-	PVOID Reserved5[3];
-	union {
-		ULONG CheckSum;
-		PVOID Reserved6;
-	};
-	ULONG TimeDateStamp;
-} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
-
-typedef struct _RTL_USER_PROCESS_PARAMETERS {
-	BYTE           Reserved1[16];
-	PVOID          Reserved2[10];
-	UNICODE_STRING ImagePathName;
-	UNICODE_STRING CommandLine;
-} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
-
-// 32位下的结构;
-typedef struct _PEB {
-	BYTE                          Reserved1[2];
-	BYTE                          BeingDebugged;
-	BYTE                          Reserved2[1];
-	PVOID                         Reserved3[2];
-	PPEB_LDR_DATA                 Ldr;
-	PRTL_USER_PROCESS_PARAMETERS  ProcessParameters;
-	PVOID                         Reserved4[3];
-	PVOID                         AtlThunkSListPtr;
-	PVOID                         Reserved5;
-	ULONG                         Reserved6;
-	PVOID                         Reserved7;
-	ULONG                         Reserved8;
-	ULONG                         AtlThunkSListPtr32;
-	PVOID                         Reserved9[45];
-	BYTE                          Reserved10[96];
-	PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
-	BYTE                          Reserved11[128];
-	PVOID                         Reserved12[1];
-	ULONG                         SessionId;
-} PEB, *PPEB;
-// 64位下的结构;
-typedef struct _PEBX64 {
-	BYTE Reserved1[2];
-	BYTE BeingDebugged;
-	BYTE Reserved2[21];
-	PPEB_LDR_DATA LoaderData;
-	PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
-	BYTE Reserved3[520];
-	PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
-	BYTE Reserved4[136];
-	ULONG SessionId;
-} PEBX64;
-
-typedef struct _PROCESS_BASIC_INFORMATION {
-	PVOID Reserved1;
-	PPEB PebBaseAddress;
-	PVOID Reserved2[2];
-	ULONG_PTR UniqueProcessId;
-	PVOID Reserved3;
-} PROCESS_BASIC_INFORMATION;
-
-// 声音函数指针;
-typedef NTSTATUS (WINAPI *pfZwQueryInformationProcess)(
-	_In_      HANDLE           ProcessHandle,
-	_In_      PROCESSINFOCLASS ProcessInformationClass,
-	_Out_     PVOID            ProcessInformation,
-	_In_      ULONG            ProcessInformationLength,
-	_Out_opt_ PULONG           ReturnLength
-	);
-
-// END
-//////////////////////////////////////////////////////////////////////////
-
-NTSTATUS GetProcessModules(HANDLE hProcess, LPCTSTR lpTypName, LPCTSTR lpName)
-{
-	NTSTATUS Status = 0;
-	pfZwQueryInformationProcess ZwQueryInformationProcess = NULL;
-
-	PROCESS_BASIC_INFORMATION ProcessInfo;
-	PPEB	pPeb;
-
-	ZwQueryInformationProcess = (pfZwQueryInformationProcess)GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "ZwQueryInformationProcess");
-	if (ZwQueryInformationProcess == NULL)
-	{
-		WriteTextLog(_T("查找进程模块名称失败"));
-		return Status;
-	}
-
-	Status = ZwQueryInformationProcess(hProcess, ProcessBasicInformation, &ProcessInfo, sizeof(ProcessInfo), NULL);
-	if (NT_SUCCESS(Status))
-	{
-		pPeb = (PPEB)ProcessInfo.PebBaseAddress;
-
-		for (PLIST_ENTRY pListEntry = pPeb->Ldr->InMemoryOrderModuleList.Flink;pListEntry != &pPeb->Ldr->InMemoryOrderModuleList;pListEntry = pListEntry->Flink)
-		{
-			//PLDR_DATA_TABLE_ENTRY pEntry = CONTAINING_RECORD(pListEntry, LDR_DATA_TABLE_ENTRY, pListEntry);
-			//wprintf(L"%s\n", pEntry->FullDllName.Buffer);
-			WriteTextLog(_T("模块名称"));
-		}
-	}
-	else
-		WriteTextLog(_T("查找进程模块名称失败1"));
-
-	CloseHandle(hProcess);
-	return Status;
-}
-
 BOOL CWeChatsApp::InitInstance()
 {
 	// 如果一个运行在 Windows XP 上的应用程序清单指定要
@@ -188,31 +52,31 @@ BOOL CWeChatsApp::InitInstance()
 	CWinAppEx::InitInstance();
 
 	AfxEnableControlContainer();
-	
+
 	// 获取配置信息;
 	GetIniInfo();
 	GetDebugPriv();
 
 	CDLG_Login dlg_login;
-	if ( dlg_login.DoModal() == IDCANCEL )
+	if (dlg_login.DoModal() == IDCANCEL)
 	{
 		return FALSE;
 	}
 
 #if 0
 	TCHAR szDllPath[MAX_PATH];
-	ZeroMemory(szDllPath,MAX_PATH);
+	ZeroMemory(szDllPath, MAX_PATH);
 	DWORD ss = sizeof(szDllPath);
-	DWORD sss = _tcslen(szDllPath)*sizeof(TCHAR);
+	DWORD sss = _tcslen(szDllPath) * sizeof(TCHAR);
 	_stprintf_s(szDllPath, _T("%shook.dll"), g_szModulePath);
 	vector<DWORD> vtPID = FindAllProcess(WECHAT);
-	if (vtPID.size() != 0 )
+	if (vtPID.size() != 0)
 	{
 		vector<DWORD>::iterator it = vtPID.begin();
 		//for (int i = 0; i < 1; i++)
-		for (;it != vtPID.end(); it++)
+		for (; it != vtPID.end(); it++)
 		{
-			CInjection inject(*it,szDllPath);
+			CInjection inject(*it, szDllPath);
 			inject.InjectDynamicLibrary();
 			Sleep(3000);
 			inject.EjectDynamicLibrary();

+ 9 - 8
source/hook/WeChats/WeChats.rc

@@ -87,16 +87,17 @@ BEGIN
     DEFPUSHBUTTON   "确定",IDOK,113,41,50,14,WS_GROUP
 END
 
-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
+IDD_WECHATS_DIALOG DIALOGEX 0, 0, 696, 399
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_MINIMIZEBOX | 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,410,50,14
-    PUSHBUTTON      "启动微信",BTN_OPEN_WX,7,244,50,14
-    CONTROL         "",WX_RECT,"Static",SS_BLACKRECT,68,7,699,417
+    PUSHBUTTON      "启动微信",BTN_OPEN_WX,14,350,50,14
+    GROUPBOX        "微信",RECT_WXLIST,7,7,82,385
+    PUSHBUTTON      "附加微信",BTN_ATTACH_WX,15,369,50,14
+    LTEXT           "",RECT_WECHAT,92,8,459,380,NOT WS_VISIBLE,WS_EX_STATICEDGE
+    GROUPBOX        "回复",IDC_STATIC,555,8,134,384
 END
 
 IDD_DLG_LOGIN DIALOGEX 0, 0, 287, 153
@@ -179,9 +180,9 @@ BEGIN
     IDD_WECHATS_DIALOG, DIALOG
     BEGIN
         LEFTMARGIN, 7
-        RIGHTMARGIN, 767
+        RIGHTMARGIN, 689
         TOPMARGIN, 7
-        BOTTOMMARGIN, 424
+        BOTTOMMARGIN, 392
     END
 
     IDD_DLG_LOGIN, DIALOG

+ 10 - 0
source/hook/WeChats/WeChats.vcxproj

@@ -124,9 +124,13 @@
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
     </ClCompile>
+    <ClCompile Include="..\skinui\BCMenu.cpp" />
+    <ClCompile Include="..\skinui\BtnST.cpp" />
+    <ClCompile Include="..\skinui\ComboTreeCtrl.cpp" />
     <ClCompile Include="..\skinui\EnBitmap.cpp" />
     <ClCompile Include="..\skinui\GfxOutBarCtrl.cpp" />
     <ClCompile Include="..\skinui\MyListCtrl.cpp" />
+    <ClCompile Include="..\skinui\PictureEx.cpp" />
     <ClCompile Include="..\skinui\SkinButton.cpp" />
     <ClCompile Include="..\skinui\SkinEdit.cpp" />
     <ClCompile Include="..\skinui\SkinStatic.cpp" />
@@ -134,6 +138,7 @@
     <ClCompile Include="..\skinui\SkinWin.cpp" />
     <ClCompile Include="..\skinui\Subclass.cpp" />
     <ClCompile Include="..\skinui\SubLabel.cpp" />
+    <ClCompile Include="..\skinui\TreeComboBox.cpp" />
     <ClCompile Include="CDLG_Login.cpp" />
     <ClCompile Include="CWxObject.cpp" />
     <ClCompile Include="Global.cpp" />
@@ -148,9 +153,13 @@
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\pb\msg.pb.h" />
+    <ClInclude Include="..\skinui\BCMenu.h" />
+    <ClInclude Include="..\skinui\BtnST.h" />
+    <ClInclude Include="..\skinui\ComboTreeCtrl.h" />
     <ClInclude Include="..\skinui\EnBitmap.h" />
     <ClInclude Include="..\skinui\GfxOutBarCtrl.h" />
     <ClInclude Include="..\skinui\MyListCtrl.h" />
+    <ClInclude Include="..\skinui\PictureEx.h" />
     <ClInclude Include="..\skinui\SkinButton.h" />
     <ClInclude Include="..\skinui\SkinEdit.h" />
     <ClInclude Include="..\skinui\SkinStatic.h" />
@@ -158,6 +167,7 @@
     <ClInclude Include="..\skinui\SkinWin.h" />
     <ClInclude Include="..\skinui\Subclass.h" />
     <ClInclude Include="..\skinui\SubLabel.h" />
+    <ClInclude Include="..\skinui\TreeComboBox.h" />
     <ClInclude Include="CDLG_Login.h" />
     <ClInclude Include="CWxObject.h" />
     <ClInclude Include="Global.h" />

+ 30 - 0
source/hook/WeChats/WeChats.vcxproj.filters

@@ -78,6 +78,21 @@
     <ClCompile Include="Injection.cpp">
       <Filter>源文件</Filter>
     </ClCompile>
+    <ClCompile Include="..\skinui\BCMenu.cpp">
+      <Filter>skinui</Filter>
+    </ClCompile>
+    <ClCompile Include="..\skinui\BtnST.cpp">
+      <Filter>skinui</Filter>
+    </ClCompile>
+    <ClCompile Include="..\skinui\ComboTreeCtrl.cpp">
+      <Filter>skinui</Filter>
+    </ClCompile>
+    <ClCompile Include="..\skinui\PictureEx.cpp">
+      <Filter>skinui</Filter>
+    </ClCompile>
+    <ClCompile Include="..\skinui\TreeComboBox.cpp">
+      <Filter>skinui</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="Global.h">
@@ -146,6 +161,21 @@
     <ClInclude Include="Injection.h">
       <Filter>头文件</Filter>
     </ClInclude>
+    <ClInclude Include="..\skinui\BCMenu.h">
+      <Filter>skinui</Filter>
+    </ClInclude>
+    <ClInclude Include="..\skinui\BtnST.h">
+      <Filter>skinui</Filter>
+    </ClInclude>
+    <ClInclude Include="..\skinui\ComboTreeCtrl.h">
+      <Filter>skinui</Filter>
+    </ClInclude>
+    <ClInclude Include="..\skinui\PictureEx.h">
+      <Filter>skinui</Filter>
+    </ClInclude>
+    <ClInclude Include="..\skinui\TreeComboBox.h">
+      <Filter>skinui</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <Image Include="res\WeChats.ico">

+ 21 - 31
source/hook/WeChats/WeChatsDlg.cpp

@@ -6,6 +6,7 @@
 #include "WeChats.h"
 #include "WeChatsDlg.h"
 #include "CWxObject.h"
+#include "WxMgr.h"
 
 #ifdef _DEBUG
 #define new DEBUG_NEW
@@ -19,10 +20,10 @@ class CAboutDlg : public CDialog
 public:
 	CAboutDlg();
 
-// 对话框数据
+	// 对话框数据
 	enum { IDD = IDD_ABOUTBOX };
 
-	protected:
+protected:
 	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
 
 // 实现
@@ -67,6 +68,7 @@ BEGIN_MESSAGE_MAP(CWeChatsDlg, CDialog)
 	//}}AFX_MSG_MAP
 	ON_BN_CLICKED(BTN_OPEN_WX, &CWeChatsDlg::OnBnClickedOpenWx)
 	ON_WM_CTLCOLOR()
+	ON_BN_CLICKED(BTN_ATTACH_WX, &CWeChatsDlg::OnBnClickedAttachWx)
 END_MESSAGE_MAP()
 
 
@@ -102,6 +104,12 @@ BOOL CWeChatsDlg::OnInitDialog()
 	SetIcon(m_hIcon, FALSE);		// 设置小图标
 
 	// TODO: 在此添加额外的初始化代码
+	CRect rcWxList, rcWxShow;
+	GetDlgItem(RECT_WXLIST)->GetWindowRect(&rcWxList);
+	GetDlgItem(RECT_WECHAT)->GetWindowRect(&rcWxShow);
+	ScreenToClient(&rcWxList);
+	ScreenToClient(&rcWxShow);
+	m_wxMgr.SetMainWnd(this, rcWxList, rcWxShow);
 
 	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
 }
@@ -144,14 +152,6 @@ void CWeChatsDlg::OnPaint()
 	}
 	else
 	{
-		if (m_wxObj.m_hWxMainWnd)
-		{
-			Invalidate();
-			GetDlgItem(WX_RECT)->Invalidate();
-			::UpdateWindow(m_wxObj.m_hWxMainWnd);
-			//::PostMessage(m_wxObj.m_hWxMainWnd, WM_MOVE, 0, 0);
-			//::PostMessage(m_wxObj.m_hWxMainWnd, WM_WINDOWPOSCHANGING, 0, 0);
-		}
 		CDialog::OnPaint();
 	}
 }
@@ -164,28 +164,17 @@ HCURSOR CWeChatsDlg::OnQueryDragIcon()
 }
 
 
-
 void CWeChatsDlg::OnBnClickedOpenWx()
 {
 	// TODO: 在此添加控件通知处理程序代码
-
-	//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)
-	{
-		m_wxObj.setInjectionObj(*vtPID.begin(), g_szDynamicLibraryPath);
-		if (m_wxObj.FindWxMainWnd())
-		{
-			m_wxObj.InjectDynamicLibrary();
-			m_wxObj.Attach2MainWnd(GetDlgItem(WX_RECT), FALSE);
-			m_wxObj.SetHook();
-		}
-	}
+	m_wxMgr.OpenWeChat();
 }
 
+void CWeChatsDlg::OnBnClickedAttachWx()
+{
+	// TODO: 在此添加控件通知处理程序代码
+	m_wxMgr.AttachUnMgrWxProc(GetDlgItem(WX_RECT));
+}
 
 HBRUSH CWeChatsDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
 {
@@ -198,15 +187,13 @@ HBRUSH CWeChatsDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
 	return hbr;
 }
 
-
 BOOL CWeChatsDlg::DestroyWindow()
 {
 	// TODO: 在此添加专用代码和/或调用基类
-	m_wxObj.DetachWxWnd();
+	m_wxMgr.DetachAllWxProc();
 	return CDialog::DestroyWindow();
 }
 
-
 BOOL CWeChatsDlg::PreTranslateMessage(MSG* pMsg)
 {
 	// TODO: 在此添加专用代码和/或调用基类
@@ -230,6 +217,9 @@ BOOL CWeChatsDlg::PreTranslateMessage(MSG* pMsg)
 			}
 		}
 	}
-	
+
 	return CDialog::PreTranslateMessage(pMsg);
 }
+
+
+

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

@@ -5,18 +5,19 @@
 #pragma once
 
 #include "CWxObject.h"
+#include "WxMgr.h"
 
 // CWeChatsDlg 对话框
 class CWeChatsDlg : public CDialog
 {
-// 构造
+	// 构造
 public:
 	CWeChatsDlg(CWnd* pParent = NULL);	// 标准构造函数
 
 // 对话框数据
 	enum { IDD = IDD_WECHATS_DIALOG };
 
-	protected:
+protected:
 	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持
 
 
@@ -34,8 +35,10 @@ protected:
 	DECLARE_MESSAGE_MAP()
 public:
 	CWxObject m_wxObj;
+	CWxMgr	m_wxMgr;
 	afx_msg void OnBnClickedOpenWx();
 	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
 	virtual BOOL DestroyWindow();
 	virtual BOOL PreTranslateMessage(MSG* pMsg);
+	afx_msg void OnBnClickedAttachWx();
 };

+ 157 - 9
source/hook/WeChats/WxMgr.cpp

@@ -2,28 +2,176 @@
 #include "WxMgr.h"
 #include "Global.h"
 
-CWxMgr::CWxMgr()
+TCHAR	CWxMgr::m_szWeChatPath[MAX_PATH] = { 0 };
+CWxMgr::CWxMgr(CWnd *pMainWnd) :m_pMainWnd(pMainWnd)
 {
+	GetWeChatPath();
 }
 
-
 CWxMgr::~CWxMgr()
 {
 }
 
-BOOL CWxMgr::AttachUnMgrWxProc()
+CRect CWxMgr::CalcRect()
+{
+	CRect rc;
+	int nCount = m_mapWx.size();
+	// 高固定大小;
+	rc.left = m_rcWxList.left + 2;
+	rc.top = 100 * nCount + m_rcWxList.top + 20;
+	rc.right = m_rcWxList.right - 2;
+	rc.bottom = rc.top + 100;
+
+	return rc;
+}
+
+BOOL CWxMgr::AttachUnMgrWxProc(CWnd *pWnd)
 {
 	vector<DWORD> vtWxProcId = FindAllProcess(WECHAT);
-	for ( DWORD pid:vtWxProcId)
+	for (DWORD pid : vtWxProcId)
 	{
-		if ( m_mapWx.count(pid) == 0)
+		if (m_mapWx.count(pid) == 0)
 		{
-			CWxObject wxObj(pid, g_szDynamicLibraryPath);
-			wxObj.InjectDynamicLibrary();
-			wxObj.FindWxMainWnd();
-			m_mapWx.insert(pair<DWORD, CWxObject>(pid, wxObj));
+			AddMapItem(pid, NULL);
 		}
 	}
 
 	return TRUE;
 }
+
+BOOL CWxMgr::AttachWx()
+{
+	return 0;
+}
+
+VOID CWxMgr::AddMapItem(DWORD dwProcId, LPCTSTR lpItemName)
+{
+	WXOBJINFO wxObjInfo;
+	// 创建微信对象;
+	wxObjInfo.pWxObject = new CWxObject(dwProcId, g_szDynamicLibraryPath);
+
+	// 创建按钮;
+	wxObjInfo.pWxButton = new CButtonST();
+	wxObjInfo.pWxButton->Create(lpItemName, NULL, CalcRect(), m_pMainWnd, dwProcId);
+	wxObjInfo.pWxButton->ShowWindow(SW_SHOW);
+
+	// 创建聊天窗口;
+	wxObjInfo.pWxChatWnd = new CStatic();
+	wxObjInfo.pWxChatWnd->Create(lpItemName, WS_CHILD | WS_VISIBLE | WS_TABSTOP | SS_GRAYRECT, m_rcWxShow, m_pMainWnd, dwProcId + 1);
+	wxObjInfo.pWxChatWnd->ShowWindow(SW_SHOW);
+
+	// 附加到窗口;
+	wxObjInfo.pWxObject->InjectDynamicLibrary();
+	if (wxObjInfo.pWxObject->FindWxMainWnd())
+	{
+		wxObjInfo.pWxObject->Attach2MainWnd(wxObjInfo.pWxChatWnd, FALSE);
+	}
+	else if (wxObjInfo.pWxObject->FindWxLoginWnd())
+	{
+		wxObjInfo.pWxObject->Attach2MainWnd(wxObjInfo.pWxChatWnd, TRUE);
+	}
+
+	m_mapWx.insert(pair<DWORD, WXOBJINFO>(dwProcId, wxObjInfo));
+}
+
+VOID CWxMgr::RemoveMapItem(DWORD dwProcId)
+{
+	for (pair<DWORD, WXOBJINFO> wxinfo : m_mapWx)
+	{
+		if (wxinfo.first == dwProcId)
+		{
+			wxinfo.second.pWxObject->DetachWxWnd();
+			delete wxinfo.second.pWxObject;
+			delete wxinfo.second.pWxButton;
+			delete wxinfo.second.pWxChatWnd;
+			// 下方的WxButton向上移动;
+			// ...
+			break;
+		}
+	}
+
+	// 移除key;
+	m_mapWx.erase(dwProcId);
+}
+
+VOID CWxMgr::DetachAllWxProc()
+{
+	for (pair<DWORD, WXOBJINFO> wxinfo : m_mapWx)
+	{
+		wxinfo.second.pWxObject->DetachWxWnd();
+		delete wxinfo.second.pWxObject;
+		delete wxinfo.second.pWxButton;
+		delete wxinfo.second.pWxChatWnd;
+	}
+
+	m_mapWx.clear();
+}
+
+BOOL CWxMgr::OpenWeChat()
+{
+	// 关闭互斥句柄;
+	PatchWeChat();
+
+	STARTUPINFO si;
+	PROCESS_INFORMATION pi;
+	ZeroMemory(&si, sizeof(si));
+	si.cb = sizeof(si);
+	ZeroMemory(&pi, sizeof(pi));
+
+	si.dwFlags = STARTF_USESHOWWINDOW;		// 指定wShowWindow成员有效
+	si.wShowWindow = SW_HIDE;				// 设置创建进程时,窗口不显示,
+	// 为FALSE的话则不显示
+	BOOL bRet = ::CreateProcess(
+		m_szWeChatPath,		// 不在此指定可执行文件的文件名
+		NULL,				// 命令行参数
+		NULL,				// 默认进程安全性
+		NULL,				// 默认线程安全性
+		FALSE,				// 指定当前进程内的句柄不可以被子进程继承
+		NULL,
+		NULL,				// 使用本进程的环境变量
+		NULL,				// 使用本进程的驱动器和目录
+		&si,
+		&pi);
+
+	if (bRet)
+	{
+		/*WaitForSingleObject(pi.hProcess, INFINITE);*/
+		//WaitForInputIdle(pi.hProcess, INFINITE);
+		Sleep(1500); // 启动微信需要1秒左右;
+		// 既然我们不使用两个句柄,最好是立刻将它们关闭
+		::CloseHandle(pi.hThread);
+		::CloseHandle(pi.hProcess);
+
+		// 当进程挂起时,是无法修改关闭微信句柄;
+		AddMapItem(pi.dwProcessId, NULL);
+	}
+
+	return 0;
+}
+
+BOOL CWxMgr::GetWeChatPath()
+{
+	static BOOL bGotPath = FALSE;
+	if (!bGotPath)
+	{
+		// 通过注册表获取微信安装目录;
+		HKEY hKey = NULL;
+		if (ERROR_SUCCESS != RegOpenKey(HKEY_CURRENT_USER, _T("Software\\Tencent\\WeChat"), &hKey))
+		{
+			return FALSE;
+		}
+
+		DWORD Type = REG_SZ;
+		DWORD cbData = MAX_PATH * sizeof(WCHAR);
+		if (ERROR_SUCCESS != RegQueryValueEx(hKey, _T("InstallPath"), 0, &Type, (LPBYTE)m_szWeChatPath, &cbData))
+		{
+			RegCloseKey(hKey);
+			return FALSE;
+		}
+
+		PathAppend(m_szWeChatPath, _T("WeChat.exe"));
+		bGotPath = TRUE;
+	}
+
+	return bGotPath;
+}

+ 27 - 3
source/hook/WeChats/WxMgr.h

@@ -3,21 +3,45 @@
 
 #include <map>
 #include "CWxObject.h"
+#include "BtnST.h"
 
 #pragma once
 
+typedef struct _WXOBJINFO_
+{
+	CButtonST	*pWxButton;
+	CStatic		*pWxChatWnd;
+	CWxObject	*pWxObject;
+}WXOBJINFO;
 
 class CWxMgr
 {
 public:
-	CWxMgr();
+	CWxMgr(CWnd *pMainWnd = NULL);
 	~CWxMgr();
 
 private:
-	std::map<DWORD, CWxObject> m_mapWx;
-	BOOL AttachUnMgrWxProc();
+	CWnd	*m_pMainWnd;
+	CRect	m_rcWxList;
+	CRect	m_rcWxShow;
+	std::map<DWORD, WXOBJINFO> m_mapWx;
+	VOID AddMapItem(DWORD dwProcId, LPCTSTR lpItemName);
+	VOID RemoveMapItem(DWORD dwProcId);
+	CRect CalcRect();
+	// ΢ÐÅ·¾¶;
+	static TCHAR	m_szWeChatPath[MAX_PATH];
 public:
+	VOID SetMainWnd(CWnd *pWnd, CRect rcWxList, CRect rcWxShow) {
+		m_pMainWnd = pWnd;
+		m_rcWxList = rcWxList;
+		m_rcWxShow = rcWxShow;
+	}
+	BOOL AttachUnMgrWxProc(CWnd *pWnd);
+	BOOL AttachWx();
+
+	VOID DetachAllWxProc();
 	BOOL OpenWeChat();
+	BOOL GetWeChatPath();
 };
 
 #endif //__WX_MRG__

+ 13 - 13
source/hook/hook/dllmain.cpp

@@ -2,7 +2,7 @@
 #include "stdafx.h"
 
 HHOOK g_hook = NULL;
-LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
+LRESULT CALLBACK Hook_CBT_Proc(int nCode, WPARAM wParam, LPARAM lParam)
 {
 	tagMSG* msg;
 	msg = (tagMSG*)lParam;
@@ -15,23 +15,23 @@ LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
 	return CallNextHookEx(g_hook, nCode, wParam, lParam);
 }
 
-BOOL APIENTRY DllMain( HMODULE hModule,
-                       DWORD  ul_reason_for_call,
-                       LPVOID lpReserved
-					 )
+BOOL APIENTRY DllMain(HMODULE hModule,
+	DWORD  ul_reason_for_call,
+	LPVOID lpReserved
+)
 {
 	g_hCurModule = hModule;
 	switch (ul_reason_for_call)
 	{
 	case DLL_PROCESS_ATTACH:
-		{
-			if ( g_hook == NULL)
-				g_hook = SetWindowsHookEx(WH_CBT, HookProc, NULL, ::GetCurrentThreadId());
-			WriteTextLog(_T("dllÒѳɹ¦×¢Èë:%d"), ::GetCurrentThreadId());
-			WxInfo wxInfo;
-			GetWxInfo(wxInfo);
-		}
-		break;
+	{
+		if (g_hook == NULL)
+			g_hook = SetWindowsHookEx(WH_CBT, Hook_CBT_Proc, NULL, ::GetCurrentThreadId());
+		WriteTextLog(_T("dllÒѳɹ¦×¢Èë:%d,%d"), ::GetCurrentThreadId(), ::GetCurrentProcessId());
+		WxInfo wxInfo;
+		GetWxInfo(wxInfo);
+	}
+	break;
 	case DLL_THREAD_ATTACH:
 		break;
 	case DLL_THREAD_DETACH: