国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
DLL的遠(yuǎn)程注入技術(shù)詳解

DLL的遠(yuǎn)程注入技術(shù)詳解 

DLL的遠(yuǎn)程注入技術(shù)是目前Win32病毒廣泛使用的一種技術(shù)。使用這種技術(shù)的病毒體通常位于一個(gè)DLL中,在系統(tǒng)啟動(dòng)的時(shí)候,一個(gè)EXE程序會(huì)將這個(gè)DLL加載至某些系統(tǒng)進(jìn)程(如Explorer.exe)中運(yùn)行。

  這樣一來,普通的進(jìn)程管理器就很難發(fā)現(xiàn)這種病毒了,而且即使發(fā)現(xiàn)了也很難清除,因?yàn)橹灰《炯纳倪M(jìn)程不終止運(yùn)行,那么這個(gè)DLL就不會(huì)在內(nèi)存中卸載,用戶也就無法在資源管理器中刪除這個(gè)DLL文件,真可謂一箭雙雕哉。

  記得2003年QQ尾巴病毒肆虐的時(shí)候,就已經(jīng)有些尾巴病毒的變種在使用這種技術(shù)了。

  到了2004年初,我曾經(jīng)嘗試著仿真了一個(gè)QQ尾巴病毒,但獨(dú)是跳過了DLL的遠(yuǎn)程加載技術(shù)。

  直到最近在學(xué)校論壇上看到了幾位朋友在探討這一技術(shù),便忍不住將這一塵封已久的技術(shù)從我的記憶中揀了出來,以滿足廣大的技術(shù)愛好者們。


  必備知識(shí)

  在閱讀本文之前,你需要了解以下幾個(gè)API函數(shù):

  ·OpenProcess - 用于打開要寄生的目標(biāo)進(jìn)程。

  ·VirtualAllocEx/VirtualFreeEx - 用于在目標(biāo)進(jìn)程中分配/釋放內(nèi)存空間。

  ·WriteProcessMemory - 用于在目標(biāo)進(jìn)程中寫入要加載的DLL名稱。

  ·CreateRemoteThread - 遠(yuǎn)程加載DLL的核心內(nèi)容,用于控制目標(biāo)進(jìn)程調(diào)用API函數(shù)。

  ·LoadLibrary - 目標(biāo)進(jìn)程通過調(diào)用此函數(shù)來加載病毒DLL。

  在此我只給出了簡(jiǎn)要的函數(shù)說明,關(guān)于函數(shù)的詳細(xì)功能和介紹請(qǐng)參閱MSDN。


  示例程序

  我將在以下的篇幅中用一個(gè)簡(jiǎn)單的示例Virus.exe來實(shí)現(xiàn)這一技術(shù)。這個(gè)示例的界面如下圖:

首先運(yùn)行Target.exe,這個(gè)文件是一個(gè)用Win32 Application向?qū)傻摹癏ello, World”程序,
用來作為寄生的目標(biāo)進(jìn)程。

  然后在界面的編輯控件中輸入進(jìn)程的名稱“Target.exe”,單擊“注入DLL”按鈕,
這時(shí)候Virus.exe就會(huì)將當(dāng)前目錄下的DLL.dll注入至Target.exe進(jìn)程中。

  在注入DLL.dll之后,你也可以單擊“卸載DLL”來將已經(jīng)注入的DLL卸載。

  模擬的病毒體DLL.dll

  這是一個(gè)簡(jiǎn)單的Win32 DLL程序,它僅由一個(gè)入口函數(shù)DllMain組成:

BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
{
 switch ( fdwReason )
 {
  case DLL_PROCESS_ATTACH:
  {
   MessageBox( NULL, _T("DLL已進(jìn)入目標(biāo)進(jìn)程。"), _T("信息"), MB_ICONINFORMATION );
  }
  break;
  case DLL_PROCESS_DETACH:
  {
   MessageBox( NULL, _T("DLL已從目標(biāo)進(jìn)程卸載。"), _T("信息"), MB_ICONINFORMATION );
  }
  break;
 }
 return TRUE;
}

  如你所見,這里我在DLL被加載和卸載的時(shí)候調(diào)用了MessageBox,這是用來顯示我的遠(yuǎn)程注入/
卸載工作是否成功完成。而對(duì)于一個(gè)真正的病毒體來說,它往往就是處理DLL_PROCESS_ATTACH事件,在其中加入了啟動(dòng)病毒代碼的部分:

case DLL_PROCESS_ATTACH:
{
 StartVirus();
}
break;
注入!
現(xiàn)在要開始我們的注入工作了。首先,我們需要找到目標(biāo)進(jìn)程:

