Ver código fonte

添加Connect等Call的劫持,以及InjectDllDlg的部分问题修复。

Jeff 3 anos atrás
pai
commit
81059f5450

+ 135 - 54
Source/Assist/Assist/Assist.cpp

@@ -12,12 +12,15 @@ CALLDATA _cd_Disconnect;
 CALLDATA _cd_CheckFW;
 CALLDATA _cd_SaveAsOutputData;
 CALLDATA _cd_Go_SN;
+CALLDATA _cd_Initial_failed;
 
 // 调试耗时值ms;
 DWORD dwElapsed = 0;
 
 TCHAR g_szGoSN[32] = {0};
 
+DWORD dwCallAddr = 0;
+
 // 8组寄存器存储;
 DWORD dwEAX = 0;
 DWORD dwEBX = 0;
@@ -35,6 +38,7 @@ void Call_MyGo();
 void Call_MyCheckFW();
 void Call_MySaveAsOutputData();
 void Call_MyGoSN();
+void Call_MyInitial_Failed();
 // 其他函数;
 void SetChannel(int nChannel);
 void SetSN(LPCTSTR lpSN);
@@ -42,31 +46,69 @@ void ChangeSDK(int nSDK);   // 0=410SDK, 1=310SDK;
 
 void InitCallData()
 {
-    // Go 
-    _cd_Go.myCall = Call_MyGo;
-    _cd_Go.dwBack2Addr = 0x004376B0;
-    // 004376AB | E8 50A30C00 | call demo.501A00 
-    _cd_Go.dwOriginalAddr = 0x004376AB;
-    _cd_Go.dwOriginalCallAddr = 0x00501A00;
-
-    _cd_Go.nMyCallDataLen = JMP_DLEN;
-    memset(_cd_Go.szMyCallData, 0x90, CALL_LEN);
-    _cd_Go.szMyCallData[0] = 0xE9; // 汇编硬编码:jmp [4字节地址];
-    *(LPDWORD)(&_cd_Go.szMyCallData[1]) = (DWORD)_cd_Go.myCall - _cd_Go.dwOriginalAddr - JMP_DLEN;
-
-    // Go SN 
-    // 00417AEC | E8 9BA5FEFF | call demo.40208C |
-    // 00417AF1 | E8 722C0700 | call demo.48A768 |
-    _cd_Go_SN.myCall = Call_MyGoSN;
-    _cd_Go_SN.dwBack2Addr = 0x00417AF1;
-    // 004376AB | E8 50A30C00 | call demo.501A00 
-    _cd_Go_SN.dwOriginalAddr = 0x00417AEC;
-    _cd_Go_SN.dwOriginalCallAddr = 0x0040208C;
-
-    _cd_Go_SN.nMyCallDataLen = JMP_DLEN;
-    memset(_cd_Go_SN.szMyCallData, 0x90, CALL_LEN);
-    _cd_Go_SN.szMyCallData[0] = 0xE9; // 汇编硬编码:jmp [4字节地址];
-    *(LPDWORD)(&_cd_Go_SN.szMyCallData[1]) = (DWORD)_cd_Go_SN.myCall - _cd_Go_SN.dwOriginalAddr - JMP_DLEN;
+#pragma region 启动时Initial Communication:需要程序启动时注入;
+	// 00401EB8 | E8 7BCB0C00 | call demo.4CEA38 | # 弹出Messagebox:Initial Communication Failed!
+	_cd_Initial_failed.myCall = Call_MyInitial_Failed;
+	// 00401EBD | FF4D CC | dec dword ptr ss:[ebp-34] |
+	_cd_Initial_failed.dwBack2Addr = 0x00401EBD;
+	// 00401EB8 | E8 7BCB0C00 | call demo.4CEA38 | # 弹出Messagebox:Initial Communication Failed!
+	_cd_Initial_failed.dwOriginalAddr = 0x00401EB8;
+	_cd_Initial_failed.dwOriginalCallAddr = 0x004CEA38;
+
+	_cd_Initial_failed.nMyCallDataLen = JMP_DLEN;
+	memset(_cd_Initial_failed.szMyCallData, 0x90, CALL_LEN);
+	_cd_Initial_failed.szMyCallData[0] = 0xE9; // 汇编硬编码:jmp [4字节地址];
+	*(LPDWORD)(&_cd_Initial_failed.szMyCallData[1]) = (DWORD)_cd_Initial_failed.myCall - _cd_Initial_failed.dwOriginalAddr - JMP_DLEN;
+#pragma endregion
+
+#pragma region Connect按钮劫持
+	//00415ECB | 0F84 6A040000 | je demo.41633B | # 关键跳:如果Connect失败实现跳转
+	_cd_Connect.myCall = Call_MyConnect;
+	// 00415ED1 | 6A 00                  | push 0                                   |
+	_cd_Connect.dwBack2Addr = 0x00415ED1;
+	_cd_Connect.dwOriginalAddr = 0x00415ECB;
+	_cd_Connect.dwOriginalCallAddr = 0x0041633B;	// 此处是JMP,注意注入时不要调用为Call
+
+	_cd_Connect.nMyCallDataLen = JMP_DLEN;
+	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;
+#pragma endregion
+
+
+#pragma region Disconnect按钮劫持
+
+#pragma endregion
+
+
+#pragma region Go按钮劫持
+	// Go 
+	_cd_Go.myCall = Call_MyGo;
+	_cd_Go.dwBack2Addr = 0x004376B0;
+	// 004376AB | E8 50A30C00 | call demo.501A00 
+	_cd_Go.dwOriginalAddr = 0x004376AB;
+	_cd_Go.dwOriginalCallAddr = 0x00501A00;
+
+	_cd_Go.nMyCallDataLen = JMP_DLEN;
+	memset(_cd_Go.szMyCallData, 0x90, CALL_LEN);
+	_cd_Go.szMyCallData[0] = 0xE9; // 汇编硬编码:jmp [4字节地址];
+	*(LPDWORD)(&_cd_Go.szMyCallData[1]) = (DWORD)_cd_Go.myCall - _cd_Go.dwOriginalAddr - JMP_DLEN;
+
+	// Go SN 
+	// 00417AEC | E8 9BA5FEFF | call demo.40208C |
+	// 00417AF1 | E8 722C0700 | call demo.48A768 |
+	_cd_Go_SN.myCall = Call_MyGoSN;
+	_cd_Go_SN.dwBack2Addr = 0x00417AF1;
+	// 004376AB | E8 50A30C00 | call demo.501A00 
+	_cd_Go_SN.dwOriginalAddr = 0x00417AEC;
+	_cd_Go_SN.dwOriginalCallAddr = 0x0040208C;
+
+	_cd_Go_SN.nMyCallDataLen = JMP_DLEN;
+	memset(_cd_Go_SN.szMyCallData, 0x90, CALL_LEN);
+	_cd_Go_SN.szMyCallData[0] = 0xE9; // 汇编硬编码:jmp [4字节地址];
+	*(LPDWORD)(&_cd_Go_SN.szMyCallData[1]) = (DWORD)_cd_Go_SN.myCall - _cd_Go_SN.dwOriginalAddr - JMP_DLEN;
+#pragma endregion
+
 
 }
 
