主題: DLL注入詳解
查看單個文章
舊 2005-09-18, 05:28 PM   #3 (permalink)
psac
榮譽會員
 
psac 的頭像
榮譽勳章
UID - 3662
在線等級: 級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時
註冊日期: 2002-12-07
住址: 木柵市立動物園
文章: 17381
現金: 5253 金幣
資產: 33853 金幣
預設

DWORD dwID;
LPVOID pFunc = LoadLibraryA;
HANDLE hThread = CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, (LPVOID)"DLL.dll", 0, &dwID );
  不過結果肯定會讓你大失所望——注入DLL失敗!
  那麼現在讓我們來分析一下失敗的原因吧。我是前說過,在Win32系統下,每個進程都擁有自己的4G虛擬地址空間,各個進程之間都是相互獨立的。在這裡,我們當作參數傳入的字符串"DLL.dll"其實是一個數值,它表示這個字符串位於Virus.exe地址空間之中的地址,而這個地址在傳給Target.exe之後,它指向的東西就失去了有效性。舉個例子來說,譬如A、B兩棟大樓,我住在A樓的401;那麼B樓的401住的是誰我當然不能確定——也就是401這個門牌號在B樓失去了有效性,而且如果我想要入住B樓的話,我就必須請B樓的樓長為我在B樓中安排新的住處(當然這個新的住處是否401也就不一定了
  由此看來,我就需要做這麼一系列略顯繁雜的手續——首先在Target.exe目標進程中分配一段內存空間,然後向這段空間寫入我要加載的DLL名稱,最後再調用CreateRemoteThread。這段代碼就成了這樣:61et0
// 向目標進程地址空間寫入DLL名稱J03Z
DWORD dwSize, dwWritten;
dwSize = lstrlenA( lpszDll ) + 1;YYI)
LPVOID lpBuf = VirtualAllocEx( hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE );
if ( NULL == lpBuf )6\
{
CloseHandle( hProcess );
 // 失敗處理D
}
if ( WriteProcessMemory( hProcess, lpBuf, (LPVOID)lpszDll, dwSize, &dwWritten ) )Hga`+
 // 要寫入字節數與實際寫入字節數不相等,仍屬失敗>[7X{
 if ( dwWritten != dwSize ) -=aFY
  VirtualFreeEx( hProcess, lpBuf, dwSize, MEM_DECOMMIT );5h
  CloseHandle( hProcess );;`PSq
  // 失敗處理
else
 CloseHandle( hProcess );;
 // 失敗處理BP]r[j
// 使目標進程調用LoadLibrary,加載DLLsz
DWORD dwID;/h8'X
LPVOID pFunc = LoadLibraryA;\8(Ou*
HANDLE hThread = CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, lpBuf, 0, &dwID ); T
  需要說的有兩點,一是由於我要在目標進程中為ANSI字符串來分配內存空間,所以這裡凡是和目標進程相關的部分,都明確使用了後綴為「A」的API函數——當然,如果要使用Unicode字符串的話,可以換作後綴是「W」的API;第二,在這裡LoadLibrary的指針我是取的本進程的LoadLibraryA的地址,這是因為LoadLibraryA/LoadLibraryW位於kernel32.dll之中,而Win32下每個應用程序都會把kernel32.dll加載到進程地址空間中一個固定的地址,所以這裡的函數地址在Target.exe中也是有效的。


rt1+b
在調用LoadLibrary完畢之後,我們就可以做收尾工作了:
// 等待LoadLibrary加載完畢7B77b
WaitForSingleObject( hThread, INFINITE );
// 釋放目標進程中申請的空間JLD
VirtualFreeEx( hProcess, lpBuf, dwSize, MEM_DECOMMIT )
CloseHandle( hThread );
CloseHandle( hProcess );
  在此解釋一下WaitForSingleObject一句。由於我們是通過CreateRemoteThread在目標進程中另外開闢了一個LoadLibrary的線程,所以我們必須等待這個線程運行完畢才能夠釋放那段先前申請的內存。[l$DM
  好了,現在你可以嘗試著整理這些代碼並編譯運行。運行Target.exe,然後開啟一個有模塊查看功能的進程查看工具(在這裡我使用我的July)來查看Target.exe的模塊,你會發現在注入DLL之前,Target.exe中並沒有DLL.dll的存在:
  在調用了注入代碼之後,DLL.dll就位於Target.exe的模塊列表之中了:
  矛盾相生Kg
  記得2004年初我將QQ尾巴病毒成功仿真後,有很多網友詢問我如何才能殺毒,不過我都沒有回答——因為當時我研究的重點並非病毒的寄生特性。這一寄生特性直到今天可以說我才仿真完畢,那麼,我就將解毒的方法也一併公開吧。



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

// 使目標進程調用GetModuleHandle,獲得DLL在目標進程中的句柄
DWORD dwHandle, dwID;
LPVOID pFunc = GetModuleHandleA;@DA
HANDLE hThread = CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, lpBuf, 0, &dwID );
// 等待GetModuleHandle運行完畢2
WaitForSingleObject( hThread, INFINITE );
// 獲得GetModuleHandle的返回值S:&7i
GetExitCodeThread( hThread, &dwHandle );
// 釋放目標進程中申請的空間13SFR
VirtualFreeEx( hProcess, lpBuf, dwSize, MEM_DECOMMIT );
CloseHandle( hThread );
// 使目標進程調用FreeLibrary,卸載DLL|lp
pFunc = FreeLibrary;
hThread = CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, (LPVOID)dwHandle, 0, &dwID );
// 等待FreeLibrary卸載完畢9du>
WaitForSingleObject( hThread, INFINITE );,
CloseHandle( hThread );
CloseHandle( hProcess );
  用這個方法可以卸載一個進程中的DLL模塊,當然包括那些非病毒體的DLL。所以,這段代碼還是謹慎使用為好。CfH
  在完成卸載之後,如果沒有別的程序加載這個DLL,你就可以將它刪除了。
看得完的今後必定是HACKER中的HACKER
__________________
http://bbsimg.qianlong.com/upload/01/08/29/68/1082968_1136014649812.gif
psac 目前離線  
送花文章: 3, 收花文章: 1631 篇, 收花: 3205 次