Posted on 2010-02-05 21:15
S.l.e!ep.¢% 閱讀(2497)
評論(0) 編輯 收藏 引用 所屬分類:
RootKit
利用CreateRemoteThread進(jìn)行遠(yuǎn)程代碼注入的技術(shù)在64位機(jī)上可能遇到的問題
?添加時間:2008-11-27?原文發(fā)表:2008-11-27?人氣:188?來源:VC知識庫BLOG
|
零、先看看相關(guān)函數(shù)的原型 :
??? 1.模塊的加載與卸載 HMODULE WINAPI LoadLibraryA(const char* name); HMODULE WINAPI LoadLibraryW(const wchar_t* name); BOOL WINAPI FreeLibrary(HMODULE module); 逆風(fēng)編程精品
??? 2.線程函數(shù)占位符 DWORD WINAPI ThreadFunc(LPVOID param); // windows.h unsigned __stdcall thread_proc(void* param); // process.h
??? 3.獲得線程返回值 BOOL WINAPI GetExitCodeThread(HANDLE thread,LPDWORD result);
一、 利用CreateRemoteThread在遠(yuǎn)程進(jìn)程中加載模塊應(yīng)該是沒有問題的。
LoadLibraryA(const char* ); LoardLibraryW(const wchar_t* ); ThreadFunc(LPVOID ); thread_proc(void* ); 第1個參數(shù)均為指針,位長相同。
所以仍然可以 以模塊加載函數(shù)為線程函數(shù) 以被加載模塊的文件名為線程參數(shù) 啟動遠(yuǎn)程線程 CreateRemoteThread( ... , LoadLibraryA , "injectant.dll" , ...);
當(dāng)然, 這是偽代碼。 該方法能工作還需要取得LoadLibraryA在遠(yuǎn)程進(jìn)程中的地址,和在遠(yuǎn)程進(jìn)程的地址空間中,寫入"injectant.dll"。
二、 利用CreateRemoteThread在遠(yuǎn)程進(jìn)程中卸載模塊也應(yīng)該是沒有問題的。
FreeLibrary(HMODULE ); ThreadFunc(LPVOID ); thread_proc(void* );
指針為了能指向64位的地址空間, 需要64位長。 HMODULE用來表示模塊的基地址, 而地址空間是64位, HMODULE也需要64位。
所以仍然可以 以模塊卸載函數(shù)為線程函數(shù) 以被加載模塊句柄為線程參數(shù) 啟動遠(yuǎn)程線程 CreateRemoteThread( ... , FreeLibrary , hModule , ... );
三、 問題發(fā)生在:
如何取得被遠(yuǎn)程進(jìn)程加載的模塊句柄?
??? 三.1、 線程返回值
線程函數(shù)的原型從返回值類型可以分為2種: DWORD和unsigned
可以說,返回機(jī)器字長, 也就是unsigned是比較合理的。 而依賴于返回DWORD的代碼也不會因?yàn)榉祷仡愋透臑閡nsigned而出問題。 因?yàn)榍罢咝枨蟾伲?后者給于更多。 前者還需要作一次截?cái)啵?來取得32位的DWORD返回值。
線程函數(shù)以DWORD的原因, 可能是在16位機(jī)器上, 如果使用機(jī)器字長作返回值, 取值范圍太少。 所以,線程函數(shù)的返回值, 有可能會改為 uint_least32_t 16位機(jī)器上, 使用2個機(jī)器字長拼裝返回值? 32位 32位機(jī)器上, 使用機(jī)器字長作返回值?????????? ?32位 64位機(jī)器上, 使用機(jī)器字長作返回值??????????? 64位
也就是說, 線程函數(shù)是有可能返回64位的模塊句柄的。 為什么不呢?? 難道要在返回前作沒必要的自行截?cái)嗝矗?br /> ??? 三.2、 取得線程返回值
BOOL GetExitCodeThread(HANDLE thread,LPDWORDresult);
可以將第2個參數(shù)改為指向機(jī)器字長數(shù)據(jù)的指針么?? 也許不能。 因?yàn)楹瘮?shù)要求更多 : result必須是指向機(jī)器字長數(shù)據(jù)的指針, 即result所指的連續(xù)8個字節(jié)都是可寫的。 但調(diào)用者提供更少 : 調(diào)用者很有可能不提供機(jī)器字長, 而只提供指向連續(xù)4個字節(jié)的指針。
想想如下代碼是多么普遍(尤其是喜歡使用windows定義的數(shù)據(jù)類型的同學(xué)) DWORD code = 0; GetExitCodeThread( thread , &code ); GetExitCodeThread絕對不可以寫入8字節(jié)內(nèi)容。
所以, 很有可能無法取得前一步所加載的模塊的句柄, 從而無法卸載。
四、 總結(jié)
在64位機(jī)上, 仍然可以使用該技術(shù)遠(yuǎn)程加載模塊。
但是否可以卸載, 還得看: 1. 64位的線程返回值類型 2. 取得線程返回值的函數(shù)能夠取得多少字節(jié)的返回值。 如果2者都是64位, 該技術(shù)依然可行。 |