DWORD FindTarget( LPCTSTR lpszProcess )
{
 DWORD dwRet = 0;
 HANDLE hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
 PROCESSENTRY32 pe32;
 pe32.dwSize = sizeof( PROCESSENTRY32 );
 Process32First( hSnapshot, &pe32 );
 do
 {
  if ( lstrcmpi( pe32.szExeFile, lpszProcess ) == 0 )
  {
   dwRet = pe32.th32ProcessID;
   break;
  }
 } while ( Process32Next( hSnapshot, &pe32 ) );
 CloseHandle( hSnapshot );
 return dwRet;
}

  這里我使用了Tool Help函數(shù)庫(kù),當(dāng)然如果你是NT系統(tǒng)的話,也可以選擇PSAPI函數(shù)庫(kù)。

  這段代碼的目的就是通過給定的進(jìn)程名稱來在當(dāng)前系統(tǒng)中查找相應(yīng)的進(jìn)程,并返回該進(jìn)程的ID。得到進(jìn)程ID后,就可以調(diào)用OpenProcess來打開目標(biāo)進(jìn)程了:

// 打開目標(biāo)進(jìn)程
HANDLE hProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION |
PROCESS_VM_WRITE, FALSE, dwProcessID );

   現(xiàn)在有必要說一下OpenProcess第一個(gè)參數(shù)所指定的三種權(quán)限。在Win32系統(tǒng)下,每個(gè)進(jìn)程都擁有自己的4G虛擬地址空間,各個(gè)進(jìn)程之間都相互 獨(dú)立。如果一個(gè)進(jìn)程需要完成跨進(jìn)程的工作的話,那么它必須擁有目標(biāo)進(jìn)程的相應(yīng)操作權(quán)限。在這里,PROCESS_CREATE_THREAD表示我可以通 過返回的進(jìn)程句柄在該進(jìn)程中創(chuàng)建新的線程,也就是調(diào)用CreateRemoteThread的權(quán)限;同理,PROCESS_VM_OPERATION 則表示在該進(jìn)程中分配/釋放內(nèi)存的權(quán)限,也就是調(diào)用VirtualAllocEx/VirtualFreeEx的權(quán)限;PROCESS_VM_WRITE 表示可以向該進(jìn)程的地址空間寫入數(shù)據(jù),也就是調(diào)用WriteProcessMemory的權(quán)限。

  至此目標(biāo)進(jìn)程已經(jīng)打開,那么我們?cè)撊绾蝸韺LL注入其中呢?在這之前,我請(qǐng)你看一行代碼,是如何在本進(jìn)程內(nèi)顯式加載DLL的:

HMODULE hDll = LoadLibrary( "DLL.dll" );

   那么,如果能控制目標(biāo)進(jìn)程調(diào)用LoadLibrary,不就可以完成DLL的遠(yuǎn)程注入了么?的確是這樣,我們可以通過 CreateRemoteThread將LoadLibrary作為目標(biāo)進(jìn)程的一個(gè)線程來啟動(dòng),這樣就可以完成“控制目標(biāo)進(jìn)程調(diào)用 LoadLibrary”的工作了。到這里,也許你會(huì)想當(dāng)然地寫下類似這樣的代碼:

DWORD dwID;
LPVOID pFunc = LoadLibraryA;
HANDLE hThread = CreateRemoteThread( hProcess, NULL, 0,
(LPTHREAD_START_ROUTINE)pFunc,
(LPVOID)"DLL.dll", 0, &dwID );

  不過結(jié)果肯定會(huì)讓你大失所望——注入DLL失?。?
那 么現(xiàn)在讓我們來分析一下失敗的原因吧。我是前說過,在Win32系統(tǒng)下,每個(gè)進(jìn)程都擁有自己的4G虛擬地址空間,各個(gè)進(jìn)程之間都是相互獨(dú)立的。在這里,我 們當(dāng)作參數(shù)傳入的字符串"DLL.dll"其實(shí)是一個(gè)數(shù)值,它表示這個(gè)字符串位于Virus.exe地址空間之中的地址,而這個(gè)地址在傳給 Target.exe之后,它指向的東西就失去了有效性。舉個(gè)例子來說,譬如A、B兩棟大樓,我住在A樓的401;那么B樓的401住的是誰我當(dāng)然不能確 定——也就是401這個(gè)門牌號(hào)在B樓失去了有效性,而且如果我想要入住B樓的話,我就必須請(qǐng)B樓的樓長(zhǎng)為我在B樓中安排新的住處(當(dāng)然這個(gè)新的住處是否 401也就不一定了)。

  由此看來,我就需要做這么一系列略顯繁雜的手續(xù)——首先在Target.exe目標(biāo)進(jìn)程中分配一段內(nèi)存空間,然后向這段空間寫入我要加載的DLL名稱,最后再調(diào)用CreateRemoteThread。這段代碼就成了這樣:

// 向目標(biāo)進(jìn)程地址空間寫入DLL名稱
DWORD dwSize, dwWritten;
dwSize = lstrlenA( lpszDll ) + 1;
LPVOID lpBuf = VirtualAllocEx( hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE );
if ( NULL == lpBuf )
{
 CloseHandle( hProcess );
 // 失敗處理
}
if ( WriteProcessMemory( hProcess, lpBuf, (LPVOID)lpszDll, dwSize, &dwWritten ) )
{
 // 要寫入字節(jié)數(shù)與實(shí)際寫入字節(jié)數(shù)不相等,仍屬失敗
 if ( dwWritten != dwSize )
 {
  VirtualFreeEx( hProcess, lpBuf, dwSize, MEM_DECOMMIT );
  CloseHandle( hProcess );
  // 失敗處理
 }
}
else
{
 CloseHandle( hProcess );
 // 失敗處理
}
// 使目標(biāo)進(jìn)程調(diào)用LoadLibrary,加載DLL
DWORD dwID;
LPVOID pFunc = LoadLibraryA;
HANDLE hThread = CreateRemoteThread( hProcess, NULL, 0,
(LPTHREAD_START_ROUTINE)pFunc, lpBuf, 0, &dwID );

   需要說的有兩點(diǎn),一是由于我要在目標(biāo)進(jìn)程中為ANSI字符串來分配內(nèi)存空間,所以這里凡是和目標(biāo)進(jìn)程相關(guān)的部分,都明確使用了后綴為“A”的API函數(shù) ——當(dāng)然,如果要使用Unicode字符串的話,可以換作后綴是“W”的API;第二,在這里L(fēng)oadLibrary的指針我是取的本進(jìn)程的 LoadLibraryA的地址,這是因?yàn)長(zhǎng)oadLibraryA/LoadLibraryW位于kernel32.dll之中,而Win32下每個(gè)應(yīng) 用程序都會(huì)把kernel32.dll加載到進(jìn)程地址空間中一個(gè)固定的地址,所以這里的函數(shù)地址在Target.exe中也是有效的。

在調(diào)用LoadLibrary完畢之后,我們就可以做收尾工作了:

// 等待LoadLibrary加載完畢
WaitForSingleObject( hThread, INFINITE );
// 釋放目標(biāo)進(jìn)程中申請(qǐng)的空間
VirtualFreeEx( hProcess, lpBuf, dwSize, MEM_DECOMMIT );
CloseHandle( hThread );
CloseHandle( hProcess );

  在此解釋一下WaitForSingleObject一句。由于我們是通過CreateRemoteThread在目標(biāo)進(jìn)程中另外開辟了一個(gè)LoadLibrary的線程,所以我們必須等待這個(gè)線程運(yùn)行完畢才能夠釋放那段先前申請(qǐng)的內(nèi)存。
  好了,現(xiàn)在你可以嘗試著整理這些代碼并編譯運(yùn)行。運(yùn)行Target.exe,然后開啟一個(gè)有模塊查看功能的進(jìn)程查看工具(在這里我使用我的July)來查看Target.exe的模塊,你會(huì)發(fā)現(xiàn)在注入DLL之前,Target.exe中并沒有DLL.dll的存在:

  在調(diào)用了注入代碼之后,DLL.dll就位于Target.exe的模塊列表之中了:


  矛盾相生

  記得2004年初我將QQ尾巴病毒成功仿真后,有很多網(wǎng)友詢問我如何才能殺毒,不過我都沒有回答——因?yàn)楫?dāng)時(shí)我研究的重點(diǎn)并非病毒的寄生特性。

  這一寄生特性直到今天可以說我才仿真完畢,那么,我就將解毒的方法也一并公開吧。

  和DLL的注入過程類似,只不過在這里使用了兩個(gè)API:GetModuleHandle和FreeLibrary。出于篇幅考慮,我略去了與注入部分相似或相同的代碼:

// 使目標(biāo)進(jìn)程調(diào)用GetModuleHandle,獲得DLL在目標(biāo)進(jìn)程中的句柄
DWORD dwHandle, dwID;
LPVOID pFunc = GetModuleHandleA;
HANDLE hThread = CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)
pFunc, lpBuf, 0, &dwID );
// 等待GetModuleHandle運(yùn)行完畢
WaitForSingleObject( hThread, INFINITE );
// 獲得GetModuleHandle的返回值
GetExitCodeThread( hThread, &dwHandle );
// 釋放目標(biāo)進(jìn)程中申請(qǐng)的空間
VirtualFreeEx( hProcess, lpBuf, dwSize, MEM_DECOMMIT );
CloseHandle( hThread );
// 使目標(biāo)進(jìn)程調(diào)用FreeLibrary,卸載DLL
pFunc = FreeLibrary;
hThread = CreateRemoteThread( hProcess, NULL, 0,
(LPTHREAD_START_ROUTINE)pFunc,
(LPVOID)dwHandle, 0, &dwID );
// 等待FreeLibrary卸載完畢
WaitForSingleObject( hThread, INFINITE );
CloseHandle( hThread );
CloseHandle( hProcess );

  用這個(gè)方法可以卸載一個(gè)進(jìn)程中的DLL模塊,當(dāng)然包括那些非病毒體的DLL。

  所以,這段代碼還是謹(jǐn)慎使用為好。

  在完成卸載之后,如果沒有別的程序加載這個(gè)DLL,你就可以將它刪除了。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
[翻譯]多種DLL注入技術(shù)原理介紹
代碼注入的三種方法
API HOOK完全手冊(cè)
10種常見的進(jìn)程注入技術(shù)的總結(jié)
《windows核心編程系列》十九談?wù)勈褂眠h(yuǎn)程線程來注入DLL。
Dll注入經(jīng)典方法完整版
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服