當前位置:首頁 » 操作系統 » 全局鉤子源碼

全局鉤子源碼

發布時間: 2022-09-18 11:00:56

❶ 寫出一個匯編語言的框架程序,內容2個段,數據段和代碼段

呵呵,建議你下了解一下殺毒軟體的工作機制。
金山,360,瑞星等殺毒軟體,都是驅動保護的,bat因為比它高層,所以做不到關閉殺毒軟體。否則連批處理都可輕易攻破,那早就有無數病毒泛濫了。只有匯編語言這樣的底層語言才可以,(其實C語言也能做到)。當然,bat也不是不行,可以用bat匯編,叫做ASCIICoding技術,挺難的。2007年以前國內還沒有一個會的(除非會但不說,那我當然就不知道了)。也建議你學習Rootkit Hook技術,可以讀一讀這篇文章。

瘟神的尾行--Rootkit技術發展史
作者:小金
一. 無法驅逐的「助手」
網管小張正在手忙腳亂的尋找他的手工殺毒工具包,因為他在安裝一個網管工具的時候無意中走了神,點擊了「下一步」按鈕後才驚覺安裝程序的界面里一個不引人注目的角落裡寫著「安裝CNNIC網路實名」這一行小字,而且最開頭部分有一個小小的勾。於是著名的「中國網民的得力助手」便理所當然的在他的機器里安了家。
心裡把廠商罵了十八遍的小張終於翻出了他外出修機時最得意的工具IceSword和超級巡警,果然在進程列表和SSDT列表裡發現了紅色警報,小張笑了笑,對付這些一般用戶無法卸載的惡意流氓,自己可謂經驗豐富了,當下便三下五除二的把CNNIC的進程給終結了,SSDT也給恢復了初始狀態,然後小張去刪除注冊表啟動項——突然發出的一個錯誤提示聲音把小張嚇了一跳,再定睛一看,他的笑容凝固了:「刪除項時出錯」。不會吧?小張急忙去刪除CNNIC目錄,結果徹底愣在了那裡,系統彈出的錯誤提示很明確的告訴他,「無法刪除文件,文件可能正在被使用」。怎麼回事?小張一下子沒了頭緒……
達爾文的進化論告訴我們,「物競天擇,適者生存」,同樣,在這安全與入侵的網路世界裡,也在進行著這樣一場選擇的過程……

二. 被AIDS糾纏的互聯網
。。。。。。。。。
。。。。。。。。。。。。。
。。。。。。。。。。。。。。(網路長度限制。。。想看全篇自己搜吧)
三. 結語

雖然到處都在提倡和諧網路的普及,但是,「健康上網」僅僅是指代那些黃賭毒而已嗎?在利益面前,開發者的正義感越發渺小起來,我們的網路世界,是被瘟神緊緊跟隨著的。技術的斗爭越發激烈,但是用戶的電腦知識是不會跟著時代發展而自動填充的,最終,大眾上網的人民成了這一切技術較量的受害者。
這個荒謬的發展方向,何時才能休止呢?

還有這篇:

對大多數的Windows開發者來說,如何在Win32系統中對API函數的調用進行攔截一直是項極富挑戰性的課題,因為這將是對你所掌握的計算機知識較為全面的考驗,尤其是一些在如今使用RAD進行軟體開發時並不常用的知識,這包括了操作系統原理、匯編語言甚至是機器指令(聽上去真是有點恐怖,不過這是事實)。

當前廣泛使用的Windows操作系統中,像Win 9x和Win NT/2K,都提供了一種比較穩健的機制來使得各個進程的內存地址空間之間是相互獨立,也就是說一個進程中的某個有效的內存地址對另一個進程來說是無意義的,這種內存保護措施大大增加了系統的穩定性。不過,這也使得進行系統級的API攔截的工作的難度也大大加大了。

當然,我這里所指的是比較文雅的攔截方式,通過修改可執行文件在內存中的映像中有關代碼,實現對API調用的動態攔截;而不是採用比較暴力的方式,直接對可執行文件的磁碟存儲中機器代碼進行改寫。

二、API鉤子系統一般框架
通常,我們把攔截API的調用的這個過程稱為是安裝一個API鉤子(API Hook)。一個API鉤子基本是由兩個模塊組成:一個是鉤子伺服器(Hook Server)模塊,一般為EXE的形式;一個是鉤子驅動器(Hook Driver)模塊,一般為DLL的形式。

鉤子伺服器主要負責向目標進程注入鉤子驅動器,使得鉤子驅動器運行在目標進程的地址空間中,這是關鍵的第一步,而鉤子驅動器則負責實際的API攔截處理工作,以便在我們所關心的API函數調用的之前或之後能做一些我們所希望的工作。一個比較常見的API鉤子的例子就是一些實時翻譯軟體(像金山詞霸)中必備的的功能:屏幕抓詞。它主要是對一些Win32 API中的GDI函數進行了攔截,獲取它們的輸入參數中的字元串,然後在自己的窗口中顯示出來。

針對上述關於API鉤子的兩個部分,有以下兩點需要我們重點考慮的: 選用何種DLL注入技術,以及採用何種API攔截機制。

三、注入技術的選用
由於在Win32系統中各個進程的地址是互相獨立的,因此我們無法在一個進程中對另一個進程的代碼進行有效的修改,但如果你要完成API鉤子的工作又必須如此。因此,我們必須採取某種獨特的手段,使得API鉤子(准確的說是鉤子驅動器)能夠成為目標進程中的一部分,才有較大的可能來對目標進程數據和代碼進行有控制的修改。

通常可採用的幾種注入方式:

1.利用注冊表
如果我們准備攔截的進程連接了User32.dll,也就是使用了 User32.dll中的API(一般圖形界面的應用程序都是符合這個條件),那麼就可以簡單把你的鉤子驅動器DLL的名字作為值添加在下面注冊表的鍵下: HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Windows\AppInit_DLLs 值的形式可以為單個DLL的文件名,或者是一組DLL的文件名,相鄰的名稱之間用逗號或空格間隔。所有由該值標識的DLL將在符合條件的應用程序啟動的時候裝載。這是一個操作系統內建的機制,相對其他方式來說危險性較小,但它也有一些比較明顯的缺點:該方法僅適用於NT/2K操作系統,顯然看看鍵的名稱就可以明白;如果需要激活或停止鉤子的注入,只有重新啟動Windows,這個就似乎太不方便了;最後一點也很顯然,不能用此方法向沒有使用User32.dll的應用程序注入DLL,例如控制台應用程序等。另外,不管是否為你所希望,鉤子DLL將注入每一個GUI應用程序,這將導致整個系統性能的下降!

2.建立系統范圍的Windows鉤子
要向某個進程注入DLL,一個十分普遍也是比較簡單的方法就是建立在標準的Windows鉤子的基礎上。Windows鉤子一般是在DLL中實現的,這是一個全局性的Windows鉤子的基本要求,這也很符合我們的需要。當我們成功地調用SetWindowsHookEx函數之後,便在系統中安裝了某種類型的消息鉤子,這個鉤子可以是針對某個進程,也可以是針對系統中的所有進程。一旦某個進程中產生了該類型的消息,操作系統會自動把該鉤子所在的DLL映像到該進程的地址空間中,從而使得消息回調函數(在 SetWindowsHookEx的參數中指定)能夠對此消息進行適當的處理,在這里,我們所感興趣的當然不是對消息進行什麼處理,因此在消息回調函數中只需把消息鉤子向後傳遞就可以了,但是我們所需的DLL已經成功地注入了目標進程的地址空間,從而可以完成後續工作。

