面對眾多的計算機高手,考慮許久,終於還是決定出來獻丑一下,文章內盡量使用最簡潔易懂的詞匯及例子來介紹,希望能夠對一些初學與進階者有所幫助。
關於進程的隱藏,98下的例子數不勝數。WinNT/Win2K下的隱藏方法,西祠的高手shotgun在去年的6月就已經在網上發布出實例《揭開木馬的神秘面紗<四>》 ,我也多次拜讀他的文章,對他的計算機水平及熱心幫助朋友的作風十分敬佩。這裡也可算是對shotgun的文章的補充與深入介紹吧,好了,閒話少說。
在WinNT下"真正隱藏進程"這一說法,可以講是根本不可能實現,只要我們的程序是以進程內核的形式運行,都是不可能逃離CTRL+ALT+DEL的法眼。那麼奇怪了,這豈不是與我們的標題《WinNT & Win2K下實現進程的完全隱藏》相矛盾嗎?是的,實際上應該是:以非進程方式執行目標代碼,而逃避進程查看器的檢查,從而達到"進程隱藏"的目的。
我們這裡用的,是在宿主進程中,以線程的方式執行我們的代碼。實現起來非常簡單。首先,我們先建立一個不執行任何語句的線程
DWORD stdcall ThreadProc(LPVOID *lpVoid){
return 0;
}
然後,將線程代碼拷備至宿主進程所能夠執行的任何地方(即頁面屬性為PAGGE_EXECUTE_READWRITE),如:共享內存影射區、宿主進程內。這裡我們選擇宿主進程,拷備的時侯,我們需要先在宿主進程中使用VirtualAllocEx函數申請一段內存,然後再使用WriteProcessMemory將線程體寫入宿主進程中。
以上工作完成後,我們便可CreateRemoteThread函數激活其執行。下面給出一個完整的例子
//遠程線程執行體
DWORD __stdcall ThreadProc (void *lpPara){
return 0;
}
int main(int argc, char* argv[]){
const DWORD THREADSIZE=1024*4;//暫定線程體大小為4K,實際上沒這麼大,稍後我將會介紹
DWORD byte_write;
//獲得指定進程ID句柄,並設其權限為PROCESS_ALL_ACCESS,992是宿進程的ID號,獲取ID號的方法這裡我就不多講了
HANDLE hWnd = ::OpenProcess (PROCESS_ALL_ACCESS,FALSE,992);
if(!hWnd)return 0;
void *pRemoteThread =::VirtualAllocEx(hWnd,0,THREADSIZE,MEM_COMMIT| MEM_RESERVE,PAGE_EXECUTE_READWRITE);//申請
if(!pRemoteThread)return 0;
if(!::WriteProcessMemory(hWnd,pRemoteThread,&ThreadProc,THREADSIZE,0))//寫入進程
return 0;
//啟動線程
HANDLE hThread = ::CreateRemoteThread (hWnd ,0,0,(DWORD (__stdcall *)(void *))pRemoteThread ,NULL,0,&byte_write);
if(!hThread){ //還有內存分配未釋放
return 0;
}
return 0;
}