EasyHook遠注簡單監控示例 z


http://www.csdn 123.com/html/itweb/20130827/83559_83558_83544.htm

 

免費開源庫EasyHook(inline hook),下面是下載地址

http://easyhook.codeplex.com/releases/view/24401 把頭文件 lib文件全拷貝在工程文件夾中,把dll拷貝在%system32%中(PS:

64位 應該放在C:\Windows\SysWOW64文件夾中)

 

好的,現在切入正題。

假設我們的工程是要監控Troj.exe的行為。A.exe為監控應用程序,A.exe先遍歷當前進程,若找到Troj.exe則將B.dll遠程線程注入到Troj.exe進程中

PS: XP CreateRemoteThread win7用NT系列函數,如下:

 1 typedef DWORD (WINAPI *PFNTCREATETHREADEX)  
 2     (   
 3     OUT PHANDLE             ThreadHandle,     
 4     ACCESS_MASK             DesiredAccess,    
 5     LPVOID                  ObjectAttributes,     
 6     HANDLE                  ProcessHandle,    
 7     LPTHREAD_START_ROUTINE  lpStartAddress,   
 8     LPVOID                  lpParameter,      
 9     BOOL                    CreateSuspended,      
10     DWORD                   dwStackSize,      
11     DWORD                   dw1,   
12     DWORD                   dw2,   
13     LPVOID                  Unknown   
14     );   
15 
16 BOOL IsVistaOrLater()  
17 {  
18     OSVERSIONINFO osvi;  
19     ZeroMemory(&osvi, sizeof(OSVERSIONINFO));  
20     osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);  
21     GetVersionEx(&osvi);  
22     if( osvi.dwMajorVersion >= 6 )  
23     {
24         return TRUE;  
25     }
26     return FALSE;  
27 }  
28 
29 BOOL MyCreateRemoteThread(HANDLE hProcess, LPTHREAD_START_ROUTINE pThreadProc, LPVOID pRemoteBuf)  
30 {  
31     HANDLE      hThread = NULL;  
32     FARPROC     pFunc = NULL;  
33     if( IsVistaOrLater() )    // Vista, 7, Server2008  
34     {  
35         pFunc = GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtCreateThreadEx");  
36         if( pFunc == NULL )  
37         {  
38             ErrorReport(GetLastError()); 
39         }  
40         ((PFNTCREATETHREADEX)pFunc)(&hThread,  
41             0x1FFFFF,  
42             NULL,  
43             hProcess,  
44             pThreadProc,  
45             pRemoteBuf,  
46             FALSE,  
47             NULL,  
48             NULL,  
49             NULL,  
50             NULL);  
51         if( hThread == NULL )  
52         {  
53             ErrorReport(GetLastError());
54         }  
55     }  
56     else                    // 2000, XP, Server2003  
57     {  
58         hThread = CreateRemoteThread(hProcess,   
59             NULL,   
60             0,   
61             pThreadProc,   
62             pRemoteBuf,   
63             0,   
64             NULL);  
65         if( hThread == NULL )  
66         {  
67             ErrorReport(GetLastError()); 
68         }  
69     }  
70     if( WAIT_FAILED == WaitForSingleObject(hThread, INFINITE) )  
71     {  
72         ErrorReport(GetLastError());
73     }  
74     return TRUE;  
75 }   

注入成功后,DLL和A.exe建立命名管道進行進程間通信。例如,當Troj.exe調用CopyFileW被B.dll攔載時,發送相關數據(簡稱為M結構體)到A.exe文本控件上顯示。

M結構體如下構造:

 1 struct WinExec
 2 {
 3     _In_  CHAR lpCmdLine[0x400];
 4     _In_  UINT uCmdShow;
 5 };
 6 
 7 struct CopyFileW
 8 {
 9     _In_  TCHAR lpExistingFileName[0x400];
10     _In_  TCHAR lpNewFileName[0x400];
11     _In_  BOOL bFailIfExists;
12 };
13 
14 typedef struct _tag_info
15 {
16     DWORD time;
17     DWORD Return;
18     DWORD Info_Type;
19 
20     union{
21         struct WinExec WinExec_;
22         struct CopyFileW CopyFileW_;
23     };
24 
25 }taginfo, *ptaginfo;
26 
27 #define WINEXEC_INFO 1
28 #define COPYFILEW 2

 

 

我的這個實例很基礎,就攔載Winexec函數和CopyFileW函數

請先允許我展示幾個頭文件 

 hook.h

 1 #pragma once
 2 
 3 
 4 #ifndef _M_X64
 5 #pragma comment(lib, "EasyHook32.lib")
 6 #else
 7 #pragma comment(lib, "EasyHook64.lib")
 8 #endif
 9 
10 UINT WINAPI MyWinExec(
11     _In_  LPCSTR lpCmdLine,
12     _In_  UINT uCmdShow
13     );
14 
15 typedef UINT (WINAPI * ptrWinExec)(
16     _In_  LPCSTR lpCmdLine,
17     _In_  UINT uCmdShow
18     );
19 
20 extern ptrWinExec realWinExec;
21 
22 BOOL WINAPI MyCopyFileW(
23     _In_  LPCTSTR lpExistingFileName,
24     _In_  LPCTSTR lpNewFileName,
25     _In_  BOOL bFailIfExists
26     );
27 
28 typedef BOOL (WINAPI *ptrCopyFileW)(
29     _In_  LPCTSTR lpExistingFileName,
30     _In_  LPCTSTR lpNewFileName,
31     _In_  BOOL bFailIfExists
32     );
33 
34 extern ptrCopyFileW realCopyFileW;
hook.h

 

 head.h

 1 #include "easyhook.h"  
 2 #include "Hook.h"
 3 #include <Shlwapi.h>
 4 #include <stdio.h>
 5 
 6 #pragma comment(lib, "Shlwapi.lib")
 7 #pragma comment(lib, "winmm.lib")
 8 
 9 ptrWinExec              realWinExec = NULL; //真實地址
10 ptrCopyFileW            realCopyFileW   = NULL;
11 
12 TRACED_HOOK_HANDLE      hHookWinExec = new HOOK_TRACE_INFO();
13 TRACED_HOOK_HANDLE      hHookCopyFileW   = new HOOK_TRACE_INFO();
14 
15 ULONG                   HookWinExec_ACLEntries[1]   = {0};
16 ULONG                   HookCopyFileW_ACLEntries[1]   = {0};
17 
18 HANDLE                  hNamedPipe;//命名管道句柄
19 
20 DWORD StartTime = 0;//應用程序起始時間
21 
22 #define sizeofpipe 0x800 //管道的大小
23 
24 void CreateNamedPipeInServer();//聲明函數 部分內容非關鍵內容沒有列出來
25 void ErrorReport(DWORD errorid);
head.h

 

DllMain.cpp

 1 #include "Header.h" 
 2 
 3 int PrepareRealApiEntry()  
 4 {  
 5     HMODULE hKernel32 = LoadLibrary(L"Kernel32.dll");  
 6     if (!(realWinExec = (ptrWinExec)GetProcAddress(hKernel32, "WinExec")) ||
 7         !(realCopyFileW = (ptrCopyFileW)GetProcAddress(hKernel32, "CopyFileW")))
 8     {
 9         ErrorReport(GetLastError());
10     }
11     return 0;
12 } 
13 
14 void DoHook()  
15 {  
16      LhInstallHook(realWinExec, MyWinExec, NULL, hHookWinExec);
17      LhSetExclusiveACL(HookWinExec_ACLEntries, 1, hHookWinExec);
18 
19      LhInstallHook(realCopyFileW,  MyCopyFileW, NULL, hHookCopyFileW);
20      LhSetExclusiveACL(HookCopyFileW_ACLEntries, 1, hHookCopyFileW);
21 }  
22 
23 void DoneHook()  
24 {  
25     // this will also invalidate "hHook", because it is a traced handle...  
26     LhUninstallAllHooks();  
27 
28     // this will do nothing because the hook is already removed...  
29 
30     LhUninstallHook(hHookWinExec);
31     LhUninstallHook(hHookCopyFileW);
32 
33     // now we can safely release the traced handle  
34     delete hHookWinExec;
35     hHookWinExec = NULL;
36 
37     delete hHookCopyFileW;
38     hHookCopyFileW = NULL;
39 
40     // even if the hook is removed, we need to wait for memory release  
41     LhWaitForPendingRemovals();  
42 }  
43 
44 BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved  )  
45 {  
46     switch (ul_reason_for_call)  
47     {  
48     case DLL_PROCESS_ATTACH:  
49         {  
50             StartTime = timeGetTime();
51             CreateNamedPipeInServer(); 
52             if (PrepareRealApiEntry() != 0)  
53             {  
54                 return FALSE;  
55             }  
56             DoHook();  
57 
58             break;  
59         }  
60     case DLL_THREAD_ATTACH:  
61         {  
62             break;  
63         }  
64     case DLL_THREAD_DETACH:  
65         {  
66             break;  
67         }  
68 
69     case DLL_PROCESS_DETACH:  
70         {  
71             DoneHook();  
72             break;  
73         }  
74     }  
75     return TRUE;  
76 }

 

hook_fakefunction.cpp

 1 BOOL WINAPI MyCopyFileW( //Mystery of Panda
 2     _In_  LPCTSTR lpExistingFileName,
 3     _In_  LPCTSTR lpNewFileName,
 4     _In_  BOOL bFailIfExists
 5     )
 6 {
 7     //進入真實函數前,跳轉到此處
 8     bool status = false;
 9     status = (realCopyFileW)(lpExistingFileName, lpNewFileName, bFailIfExists);//執行真正的CopyFileW函數
10     ptaginfo tagstruct;//上述M結構體
11     ZeroMemory(tagstruct, sizeof(tagstruct));
12     if (!(tagstruct = (ptaginfo)malloc(sizeof(_tag_info))))
13     {
14         return status;
15     }
16     HANDLE hThread;
17     tagstruct->time = timeGetTime() - StartTime;//填充結構體開始
18     tagstruct->Return = status;
19     tagstruct->Info_Type = COPYFILEW;
20     if (lpExistingFileName != NULL) //檢查參數 在實際調試中發現如果不檢查參數,DLL可能會崩潰
21     {
22         wcscpy(tagstruct->CopyFileW_.lpExistingFileName, lpExistingFileName);
23     }
24     else
25     {
26         free(tagstruct);
27         return status;
28     }
29     tagstruct->CopyFileW_.bFailIfExists = bFailIfExists;
30     if (lpNewFileName != NULL) //檢查參數
31     {
32         wcscpy(tagstruct->CopyFileW_.lpNewFileName, lpNewFileName);
33     }
34     else
35     {
36         free(tagstruct);
37         return status;
38     }
39     //填充結構體完畢
40     hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WritePipe, (ptaginfo)tagstruct, 0, 0);//創建線程發送數據到管道
41     if (hThread)
42     {
43         WaitForSingleObject(hThread, INFINITE);
44         CloseHandle(hThread);
45     }
46     free(tagstruct);
47     return status;
48 } 49 50 UINT WINAPI MyWinExec( 51 _In_ LPCSTR lpCmdLine, 52 _In_ UINT uCmdShow 53 ) 54 { 55 ... 56 }

 

至此,這個簡單監控示例就完成了。

題外話:這只是應用層的最簡單的鈎子,可以輕易的被繞過。如果在應用層上想做的更深一點,例如監控troj.exe的進程創建,可以考慮鈎R3上的NtCreateUserProcess函數,下面是網上逆出來的函數參數

 1 typedef struct _NT_PROC_THREAD_ATTRIBUTE_ENTRY {
 2     ULONG Attribute;    // PROC_THREAD_ATTRIBUTE_XXX,參見MSDN中UpdateProcThreadAttribute的說明
 3     SIZE_T Size;        // Value的大小
 4     ULONG_PTR Value;    // 保存4字節數據(比如一個Handle)或數據指針
 5     ULONG Unknown;      // 總是0,可能是用來返回數據給調用者
 6 } PROC_THREAD_ATTRIBUTE_ENTRY, *PPROC_THREAD_ATTRIBUTE_ENTRY;
 7 
 8 typedef struct _NT_PROC_THREAD_ATTRIBUTE_LIST {
 9     ULONG Length;       // 結構總大小
10     NT_PROC_THREAD_ATTRIBUTE_ENTRY Entry[1];
11 } NT_PROC_THREAD_ATTRIBUTE_LIST, *PNT_PROC_THREAD_ATTRIBUTE_LIST;
12 NTSTATUS NtCreateUserProcess(
13     OUT PHANDLE ProcessHandle,
14     OUT PHANDLE ThreadHandle,
15     IN ACCESS_MASK ProcessDesiredAccess,
16     IN ACCESS_MASK ThreadDesiredAccess,
17     IN POBJECT_ATTRIBUTES ProcessObjectAttributes OPTIONAL,
18     IN POBJECT_ATTRIBUTES ThreadObjectAttributes OPTIONAL,
19     IN ULONG CreateProcessFlags,
20     IN ULONG CreateThreadFlags,
21     IN PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
22     IN PVOID Parameter9,
23     IN PNT_PROC_THREAD_ATTRIBUTE_LIST AttributeList
24 );

不過只能作為統計創建進程數,不能在應用層上得到創建的進程信息(INVALID_HANDLE_VALUE)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM