WinNT下 真正隱藏程序

2021-04-13 04:56:02 字數 4788 閱讀 3649

面對眾多的計算機高手,考慮許久,終於還是決定出來獻醜一下,文章內盡量使用最簡潔易懂的詞彙及例子來介紹,希望能夠對一些初學與高階者有所幫助。   

關於程序的隱藏,98下的例子數不勝數。winnt/win2k下的隱藏方法,西祠的高手shotgun在去年的6月就已經在網上發布出例項《揭開木馬的神秘面紗《四》   ,我也多次拜讀他的文章,對他的計算機水平及熱心幫助朋友的作風十分敬佩。這裡也可算是對shotgun的文章的補充與深入介紹吧,好了,閒話少說。   

在winnt下/"真正隱藏程序/"這一說法,可以講是根本不可能實現,只要我們的程式是以程序核心的形式執行,都是不可能逃離ctrl+alt+del的法眼。那麼奇怪了,這豈不是與我們的標題《winnt   &   win2k下實現程序的完全隱藏》相矛盾嗎?是的,實際上應該是:以非程序方式執行目標**,而逃避程序檢視器的檢查,從而達到/"程序隱藏/"的目的。   

我們這裡用的,是在宿主程序中,以執行緒的方式執行我們的**。實現起來非常簡單。首先,我們先建立乙個不執行任何語句的執行緒   

dword   stdcall   threadproc(lpvoid   *lpvoid)   

然後,將執行緒**拷備至宿主程序所能夠執行的任何地方(即頁面屬性為pagge_execute_readwrite),如:共享記憶體影射區、宿主程序內。這裡我們選擇宿主程序,拷備的時侯,我們需要先在宿主程序中使用virtualallocex函式申請一段記憶體,然後再使用writeproces**emory將執行緒體寫入宿主程序中。   

以上工作完成後,我們便可createremotethread函式啟用其執行。下面給出乙個完整的例子   

//遠端執行緒執行體   

dword   __stdcall   threadproc   (void   *lppara)   

int   main(int   argc,   char*   argv)

return   0;   

}   

到這裡,對於隱藏的方法就算告一段落,相信看過的朋友對這個思路有個非常明確的概念了吧。     

在理解隱藏的方法後,我們著重開始寫執行緒的執行部分了。如下:   

dword   __stdcall   threadproc(void   *lppara)   

編譯執行後,你會發現出現乙個非法操作錯誤,為什麼呢?在我們以段頁式記憶體管理的win2k作業系統中,編譯時會把所有的常量編譯在pe檔案的.data節中,而**段則在.text中,所以,我們拷備到宿主程序中的**是在.text中的**,messagebox(null,(char   *)指標,p,0);所指向的位址是本程序的記憶體虛擬位址。而在宿主程序中是無法訪問的。解決的方法很簡單,按舊照搬的將/"hello/"也拷備到目標程序中,然後再引用。同理,messagebox函式位址編譯時,也是儲存在.import中,寫過win2k病毒的朋友都知道,所有常量與函式入口位址都需在**段定義與得出,我們這裡也與他有點類似。言歸正傳,同樣情況我們也把函式的入口位址一起寫入目標程序中。   

//先定義引數結構   

typedef   struct   _remotepararemotepara;   

//付值   

remotepara   myremotepara;   

::zeromemory(&myremotepara,sizeof(remotepara));   

hinstance   huser32   =   ::loadlibrary   (/"user32.dll/");   

myremotepara.dwmessagebox   =(dword)   ::getprocaddress   (huser32   ,   /"messageboxa/");   

strcat(myremotepara.pmessagebox,/"hello//0/");   

//寫進目標程序   

remotepara   *premotepara   =(remotepara   *)   ::virtualallocex   (hwnd   ,0,sizeof(remotepara),mem_commit,page_readwrite);//注意申請空間時的頁面保護屬性   

if(!premotepara)return   0;   

if(!::writeproces**emory   (hwnd   ,premotepara,&myremotepara,sizeof   myremotepara,0))return   0;   

//啟動進將引數傳遞進入   

handle   hthread   =   ::createremotethread   (hwnd   ,0,0,(dword   (__stdcall   *)(void   *))premotethread   ,premotepara,0,&byte_write);   

if(!hthread)   

好了,就這麼簡單,下在給出乙個彈出乙個messagebox的例項:   

//   

#include   /"stdafx.h/"   

typedef   struct   _remotepararemotepara;   

//遠端執行緒   

dword __stdcall threadproc(remotepara   *lppara)

void   enabledebugpriv();//提公升應用級除錯許可權   

int main(int argc,char* argv)

return   0;   

}   

//提公升許可權   

void   enabledebugpriv(   void   )   

tkp.privilegecount   =   1;   

tkp.privileges[0].luid   =   sedebugnamevalue;   

tkp.privileges[0].attributes   =   se_privilege_enabled;   

if   (   !   adjusttokenprivileges(   htoken,   false,   &tkp,   sizeof   tkp,   null,   null   )   )   

closehandle(   htoken   );   

}   

好了,程式編譯執行後會在程序號為992的程序中建立一線程,彈出hello對話方塊。是不是非常簡單呢!   

這裡有幾個地方需要注意的:   

1、遠端執行緒在宿主程序中申請空間時,空間大小的確定了是我一直無法解決的問題。我曾使用兩個貼近一起的執行緒,以執行緒間的距離大小,並加上引數大小,作為申請空間時,仍然會出現非法操作,如下:   

static   void   startthread   (lpvoid   *lppara)   

static   void   endthread(lpvoid   *lppara)   

然後使用dword   dwlenght   =   (dword)((char   *)&startthread   -   (char   *)&endthread);//得到startthread執行緒**長度,   

dwlenght   +=   sizeof(threadpara);   

2、什麼時侯,什麼引數是需要從外部傳遞進來的呢?我這裡並沒有乙個十分有力的答案,我的理解是:pe檔案中除了.text節以外的所有節,均需使用外部引數傳遞到執行緒中使用,如:.rsrc、.data、rdata等其他的15個節。在我們實際編寫的過程中,初學者並不知道我們的**會編譯在什麼地方,這個時侯,我們可以在執行的時侯alt   +   8(vc中快捷鍵)反編譯過來,一般有lea   eax   p、push   offset   p等取位址語句,這個時侯,我們大都需要以引數傳遞進來。所以,大家在編寫的時侯,一定要注意引數,因為執行緒的執行是在別的程序中,乙個普通許可權的應用程式是無法跨越程序來除錯其他程序的。包括vc,也無法除錯我們的遠端執行緒,熟悉彙編的朋友,可用softice除錯,這需要一定的功底。   

3、許可權,這一點很重要,shotgun在這方面也介紹得很清楚了,網上相關的文章也很多,我就不多說了。文中的enabledebugpriv函式可使本程序在internet、winlogin、lsass等程序中建立執行緒。win2k的程序檢視器無法將其殺除。   

4、程序id獲方法較多,如:enumprocesses、createtoolhelp32snapshot/process32first/process32next、ntquerysysteminformation等函式均可,為減少**,例子中的程序id是直接在程序檢視器中得到的。   

最後,我們再回到shotgun的文章中,這時侯我們因已經非常清楚他的方法中為何會多出乙個dll檔案了。遠端執行緒的執行緒體本身就是loadlibrary函式,即,執行緒的入口位址就是loadlibrary的入口位址,這是系統kernel32.dll中的函式,任何程序都可呼叫。執行緒中使用loadlibrary函式將我們的dll載入到系統空間內,執行緒一執行,我們的dll就開始工作了。執行緒執行結束後,別忘了使用virtualfreeex將其申請的記憶體區釋放。   

兩種方法一比較,很明顯:   

1、在使用dll時,建立十分簡單,也不需要太多的作業系統與記憶體操作知識,並可直接除錯dll檔案。實現起來比較簡單。   

2、直接拷備到程序中的方法稍為複雜一點,一不小心,很容易出現非法操作。當然,也去掉那了個讓人討厭dll檔案。程式執行後,很難找到他的**地,是除了病毒以外的木馬隱藏的首選方法。   

這裡我大量參考了nongmin.cn(農民)程式的原始碼,他的程式對我的幫助非常大。雖然未有謀面,但對他的計算機水平與作為十分的敬佩,並尊從他的作風,以後我所寫的所有非商業軟體或小**,均以原始碼形式出現。這裡寫得有點亂,希望對大家能夠有所幫助,願與所有愛好計算機,從事計算機工作的朋友們共勉。   

Linux程序隱藏問題 顯示隱藏程序

阿里云云監控到有兩台redis伺服器cpu被某程序消耗400 cpu資源 系統檢視top 情況並未找到高消耗程序x7但cpu100 ni netstat 查詢到了一些異常請求,初步判斷出元件被提權入侵了 嘗試查詢異常程序x7關聯的檔案,排查還在 etc hosts發現增加了如下異常對映,檢視相關異常...

win10下c c 隱藏程序

原理 通過將程序註冊為系統服務來隱藏程序 環境 win10 不需要管理員許可權 typedef dword lpregisterserviceprocess dword,dword updatedata true hinstance hdll lpregisterserviceprocess lpr...

linux 隱藏程序 crux實現

本文在不修改ps或top命令的任何 與採用將程序號置0的方法的前提下,實現隱藏程序,本程式在crux 2.2上實現 1 原理 linux中,可以通過 proc檔案系統訪問到許多核心的內部資訊。proc檔案系統最初的設計也是用於方便地訪問程序相關的資訊,因此命名為proc。現在這個檔案系統已用於反映系...