我們知道,不同的進程之間是不能直接共享數據的,因為它們活動在不同的地址空間中。但在Windows鉤子 DLL中,有一些數據,例如Windows鉤子句柄HHook,這是由SetWindowsHookEx函數返回值得到的,並且作為參數將在 CallNextHookEx函數和UnhookWindoesHookEx函數中使用,顯然使用SetWindowsHookEx函數的進程和使用 CallNextHookEx函數的進程一般不會是同一個進程,因此我們必須能夠使句柄在所有的地址空間中都是有效的有意義的,也就是說,它的值必須必須在這些鉤子DLL所掛鉤的進程之間是共享的。為了達到這個目的,我們就應該把它存儲在一個共享的數據區域中。

在VC++中我們可以採用預編譯指令#pragma data_seg在DLL文件中創建一個新的段,並且在DEF文件中把該段的屬性設置為"shared",這樣就建立了一個共享數據段。對於使用 Delphi的人來說就沒有這么幸運了:沒有類似的比較簡單的方法(或許是有的,但我沒有找到)。不過我們還是可以利用內存映像技術來申請使用一塊各進程可以共享的內存區域,主要是利用了CreateFileMapping和MapViewOfFile這兩個函數,這倒是一個通用的方法,適合所有的開發語言,只要它能直接或間接的使用Windows的API。

在Borland的BCB中有一個指令#pragma codeseg與VC++中的#pragma data_seg指令有點類似,應該也能起到一樣的作用,但我試了一下,沒有沒有效果,而且BCB的聯機幫助中對此也提到的不多,不知怎樣才能正確的使用(或許是另外一個指令,呵呵)。

一旦鉤子DLL載入進入目標進程的地址空間後,在我們調用UnHookWindowsHookEx函數之前是無法使它停止工作的,除非目標進程關閉。

這種DLL注入方式有兩個優點: 這種機制在Win 9x/Me和Win NT/2K中都是得到支持的,預計在以後的版本中也將得到支持;鉤子DLL可以在不需要的時候,可由我們主動的調用 UnHookWindowsHookEx來卸載,比起使用注冊表的機制來說方便了許多。盡管這是一種相當簡潔明了的方法,但它也有一些顯而易見的缺點:首先值得我們注意的是,Windows鉤子將會降低整個系統的性能,因為它額外增加了系統在消息處理方面的時間;其次,只有當目標進程准備接受某種消息時,鉤子所在的DLL才會被系統映射到該進程的地址空間中,鉤子才能真正開始發揮作用,因此如果我們要對某些進程的整個生命周期內的API調用情況進行監控,用這種方法顯然會遺漏某些API的調用 。

3.使用 CreateRemoteThread函數
在我看來這是一個相當棒的方法,然而不幸的是,CreateRemoteThread這個函數只能在Win NT/2K系統中才得到支持,雖然在Win 9x中這個API也能被安全的調用而不出錯,但它除了返回一個空值之外什麼也不做。該注入過程也十分簡單:我們知道,任何一個進程都可以使用 LoadLibrary來動態地載入一個DLL。但問題是,我們如何讓目標進程(可能正在運行中)在我們的控制下來載入我們的鉤子DLL(也就是鉤子驅動器)呢?有一個API函數CreateRemoteThread,通過它可在一個進程中可建立並運行一個遠程的線程--這個好像和注入沒什麼關系嘛?往下看!

調用該API需要指定一個線程函數指針作為參數,該線程函數的原型如下: Function ThreadProc(lpParam: Pointer): DWORD,我們再來看一下LoadLibrary的函數原型: Function LoadLibrary(lpFileName: PChar): HMole。發現了吧!這兩個函數原型幾乎是一樣的(其實返回值是否相同關系不大,因為我們是無法得到遠程線程函數的返回值的),這種類似使得我們可以把直接把LoadLibrary當做線程函數來使用,從而在目標進程中載入鉤子DLL。

與此類似,當我們需要卸載鉤子DLL時,也可以FreeLibrary作為線程函數來使用,在目標進程中卸載鉤子DLL,一切看來是十分的簡潔方便。通過調用GetProcAddress函數,我們可以得到LoadLibrary函數的地址。由於 LoadLibrary是Kernel32中的函數,而這個系統DLL的映射地址對每一個進程來說都是相同的,因此LoadLibrary函數的地址也是如此。這點將確保我們能把該函數的地址作為一個有效的參數傳遞給CreateRemoteThread使用。 FreeLibrary也是一樣的。

AddrOfLoadLibrary := GetProcAddress(GetMoleHandle(『Kernel32.dll'), 『LoadLibrary');

HRemoteThread := CreateRemoteThread(HTargetProcess, nil, 0, AddrOfLoadLibrary, HookDllName, 0, nil);

要使用CreateRemoteThread,我們需要目標進程的句柄作為參數。當我們用 OpenProcess函數來得到進程的句柄時,通常是希望對此進程有全權的存取操作,也就是以PROCESS_ALL_ACCESS為標志打開進程。但對於一些系統級的進程,直接這樣顯然是不行的,只能返回一個的空句柄(值為零)。為此,我們必須把自己設置為擁有調試級的特權,這樣將具有最大的存取許可權,從而使得我們能對這些系統級的進程也可以進行一些必要的操作。

4.通過BHO來注入DLL
有時,我們想要注入DLL的對象僅僅是Internet Explorer,很幸運,Windows操作系統為我們提供了一個簡單的歸檔方法(這保證了它的可靠性!)―― 利用Browser Helper Objects(BHO)。一個BHO是一個在 DLL中實現的COM對象,它主要實現了一個IObjectWithSite介面,而每當IE運行時,它會自動載入所有實現了該介面的COM對象。

四、攔截機制
在鉤子應用的系統級別方面,有兩類API攔截的機制――內核級的攔截和用戶級的攔截。內核級的鉤子主要是通過一個內核模式的驅動程序來實現,顯然它的功能應該最為強大,能捕捉到系統活動的任何細節,但難度也較大,不在本文的探討范圍之內(尤其對我這個使用Delphi的人來說,還沒涉足這塊領域,因此也無法探討,呵呵)。

而用戶級的鉤子則通常是在普通的DLL中實現整個API的攔截工作,這才是此次重點關注的。攔截API函數的調用,一般可有以下幾種方法:

1. 代理DLL(特洛伊木馬
一個容易想到的可行的方法是用一個同名的DLL去替換原先那個輸出我們准備攔截的API所在的DLL。當然代理DLL也要和原來的一樣,輸出所有函數。但如果想到DLL中可能輸出了上百個函數,我們就應該明白這種方法的效率是不高的,估計是要累死人的。另外,我們還不得不考慮DLL的版本問題,很是麻煩。

2.改寫執行代碼
有許多攔截的方法是基於可執行代碼的改寫,其中一個就是改變在CALL指令中使用的函數地址,這種方法有些難度,也比較容易出錯。它的基本思路是檢索出在內存中所有你所要攔截的API的CALL指令,然後把原先的地址改成為你自己提供的函數的地址。

另外一種代碼改寫的方法的實現方法更為復雜,它的主要的實現步驟是先找到原先的API函數的地址,然後把該函數開始的幾個位元組用一個JMP指令代替(有時還不得不改用一個INT指令),從而使得對該API函數的調用能夠轉向我們自己的函數調用。實現這種方法要牽涉到一系列壓棧和出棧這樣的較底層的操作,顯然對我們的匯編語言和操作系統底層方面的知識是一種考驗。這個方法倒和很多文件型病毒的感染機制相類似。

3.以調試器的身份進行攔截
另一個可選的方法是在目標函數中安置一個調試斷點,使得進程運行到此處就進入調試狀態。然而這樣一些問題也隨之而來,其中較主要的是調試異常的產生將把進程中所有的線程都掛起。它也需要一個額外的調試模塊來處理所有的異常,整個進程將一直在調試狀態下運行,直至它運行結束。

4.改寫PE文件的輸入地址表
這種方法主要得益於現如今Windows系統中所使用的可執行文件(包括EXE文件和DLL文件)的良好結構――PE文件格式(Portable Executable File Format),因此它相當穩健,又簡單易行。要理解這種方法是如何運作的,首先你得對PE文件格式有所理解。

一個PE文件的結構大致如下所示:一般PE文件一開始是一段DOS程序,當你的程序在不支持Windows的環境中運行時,它就會顯示"This Program cannot be run in DOS mode"這樣的警告語句;接著這個DOS文件頭,就開始真正的PE文件內容了,首先是一段稱為"IMAGE_NT_HEADER"的數據,其中是許多關於整個PE文件的消息,在這段數據的尾端是一個稱為Data Directory的數據表,通過它能快速定位一些PE文件中段(section)的地址;在這段數據之後,則是一個"IMAGE_SECTION_HEADER"的列表,其中的每一項都詳細描述了後面一個段的相關信息;接著它就是PE文件中最主要的段數據了,執行代碼、數據和資源等等信息就分別存放在這些段中。

在所有的這些段里,有一個被稱為".idata"的段(輸入數據段)值得我們去注意,該段中包含著一些被稱為輸入地址表(IAT,Import Address Table)的數據列表,每個用隱式方式載入的API所在的DLL都有一個IAT與之對應,同時一個API的地址也與IAT中一項相對應。當一個應用程序載入到內存中後,針對每一個API函數調用,相應的產生如下的匯編指令:

JMP DWORD PTR [XXXXXXXX]

如果在VC++中使用了_delcspec(import),那麼相應的指令就成為:

CALL DWORD PTR [XXXXXXXX]。

不管怎樣,上述方括弧中的總是一個地址,指向了輸入地址表中一個項,是一個DWORD,而正是這個 DWORD才是API函數在內存中的真正地址。因此我們要想攔截一個API的調用,只要簡單的把那個DWORD改為我們自己的函數的地址,那麼所有關於這個API的調用將轉到我們自己的函數中去,攔截工作也就宣告順利的成功了。這里要注意的是,自定義的函數的調用約定應該是API的調用約定,也就是 stdcall,而Delphi中默認的調用約定是register,它們在參數的傳遞方法等方面存在著較大的區別。

另外,自定義的函數的參數形式一般來講和原先的API函數是相同的,不過這也不是必須的,而且這樣的話在有些時候也會出現一些問題,我在後面將會提到。因此要攔截API的調用,首先我們就要得到相應的IAT的地址。系統把一個進程模塊載入到內存中,其實就是把 PE文件幾乎是原封不動的映射到進程的地址空間中去,而模塊句柄HMole實際上就是模塊映像在內存中的地址,PE文件中一些數據項的地址,都是相對於這個地址的偏移量,因此被稱為相對虛擬地址(RVA,Relative Virtual Address)。

於是我們就可以從HMole開始,經過一系列的地址偏移而得到IAT的地址。不過我這里有一個簡單的方法,它使用了一個現有的API函數ImageDirectoryEntryToData,它幫助我們在定位IAT時能少走幾步,省得把偏移地址弄錯了,走上彎路。不過純粹使用RVA從HMole開始來定位IAT的地址其實並不麻煩,而且這樣還更有助於我們對PE文件的結構的了解。上面提到的那個API 函數是在DbgHelp.dll中輸出的(這是從Win 2K才開始有的,在這之前是由ImageHlp.dll提供的),有關這個函數的詳細介紹可參見MSDN。

在找到IAT之後,我們只需在其中遍歷,找到我們需要的API地址,然後用我們自己的函數地址去覆蓋它,下面給出一段對應的源碼

procere RedirectApiCall; var ImportDesc:PIMAGE_IMPORT_DESCRIPTOR; FirstThunk:PIMAGE_THUNK_DATA32; sz:DWORD;
begin

//得到一個輸入描述結構列表的首地址,每個DLL都對應一個這樣的結構 ImportDesc:=ImageDirectoryEntryToData(Pointer(HTargetMole), true, IMAGE_DIRECTORY_ENTRY_IMPORT, sz);

while Pointer(ImportDesc.Name)<>nil do
begin //判斷是否是所需的DLL輸入描述

if StrIComp(PChar(DllName),PChar(HTargetMole+ImportDesc.Name))=0 then begin

//得到IAT的首地址
FirstThunk:=PIMAGE_THUNK_DATA32(HTargetMole+ImportDesc.FirstThunk);

while FirstThunk.Func<>nil do
begin

if FirstThunk.Func=OldAddressOfAPI then
begin

//找到了匹配的API地址 ......
//改寫API的地址

break;

end;

Inc(FirstThunk);

end;

end;

Inc(ImportDesc);

end;

end;

最後有一點要指出,如果我們手工執行鉤子DLL的退出目標進程,那麼在退出前應該把函數調用地址改回原先的地址,也就是API的真正地址,因為一旦你的DLL退出了,改寫的新的地址將指向一個毫無意義的內存區域,如果此時目標進程再使用這個函數顯然會出現一個非法操作。

五、替換函數的編寫
前面關鍵的兩步做完了,一個API鉤子基本上也就完成了。不過還有一些相關的東西需要我們研究一番的,包括怎樣做一個替換函數。 下面是一個做替換函數的步驟: 首先,不失一般性,我們先假設有這樣的一個API函數,它的原型如下:

function SomeAPI(param1: Pchar;param2: Integer): DWORD;

接著再建立一個與之有相同參數和返回值的函數類型:

type FuncType= function (param1: Pchar;param2: Integer): DWORD;

然後我們把SomeAPI函數的地址存放在OldAddress指針中。接著我們就可以著手寫替換函數的代碼了:

function DummyFunc(param1: Pchar;param2: Integer): DWORD; begin ......

//做一些調用前的操作

//調用被替換的函數,當然也可以不調用
result := FuncType(OldAddress) (param1 , param2);

//做一些調用後的操作

end;

我們再把這個函數的地址保存到NewAddress中,接著用這地址覆蓋掉原先API的地址。這樣當目標進程調用該API的時候,實際上是調用了我們自己的函數,在其中我們可以做一些操作,然後在調用原先的API函數,結果就像什麼也沒發生過一樣。當然,我們也可以改變輸入參數的值,甚至是屏蔽調這個API函數的調用。

盡管上述方法是可行的,但有一個明顯的不足:這種替換函數的製作方法不具有通用性,只能針對少量的函數。如果只有幾個API要攔截,那麼只需照上述說的重復做幾次就行了。但如果有各種各樣的API要處理,它們的參數個數和類型以及返回值的類型是各不相同的,仍然採用這種方法就太沒效率了。

的確是的,上面給出的只是一個最簡單最容易想到的方法,只是一個替換函數的基本構架。正如我前面所提到的,替換函數的與原先的API函數的參數類型不必相同,一般的我們可以設計一個沒有調用參數也沒有返回值的函數,通過一定的技巧,使它能適應各種各樣的API 函數調用,不過這得要求你對匯編語言有一定的了解。

首先,我們來看一下執行到一個函數體內前的系統堆棧情況(這里函數的調用方式為stdcall),函數的調用參數是按照從右到左的順序壓入堆棧的(堆棧是由高端向低端發展的),同時還壓入了一個函數返回地址。在進入函數之前,ESP正指向返回地址。因此,我們只要從ESP+4開始就可以取得這個函數的調用參數了,每取一個參數遞增4。另外,當從函數中返回時,一般在EAX中存放函數的返回值。

了解了上述知識,我們就可以設計如下的一個比較通用的替換函數,它利用了Delphi的內嵌式匯編語言的特性。

Procere DummyFunc;

asm add esp,4 mov eax,esp//得到第一個參數

mov eax,esp+4//得到第二個參數 ......

//做一些處理,這里要保證esp在這之後恢復原樣

call OldAddress //調用原先的API函數 ......

//做一些其它的事情

end;

當然,這個替換函數還是比較簡單的,你可以在其中調用一些純粹用OP語言寫的函數或過程,去完成一些更復雜的操作(要是都用匯編來完成,那可得把你忙死了),不過應該把這些函數的調用方式統一設置為stdcall方式,這使它們只利用堆棧來傳遞參數,因此你也只需時刻掌握好堆棧的變化情況就行了。如果你直接把上述匯編代碼所對應的機器指令存放在一個位元組數組中,然後把數組的地址當作函數地址來使用,效果是一樣的。

六、後記
做一個API鉤子的確是件不容易的事情,尤其對我這個使用Delphi的人來說,為了解決某個問題,經常在OP、C++和匯編語言的資料中東查西找,在程序調試中還不時的發生一些意想不到的事情,弄的自己是手忙腳亂。不過,好歹總算做出了一個 API鉤子的雛形,還是令自己十分的高興,對計算機系統方面的知識也掌握了不少,受益非淺。當初在寫這篇文章之前,我只是想翻譯一篇從網上Down下來的英文資料(網址為 ,文章名叫"API Hook Revealed",示例源代碼是用VC++寫的,這里不得不佩服老外的水平,文章寫得很有深度,而且每個細節都講的十分詳細)。

❷ 易語言~安裝鍵盤鉤子怎麼使用

易語言哦,不知道怎麼弄呢。按鍵連發的話,Windows有個API叫做keybd_event,你可以在鍵盤鉤子的回調函數中多次模擬按鍵就是了。這里有完整C++鍵盤鉤子的源代碼,實現改鍵的。原理都差不多啦。。
LRESULT CALLBACK LowLevelKeyboardProc( int code, WPARAM wParam, LPARAM lParam) { if(code == HC_ACTION) { PKBDLLHOOKSTRUCT pStruct = (PKBDLLHOOKSTRUCT)lParam; DWORD dwIndex = 0; switch (pStruct->vkCode) { case L'A': case L'a': dwIndex = 0; break; case L'S': case L's': dwIndex = 1; break; case L'D': case L'd': dwIndex = 2; break; case L'W': case L'w': dwIndex = 3; break; default: return CallNextHookEx(g_hHook, code, wParam, lParam); } if (wParam == WM_KEYDOWN) { keybd_event(g_bVK[dwIndex], MapVirtualKey(g_bVK[dwIndex], 0), 0, 0); } else if (wParam == WM_KEYUP) { keybd_event(g_bVK[dwIndex], MapVirtualKey(g_bVK[dwIndex], 0), KEYEVENTF_KEYUP, 0); } return TRUE; } return CallNextHookEx(g_hHook, code, wParam, lParam); }完整的代碼就去這里看吧: http://www.programlife.net/redirect-key-by-hook-keyboard.html

❸ 易語言編寫鍵盤記錄器 源碼 說的詳細點

.程序集
窗口程序集1
.程序集變數
鉤子,
類_鉤子
.子程序
__啟動窗口_創建完畢
模塊注冊
()
.子程序
_按鈕1_被單擊
.局部變數
返回,
邏輯型
返回

鉤子_安裝鍵盤鉤子
(&鍵盤介面,
0)
信息框
(「全局鉤子已經安裝成功!」,
0,
「提示」)
編輯框1.內容

「」
.子程序
鍵盤介面,
邏輯型
.參數
虛擬鍵碼,
整數型
.參數
掃描鍵碼,
整數型
.參數
鍵盤彈起,
邏輯型
.判斷開始
(鍵盤彈起)
.默認

編輯框1.加入文本
(取鍵名
(掃描鍵碼))
.判斷結束
返回
(真)
.子程序
_按鈕2_被單擊
鉤子.卸載所有鉤子
()
.子程序
__啟動窗口_將被銷毀
_啟動窗口.銷毀
()
如果認為不詳細,留下郵箱,我把代碼傳給你

❹ 求易語言鉤子注入dll及home呼出源碼

易語言鉤子DLL注入源碼及源碼說明2010-04-06 13:52[所有要使用到的API]

.版本 2

.DLL命令 LoadLibraryA, 整數型,"kernel32.dll","LoadLibraryA"
.參數 lpLibFileName, 文本型

.DLL命令 SetWindowsHookExA, 整數型, "user32.dll", "SetWindowsHookExA", 公開, SetWindowsHookEx
.參數 鉤子類型, 整數型, , idHook
.參數 回調函數地址, 整數型, , lpfn
.參數 實例句柄, 整數型, , hmod
.參數 線程ID, 整數型, , dwThreadId

.DLL命令 FreeLibrary, 整數型, "kernel32.dll", "FreeLibrary", , 釋放指定的動態鏈接庫,它們早先是用LoadLibrary ;API函數裝載的 非零表示成功,零表示失敗。會設置GetLastError
.參數 庫句柄, 整數型, , hLibMole,要釋放的一個庫句柄,在VB里使用只能用這個函數釋放那些由應用程序明確裝載的DLL。對LoadLibrary的每一次調用都應該有一個對應的FreeLibrary調用;

.DLL命令 UnhookWindowsHookEx, 整數型, "user32.dll", "UnhookWindowsHookEx", , UnhookWindowsHookEx
.參數 鉤子句柄, 整數型, , hHook

.DLL命令 CallNextHookEx, 整數型, "user32.dll", "CallNextHookEx", 公開, CallNextHookEx
.參數 鉤子句柄, 整數型, , hHook
.參數 代碼值, 整數型, , ncode
.參數 附加參數1, 整數型, , wParam
.參數 附加參數2, 整數型, 傳址, lParam

.DLL命令 GetProcAddress, 整數型, "kernel32.dll", "GetProcAddress", , 取進程路徑
.參數 模塊句柄, 整數型, , hMole
.參數 進程名稱, 文本型, , lpProcName

.DLL命令 GetCurrentThreadId, 整數型, "kernel32.dll", "GetCurrentThreadId"

.DLL命令 獲取特別文件夾位置_, 整數型, "shell32.dll", "SHGetSpecialFolderLocation"
.參數 窗口句柄, 整數型, , hwndOwner
.參數 文件夾位置, 整數型, , nFolder
.參數 結構, 項目標識符列表_, 傳址, pIdl

.DLL命令 從列表id取路徑_, 整數型, "shell32.dll", "SHGetPathFromIDListA", , $(b)
.參數 結構指針, 整數型, , pIdl
.參數 路徑, 文本型, 傳址, pszPath

.DLL命令 CallWindowProcA, 整數型, "user32.dll", "CallWindowProcA"
.參數 動態調用代碼, 位元組集, , 一定要用本人編寫的
.參數 子程序, 子程序指針, , 子程序指針
.參數 參數, 整數型, 數組, 為整數數組,參數1為成員1…類推;文本型和位元組集型(自定義結構)為指針
.參數 參數數目, 整數型, , 一定要和參數數組相符,不然會出錯
.參數 是否C調用, 整數型, , 真為cdecl調用方式,假為stdcall調用方式(即標准WINAPI方式)

[這里函數所有代碼和一個自定義類型,API代碼在左邊]

.版本 2

.程序集 程序集1
.程序集變數 臨時呼出熱鍵, 整數型
.程序集變數 臨時載入窗口, 窗口
.程序集變數 鉤子模塊句柄, 整數型, , "1000"
.程序集變數 鉤子句柄, 整數型, , "1000"
.程序集變數 鉤子IDx, 整數型
.程序集變數 x, 整數型
.程序集變數 鉤子句柄1, 整數型
.程序集變數 temp目錄, 文本型
.程序集變數 xxx, 整數型
.程序集變數 熱鍵鉤子句柄, 整數型
.程序集變數 第一次, 邏輯型

.子程序 調用_調用子程序, 整數型, 公開, 呼叫某個函數 可以傳入無限個參數 返回函數返回值
.參數 子程序指針, 子程序指針, , 指定函數
.參數 參數, 整數型, 可空 數組, 指定參數 可以不寫, 參數為數組 格式為 參數[1]=xxx 參數[2]=xxx 文本型或位元組集請用 轉換指針 格式2 加入成員(參數,xxx)
.局部變數 動態調用代碼, 位元組集

動態調用代碼 = { 85, 139, 236, 86, 139, 117, 16, 141, 78, 255, 133, 201, 124, 21, 139, 69, 12, 141, 4, 136, 65, 139, 16, 137, 85, 16, 255, 117, 16, 131, 232, 4, 73, 117, 242, 255, 85, 8, 137, 69, 12, 139, 69, 20, 133, 192, 116, 13, 141, 4, 181, 0, 0, 0, 0, 137, 69, 16, 3, 101, 16, 139, 69, 12, 94, 93, 194, 16, 0 }
返回 (CallWindowProcA (動態調用代碼, 子程序指針, 參數, 取數組成員數 (參數), 0))

.子程序 操作_取特定目錄, 文本型, 公開, 取特定的目錄(返回所要取的指定目錄名 無效返回空)
.參數 欲獲取目錄類型, 整數型, 可空, 0我的桌面 1臨時目錄 5我的文檔 6我的收藏夾 7我的啟動 11我的開始菜單 20系統字體 36Windows安裝目錄 37系統目錄 [99更多]
.局部變數 路徑, 文本型
.局部變數 標示結構, 項目標識符列表_
.局部變數 目錄類型, 整數型

.如果真 (欲獲取目錄類型 = 99)
輸出調試文本 (「0我的桌面 2我的程序 5我的文檔 6我的收藏夾 7我的啟動 8我最近的文檔 9我的發送到 11我的開始菜單 13我的音樂 14我的視頻 16我的桌面 20系統字體 22開始菜單組 23程序組 24啟動組 25桌面 31收藏夾 32我的瀏覽器臨時目錄 33我的Cookies 34我的歷史記錄 36Windows安裝目錄 37系統目錄 38文件安裝目錄 39我的圖片 40用戶目錄 41系統目錄 46文檔 47管理工具 48我的管理工具 53音樂 54圖片 55視頻」)
.如果真結束
.如果 (欲獲取目錄類型 = 1)
目錄類型 = 34
.否則
目錄類型 = 欲獲取目錄類型
.如果結束
獲取特別文件夾位置_ (0, 目錄類型, 標示結構)
路徑 = 取空白文本 (255)
從列表id取路徑_ (標示結構.結構大小, 路徑)
.如果真 (路徑 = 「」)
返回 (「」)
.如果真結束
.如果真 (欲獲取目錄類型 = 1)
路徑 = 子文本替換 (路徑, 「History」, 「Temp」, , , 真)
.如果真結束
返回 (路徑 + 「\」)

.子程序 注入_安裝鉤子DLL, 整數型, 公開, DLL注入 返回0=失敗 整數型 DLL介面(代碼值,參數1,參數2)
.參數 線程ID, 整數型, , -1 全局鉤子
.參數 DLL全名, 文本型, , DLL全名
.參數 DLL介面, 文本型, 可空, 默認 整數型 鉤子介面(代碼值,參數1,參數2)
.局部變數 臨時變數, 整數型
.局部變數 目錄, 文本型
.局部變數 窗口句柄, 整數型

.如果真 (是否為空 (DLL介面) = 真)
DLL介面 = 「鉤子介面」
.如果真結束
.如果真 (線程ID = 0)
返回 (0)
.如果真結束
.如果真 (線程ID = -1)
線程ID = 0
.如果真結束
鉤子IDx = 鉤子IDx + 1
鉤子模塊句柄 [鉤子IDx] = LoadLibraryA (DLL全名)
鉤子句柄 [鉤子IDx] = SetWindowsHookExA (3, GetProcAddress (鉤子模塊句柄 [鉤子IDx], DLL介面), 鉤子模塊句柄 [鉤子IDx], 線程ID)
目錄 = 操作_取特定目錄 (1)
寫配置項 (目錄 + 「ada.ini」, 「ada」, 「鉤子句柄」, 到文本 (鉤子句柄 [鉤子IDx]))
輸出調試文本 (鉤子IDx, 鉤子模塊句柄 [鉤子IDx], 鉤子句柄 [鉤子IDx])
返回 (鉤子IDx)

.版本 2

.子程序 注入_卸載鉤子DLL, 邏輯型, 公開
.參數 鉤子ID, 整數型, 可空, 卸載所有時無效
.參數 卸載所有, 邏輯型, 可空
.局部變數 xx, 整數型

.如果真 (卸載所有)
.如果真 (鉤子IDx > 0)
.計次循環首 (鉤子IDx, xx)
.如果真 (鉤子模塊句柄 [xx] ≠ 0)
FreeLibrary (鉤子模塊句柄 [xx])
UnhookWindowsHookEx (鉤子句柄 [xx])
.如果真結束

.計次循環尾 ()
.如果真結束
返回 (真)
.如果真結束
.如果真 (鉤子ID > 0)
.如果真 (鉤子模塊句柄 [鉤子ID] ≠ 0)
FreeLibrary (鉤子模塊句柄 [鉤子ID])
UnhookWindowsHookEx (鉤子句柄 [鉤子ID])
返回 (真)
.如果真結束

.如果真結束
返回 (假)

.子程序 注入_初始化鉤子DLL, 整數型, 公開, DLL用.
.參數 代碼值, 整數型
.參數 參數1, 整數型
.參數 參數2, 整數型
.參數 初始, 子程序指針
.局部變數 xxxx, 整數型

.如果真 (鉤子句柄1 = 0)
temp目錄 =操作_取特定目錄 (1)
鉤子句柄1 = 到整數 (讀配置項 (temp目錄 + 「ada.ini」, 「ada」, 「鉤子句柄」, ))
.如果真結束
.如果真 (第一次 = 假)
第一次 = 真
調用_調用子程序 (初始)
.如果真結束
返回 (CallNextHookEx (鉤子句柄1, 代碼值, 參數1, 參數2))

.子程序 注入_設置呼出窗口, 邏輯型, 公開
.參數 設置熱鍵, 整數型
.參數 呼出窗口, 窗口

臨時呼出熱鍵 = 設置熱鍵
臨時載入窗口 = 呼出窗口
熱鍵鉤子句柄 = SetWindowsHookExA (2, 到整數 (&呼出鍵介面), 0, GetCurrentThreadId ())
.如果真 (熱鍵鉤子句柄 > 0)
返回 (真)
.如果真結束
返回 (假)

.子程序 呼出鍵介面, 整數型
.參數 一, 整數型
.參數 二, 整數型
.參數 三, 整數型

.如果真 (一 = 0 且 二 = 臨時呼出熱鍵 且 三 > 0)
.如果 (是否已創建 (臨時載入窗口))
.如果 (臨時載入窗口.可視)
臨時載入窗口.可視= 假
.否則
臨時載入窗口.可視= 真
.如果結束

.否則
載入 (臨時載入窗口, , 假)
臨時載入窗口.Esc鍵關閉= 假
臨時載入窗口.最小化按鈕= 真
.如果結束

.如果真結束
返回 (CallNextHookEx (熱鍵鉤子句柄, 一, 二, 三))

.版本 2

.數據類型 項目標識符列表_, , ITEMIDLIST
.成員 結構大小, 整數型, , , cb
.成員 標識符長度, 位元組型, , "255", abID

此函數是用來調用指針函數的.就是CALL

取目錄用這個我就不解釋了
下面是源碼主要函數
函數解釋:

本函數參數1為要HOOK的線程ID,參數2為要注入的DLL名,參數3[可空]為DLL介面名字空則為"鉤子介面".
下面解釋是如何實現的:

1.首先使用LoadLibraryA獲取DLL模塊地址.
2.然後設置SetWindowsHookExA

參數一為HOOK類型,使用WH_GETMESSAGE(3) Hook來監視從GetMessage or PeekMessage函數返回息。

參數二為介面地址,就是說把消息返回轉接到的位置,當然我們這里所使用的是我們DLL所公開的那個函數

參數三為介面模塊的句柄即DLL的句柄(地址)

參數四為將要被HOOK的線程ID(0為全局HOOK,不推薦使用全局HOOK)

3.設置完後將鉤子句柄寫配置項到臨時目錄(後面將要使用).

說白了其實這個才是真正的介面(DLL里的介面只是在做轉接而已),

我先講這個函數是如何實現的(上面已經說了這才是真正的介面).

1,鉤子句柄是一個程序集變數,先判斷這個變數是否為0,如果等於0那麼就是說這個函數第一次被使用,

第一次使用將讀去上個函數寫在臨時目錄的鉤子句柄.

2.用一個邏輯變數(程序集變數或全局變數),來判斷這個消息鉤子是否第一次運行(為了防止後面調用

子程序被多次調用),是的話調用一個子程序(自己設置)

3.使用CallNextHookEx(呼叫下一個鉤子)把當前HOOK的信息在傳送回被HOOK的鉤子里,那個鉤子我們

就不用管了.

下來說下到底如何使用

首先在你的EXE程序里寫這個(我就不多說這是干嗎的了).

然後在DLL里寫上這個代碼(有人可能覺得眼熟,好像在什麼地方見過,對了這個代碼和

外掛作坊的鉤子注入差不多)

下來說明下按鍵呼出窗口的函數

用變數把當前參數存起來(主要方便介面調用)

1.為當前運行線程設置一個鍵盤鉤子

2.[介面]設置按鍵判斷,如果按下我們設置的鍵將呼出窗口,如果這個窗口沒創建將判斷創建,

如果已經創建再次按下則會隱藏,

載入後的窗口把用ESC關閉的屬性弄成假,不需要ESC關閉

3.最後就是再呼叫下以前的鉤子.

最後就是卸載鉤子DLL了.

判斷是否要卸載全部的鉤子,如果是就循環將現有鉤子DLL全部卸載.

不是就按著ID來卸載

卸載方法:

1.FreeLibrary就是卸載一個載入的DLL

2.UnhookWindowsHookEx乃是卸載這個HOOK

-.-OK了這就是 鉤子DLL注入,謝謝大家閱讀,如果看不明白,

❺ 頑固木馬

dll木馬的查殺前言 後門!相信這個詞語對您來說一定不會陌生,它的危害不然而欲,但隨著人們的安全意識逐步增強,又加上殺毒軟體的「大力支持」,使傳統的後門無法在隱藏自己,任何稍微有點計算機知識的人,都知道「查埠」「看進程」,以便發現一些「蛛絲馬跡」。所以,後門的編寫者及時調整了思路,把目光放到了動態鏈接程序庫上,也就是說,把後門做成DLL文件,然後由某一個EXE做為載體,或者使用Rundll32.exe來啟動,這樣就不會有進程,不開埠等特點,也就實現了進程、埠的隱藏。本文以「DLL的原理」「DLL的清除」「DLL的防範」為主題,並展開論述,旨在能讓大家對DLL後門「快速上手」,不在恐懼DLL後門。好了,進入我們的主題。 一,DLL的原理 1,動態鏈接程序庫 動態鏈接程序庫,全稱:Dynamic Link Library,簡稱:DLL,作用在於為應用程序提供擴展功能。應用程序想要調用DLL文件,需要跟其進行「動態鏈接」;從編程的角度,應用程序需要知道DLL文件導出的API函數方可調用。由此可見,DLL文件本身並不可以運行,需要應用程序調用。正因為DLL文件運行時必須插入到應用程序的內存模塊當中,這就說明了:DLL文件無法刪除。這是由於Windows內部機製造成的:正在運行的程序不能關閉。所以,DLL後門由此而生! 2,DLL後門原理及特點 把一個實現了後門功能的代碼寫成一個DLL文件,然後插入到一個EXE文件當中,使其可以執行,這樣就不需要佔用進程,也就沒有相對應的PID號,也就可以在任務管理器中隱藏。DLL文件本身和EXE文件相差不大,但必須使用程序(EXE)調用才能執行DLL文件。DLL文件的執行,需要EXE文件載入,但EXE想要載入DLL文件,需要知道一個DLL文件的入口函數(既DLL文件的導出函數),所以,根據DLL文件的編寫標准:EXE必須執行DLL文件中的DLLMain()作為載入的條件(如同EXE的mian())。做DLL後門基本分為兩種:1)把所有功能都在DLL文件中實現;2)把DLL做成一個啟動文件,在需要的時候啟動一個普通的EXE後門。 常見的編寫方法: (1),只有一個DLL文件 這類後門很簡單,只把自己做成一個DLL文件,在注冊表Run鍵值或其他可以被系統自動載入的地方,使用Rundll32.exe來自動啟動。Rundll32.exe是什麼?顧名思意,「執行32位的DLL文件」。它的作用是執行DLL文件中的內部函數,這樣在進程當中,只會有Rundll32.exe,而不會有DLL後門的進程,這樣,就實現了進程上的隱藏。如果看到系統中有多個Rundll32.exe,不必驚慌,這證明用Rundll32.exe啟動了多少個的DLL文件。當然,這些Rundll32.exe執行的DLL文件是什麼,我們都可以從系統自動載入的地方找到。 現在,我來介紹一下Rundll32.exe這個文件,意思上邊已經說過,功能就是以命令行的方式調用動態鏈接程序庫。系統中還有一個Rundll.exe文件,他的意思是「執行16位的DLL文件」,這里要注意一下。在來看看Rundll32.exe使用的函數原型: Void CALLBACK FunctionName ( HWND hwnd, HINSTANCE hinst, LPTSTR lpCmdLine, Int nCmdShow ); 其命令行下的使用方法為:Rundll32.exe DLLname,Functionname [Arguments] DLLname為需要執行的DLL文件名;Functionname為前邊需要執行的DLL文件的具體引出函數;[Arguments]為引出函數的具體參數。 (2),替換系統中的DLL文件 這類後門就比上邊的先進了一些,它把實現了後門功能的代碼做成一個和系統匹配的DLL文件,並把原來的DLL文件改名。遇到應用程序請求原來的DLL文件時, DLL後門就啟一個轉發的作用,把「參數」傳遞給原來的DLL文件;如果遇到特殊的請求時(比如客戶端),DLL後門就開始,啟動並運行了。對於這類後門,把所有操作都在DLL文件中實現最為安全,但需要的編程知識也非常多,也非常不容易編寫。所以,這類後門一般都是把DLL文件做成一個「啟動」文件,在遇到特殊的情況下(比如客戶端的請求),就啟動一個普通的EXE後門;在客戶端結束連接之後,把EXE後門停止,然後DLL文件進入「休息」狀態,在下次客戶端連接之前,都不會啟動。但隨著微軟的「數字簽名」和「文件恢復」的功能出台,這種後門已經逐步衰落。 提示: 在WINNTsystem32目錄下,有一個dllcache文件夾,里邊存放著眾多DLL文件(也包括一些重要的EXE文件),在DLL文件被非法修改之後,系統就從這里來恢復被修改的DLL文件。如果要修改某個DLL文件,首先應該把dllcache目錄下的同名DLL文件刪除或更名,否則系統會自動恢復。 (3),動態嵌入式 這才是DLL後門最常用的方法。其意義是將DLL文件嵌入到正在運行的系統進程當中。在Windows系統中,每個進程都有自己的私有內存空間,但還是有種種方法來進入其進程的私有內存空間,來實現動態嵌入式。由於系統的關鍵進程是不能終止的,所以這類後門非常隱蔽,查殺也非常困難。常見的動態嵌入式有:「掛接API」「全局鉤子(HOOK)」「遠程線程」等。 遠程線程技術指的是通過在一個進程中創建遠程線程的方法來進入那個進程的內存地址空間。當EXE載體(或Rundll32.exe)在那個被插入的進程里創建了遠程線程,並命令它執行某個DLL文件時,我們的DLL後門就掛上去執行了,這里不會產生新的進程,要想讓DLL後門停止,只有讓這個鏈接DLL後門的進程終止。但如果和某些系統的關鍵進程鏈接,那就不能終止了,如果你終止了系統進程,那Windows也隨即被終止!!! 3,DLL後門的啟動特性 啟動DLL後門的載體EXE是不可缺少的,也是非常重要的,它被稱為:Loader。如果沒有Loader,那我們的DLL後門如何啟動呢?因此,一個好的DLL後門會盡力保護自己的Loader不被查殺。Loader的方式有很多,可以是為我們的DLL後門而專門編寫的一個EXE文件;也可以是系統自帶的Rundll32.exe,即使停止了Rundll32.exe,DLL後門的主體還是存在的。3721網路實名就是一個例子,雖然它並不是「真正」的後門。 二,DLL的清除 本節以三款比較有名的DLL後門例,分別為「SvchostDLL.dll」「BITS.dll」「QoServer.dll」。詳細講解其手工清除方法。希望大家在看過這三款DLL後門的清除方法之後,能夠舉一反三,靈活運用,在不懼怕DLL後門。其實,手工清除DLL後門還是比較簡單的,無非就是在注冊表中做文章。具體怎麼做,請看下文。 1,PortLess BackDoor 這是一款功能非常強大的DLL後門程序,除了可以獲得Local System許可權的Shell之外,還支持如「檢測克隆帳戶」「安裝終端服務」等一系列功能(具體可以參見程序幫助),適用Windows2000/xp/2003等系統。程序使用svchost.exe來啟動,平常不開埠,可以進行反向連接(最大的特點哦),對於有_blank">防火牆的主機來說,這個功能在好不過了。 在介紹清除方法之前,我們先來簡單的介紹一下svchost.exe這個系統的關鍵服務: Svchost只是做為服務的宿主,本身並不實現什麼功能,如果需要使用Svchost來啟動服務,則某個服務是以DLL形式實現的,該DLL的載體Loader指向svchost,所以,在啟動服務的時候由svchost調用該服務的DLL來實現啟動的目的。使用svchost啟動某個服務的DLL文件是由注冊表中的參數來決定的,在需要啟動服務的下邊都有一個Parameters子鍵,其中的ServiceDll表明該服務由哪個DLL文件負責,並且這個DLL文件必須導出一個ServiceMain()函數,為處理服務任務提供支持。 呵呵!看了上邊的理論,是不是有點蒙(我都快睡著了),別著急,我們來看看具體的內容)。我們可以看到HKEY_LOCAL_下的Parameters子鍵,其鍵值為%SystemRoot%system32rpcss.dll。這就說明:啟動RpcSs服務時。Svchost調用WINNTsystem32目錄下的rpcss.dll。 這是注冊表的HKEY_LOCAL_ NTCurrentVersionSvchost,里邊存放著Svchost啟動的組和組內的各個服務,其中netsvcs組的服務最多。要使用Svchost啟動某個服務,則該服務名就會出現在HKEY_LOCAL_ NTCurrentVersionSvchost下。這里有四種方法來實現: 1, 添加一個新的組,在組里添加服務名 2, 在現有組里添加服務名 3, 直接使用現有組里的一個服務名,但是本機沒有安裝的服務 4, 修改現有組里的現有服務,把它的ServiceDll指向自己的DLL後門 我測試的PortLess BackDoor使用的第三種方法。 好了,我想大家看完了上邊的原理,一定可以想到我們清除PortLess BackDoor的方法了,對,就是在注冊表的Svchost鍵下做文章。好,我們現在開始。 註:由於本文只是介紹清除方法,使用方法在此略過。 後門的Loader把SvchostDLL.dll插入Svchost進程當中,所以,我們先打開Windows優化大師中的Windows進程管理2.5,查看Svchost進程中的模塊信息,SvchostDLL.dll已經插入到Svchost進程中了,在根據「直接使用現有組里的一個服務名,但是本機沒有安裝的服務」的提示,我們可以斷定,在「管理工具」—「服務」中會有一項新的服務。證明了我的說法,此服務名稱為:IPRIP,由Svchost啟動,-k netsvcs表示此服務包含在netsvcs服務組中。 我們把該服務停掉,然後打開注冊表編輯器(開始—運行--regedit),來到HKEY_LOCAL_下,查看其Parameters子鍵)。Program鍵的鍵值SvcHostDLL.exe為後門的Loader;ServiceDll的鍵值C:WINNTsystem32svchostdll.dll為調用的DLL文件,這正是後門的DLL文件。現在我們刪除IPRIP子鍵(或者用SC來刪除),然後在來到HKEY_LOCAL_ NTCurrentVersionSvchost下,編輯netsvcs服務組,把49 00 70 00 72 00 69 00 70 00 00 00刪除,這里對應的就是IPRIP的服務名。然後退出,重啟。重啟之後刪除WINNTsystem32目錄下的後門文件即可。2,BITS.dll 這是榕哥的作品,也是DLL後門,和SvchostDLL.dll原理基本一樣,不過這里使用的是上邊介紹的第四種方法,即「修改現有組里的現有服務,把它的ServiceDll指向自己的DLL後門」。換句話說,該後門修改現有的某一個服務,把其原有服務的DLL指向自己(也就是BITS.dll),這樣就達到了自動載入的目的;其次,該後門沒有自己的Loader,而是使用系統自帶的Rundll32.exe來載入。我們還是用Windows 進程管理2.5來查看,從圖7中,我們可以看到bits.dll已經插入到Svchost進程當中。 好,現在我們來看看具體的清除方法,由於該後門是修改現有服務,而我們並不知道具體是修改了哪個服務,所以,在注冊表中搜索bits.dll,最後在HKEY_LOCAL_下搜索到了bits.dll,查看Parameters子鍵下的ServiceDll,其鍵值為C:WINNTsystem32bits.dll(如圖8)。原來,該後門把RasAuto服務原來的DLL文件替換為bits.dll了,這樣來實現自動載入。知道了原因就好辦了,現在我們把ServiceDll的鍵值修改為RasAuto服務原有的DLL文件,即%SystemRoot%System32rasauto.dll,退出,重啟。之後刪除WINNTsystem32目錄下的bits.dll即可。 3,NOIR--QUEEN NOIR--QUEEN(守護者)是一個DLL後門&木馬程序,服務端以DLL文件的形式插入到系統的Lsass.exe進程里,由於Lsass.exe是系統的關鍵進程,所以不能終止。在來介紹清除方法之前,我先介紹一下Lsass.exe進程: 這是一個本地的安全授權服務,並且它會為使用Winlogon服務的授權用戶生成一個進程,如果授權是成功的,Lsass就會產生用戶的進入令牌,令牌使用啟動初始 的Shell。其他的由用戶初始化的進程會繼承這個令牌。 從上邊的介紹我們就可以看出Lsass對系統的重要性,那具體怎麼清除呢?請看下文。 後門在安裝成功後,會在服務中添加一個名為QoSserver的服務,並把QoSserver.dll後門文件插入到Lsass進程當中,使其可以隱藏進程並自動啟動(如圖9)。現在我們打開注冊表,來到HKEY_LOCAL_,直接刪除QoSserver鍵,然後重啟。重啟之後,我們在來到服務列表中,會看到QoSserver服務還在,但沒有啟動,類別是自動,我們把他修改為「已禁用」;然後往上看,會發現一個服務名為AppCPI的服務,其可執行程序指向QoSserver.exe(原因後邊我會說到),具體如圖11所示。我們再次打開注冊表,來到HKEY_LOCAL_,刪除AppCPI鍵,重啟,再刪除QoSserver,最後刪除WINNTsystem32目錄下的後門文件。 本人和這個後門「搏鬥」了3個多小時,重啟N次。原因在於即使刪除了QoSserver服務,後門還是在運行,而且服務列表中的QoSserver服務又「死灰復燃」。後來才知道原因:在我刪除了QoSserver服務並重啟之後,插入到Lsass進程當中的QoSserver.dll文件又恢復了QoSserver服務,並且生成了另外一個服務,即AppCPI,所以我們必須在到注冊表中刪除AppCPI服務才算是把該後門清除。由此可以看出,現在的後門的保護措施,真是一環扣環。 注意:在刪除QoSserver服務並重啟之後,恢復的QoSserver的啟動類別要修改為「已禁用」,否則即便刪除了AppCPI服務,QoSserver服務又運行了。 三,DLL的防範 看了上邊的例子,我想大家對清除DLL後門的方法有了一定的了解,但在現實中,DLL後門並不會使用默認的文件名,所以你也就不能肯定是否中了DLL後門。對於DLL後門,system32目錄下是個好地方,大多數後門也是如此,所以這里要非常注意。下面我來具體介紹一下怎麼發現DLL後門,希望對大家有所幫助。 1,安裝好系統和所有的應用程序之後,備份system32目錄下的EXE和DLL文件:打開CMD,來到WINNTsystem32目錄下,執行:dir *.exe>exe.txt & dir *.dll>dll.txt,這樣,就會把所有的EXE和DLL文件備份到exe.txt和dll.txt文件中;日後,如發現異常,可以使用相同的命令再次備份EXE和DLL文件(這里我們假設是exe0.txt和dll0.txt),並使用:fc exe.txt exe0.txt>exedll.txt & fc dll.txt dll0.txt>exedll.txt,其意思為使用FC命令比較兩次的EXE文件和DLL文件,並將比較結果保存到exedll.txt文件中。通過這種方法,我們就可以發現多出來的EXE和DLL文件,並通過文件大小,創建時間來判斷是否是DLL後門。 2,使用內存/模塊工具來查看進程調用的DLL文件,比如Windows優化大師中的Windows 進程管理 2.5。這樣,可以發現進程到底調用了什麼DLL文件,在結合上邊用FC命令比較出來的結果,又能進一步來確定是否中了DLL後門。如果沒有優化大師,可以使用TaskList,這個小工具也可以顯示進程調用的DLL文件,而且還有源代碼,方便修改。 3,普通後門連接需要打開特定的埠,DLL後門也不例外,不管它怎麼隱藏,連接的時候都需要打開埠。我們可以用netstat –an來查看所有TCP/UDP埠的連接,以發現非法連接。大家平時要對自己打開的埠心中有數,並對netstat –an中的state屬性有所了解。當然,也可以使用Fport來顯示埠對應的進程,這樣,系統有什麼不明的連接和埠,都可以盡收眼底。 4,定期檢查系統自動載入的地方,比如:注冊表,Winstart.bat,Autoexec.bat,win.ini,system.ini,wininit.ini,Autorun.inf,Config.sys等。其次是對服務進行管理,對系統默認的服務要有所了解,在發現有問題的服務時,可以使用Windows 2000 Server Resource Kit中的SC來刪除。以上這些地方都可以用來載入DLL後門的Loader,如果我們把DLL後門Loader刪除了,試問?DLL後門還怎麼運行?! 通過使用上邊的方法,我想大多數DLL後門都可以「現形」,如果我們平時多做一些備份,那對查找DLL後門會啟到事半功倍的效果.

❻ C++鍵盤鉤子

g_hKBHook = ::SetWindowsHookEx(WH_KEYBOARD_LL,(HOOKPROC)KeyboardHookProc,g_hInstance,0);//GlobalKeyBoardHook

這是全局的,第一個參數使用WH_KEYBOARD_LL即可

熱點內容
數字化儲存與編譯是什麼 發布:2025-05-18 02:56:55 瀏覽:217
個人網站模板源碼 發布:2025-05-18 02:51:17 瀏覽:489
主伺服器ip地址 發布:2025-05-18 02:46:29 瀏覽:856
電腦配置太低玩不了絕地求生怎麼辦 發布:2025-05-18 02:38:39 瀏覽:797
存儲過程怎麼出錯了 發布:2025-05-18 02:37:16 瀏覽:368
32寸演算法 發布:2025-05-18 02:22:14 瀏覽:743
寶塔資料庫備份 發布:2025-05-18 02:14:18 瀏覽:192
安卓商店下載的光遇是什麼服 發布:2025-05-18 02:13:38 瀏覽:31
網頁挖礦源碼 發布:2025-05-18 02:13:34 瀏覽:307
centosftp伺服器設置參數 發布:2025-05-18 02:12:55 瀏覽:216