@@ -168,6 +210,21 @@ BOOL RecoveryCall(CALLDATA *pCallData)
     return TRUE;
 }
 
+void MyInitialFailed()
+{
+	MessageBox(NULL, _T("MyInitialFailed"), _T("MyInitialFailed"), MB_OK);
+}
+
+void __declspec(naked) Call_MyInitial_Failed()
+{
+	__asm pushad;
+	MyInitialFailed();
+	__asm popad;
+	// 不执行原call;
+	// __asm call _cd_Initial_failed.dwOriginalCallAddr;
+	__asm jmp _cd_Initial_failed.dwBack2Addr;
+}
+
 void __declspec(naked) Call_MySaveAsOutputData()
 {
     //004AB3FC
@@ -285,39 +342,48 @@ void __declspec(naked) Call_MyGoSN()
     }
 }
 
+BOOL MyConnect()
+{
+	// 读取AL的值; 0表示Connect失败;1表示成功;
+	BYTE AL = LOBYTE(LOWORD(dwEAX));
+	if ( AL == 0 )
+	{
+		MessageBox(NULL, _T("连接失败"), _T("连接提示"), MB_OK);
+		return FALSE;
+	}
+	else
+	{
+		MessageBox(NULL, _T("连接成功"), _T("连接提示"), MB_OK);
+	}
+	return TRUE;
+}
 
 void __declspec(naked) Call_MyConnect()
 {
     // 备份寄存器;
-    __asm{
-        // 保存寄存器;
-        mov dwEAX, EAX;
-        mov dwEBX, EBX;
-        mov dwECX, ECX;
-        mov dwEDX, EDX;
-        mov dwEBP, EBP;
-        mov dwESP, ESP;
-        mov dwESI, ESI;
-        mov dwEDI, EDI;
-    }
-
-
-    MessageBox(NULL, _T("MyGo Function"), _T("MyGo"), MB_OK);
-
-
-    __asm{
-        // 恢复寄存器; 
-        mov EAX, dwEAX;
-        mov EBX, dwEBX;
-        mov ECX, dwECX;
-        mov EDX, dwEDX;
-        mov EBP, dwEBP;
-        mov ESP, dwESP;
-        mov ESI, dwESI;
-        mov EDI, dwEDI;
-        // 最后返回原Call地址下一行;
-        jmp _cd_Go.dwBack2Addr;
-    }
+	__asm mov dwEAX, eax;
+    __asm pushad;
+
+
+    if ( MyConnect() )
+	{
+		__asm{
+			// 恢复寄存器; 
+			popad;
+			// 成功:则继续正常的流程;
+			jmp _cd_Connect.dwBack2Addr;
+		}
+
+	}
+	else
+	{
+		__asm{
+			// 恢复寄存器; 
+			popad;
+			// 失败:JMP到出错处理;
+			jmp _cd_Connect.dwOriginalCallAddr;
+		}
+	}   
 }
 
 void __declspec(naked) Call_MyDisconnect()
@@ -430,4 +496,19 @@ void SetSN(LPCTSTR lpSN)
 void ChangeSDK(int nSDK)   // 0=410SDK, 1=310SDK;
 {
 
+}
+
+void __declspec(naked) Call_Connect()
+{
+	//dwCallAddr = 0x004D5864;//0x004378B0;
+	dwCallAddr = 0x004378B0;
+	__asm {
+		pushad;
+		mov eax,0x02393F78;
+		mov ebx,0x024856CC;
+		mov ecx,0x004AB16C;
+		mov edx,0x024156CC;
+		call dwCallAddr;
+		popad;
+	}
 }

+ 4 - 1
Source/Assist/Assist/Assist.h

@@ -31,8 +31,11 @@ extern CALLDATA _cd_Disconnect;
 extern CALLDATA _cd_CheckFW;
 extern CALLDATA _cd_SaveAsOutputData;
 extern CALLDATA _cd_Go_SN;
+extern CALLDATA _cd_Initial_failed;
 
 
 void InitCallData();
 BOOL HijackedCall(CALLDATA *pCallData);
-BOOL HijackedCall(LPVOID MyCall, LPVOID OriginalCall, BYTE (&szOriginalCallData)[CALL_LEN]);
+BOOL HijackedCall(LPVOID MyCall, LPVOID OriginalCall, BYTE (&szOriginalCallData)[CALL_LEN]);
+
+void Call_Connect();

+ 1 - 0
Source/Assist/Assist/Assist.rc

@@ -62,6 +62,7 @@ BEGIN
     PUSHBUTTON      "È¡Ïû",IDCANCEL,260,161,50,14
     PUSHBUTTON      "SaveAsOutputData",BTN_SAVE_AS_OUTPUT_DATA,19,18,92,14
     PUSHBUTTON      "MyGo",BTN_GO,27,43,50,14
+    PUSHBUTTON      "Call_Connect",BTN_CONNECT,112,44,50,14
 END
 
 

+ 9 - 0
Source/Assist/Assist/dllmain.cpp

@@ -103,6 +103,15 @@ BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
                     }
                 }
                 break;
+			case BTN_CONNECT:
+				{
+					//Call_Connect();
+					if ( HijackedCall(&_cd_Connect) )
+					{
+						MessageBox(hwndDlg, _T("½Ù³ÖConnect Call³É¹¦"), _T("½Ù³Ö"), MB_OK);
+					}
+				}
+				break;
             default:
                 break;
             }                

+ 3 - 2
Source/Assist/Assist/resource.h

@@ -5,8 +5,9 @@
 #define IDD_DIALOG1                     101
 #define IDD_DLG_ASSIST                  101
 #define BTN_SAVE_AS_OUTPUT_DATA         1001
-#define IDC_BUTTON1                     1002
 #define BTN_GO                          1002
+#define IDC_BUTTON1                     1003
+#define BTN_CONNECT                     1003
 
 // Next default values for new objects
 // 
@@ -14,7 +15,7 @@
 #ifndef APSTUDIO_READONLY_SYMBOLS
 #define _APS_NEXT_RESOURCE_VALUE        102
 #define _APS_NEXT_COMMAND_VALUE         40001
-#define _APS_NEXT_CONTROL_VALUE         1003
+#define _APS_NEXT_CONTROL_VALUE         1004
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif

+ 18 - 10
Source/InjectDLL/InjectDLL/Global.cpp

@@ -26,6 +26,8 @@ TCHAR g_szDynamicLibraryPath[MAX_PATH] = _T("");
 // 控制台输出;
 BOOL g_bStdOut = FALSE;
 
+#define TRACE4(sz, p1, p2, p3, p4)  TRACE(_T(sz), p1, p2, p3, p4)
+
 /************************************************************************/
 /*  函数:[1/6/2019 Home];
 /*  描述:;
@@ -1003,11 +1005,14 @@ BOOL CALLBACK EnumChildWindowCallBack(HWND hWnd, LPARAM lParam)
     GetWindowThreadProcessId(hWnd, &dwPid); // 获得找到窗口所属的进程  
     if(dwPid == lpWndData->dwPid) // 判断是否是目标进程的窗口  
     {  
-        TCHAR buf[MAX_PATH];
-        TCHAR szClassName[MAX_PATH] = {0};
-        SendMessage(hWnd, WM_GETTEXT, MAX_PATH, (LPARAM)buf); 
-        GetClassName(hWnd, szClassName, MAX_PATH);
-        TRACE3("B-0x%08X, %s, %s\n", hWnd, szClassName, buf);  // 输出窗口信息  
+        WNDINFO wndInfo;
+		wndInfo.hWnd=hWnd;
+        SendMessage(hWnd, WM_GETTEXT, MAX_PATH, (LPARAM)wndInfo.szWndTitle);  
+        GetClassName(hWnd, wndInfo.szClassName, MAX_PATH);
+		wndInfo.dwCtrlId = ::GetDlgCtrlID(hWnd);
+		lpWndData->AddWnd(wndInfo);
+		// 输出窗口信息  
+		TRACE4("A-0x%08X, %ld, %s, %s\n", hWnd, wndInfo.dwCtrlId, wndInfo.szClassName, wndInfo.szWndTitle);  
         // 此处如果再递归,会导致重复查找2次子窗口;
         //EnumChildWindows(hWnd, EnumChildWindowCallBack, lParam);    // 递归查找子窗口 
         return TRUE;
@@ -1023,11 +1028,14 @@ BOOL CALLBACK EnumWindowCallBack(HWND hWnd, LPARAM lParam)
     GetWindowThreadProcessId(hWnd, &dwPid); // 获得找到窗口所属的进程  
     if(dwPid == lpWndData->dwPid) // 判断是否是目标进程的窗口  
     {  
-        TCHAR buf[MAX_PATH];  
-        TCHAR szClassName[MAX_PATH] = {0};
-        SendMessage(hWnd, WM_GETTEXT, MAX_PATH, (LPARAM)buf);  
-        GetClassName(hWnd, szClassName, MAX_PATH);
-        TRACE3("A-0x%08X, %s, %s\n", hWnd, szClassName, buf);  // 输出窗口信息  
+		WNDINFO wndInfo;
+		wndInfo.hWnd=hWnd;
+        SendMessage(hWnd, WM_GETTEXT, MAX_PATH, (LPARAM)wndInfo.szWndTitle);  
+        GetClassName(hWnd, wndInfo.szClassName, MAX_PATH);
+		wndInfo.dwCtrlId = ::GetDlgCtrlID(hWnd);
+		lpWndData->AddWnd(wndInfo);
+		// 输出窗口信息  
+        TRACE4("A-0x%08X, %ld, %s, %s\n", hWnd, wndInfo.dwCtrlId, wndInfo.szClassName, wndInfo.szWndTitle);  
         EnumChildWindows(hWnd, EnumChildWindowCallBack, lParam);    // 继续查找子窗口  
     }
 

+ 37 - 0
Source/InjectDLL/InjectDLL/Global.h

@@ -26,19 +26,56 @@ typedef struct __PROCINFO__
 typedef struct __WNDINFO__
 {
     HWND    hWnd;
+	DWORD	dwCtrlId;
     TCHAR   szClassName[MAX_PATH];
     TCHAR   szWndTitle[MAX_PATH];
     __WNDINFO__()
     {
+		dwCtrlId = 0;
         memset(szClassName, 0, sizeof(TCHAR)*MAX_PATH);
         memset(szWndTitle, 0, sizeof(TCHAR)*MAX_PATH);
     }
+
+	__WNDINFO__ &operator=(const __WNDINFO__ &that)
+	{
+		if ( this == &that )
+			return *this;
+
+		hWnd = that.hWnd;
+		dwCtrlId = that.dwCtrlId;
+		_stprintf(szWndTitle, _T("%s"), that.szWndTitle);
+		_stprintf(szClassName, _T("%s"), that.szClassName);
+
+		return *this;
+	}
+
 }WNDINFO, *LPWNDINFO;
 
 typedef struct __WNDDATA__
 {
     DWORD   dwPid;
     std::vector<WNDINFO> vtWndInfo;
+
+	void AddWnd(WNDINFO &data)
+	{
+		if (!IsExistWnd(data.hWnd))
+			vtWndInfo.push_back(data);
+	}
+
+	bool IsExistWnd(HWND hWnd)
+	{
+		bool bExist = false;
+		for (std::vector<WNDINFO>::iterator it = vtWndInfo.begin(); it != vtWndInfo.end(); it++ )
+		{
+			if ( it->hWnd == hWnd )
+			{
+				bExist = true;
+				break;
+			}
+		}
+
+		return bExist;
+	}
 }WNDDATA,*LPWNDDATA;
 
 // È«¾Ö±äÁ¿;

+ 12 - 4
Source/InjectDLL/InjectDLL/InjectDLL.rc

@@ -88,14 +88,14 @@ BEGIN
     DEFPUSHBUTTON   "确定",IDOK,113,41,50,14,WS_GROUP
 END
 
-IDD_INJECTDLL_DIALOG DIALOGEX 0, 0, 319, 106
+IDD_INJECTDLL_DIALOG DIALOGEX 0, 0, 319, 187
 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
 EXSTYLE WS_EX_APPWINDOW
 CAPTION "InjectDLL"
 FONT 9, "MS Shell Dlg", 0, 0, 0x1
 BEGIN
-    DEFPUSHBUTTON   "确定",IDOK,209,85,50,14
-    PUSHBUTTON      "取消",IDCANCEL,262,85,50,14
+    DEFPUSHBUTTON   "确定",IDOK,209,166,50,14
+    PUSHBUTTON      "取消",IDCANCEL,262,166,50,14
     LTEXT           "选择要注入的进程 :",IDC_STATIC,10,21,65,8
     COMBOBOX        COMBO_PROCESS,74,19,187,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
     PUSHBUTTON      "注入DLL",BTN_INJECT,74,35,50,14
@@ -103,6 +103,14 @@ BEGIN
     PUSHBUTTON      "刷新",BTN_REFLESH,264,17,46,14
     PUSHBUTTON      "隐藏窗口",BTN_HIDE_WND,181,35,50,14
     PUSHBUTTON      "显示窗口",BTN_SHOW_WND,235,35,50,14
+    PUSHBUTTON      "测试按钮",BTN_TEST,74,55,50,14
+    EDITTEXT        TX_DATA,74,99,103,14,ES_AUTOHSCROLL
+    COMBOBOX        COMBOX_BTN_NAME,127,56,102,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+    LTEXT           "地址:",IDC_STATIC,47,83,22,8
+    EDITTEXT        TX_ID,74,80,40,14,ES_AUTOHSCROLL | ES_NUMBER
+    LTEXT           "赋值:",IDC_STATIC,47,101,22,8
+    PUSHBUTTON      "编辑框赋值",BTN_SETDATA,74,117,50,14
+    CONTROL         "下拉框",CH_DROPLIST,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,130,120,37,10
 END
 
 
@@ -166,7 +174,7 @@ BEGIN
         LEFTMARGIN, 7
         RIGHTMARGIN, 312
         TOPMARGIN, 7
-        BOTTOMMARGIN, 99
+        BOTTOMMARGIN, 180
     END
 END
 #endif    // APSTUDIO_INVOKED

+ 172 - 31
Source/InjectDLL/InjectDLL/InjectDLLDlg.cpp

@@ -11,6 +11,13 @@
 #endif
 
 
+// OGC Tool无序句柄;
+HWND g_hWnd_SN = NULL;
+HWND g_hWnd_SN_Combobox = NULL;
+HWND g_hWnd_Tester = NULL;
+HWND g_hWnd_FWVersion = NULL;
+HWND g_hWnd_Channel = NULL;
+
 // 用于应用程序“关于”菜单项的 CAboutDlg 对话框
 
 class CAboutDlg : public CDialog
@@ -55,8 +62,9 @@ CInjectDLLDlg::CInjectDLLDlg(CWnd* pParent /*=NULL*/)
 
 void CInjectDLLDlg::DoDataExchange(CDataExchange* pDX)
 {
-    CDialog::DoDataExchange(pDX);
-    DDX_Control(pDX, COMBO_PROCESS, m_cbProcess);
+	CDialog::DoDataExchange(pDX);
+	DDX_Control(pDX, COMBO_PROCESS, m_cbProcess);
+	DDX_Control(pDX, COMBOX_BTN_NAME, m_cbBtnName);
 }
 
 BEGIN_MESSAGE_MAP(CInjectDLLDlg, CDialog)
@@ -69,6 +77,8 @@ BEGIN_MESSAGE_MAP(CInjectDLLDlg, CDialog)
     ON_BN_CLICKED(BTN_REFLESH, &CInjectDLLDlg::OnBnClickedReflesh)
     ON_BN_CLICKED(BTN_HIDE_WND, &CInjectDLLDlg::OnBnClickedHideWnd)
     ON_BN_CLICKED(BTN_SHOW_WND, &CInjectDLLDlg::OnBnClickedShowWnd)
+	ON_BN_CLICKED(BTN_TEST, &CInjectDLLDlg::OnBnClickedTest)
+	ON_BN_CLICKED(BTN_SETDATA, &CInjectDLLDlg::OnBnClickedSetdata)
 END_MESSAGE_MAP()
 
 
@@ -197,6 +207,7 @@ void CInjectDLLDlg::InitCommbox()
 {
     m_vtProInfo.clear();
     m_cbProcess.ResetContent();
+	m_wndData.vtWndInfo.clear();
     // 获取全部进程到Commbox;
     FindAllProcess(m_vtProInfo);
 
@@ -210,9 +221,26 @@ void CInjectDLLDlg::InitCommbox()
 #ifdef _DEBUG
         TRACE3("%ld-%s:%p\n", it->dwProId, it->strProName.c_str(), *it);
 #endif
-    }
+	}
+
+	if ( (nIndex = m_cbProcess.SelectString(0, _T("Demo"))) != -1 )
+	{
+		ProInfo *ptr = (ProInfo*)m_cbProcess.GetItemDataPtr(nIndex);
+		if ( ptr )
+		{
+			m_wndData.dwPid = ptr->dwProId;
+			EnumProcessAllWnd(&m_wndData);
+			for (std::vector<WNDINFO>::iterator it = m_wndData.vtWndInfo.begin(); it != m_wndData.vtWndInfo.end(); it++ )
+			{
+				if ( _tcscmp(it->szClassName, _T("TButton")) == 0 )
+				{
+					m_cbBtnName.AddString(it->szWndTitle);
+				}
+			}
+		}
+	}
 
-    m_cbProcess.SelectString(0, _T("Demo"));
+	FetchOGCWnd();
 }
 
 CString CInjectDLLDlg::OpenInectDLL()
@@ -265,23 +293,32 @@ void CInjectDLLDlg::OnBnClickedHideWnd()
         return;
     }
 
-    ProInfo *ptr = (ProInfo*)m_cbProcess.GetItemDataPtr(nCurSel);
-    if ( ptr )
-    {
-        WNDDATA wndData;
-        wndData.dwPid = ptr->dwProId;
-        EnumProcessAllWnd(&wndData);
-        g_hCurrentProWnd = GetProcessMainWnd(ptr->dwProId, _T("Demo"));
-        //g_hCurrentProWnd = GetProcessMainWnd(ptr->dwProId, NULL);
-        if ( g_hCurrentProWnd )
-        {//(TPV 2021/09/29) UHD Series OGC Tool V2.21.1.3
-            // Demo是多窗口程序,Demo是最外层的影子窗口,Spy++无法直接获取;
-            g_hCurrentProWnd2 = GetProcessMainWnd(ptr->dwProId, _T("(TPV 2021/09/29) UHD Series OGC Tool V2.21.1.3"));
-            ::ShowWindow(g_hCurrentProWnd2, SW_HIDE);
-            ::ShowWindow(g_hCurrentProWnd, SW_HIDE);
-            //ShowInTaskbar(g_hCurrentProWnd, FALSE);
-        }
-    }
+	HWND hWnd = NULL;
+	if ( hWnd = FindWindow(_T("TfrmDemo")) )
+		::ShowWindow(hWnd, SW_HIDE);
+
+	if ( hWnd = FindWindow(_T("TApplication")) )
+		::ShowWindow(hWnd, SW_HIDE);
+
+}
+
+HWND CInjectDLLDlg::FindWindow(LPCTSTR lpClassName)
+{
+	HWND hWnd = NULL;
+	if ( lpClassName == NULL || lpClassName[0] == '\0' )
+		return hWnd;
+
+	for (std::vector<WNDINFO>::iterator it = m_wndData.vtWndInfo.begin(); it != m_wndData.vtWndInfo.end(); it++ )
+	{
+		// 返回第一个找到的类名;
+		if ( _tcscmp(lpClassName, it->szClassName) == 0 )
+		{
+			hWnd = it->hWnd;
+			break;
+		}
+	}
+
+	return hWnd;
 }
 
 void CInjectDLLDlg::OnBnClickedShowWnd()
@@ -294,14 +331,118 @@ void CInjectDLLDlg::OnBnClickedShowWnd()
         return;
     }
 
-    ProInfo *ptr = (ProInfo*)m_cbProcess.GetItemDataPtr(nCurSel);
-    if ( ptr )
-    {
-        if ( g_hCurrentProWnd )
-        {
-            ::ShowWindow(g_hCurrentProWnd, SW_SHOW);
-            ::ShowWindow(g_hCurrentProWnd2, SW_SHOW);
-            //ShowInTaskbar(g_hCurrentProWnd, TRUE);
-        }
-    }
+	HWND hWnd = NULL;
+	if ( hWnd = FindWindow(_T("TfrmDemo")) )
+		::ShowWindow(hWnd, SW_SHOW);
+
+	if ( hWnd = FindWindow(_T("TApplication")) )
+		::ShowWindow(hWnd, SW_SHOW);
 }
+
+void CInjectDLLDlg::OnBnClickedTest()
+{
+	TCHAR szBtnName[MAX_PATH] = {0};
+	INT nCurSel = m_cbBtnName.GetCurSel();
+	if ( nCurSel == CB_ERR )
+	{
+		MessageBox(_T("请选择要测试的按钮名称"), _T("提醒"), MB_ICONWARNING);
+		return;
+	}
+
+	m_cbBtnName.GetLBText(nCurSel, szBtnName);
+
+	// TODO: 在此添加控件通知处理程序代码
+	HWND hWnd = NULL;
+	for ( std::vector<WNDINFO>::iterator it = m_wndData.vtWndInfo.begin(); it != m_wndData.vtWndInfo.end(); it++ )
+	{
+		if ( _tcscmp(it->szWndTitle, szBtnName) == 0 )
+		{
+			hWnd = it->hWnd;
+			break;
+		}
+	}
+
+	if ( hWnd )
+	{
+		::PostMessage(hWnd, WM_LBUTTONDOWN, 0, 0);
+		Sleep(20);
+		::PostMessage(hWnd, WM_LBUTTONUP, 0, 0);
+	}
+	else
+	{
+		AfxMessageBox(_T("没有找到控件句柄"));
+	}
+}
+
+void CInjectDLLDlg::OnBnClickedSetdata()
+{
+	// TODO: 在此添加控件通知处理程序代码
+	UINT dwAddr = GetDlgItemInt(TX_ID);
+	TCHAR szData[MAX_PATH] =  {0};
+	GetDlgItemText(TX_DATA, szData, MAX_PATH);
+	BOOL bIsDropList = ((CButton*)GetDlgItem(CH_DROPLIST))->GetCheck();
+
+	if ( dwAddr != -1 )
+	{
+		//WNDINFO &info = m_wndData.vtWndInfo.at(nID);
+	
+		//::SetWindowText(info.hWnd, szData);	// 此方法:设置句柄文本失败;
+		//::SendMessage(info.hWnd, WM_SETTEXT, 0, (LPARAM)&szData);	// 此方法:设置句柄文本成功;
+		if ( bIsDropList )
+			::SendMessage(HWND(dwAddr), CB_SELECTSTRING, 0, (LPARAM)&szData);	// 此方法:设置句柄文本成功;
+		else
+			::SendMessage(HWND(dwAddr), WM_SETTEXT, 0, (LPARAM)&szData);	// 此方法:设置句柄文本成功;
+	}
+}
+
+void CInjectDLLDlg::FetchOGCWnd()
+{
+	// SN Combobox;
+	for(std::vector<WNDINFO>::iterator it = m_wndData.vtWndInfo.begin(); it != m_wndData.vtWndInfo.end(); it++ )
+	{
+		if ( _tcscmp(_T("TfrmDemo"), it->szClassName) == 0 )
+		{
+			g_hWnd_SN_Combobox = (++it)->hWnd;
+			break;
+		}
+	}
+
+	// SN Edit && Tester;
+	for(std::vector<WNDINFO>::iterator it = m_wndData.vtWndInfo.begin(); it != m_wndData.vtWndInfo.end(); it++ )
+	{
+		if ( !_tcscmp(_T("OCC"), it->szWndTitle) &&  !_tcscmp(_T("TCheckBox"), it->szClassName) )
+		{
+			g_hWnd_SN = (--it)->hWnd;
+			g_hWnd_Tester = (--it)->hWnd;
+			break;
+		}
+	}
+
+	// Channel Edit;
+	for(std::vector<WNDINFO>::iterator it = m_wndData.vtWndInfo.begin(); it != m_wndData.vtWndInfo.end(); it++ )
+	{
+		if ( !_tcscmp(_T("Connect CA310"), it->szWndTitle) &&  !_tcscmp(_T("TButton"), it->szClassName) )
+		{
+			g_hWnd_Channel = (--it)->hWnd;
+			break;
+		}
+	}
+
+	// FW Version;
+	for(std::vector<WNDINFO>::iterator it = m_wndData.vtWndInfo.begin(); it != m_wndData.vtWndInfo.end(); it++ )
+	{
+		if ( !_tcscmp(_T("FS2"), it->szWndTitle) &&  !_tcscmp(_T("TCheckBox"), it->szClassName) )
+		{
+			g_hWnd_FWVersion = (--it)->hWnd;
+			break;
+		}
+	}
+
+#ifdef _DEBUG
+	TCHAR szMsg[MAX_PATH] = {0};
+	//_stprintf(szMsg, _T("Channel=%08X, SN=%08X, Combobox=%08X, Tester=%08X, FWVersion=%08X\n"), g_hWnd_Channel, g_hWnd_SN, g_hWnd_SN_Combobox, g_hWnd_Tester, g_hWnd_FWVersion);
+	_stprintf(szMsg, _T("Channel=%ld, SN=%ld, Combobox=%ld, Tester=%ld, FWVersion=%ld\n"), g_hWnd_Channel, g_hWnd_SN, g_hWnd_SN_Combobox, g_hWnd_Tester, g_hWnd_FWVersion);
+	//TRACE(szMsg);
+	WriteTextLog(szMsg);
+#endif
+}

+ 6 - 0
Source/InjectDLL/InjectDLL/InjectDLLDlg.h

@@ -42,4 +42,10 @@ public:
     CComboBox m_cbProcess;
     afx_msg void OnBnClickedHideWnd();
     afx_msg void OnBnClickedShowWnd();
+	afx_msg void OnBnClickedTest();
+	CComboBox m_cbBtnName;
+	WNDDATA m_wndData;
+	afx_msg void OnBnClickedSetdata();
+	HWND FindWindow(LPCTSTR lpClassName);
+	void FetchOGCWnd();
 };

+ 8 - 2
Source/InjectDLL/InjectDLL/resource.h

@@ -12,8 +12,14 @@
 #define BTN_EJECT                       1002
 #define BTN_REFLESH                     1003
 #define BTN_HIDE_WND                    1004
-#define IDC_BUTTON2                     1005
 #define BTN_SHOW_WND                    1005
+#define BTN_TEST                        1006
+#define TX_DATA                         1007
+#define COMBOX_BTN_NAME                 1008
+#define TX_ID                           1009
+#define BTN_SETDATA                     1010
+#define IDC_CHECK1                      1011
+#define CH_DROPLIST                     1011
 
 // Next default values for new objects
 // 
@@ -21,7 +27,7 @@
 #ifndef APSTUDIO_READONLY_SYMBOLS
 #define _APS_NEXT_RESOURCE_VALUE        129
 #define _APS_NEXT_COMMAND_VALUE         32771
-#define _APS_NEXT_CONTROL_VALUE         1005
+#define _APS_NEXT_CONTROL_VALUE         1012
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif