DLL注入_攔截技術之Hook方式


后衛大師教你進程注入
首先提一下,由於文章完全是我手寫,所以打不了太多,請包含,由於我已經提供了源代碼,所以我在這里詳細講一下理論,至於想看代碼的下載代碼就可以了。代碼中關於注入的部分做了詳細的注釋。MFC界面部分的注釋沒有寫,(畢竟太膚淺了。)
     好,言歸正傳。
     所謂DLL注入,既把一個DLL文件放到目標進程中。
     下面介紹2種注入方式:
     1.遠程線程注入。
     2.利用hook注入。(可以過卡巴斯基)
由於本文篇幅限制,不寫如何編寫DLL。
一.首先講一下遠程線程注入的方法:
1.假設我們已經寫好了一個DLL文件。
2.設置本進程權限為debug權限,既調試權限,可以打開其他進程。代碼如下:

BOOL SetToken(void)
{
 HANDLE hToken;
 TOKEN_PRIVILEGES Privileges;
 LUID luid;
 OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_READ,&hToken);
 Privileges.PrivilegeCount=1;
 LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&luid);
 Privileges.Privileges[0].Luid=luid;
 Privileges.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
 if(!AdjustTokenPrivileges(hToken,FALSE,&Privileges,NULL,NULL,NULL)!=0)
  return FALSE;
 CloseHandle(hToken);
 return (GetLastError() == ERROR_SUCCESS);
}
3.獲得目標進程的句柄。
OpenProcess(權限類型,是否可被繼承,進程ID)功能:返回目標進程句柄.
4.在遠程進程中分配內存,用來存儲,我們要注入的dll的路徑
VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);

//VirtualAllocEx()函數功能:為制定的進程分配虛擬地址
//參1:要分配的進程句柄
//參2:要分配的虛擬地址的位置,0表示,自動分配位置
//參3:分配的大小
//參4:MEM_COMMIT表示,分配物理內存或者頁面內存,並且初始化內存為0
//參5:存儲選項:PAGE_READWRITE表示可以在頁面內存中 “讀寫”
//返回值:如果分配內存成功,則返回分配內存的地址,如果分配失敗則返回NULL,調用GetLastError()查看錯誤原因

5.在遠程進程中剛才分配的內存處,寫入目標DLL路徑:
WriteProcessMemory(hProcess, pszLibFileRemote,PVOID) pszLibFile, cb, NULL)
//WriteProcessMemory()函數功能:在制定進程中寫入內存
//參1:寫入進程的句柄
//參2:寫入內存的起始地址,必須是已經創建的地址,比如上面用VirtualAllocEx()在進程中創建的內存地址
//參3:寫入內存中的數據內容的緩存
//參4:寫入數據大小
//參5:一個選項,0表示忽視
//返回值: 非0值表示成功, 返回0則表示寫入錯誤。調用GetLastError()查看錯誤原因

6.獲取LoadLibrary()函數地址,因為要用他來動態加載DLL,該函數在kernel32.dll文件中
PROC AdrMyDllDir=(PROC)::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")),"LoadLibraryW");//W代表UNICODE版本,說實話,A代表多字節字符集,本人喜歡UNICODE版本

GetProcAddress()
FARPROC GetProcAddress(HMODULE hModule,LPCWSTR lpProcName); 
//功能:返回指定的DLL輸出函數的函數地址
//參數1:DLL模塊句柄
//參數2:DLL輸出函數的函數名
這個函數的返回值,就是LoadLibraryW的地址了

7.創建遠程線程,既在目標進程中創建一個線程,這里的線程跟普通的線程不同,普通線程有線程處理函數ProcThread()
CreateRemoteThread()
HANDLE CreateRemoteThread(
  HANDLE hProcess,
  LPSECURITY_ATTRIBUTES lpThreadAttributes,
  SIZE_T dwStackSize,
  LPTHREAD_START_ROUTINE lpStartAddress,
  LPVOID lpParameter,
  DWORD dwCreationFlags,
  LPDWORD lpThreadId
);
//函數功能:在制定進程中的虛擬地址中創建一個線程
//參數1:進程句柄,線程被創建在這個進程中
//參數2:安全等級,0表示默認安全等級
//參數3:創建線程的大小,0表示系統自動分配線程實際需要的大小
//參數4:線程起始地址,使用LPTHREAD_START_ROUTINE 定義的線程,並且線程是在遠程進程中已經存在。
//參數5: 給線程函數傳遞的參數
//參數6:創建標志,如果參數是0,則線程創建后立即運行
//參數7:線程ID,如果 ID給0 ,則不返回創建線程的ID

::CreateRemoteThread(hProcess,0,0,(LPTHREAD_START_ROUTINE)AdrMyDllDir,bufRemote,0,0);
這里的AdrMyDllDir存放LoadLibraryW ,也就是說把LoadLibraryW當做線程處理函數,傳入的參數bufRemote存放的是目標DLL文件的地址。


二。下面講解一下如何用hook既鈎子注入DLL文件。
首先給不懂鈎子的人簡單介紹一下原理:所謂hook,既鈎子。hook會在應用程序接到消息之前,攔截應用程序的信息,比如鼠標鍵盤鈎子會攔截一個應用程序的鼠標鍵盤信息。要做盜號木馬?用WH_KEYBOARD類型的hook
1.我們要跨進程使用鈎子,要把hook函數寫在DLL文件中,這是微軟明確規定的。也有其他方法,這里不多敘述
2.在DLL文件中 設置鈎子.
這里需要調用線程ID,threadId,我們會在下面調用DLL的調用端中寫入
hhookGetMsg=::SetWindowsHookEx(WH_GETMESSAGE,GetMessageHookProc,::GetModuleHandle(TEXT("dll.dll")),threadId);
//參數1:鈎子類型
//參數2:鈎子處理函數
//參數3:鈎子所在的模塊
//參數4:鈎子要攔截的線程ID,如果要設置全局鈎子,這里給0。
把這個SetWindowsHookEx()函數寫在一個導出函數中,允許調用dll文件的程序調用
_declspec(dllexport) void SetHook(DWORD threadId)
{
 hhookGetMsg=::SetWindowsHookEx(WH_GETMESSAGE,GetMessageHookProc,::GetModuleHandle(TEXT("dll.dll")),threadId);
}
SetHook()就是本dll的導出函數
3.在鈎子處理函數中寫入功能,當鈎子截取到WM_NULL消息的時候,注入DLL文件。由於WM_NULL消息,是個沒用的消息,應用程序一般不會收到這個消息,除非我們自己發送一個這個消息,所以我們在注入DLL的時候,只要給要注入的應用程序發一個WM_NULL消息,當鈎子截取到WM_NULL的時候就注入鈎子,就可以了。
LRESULT CALLBACK GetMessageHookProc(int nCode,WPARAM wParam,LPARAM lParam)
{
MSG* pMsg=(MSG*)lParam;
if(WM_NULL==pMsg->message)
 ::LoadLibraryW(TEXT("D://MyDLL.dll"));
}
好了,編譯DLL項目,產生DLL文件。

4.編寫調用端,調用鈎子
首先獲取窗口句柄
HWND FindWindow(          LPCTSTR lpClassName,
    LPCTSTR lpWindowName
);
返回窗體句柄。hWnd.
hWnd=FindWindow(0,要注入dll的窗體的名稱(例如:千千靜聽))
利用hWnd,查找窗體線程ID
threadId=GetWindowThreadProcessId(hWnd,0);
好了,我們有了線程ID了,可以調用鈎子了。
SetHook(threadId);
這時鈎子已經加載到目標線程中了。
向目標窗體發送WM_NULL消息
SendMessage(hWnd,WM_NULL,0,0);
鈎子會在目標窗體受到消息前受到WM_NULL消息。由於鈎子處理函數中做了判斷,當受到WM_NULL消息時,加載DLL文件。所以DLL文件就注入到目標線程中了。

你可以把你的DLL文件中寫入許多功能,而且DLL已經被目標程序加載了,也就是說,你的DLL程序已經打入到目標程序內部了,所以現在你可以為所欲為了

 


免責聲明!

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



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