Browse Source

Connect成功和失败需要单独劫持处理。

JeffWang 3 years ago
parent
commit
72d7065e06

+ 102 - 13
Source/OGCAssist/OGCAssist/OGCAssist.cpp

@@ -11,6 +11,8 @@ namespace Assist
 	// 全局Call Data;
 	CALLDATA _cd_Go;
 	CALLDATA _cd_Connect;
+	CALLDATA _cd_Connect_True;
+	CALLDATA _cd_Connect_False;
 	CALLDATA _cd_Disconnect;
 	CALLDATA _cd_CheckFW;
 	CALLDATA _cd_CheckFW_CommunicationError;
@@ -48,6 +50,8 @@ namespace Assist
 	// 自定义跳转函数;
 	void Call_MyDisconnect();
 	void Call_MyConnect();
+	void Call_MyConnectTrue();
+	void Call_MyConnectFalse();
 	void Call_MyGo();
 	void Call_MyGoSN();
 	void Call_MyCheckFW();
@@ -87,6 +91,30 @@ namespace Assist
 		memset(_cd_Connect.szMyCallData, 0x90, CALL_LEN);
 		_cd_Connect.szMyCallData[0] = 0xE9; // 汇编硬编码:jmp [4字节地址];
 		*(LPDWORD)(&_cd_Connect.szMyCallData[1]) = (DWORD)_cd_Connect.myCall - _cd_Connect.dwOriginalAddr - JMP_DLEN;
+
+		// 连接成功时;
+		_cd_Connect_True.myCall = Call_MyConnectTrue;
+		// 00415ED1 | 6A 00                  | push 0 
+		_cd_Connect_True.dwBack2Addr = 0;	// 无下行代码;
+		_cd_Connect_True.dwOriginalAddr = 0x00416336;
+		_cd_Connect_True.dwOriginalCallAddr = 0x00416525;	// 此处是JMP,注意注入时不要调用为Call
+
+		_cd_Connect_True.nMyCallDataLen = JMP_DLEN;
+		memset(_cd_Connect_True.szMyCallData, 0x90, CALL_LEN);
+		_cd_Connect_True.szMyCallData[0] = 0xE9; // 汇编硬编码:jmp [4字节地址];
+		*(LPDWORD)(&_cd_Connect_True.szMyCallData[1]) = (DWORD)_cd_Connect_True.myCall - _cd_Connect_True.dwOriginalAddr - JMP_DLEN;
+
+		// 连接失败时;
+		_cd_Connect_False.myCall = Call_MyConnectFalse;
+		// 00415ED1 | 6A 00                  | push 0 
+		_cd_Connect_False.dwBack2Addr = 0;	// 无下行代码;
+		_cd_Connect_False.dwOriginalAddr = 0x00416342;
+		_cd_Connect_False.dwOriginalCallAddr = 0x004164BD;	// 此处是JMP,注意注入时不要调用为Call
+
+		_cd_Connect_False.nMyCallDataLen = JMP_DLEN;
+		memset(_cd_Connect_False.szMyCallData, 0x90, CALL_LEN);
+		_cd_Connect_False.szMyCallData[0] = 0xE9; // 汇编硬编码:jmp [4字节地址];
+		*(LPDWORD)(&_cd_Connect_False.szMyCallData[1]) = (DWORD)_cd_Connect_False.myCall - _cd_Connect_False.dwOriginalAddr - JMP_DLEN;
 #pragma endregion
 
 #pragma region Disconnect按钮劫持
@@ -209,6 +237,12 @@ namespace Assist
 		if ( !(bHijack = HijackedCall(&_cd_Connect)) )
 			goto end;
 
+		if ( !(bHijack = HijackedCall(&_cd_Connect_True)) )
+			goto end;
+
+		if ( !(bHijack = HijackedCall(&_cd_Connect_False)) )
+			goto end;
+
 		if ( !(bHijack = HijackedCall(&_cd_Disconnect)) )
 			goto end;
 
@@ -245,6 +279,12 @@ end:
 		if ( !(bRestor = RecoveryCall(&_cd_Connect)) )
 			goto end;
 
+		if ( !(bRestor = RecoveryCall(&_cd_Connect_True)) )
+			goto end;
+
+		if ( !(bRestor = RecoveryCall(&_cd_Connect_False)) )
+			goto end;
+
 		if ( !(bRestor = RecoveryCall(&_cd_Disconnect)) )
 			goto end;
 
@@ -577,18 +617,6 @@ namespace Assist
 #endif
 		}
 
-#pragma region 向服务器发送消息;
-		MSG_INFO msg;
-		msg.byResult = bConnectStatus;
-		_stprintf((TCHAR*)msg.byData, _T("%s"), _T("OGCAssist Connect"));
-
-		DATAHEADER head;				
-		head.byMsgType = C2S_CONNECT;
-		head.dwPackageLen = sizeof(DATAHEADER) + sizeof(MSG_INFO);
-
-		Utility::g_pPipeClient->SendPackage(head, msg);
-#pragma endregion
-
 		return TRUE;
 	}
 
@@ -606,7 +634,6 @@ namespace Assist
 				// 成功:则继续正常的流程;
 				jmp _cd_Connect.dwBack2Addr;
 			}
-
 		}
 		else
 		{
@@ -619,6 +646,68 @@ namespace Assist
 		}   
 	}
 
+	void MyConnectTrue()
+	{
+		bConnectStatus = TRUE;
+#pragma region 向服务器发送消息;
+		MSG_INFO msg;
+		msg.byResult = bConnectStatus;
+		_stprintf((TCHAR*)msg.byData, _T("%s"), _T("OGCAssist Connect"));
+
+		DATAHEADER head;				
+		head.byMsgType = C2S_CONNECT;
+		head.dwPackageLen = sizeof(DATAHEADER) + sizeof(MSG_INFO);
+
+		Utility::g_pPipeClient->SendPackage(head, msg);
+#pragma endregion
+	}
+
+	void __declspec(naked) Call_MyConnectTrue()
+	{
+		// 备份寄存器;
+		__asm pushad;
+
+		MyConnectTrue();
+
+		__asm{
+			// 恢复寄存器; 
+			popad;
+			// 执行原Call或Jmp;
+			jmp _cd_Connect_True.dwOriginalCallAddr;
+		}    
+	}
+
+	void MyConnectFalse()
+	{
+		bConnectStatus = FALSE;
+#pragma region 向服务器发送消息;
+		MSG_INFO msg;
+		msg.byResult = bConnectStatus;
+		_stprintf((TCHAR*)msg.byData, _T("%s"), _T("OGCAssist Connect"));
+
+		DATAHEADER head;				
+		head.byMsgType = C2S_CONNECT;
+		head.dwPackageLen = sizeof(DATAHEADER) + sizeof(MSG_INFO);
+
+		Utility::g_pPipeClient->SendPackage(head, msg);
+#pragma endregion
+	}
+
+	void __declspec(naked) Call_MyConnectFalse()
+	{
+		// 备份寄存器;
+		__asm pushad;
+
+		MyConnectFalse();
+
+		__asm{
+			// 恢复寄存器; 
+			popad;
+			// 执行原Call或Jmp;
+			jmp _cd_Connect_False.dwOriginalCallAddr;
+		}  
+	}
+
 	void MyExternalException()
 	{
 		// 产生异常,设置为未连接;

+ 3 - 4
Source/OGCAssistTool/OGCAssistTool/OGCAssistTool.rc

@@ -135,11 +135,10 @@ BEGIN
     GROUPBOX        "结果:",IDC_STATIC,7,284,717,31
     LTEXT           "▲E平均值:",IDC_STATIC,15,298,43,8
     EDITTEXT        EDIT_ARG_EVALUE,64,295,73,14,ES_AUTOHSCROLL | ES_READONLY
-    PUSHBUTTON      "显示窗口",BTN_SHOW_WND,503,295,50,14
-    PUSHBUTTON      "隐藏窗口",BTN_HIDE_WND,560,295,50,14
-    CONTROL         "劫持窗口",CHECK_HIJACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,617,297,48,10
-    CONTROL         "恢复劫持",CHECK_RESUME_HIJACKING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,672,297,48,10
+    PUSHBUTTON      "显示窗口",BTN_SHOW_WND,557,295,50,14
+    CONTROL         "劫持窗口",CHECK_HIJACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,669,297,48,10
     PUSHBUTTON      "测试",BTN_TEST,663,18,50,14
+    PUSHBUTTON      "连接设备",BTN_CONNECT,612,295,50,14
 END
 
 PAGE_LOG DIALOGEX 0, 0, 732, 322

+ 2 - 8
Source/OGCAssistTool/OGCAssistTool/OGCAssistToolDlg.cpp

@@ -387,14 +387,8 @@ void COGCAssistToolDlg::OnTimer(UINT_PTR nIDEvent)
 				// ÉèÖþä±ú;
 				GLOBAL::g_IOCP.SetMainDlg(this);
 
-#pragma region Òþ²Ø´°¿Ú;
-				HWND hWnd = NULL;
-				if ( hWnd = MyFindWindow(_T("TfrmDemo")) )
-					::ShowWindow(hWnd, SW_HIDE);
-
-				if ( hWnd = MyFindWindow(_T("TApplication")) )
-					::ShowWindow(hWnd, SW_HIDE);
-#pragma endregion
+				// Òþ²Ø´°¿Ú;
+				((CPageDebug*)m_pDialog[0])->ShowOGCWnd(SW_HIDE);
 
 				KillTimer(nIDEvent);
 			}			

+ 157 - 53
Source/OGCAssistTool/OGCAssistTool/PageDebug.cpp

@@ -39,10 +39,10 @@ void CPageDebug::DoDataExchange(CDataExchange* pDX)
 BEGIN_MESSAGE_MAP(CPageDebug, CDialogEx)
 	ON_WM_CTLCOLOR()
 	ON_BN_CLICKED(BTN_SHOW_WND, &CPageDebug::OnBnClickedShowWnd)
-	ON_BN_CLICKED(BTN_HIDE_WND, &CPageDebug::OnBnClickedHideWnd)
 	ON_BN_CLICKED(CHECK_HIJACK, &CPageDebug::OnBnClickedHijack)
-	ON_BN_CLICKED(CHECK_RESUME_HIJACKING, &CPageDebug::OnBnClickedResumeHijacking)
 	ON_BN_CLICKED(BTN_TEST, &CPageDebug::OnBnClickedTest)
+	ON_BN_CLICKED(BTN_CONNECT, &CPageDebug::OnBnClickedConnect)
+	ON_WM_TIMER()
 END_MESSAGE_MAP()
 
 
@@ -130,85 +130,189 @@ HWND MyFindWindow(LPCTSTR lpClassName)
 void CPageDebug::OnBnClickedShowWnd()
 {
 	// TODO: 在此添加控件通知处理程序代码
-	HWND hWnd = NULL;
-	if ( hWnd = MyFindWindow(_T("TfrmDemo")) )
-		::ShowWindow(hWnd, SW_SHOW);
-
-	if ( hWnd = MyFindWindow(_T("TApplication")) )
-		::ShowWindow(hWnd, SW_SHOW);
+	CString strText;
+	GetDlgItemText(BTN_SHOW_WND, strText);
+	if ( strText == _T("显示窗口") )
+	{
+		ShowOGCWnd(SW_SHOW);
+	}
+	else
+	{
+		ShowOGCWnd(SW_HIDE);
+	}
 }
 
-void CPageDebug::OnBnClickedHideWnd()
+void CPageDebug::OnBnClickedHijack()
 {
 	// TODO: 在此添加控件通知处理程序代码
-	HWND hWnd = NULL;
-	if ( hWnd = MyFindWindow(_T("TfrmDemo")) )
-		::ShowWindow(hWnd, SW_HIDE);
-
-	if ( hWnd = MyFindWindow(_T("TApplication")) )
-		::ShowWindow(hWnd, SW_HIDE);
+	BOOL bCheck = ((CButton*)GetDlgItem(CHECK_HIJACK))->GetCheck();
+	if ( bCheck )
+	{
+		// 劫持窗口;
+	}
+	else
+	{
+		// 恢复窗口;
+	}
 }
 
-void CPageDebug::OnBnClickedHijack()
+void CPageDebug::OnBnClickedTest()
 {
-	// TODO: 在此添加控件通知处理程序代码
+	if ( GLOBAL::g_procWndInfo.bHijackStatus && GLOBAL::g_procWndInfo.bConnectStatus )
+	{
+		CString strSN;
+		GetDlgItemText(EDIT_SN, strSN);
+		if ( strSN.IsEmpty() )
+		{
+			MessageBox(_T("错误:SN不能空,请输入SN!"), _T("错误!"), MB_ICONERROR);
+			return;
+		}
+
+		if ( strSN.GetLength() > 25 )
+		{
+			MessageBox(_T("错误:SN长度不能超过25!"), _T("错误!"), MB_ICONERROR);
+			return;
+		}
+
+		// 设置SN下拉框长度;
+		if ( g_hWnd_SN_Combobox )
+		{
+			TCHAR szLen[10] = {0};
+			_ltot_s(strSN.GetLength(), szLen, 10, 10);
+			::SendMessage(g_hWnd_SN_Combobox, CB_SELECTSTRING, 0, (LPARAM)&szLen);	// 此方法:设置句柄文本成功;
+		}
+
+		// 设置SN编辑框;
+		if ( g_hWnd_SN )
+		{
+			TCHAR szSN[26] = {0};
+			_stprintf_s(szSN, _T("%s"), strSN.GetString());
+			::SendMessage(g_hWnd_SN, WM_SETTEXT, 0, (LPARAM)&szSN);
+		}
+
+		// 按钮Go按钮;
+		HWND hWnd = GLOBAL::g_procWndInfo.GetButtonWnd(_T("Go"));
+		if ( hWnd )
+		{
+			::PostMessage(hWnd, WM_LBUTTONDOWN, 0, 0);
+			Sleep(20);
+			::PostMessage(hWnd, WM_LBUTTONUP, 0, 0);
+		}
+
+		GetDlgItem(BTN_TEST)->EnableWindow(FALSE);
+		SetTimer(1, 500, NULL);
+	}
+	else
+	{
+		MessageBox(_T("未连接设备,请先按“连接设备”按钮!"), _T("提示"), MB_ICONWARNING);
+	}
 }
 
-void CPageDebug::OnBnClickedResumeHijacking()
+void CPageDebug::OnBnClickedConnect()
 {
-	// TODO: 在此添加控件通知处理程序代码
+	CString strText;
+	GetDlgItemText(BTN_CONNECT, strText);
+	if ( strText == _T("连接设备") )
+	{
+		// 1、执行一次Connect按钮事件;
+		//// 1.1、Connect成功后, 目标进程会返回消息;
+		//// 1.2、若没有消息返回,需要判断是否在程序启动前已注入过并且Connect过。
+		//// 1.3、要避免2的情况,主进程应该每次启动时,都向目标进程发送消息获取按钮状态。
+		// 2、读取SN长度,设置一次SN长度下拉框;
+		// 3、将SN赋值到目标进程SN编辑框;
+		// 4、执行Go函数;
+		// 5、劫持的Go函数未返回消息时,Test按钮和SN编辑框禁止输入;
+		switch ( StartOGCTool() )
+		{
+		case -1:
+			// 退出新开;
+			break;
+		case 0:
+			// 新开失败;
+			break;
+		case 1:
+			// 新开成功;
+			{
+				AfxGetApp()->GetMainWnd()->SetTimer(0, 500, NULL);
+				MessageBox(_T("OGC程序启动中,请稍后再尝试,谢谢!"), _T("提示"), MB_OK|MB_ICONWARNING);
+			}
+			break;
+		case 2:
+			// 已存在进程;
+			{
+				// 执行Connect按钮;
+				if ( GLOBAL::g_procWndInfo.bHijackStatus && !GLOBAL::g_procWndInfo.bConnectStatus )
+				{
+					HWND hWnd = GLOBAL::g_procWndInfo.GetButtonWnd(_T("Connect CA310"));
+					if ( hWnd )
+					{
+						::PostMessage(hWnd, WM_LBUTTONDOWN, 0, 0);
+						Sleep(20);
+						::PostMessage(hWnd, WM_LBUTTONUP, 0, 0);
+					}
+
+					SetDlgItemText(BTN_CONNECT, _T("连接中……"));
+					SetTimer(0, 500, NULL);
+				}
+				else
+				{
+					MessageBox(_T("设备已连接成功~"), _T("提示!"), MB_OK);
+					SetDlgItemText(BTN_CONNECT, _T("断开设备"));
+				}
+			}
+			break;
+		default:
+			break;
+		}
+	}
+	else
+	{
+		HWND hWnd = GLOBAL::g_procWndInfo.GetButtonWnd(_T("Disconnect"));
+		if ( hWnd )
+		{
+			::PostMessage(hWnd, WM_LBUTTONDOWN, 0, 0);
+			Sleep(20);
+			::PostMessage(hWnd, WM_LBUTTONUP, 0, 0);
+		}
+
+		SetDlgItemText(BTN_CONNECT, _T("连接设备"));
+	}	
 }
 
-void CPageDebug::OnBnClickedTest()
+void CPageDebug::OnTimer(UINT_PTR nIDEvent)
 {
-	// 1、执行一次Connect按钮事件;
-	//// 1.1、Connect成功后, 目标进程会返回消息;
-	//// 1.2、若没有消息返回,需要判断是否在程序启动前已注入过并且Connect过。
-	//// 1.3、要避免2的情况,主进程应该每次启动时,都向目标进程发送消息获取按钮状态。
-	// 2、读取SN长度,设置一次SN长度下拉框;
-	// 3、将SN赋值到目标进程SN编辑框;
-	// 4、执行Go函数;
-	// 5、劫持的Go函数未返回消息时,Test按钮和SN编辑框禁止输入;
-	switch ( StartOGCTool() )
+	// TODO: 在此添加消息处理程序代码和/或调用默认值
+	switch ( nIDEvent )
 	{
-	case -1:
-		// 退出新开;
-		break;
 	case 0:
-		// 新开失败;
-		break;
-	case 1:
-		// 新开成功;
 		{
-			AfxGetApp()->GetMainWnd()->SetTimer(0, 500, NULL);
-			MessageBox(_T("OGC程序启动中,请稍后再尝试,谢谢!"), _T("提示"), MB_OK|MB_ICONWARNING);
-		}
-		break;
-	case 2:
-		// 已存在进程;
-		{
-			// 执行Connect按钮;
-			if ( GLOBAL::g_procWndInfo.bHijackStatus && !GLOBAL::g_procWndInfo.bConnectStatus )
+			if ( GLOBAL::g_procWndInfo.bConnectStatus )
 			{
-				HWND hWnd = GLOBAL::g_procWndInfo.GetButtonWnd(_T("Connect CA310"));
+				//GetDlgItem(BTN_CONNECT)->EnableWindow(FALSE);
+				SetDlgItemText(BTN_CONNECT, _T("断开连接"));
+				// 按钮CheckFW按钮;
+				HWND hWnd = GLOBAL::g_procWndInfo.GetButtonWnd(_T("Check FW"));
 				if ( hWnd )
 				{
 					::PostMessage(hWnd, WM_LBUTTONDOWN, 0, 0);
 					Sleep(20);
 					::PostMessage(hWnd, WM_LBUTTONUP, 0, 0);
 				}
-			}
 
-			// 按钮CheckFW按钮;
-
-			// 设置SN下拉框长度;
-
-			// 设置SN编辑框;
+				KillTimer(nIDEvent);
+			}
+		}
+		break;
+	case 1:
+		{
+			if ( GLOBAL::g_procWndInfo )
+			{
 
-			// 按钮Go按钮;
+			}
 		}
 		break;
 	default:
 		break;
 	}
+	CDialogEx::OnTimer(nIDEvent);
 }

+ 14 - 2
Source/OGCAssistTool/OGCAssistTool/PageDebug.h

@@ -3,6 +3,7 @@
 
 
 // CDlgDebug 对话框
+extern HWND MyFindWindow(LPCTSTR lpClassName);
 
 class CPageDebug : public CDialogEx
 {
@@ -24,9 +25,20 @@ public:
 	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
 	CListCtrl m_ctrlList;
 	void InitListCtrl();
+	inline void ShowOGCWnd(int nCmdShow = SW_SHOW)
+	{
+		HWND hWnd = NULL;
+		if ( hWnd = MyFindWindow(_T("TfrmDemo")) )
+			::ShowWindow(hWnd, nCmdShow);
+
+		if ( hWnd = MyFindWindow(_T("TApplication")) )
+			::ShowWindow(hWnd, nCmdShow);
+
+		SetDlgItemText(BTN_SHOW_WND, nCmdShow == SW_SHOW ? _T("隐藏窗口") : _T("显示窗口"));
+	}
 	afx_msg void OnBnClickedShowWnd();
-	afx_msg void OnBnClickedHideWnd();
 	afx_msg void OnBnClickedHijack();
-	afx_msg void OnBnClickedResumeHijacking();
 	afx_msg void OnBnClickedTest();
+	afx_msg void OnBnClickedConnect();
+	afx_msg void OnTimer(UINT_PTR nIDEvent);
 };

+ 12 - 2
Source/OGCAssistTool/OGCAssistTool/PipeService.cpp

@@ -484,36 +484,41 @@ void CIOCPPipe::RecvProcess(PER_PIPE_CONTEXT* pPipeContext, PER_IO_CONTEXT* pIoC
 		{
 		case C2S_HIJACK:
 			{
+				dprintf(_T("接收到客户端消息:劫持"));
 				GLOBAL::g_procWndInfo.bHijackStatus = msg_info.byResult;
 			}
 			break;
 		case C2S_RESUME:
 			{
+				dprintf(_T("接收到客户端消息:恢复"));
 				GLOBAL::g_procWndInfo.bHijackStatus = !msg_info.byResult;
 			}
 			break;
 		case C2S_CONNECT:
 			{
+				dprintf(_T("接收到客户端消息:连接"));
 				GLOBAL::g_procWndInfo.bConnectStatus = msg_info.byResult;
 			}
 			break;
 		case C2S_DISCONNECT:
 			{
+				dprintf(_T("接收到客户端消息:断开"));
 				GLOBAL::g_procWndInfo.bConnectStatus = !msg_info.byResult;
 			}
 			break;
 		case C2S_CHECKFW:
 			{
-
+				dprintf(_T("接收到客户端消息:CheckFW"));
 			}
 			break;
 		case C2S_EXCEPTION:
 			{
-
+				dprintf(_T("接收到客户端消息:异常"));
 			}
 			break;
 		case C2S_GO:
 			{
+				dprintf(_T("接收到客户端消息:Go"));
 				if ( msg_info.byResult )
 				{
 					// 执行成功;
@@ -524,6 +529,11 @@ void CIOCPPipe::RecvProcess(PER_PIPE_CONTEXT* pPipeContext, PER_IO_CONTEXT* pIoC
 				}
 			}
 			break;
+		case C2S_COMMUNICATION_ERROR:
+			{
+				dprintf(_T("接收到客户端消息:通信错误"));
+			}
+			break;
 		default:
 			break;
 		}

+ 2 - 1
Source/OGCAssistTool/OGCAssistTool/resource.h

@@ -39,6 +39,7 @@
 #define BTN_SHOW_WND                    1013
 #define CHECK_RESUME_HIJACKING          1014
 #define BTN_TEST                        1015
+#define BTN_CONNECT                     1016
 
 // Next default values for new objects
 // 
@@ -46,7 +47,7 @@
 #ifndef APSTUDIO_READONLY_SYMBOLS
 #define _APS_NEXT_RESOURCE_VALUE        133
 #define _APS_NEXT_COMMAND_VALUE         32771
-#define _APS_NEXT_CONTROL_VALUE         1016
+#define _APS_NEXT_CONTROL_VALUE         1017
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif