Jelajahi Sumber

客户端管道实例

sat23 3 tahun lalu
induk
melakukan
43398aa0ba

+ 8 - 0
DLLInjection/RegistryInjection/InjectionDLL/InjectionDLL/InjectionDLL.vcproj

@@ -200,6 +200,10 @@
 				RelativePath=".\InjectionDLL.cpp"
 				>
 			</File>
+			<File
+				RelativePath=".\PipeClient.cpp"
+				>
+			</File>
 			<File
 				RelativePath=".\stdafx.cpp"
 				>
@@ -226,6 +230,10 @@
 			Filter="h;hpp;hxx;hm;inl;inc;xsd"
 			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
 			>
+			<File
+				RelativePath=".\PipeClient.h"
+				>
+			</File>
 			<File
 				RelativePath=".\stdafx.h"
 				>

+ 164 - 0
DLLInjection/RegistryInjection/InjectionDLL/InjectionDLL/PipeClient.cpp

@@ -0,0 +1,164 @@
+#include "StdAfx.h"
+#include "PipeClient.h"
+
+#define BUFSIZE 512
+
+CPipeClient::CPipeClient(LPCTSTR lpPipeName, DWORD dwMode)
+{
+    m_hPipeInst = INVALID_HANDLE_VALUE;
+    m_bClientStop = FALSE;
+    m_dwMode = dwMode;
+    memset(m_szPipeName, 0, MAX_PATH*sizeof(TCHAR));
+    if ( lpPipeName )
+        _stprintf_s(m_szPipeName, _T("%s"), lpPipeName);
+}
+
+CPipeClient::~CPipeClient(void)
+{
+
+}
+
+BOOL CPipeClient::StartWork()
+{
+    if ( !m_bClientStop )
+    {
+        BOOL bRet = TRUE;
+        HANDLE hConnect = CreateThread(NULL, 0, ConnectThread, this, 0, NULL);
+        HANDLE hReadMsg = CreateThread(NULL, 0, ReadMsgThread, this, 0, NULL);
+
+        if ( hConnect == NULL || hReadMsg == NULL )
+            bRet = FALSE;
+
+        if ( hConnect )
+            CloseHandle(hConnect);
+
+        if ( hReadMsg )
+            CloseHandle(hReadMsg);
+
+        return bRet;
+    }
+
+    return TRUE;
+}
+
+DWORD CPipeClient::ConnectThread(LPVOID lpParam)
+{
+    CPipeClient *pInstance = (CPipeClient*)lpParam;
+    if ( !pInstance ) 
+        return 0L;
+
+    while(!pInstance->m_bClientStop)
+    {
+        if ( pInstance->m_hPipeInst != INVALID_HANDLE_VALUE ) {
+            // 1分钟检测;
+            Sleep(600000);
+            OutputDebugString(_T("<Injecter> m_hPipeInst 已存在\n"));
+            continue;
+        }
+
+        // 等待10秒;
+        if ( !WaitNamedPipe(pInstance->m_szPipeName, 100000) )
+        {// 如果管道不存在,会立即返回而不考虑超时值,所以此处仍要Sleep;
+            OutputDebugString(_T("<Injecter> WaitNamedPipe 失败\n"));
+            Sleep(100000);
+            continue;
+        }
+
+        pInstance->m_hPipeInst = CreateFile(
+            pInstance->m_szPipeName,        // pipe name 
+            GENERIC_READ | GENERIC_WRITE,   // read and write access 
+            0,                              // no sharing 
+            NULL,                           // default security attributes
+            OPEN_EXISTING,                  // opens existing pipe 
+            0,                              // default attributes 
+            NULL);                          // no template file 
+
+        // 创建成功,退出;
+        if ( pInstance->m_hPipeInst != INVALID_HANDLE_VALUE ) 
+        {
+            // 管道连接成功,修改管道通信模式:message-read mode. 
+            BOOL fSuccess = SetNamedPipeHandleState( 
+                pInstance->m_hPipeInst,     // pipe handle 
+                &pInstance->m_dwMode,       // new pipe mode 
+                NULL,                       // don't set maximum bytes 
+                NULL);                      // don't set maximum time 
+
+            if (!fSuccess) {
+                _tprintf( TEXT("SetNamedPipeHandleState failed. GLE=%d\n"), GetLastError() ); 
+                CloseHandle(pInstance->m_hPipeInst);
+            }
+        }
+        else
+        {
+            // Exit if an error other than ERROR_PIPE_BUSY occurs. 
+            if ( GetLastError() != ERROR_PIPE_BUSY ) 
+            {
+                _tprintf( TEXT("Could not open pipe. GLE=%d\n"), GetLastError() ); 
+            }
+        }
+    }
+
+    OutputDebugString(_T("<Injecter> ConnectThread 退出\n"));
+
+    return 0;
+}
+
+DWORD CPipeClient::ReadMsgThread(LPVOID lpParam)
+{
+    DWORD cbRead = 0;
+    BOOL bSuccess = FALSE;
+    TCHAR chBuf[BUFSIZE]; 
+    DWORD dwDataIndex = 0;
+    DWORD dwError = 0;
+    
+    CPipeClient *pInstance = (CPipeClient*)lpParam;
+    if ( !pInstance ) 
+        return 0L;
+
+    while(!pInstance->m_bClientStop)
+    {
+        if ( pInstance->m_hPipeInst == INVALID_HANDLE_VALUE ) {
+            Sleep(2000);
+            continue;
+        }
+
+        do 
+        { 
+            bSuccess = ReadFile( 
+                pInstance->m_hPipeInst,     // pipe handle 
+                chBuf,                      // buffer to receive reply 
+                BUFSIZE*sizeof(TCHAR),      // size of buffer 
+                &cbRead,                    // number of bytes read 
+                NULL);                      // not overlapped 
+
+            if ( !bSuccess && (dwError = GetLastError()) != ERROR_MORE_DATA )
+                break; 
+
+            // 追回数据;
+            memcpy(pInstance->m_szReceiveBuff + dwDataIndex, chBuf, cbRead);
+            dwDataIndex += cbRead;
+        } while ( !bSuccess );  // repeat loop if ERROR_MORE_DATA 
+
+        // 清空缓存数据;
+        dwDataIndex = 0;
+        memset(chBuf, 0, BUFSIZE*sizeof(TCHAR));
+       
+        if ( bSuccess )
+        {
+
+        }
+        else
+        {
+            _tprintf( TEXT("ReadFile from pipe failed. GLE=%d\n"), dwError );
+            if ( dwError == ERROR_PIPE_NOT_CONNECTED )
+            {
+                CloseHandle(pInstance->m_hPipeInst);
+                pInstance->m_hPipeInst = INVALID_HANDLE_VALUE;
+            }
+        }
+    }
+
+    OutputDebugString(_T("<Injecter> ReadMsgThread 退出\n"));
+
+    return 0;
+}

+ 28 - 0
DLLInjection/RegistryInjection/InjectionDLL/InjectionDLL/PipeClient.h

@@ -0,0 +1,28 @@
+#pragma once
+
+class CPipeClient
+{
+public:
+    // 客户端只有PIPE_READMODE_BYTE PIPE_READMODE_MESSAGE两种模式;
+    CPipeClient(LPCTSTR lpPipeName, DWORD dwMode=PIPE_READMODE_MESSAGE);
+    ~CPipeClient(void);
+
+private:
+    HANDLE m_hPipeInst;
+    // 客户端状态;
+    BOOL m_bClientStop;
+    // 管道名称;
+    TCHAR m_szPipeName[MAX_PATH];
+    // 管道通信模式;
+    DWORD m_dwMode;
+    // 缓存区;
+    TCHAR m_szWriteBuff[1024];
+    TCHAR m_szReceiveBuff[1024];
+public:
+    BOOL StartWork();
+    void StopWork() { m_bClientStop = TRUE;}
+    // 连续管道服务器线程;
+    static DWORD WINAPI ConnectThread(LPVOID lpParam);
+    // 读取管道消息线程;
+    static DWORD WINAPI ReadMsgThread(LPVOID lpParam);
+};

+ 11 - 29
DLLInjection/RegistryInjection/InjectionDLL/InjectionDLL/dllmain.cpp

@@ -1,5 +1,6 @@
 // dllmain.cpp : 定义 DLL 应用程序的入口点。
 #include "stdafx.h"
+#include "PipeClient.h"
 
 HMODULE g_hModule = NULL;
 HANDLE hThreadProc = NULL;
@@ -14,6 +15,8 @@ TCHAR g_szWindowTitle[MAX_PATH] = {0};
 TCHAR g_szProcessName[MAX_PATH] = {0};
 // 管道名称;
 TCHAR g_szPipeName[MAX_PATH] = {0};
+// 管道实例;
+CPipeClient *g_pPipeClient = NULL;
 
 typedef struct PIPE_MSG
 {
@@ -76,7 +79,7 @@ HWND GetMainWnd()
 DWORD WINAPI WorkThreadProc(LPVOID lParam)
 {
 #ifdef _DEBUG
-	Sleep(20000);
+	Sleep(5000);
 #endif
 	TCHAR szLog[MAX_PATH] = {0};
 	TCHAR szWndTitle[MAXBYTE] = {0};
@@ -104,32 +107,11 @@ DWORD WINAPI WorkThreadProc(LPVOID lParam)
 		// 2、创建后台线程;
 		MessageBox(NULL, szWndTitle, g_szWindowTitle, MB_OK);
 #if 1
-		// 等待连接服务器管道;
-		if ( WaitNamedPipe(g_szPipeName, NMPWAIT_WAIT_FOREVER) )
-		{
-			// 连接成功后,创建客户端管道;
-			if ( (g_hPipe = CreateFile(g_szPipeName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL) ) == INVALID_HANDLE_VALUE )
-			{
-				// 创建失败;
-			}
-			else
-			{
-				DWORD dwWrite = 0;
-				TCHAR szValue[MAX_PATH] = {"test pipe"};
-				if ( WriteFile(g_hPipe, szValue, sizeof(szValue)*sizeof(TCHAR), &dwWrite, NULL ) )
-				{
-					// 写完之后,进行读取;
-				}
-				else
-				{
-					// 写失败;
-				}
-			}
-		}
-		else
-		{
-			// 等待失败;
-		}
+        if ( g_pPipeClient == NULL )
+        {
+            g_pPipeClient = new CPipeClient(g_szPipeName);
+            g_pPipeClient->StartWork();
+        }
 #endif
 	}
 	else
@@ -156,12 +138,12 @@ BOOL APIENTRY DllMain( HMODULE hModule,DWORD  ul_reason_for_call,LPVOID lpReserv
 	_tcscpy_s(g_szCurModulePath, szDrive);
 	_tcscat_s(g_szCurModulePath, szDir);
 	// 设置配置文件;
-	_stprintf_s(g_szConfigFile, _T("%s%s"), g_szCurModulePath, _T("Assit.ini"));
+	_stprintf_s(g_szConfigFile, _T("%s%s"), g_szCurModulePath, _T("Assist.ini"));
 
 	// 读取配置文件;
 	TCHAR szValue[MAX_PATH] = {0};
 	GetPrivateProfileString(_T("Windows"), _T("Title"), _T(""), g_szWindowTitle, MAX_PATH, g_szConfigFile);
-	GetPrivateProfileString(_T("Pipe"), _T("Name"), _T("Assit"), szValue, MAX_PATH, g_szConfigFile);
+	GetPrivateProfileString(_T("Pipe"), _T("Name"), _T("Assist"), szValue, MAX_PATH, g_szConfigFile);
 	_stprintf_s(g_szPipeName, _T("\\\\.\\pipe\\%s"), szValue);
 	GetPrivateProfileString(_T("Process"), _T("Name"), _T("Game.exe"), g_szProcessName, MAX_PATH, g_szConfigFile);
 #endif