Ring3下注入DLL的另類方法,能過(guò)殺軟和游戲NP(源碼)
Posted on 2010-01-04 21:52 S.l.e!ep.¢% 閱讀(1321) 評(píng)論(0) 編輯 收藏 引用 所屬分類: RootKitRing3下注入DLL的另類方法,能過(guò)殺軟和游戲NP(源碼)
????注入DLL是做全局鉤子或者攔截類軟件都有可能用到的技術(shù),如果做外掛的話我們也有可能需要注入一個(gè)DLL到游戲進(jìn)程中去干點(diǎn)什么“壞事”。?但我們知道現(xiàn)在要注入DLL是越來(lái)越難了。場(chǎng)景1:制作火星文輸入法外掛,原理是利用API?HOOK攔截并修改輸入法相關(guān)函數(shù),需要注入一個(gè)DLL到所有進(jìn)程中,但是后來(lái)發(fā)現(xiàn),在開(kāi)啟了瑞星的帳號(hào)保險(xiǎn)箱后,用戶將不能在QQ中輸入火星文。原因是瑞星保護(hù)了QQ進(jìn)程,禁止對(duì)其注入DLL,解決方法是提示用戶關(guān)閉帳號(hào)保險(xiǎn)箱?-_-|??確實(shí)是很降低用戶體驗(yàn)的一個(gè)不是辦法的辦法。場(chǎng)景2:制作某游戲外掛,需要注入一個(gè)DLL到游戲進(jìn)程中去直接調(diào)用游戲函數(shù)完成某一功能。結(jié)果發(fā)現(xiàn)該游戲有NP保護(hù),OpenProcess打不開(kāi),創(chuàng)建遠(yuǎn)程線程也不行,試用其它方法也一一失敗。遇到上面的情況,高手們自然是轉(zhuǎn)到Ring0下面去,使用驅(qū)動(dòng)之類的辦法來(lái)對(duì)付啦,不過(guò)吾等菜鳥(niǎo)可就是酒井沒(méi)法子了?-_-|?
????不過(guò)也別太灰心,凡事總會(huì)有辦法的。我想我們需要一種持久的、穩(wěn)定的、不容易被安全軟件屏蔽的DLL注入方法,后來(lái)發(fā)現(xiàn),輸入法程序就是能完成這一任務(wù)的理想人選。輸入法程序程序到底是什么?它沒(méi)有自己的進(jìn)程,并且在系統(tǒng)還沒(méi)有登錄時(shí)就已被加載(在歡迎界面你也可以調(diào)出輸入法),它可以在游戲中打開(kāi),也可以在控制臺(tái)程序中打開(kāi),還可以在瑞星保護(hù)下的QQ中打開(kāi),在殺軟中也可以打開(kāi),這不就是我們要找的特性嗎。那么,輸入法到底是什么呢?根據(jù)Windows的規(guī)定,輸入法其實(shí)就是一個(gè)DLL,不過(guò)它是一個(gè)特殊的DLL,它必須具有標(biāo)準(zhǔn)輸入法程序所規(guī)定的那些接口,輸入法是由輸入法管理器(imm32.dll)控制的,輸入法管理器又是由user32.dll控制的。輸入法在系統(tǒng)目錄是以IME為擴(kuò)展名的文件,當(dāng)在應(yīng)用程序中激活某個(gè)輸入法時(shí),輸入法管理器就會(huì)在那個(gè)應(yīng)用程序的進(jìn)程中加載對(duì)應(yīng)的IME文件,注意,加載IME文件跟加載普通的DLL并沒(méi)有本質(zhì)區(qū)別,所以,可以認(rèn)為,輸入法其實(shí)就是注入到應(yīng)用程序中的一個(gè)DLL文件,并且,這種“注入”是不會(huì)被殺軟和游戲NP攔截的(至少目前是)。現(xiàn)在,我們已經(jīng)有了一個(gè)注入DLL的另類方法,那就是利用輸入法。具體流程是這樣,首先制作一個(gè)標(biāo)準(zhǔn)輸入法文件,但是這個(gè)輸入法并不完成文字輸入工作,它的唯一任務(wù)就是用來(lái)注入DLL,所以稱為“服務(wù)輸入法”,然后,制作一個(gè)控制程序,來(lái)控制服務(wù)輸入法,當(dāng)然最后還需要一個(gè)用于注入的目標(biāo)DLL,這樣一共就有3個(gè)文件。開(kāi)始工作后,控制程序首先將服務(wù)輸入法安裝到系統(tǒng)中,然后傳遞幾個(gè)參數(shù)給服務(wù)輸入法,參數(shù)中包括了需要注入的DLL文件的名稱和路徑,然后,控制程序?qū)⒎?wù)輸入法設(shè)置為系統(tǒng)的默認(rèn)輸入法,這樣新的程序一打開(kāi),服務(wù)輸入法就會(huì)注入那個(gè)程序。當(dāng)然,在服務(wù)輸入法安裝之前打開(kāi)的程序不會(huì)被注入,這時(shí)需要向系統(tǒng)中的所有窗口POST一條WM_INPUTLANGCHANGEREQUEST消息,該消息可以在指定窗口中后臺(tái)激活服務(wù)輸入法,這樣,系統(tǒng)中所有擁有窗口的進(jìn)程就都被我們的服務(wù)輸入法注入了。服務(wù)輸入法注入程序之后,就會(huì)根據(jù)控制程序傳遞過(guò)來(lái)的參數(shù)加載目標(biāo)DLL,這樣目標(biāo)DLL也就隨著服務(wù)輸入法一同注入到目標(biāo)程序中了。注意服務(wù)輸入法是控制程序用WM_INPUTLANGCHANGEREQUEST消息在所有窗口中自動(dòng)激活的,如果某個(gè)窗口自動(dòng)激活失敗,你就需要在那個(gè)窗口中手工切換到服務(wù)輸入法,這樣才能注入進(jìn)去了。至于注入以后,你就可以在窗口中切換到別的輸入法,這并不會(huì)影響已經(jīng)注入進(jìn)去的DLL。我將這一套功能制作成一個(gè)完整的示例,你可以在以下地址下載:?http://www.pen88.com/download/imehook.rar??壓縮包中的第6個(gè)和第8個(gè)文件夾演示了此功能并包含所有源代碼。其中文件imedllhost09.dll就是服務(wù)輸入法,運(yùn)行時(shí)會(huì)被安裝到系統(tǒng)中,控制程序退出時(shí)會(huì)自動(dòng)卸載該輸入法,這樣用戶就不太容易察覺(jué),你還可以重新編譯該輸入法,將名稱改為“中文(中國(guó))”,這樣隱蔽性更好。文件hxwdllwx.dll是演示用的目標(biāo)DLL,你可以替換成自己的DLL,然后那個(gè)exe文件就是控制程序了。輸入法imedllhost09.dll在運(yùn)行時(shí)會(huì)被復(fù)制到系統(tǒng)目錄并更名為imedllhost09.ime,它導(dǎo)出了2個(gè)函數(shù)用于控制。在VB中的聲明為:
Public?Declare?Function?IMESetPubString?Lib?"imedllhost09.ime"?(ByVal?RunDLLStr?As?String,?ByVal?UnloadDll?As?Long,?ByVal?loadNextIme?As?Long,?ByVal?DllData1?As?Long,?ByVal?DllData2?As?Long,?ByVal?DllData3?As?Long)?As?Long
Public?Declare?Function?IMEClearPubString?Lib?"imedllhost09.ime"?()?As?Long
其中IMESetPubString用于向輸入法傳遞要注入的DLL等參數(shù)。RunDLLStr,要注入的DLL命令和完整路徑。UnloadDll,當(dāng)輸入法退出時(shí),是否同時(shí)卸載目標(biāo)DLL?0-是,1-否。loadNextIme,當(dāng)切換至該服務(wù)輸入法時(shí),是否直接切換到下一個(gè)輸入法(這樣服務(wù)輸入法就好像被跳過(guò)了,可最小限度影響用戶的輸入法順序)?0-否,1-是。DllData1,DllData2,DllData3是傳遞給目標(biāo)DLL的回調(diào)函數(shù)(函數(shù)名稱必須為RunDllHostCallBack)的參數(shù),你可以在目標(biāo)DLL中導(dǎo)出一個(gè)函數(shù),名稱為RunDllHostCallBack,這樣當(dāng)輸入法注入時(shí)會(huì)調(diào)用目標(biāo)DLL的該回調(diào)函數(shù)并向其傳遞這3個(gè)參數(shù)。函數(shù)原型為(VC):
DWORD?RunDllHostCallBack(DWORD?calldata1,?DWORD?calldata2,DWORD?calldata3);
IMEClearPubString函數(shù)用于清除輸入法的配置,清除后,輸入法將停止在新的程序中注入目標(biāo)DLL,但已注入的DLL不會(huì)卸載。
好了,利用輸入法來(lái)注入DLL基本上就是這樣了,詳細(xì)的用法大家可以看壓縮包中的第8個(gè)文件夾,其中服務(wù)輸入法是VC寫的,控制程序是VB的,代碼都是有注釋的。測(cè)試發(fā)現(xiàn)該方法能過(guò)目前所有殺軟,也能注入冰刃。當(dāng)然缺點(diǎn)還是有的,就是目標(biāo)程序如果不接受輸入法那就沒(méi)辦法了,但是現(xiàn)在一般的游戲都不會(huì)禁止玩家在里面打字吧,而且殺軟也不能禁止用戶輸入漢字吧,哈哈,所以通用性應(yīng)該還是蠻好的。
最后,我再介紹另一個(gè)注入DLL的方法,估計(jì)也很少被用到。是利用一個(gè)未公開(kāi)函數(shù)RegisterUserApiHook,可以在網(wǎng)上搜索關(guān)鍵詞“RegisterUserApiHook”,查到有人在Windows?2003下測(cè)試成功,但是我在Windows?XP測(cè)試卻失敗。后來(lái)終于找到了失效的原因。RegisterUserApiHook函數(shù)可以在系統(tǒng)中注冊(cè)一個(gè)全局鉤子,你需要在鉤子中指定一個(gè)DLL和一個(gè)回調(diào)函數(shù),然后,所有加載了user32.dll的程序就都會(huì)在啟動(dòng)時(shí)加載你指定的這個(gè)DLL。用這個(gè)函數(shù)來(lái)注入DLL也是很不錯(cuò)的。但是測(cè)試發(fā)現(xiàn)它的注入能力似乎趕不上上面提到的利用輸入法來(lái)注入的辦法,可以注入一般的程序和某些安全程序,但是對(duì)冰刃無(wú)效。而且它有一個(gè)限制,就是系統(tǒng)中只能同時(shí)存在一個(gè)這樣的鉤子。實(shí)際上這個(gè)鉤子平時(shí)是被系統(tǒng)中的Themes服務(wù)占用了,Themes服務(wù)正是利用這個(gè)鉤子HOOK了繪制窗口的相關(guān)API,所以才讓所有程序窗口變成XP主題樣式的。所以我們要用這個(gè)鉤子的話,必須先關(guān)閉Themes服務(wù),這樣在XP下也可以用了,但是這樣系統(tǒng)就變成Windows?2000的樣式了?-_-|?
RegisterUserApiHook函數(shù)的VB聲明如下:
Public?Declare?Function?RegisterUserApiHookXP?Lib?"user32"?Alias?"RegisterUserApiHook"?(ByVal?hInstance?As?Long,?ByVal?fnUserApis?As?Long)?As?Long
Public?Declare?Function?RegisterUserApiHook2003?Lib?"user32"?Alias?"RegisterUserApiHook"?(pRegInfo?As?HookAPIRegInfo2003)?As?Long
可以看到,在XP和2003下這個(gè)函數(shù)的參數(shù)是不一樣的。關(guān)于此函數(shù)的示例代碼,請(qǐng)參見(jiàn)壓縮包中的第5個(gè)文件夾。
最后的最后,再介紹一個(gè)未公開(kāi)函數(shù)InitializeLpkHooks,這個(gè)函數(shù)在網(wǎng)上能找到的資料更少,只有一個(gè)聲明而已。但是它名稱中最后那個(gè)“Hooks”誤導(dǎo)了我,我以為又是一個(gè)可以用來(lái)注入DLL的不錯(cuò)函數(shù),用OD反出來(lái)一看,原來(lái)只是個(gè)局部HOOK而已。雖然沒(méi)太大用,還是一并寫上吧,也許誰(shuí)用得著呢。InitializeLpkHooks顧名思義就是HOOK?LPK的,Windows有個(gè)lpk.dll,就是支持多語(yǔ)言包的那么個(gè)功能。測(cè)試發(fā)現(xiàn)好多程序在TextOut之前似乎是要調(diào)用lpk.dll里面的相關(guān)函數(shù)的,可能是支持多語(yǔ)言的程序就需要用這個(gè)來(lái)判斷到底要顯示那種語(yǔ)言吧。而InitializeLpkHooks,就是用來(lái)HOOK?lpk.dll里面的4個(gè)函數(shù)的,這4個(gè)函數(shù)是LpkTabbedTextOut,LpkPSMTextOut,LpkDrawTextEx,LpkEditControl。我們先打開(kāi)VB,在窗體中加入以下代碼吧:
Private?Sub?Form_Load()
DLLhwnd?=?LoadLibrary("lpk.dll")???'加載DLL
DLLFunDre?=?GetProcAddress(DLLhwnd,?"LpkDrawTextEx")???'獲取回調(diào)函數(shù)地址
LpkHooksInfo.lpHookProc_LpkTabbedTextOut?=?0
LpkHooksInfo.lpHookProc_LpkPSMTextOut?=?0
LpkHooksInfo.lpHookProc_LpkDrawTextEx?=?GetLocalProcAdress(AddressOf?HookProc1)???'設(shè)置要HOOK的LPK函數(shù)
LpkHooksInfo.lpHookProc_LpkEditControl?=?0
InitializeLpkHooks?LpkHooksInfo
End?Sub
Private?Sub?Form_Unload(Cancel?As?Integer)
LpkHooksInfo.lpHookProc_LpkTabbedTextOut?=?0
LpkHooksInfo.lpHookProc_LpkPSMTextOut?=?0
LpkHooksInfo.lpHookProc_LpkDrawTextEx?=?DLLFunDre
LpkHooksInfo.lpHookProc_LpkEditControl?=?0
InitializeLpkHooks?LpkHooksInfo
FreeLibrary?DLLhwnd
End?Sub
然后新建一個(gè)模塊,在模塊中加入以下代碼:
Public?Declare?Function?LoadLibrary?Lib?"kernel32"?Alias?"LoadLibraryA"?(ByVal?lpLibFileName?As?String)?As?Long
Public?Declare?Function?GetProcAddress?Lib?"kernel32"?(ByVal?hModule?As?Long,?ByVal?lpProcName?As?String)?As?Long
Public?Declare?Function?FreeLibrary?Lib?"kernel32"?(ByVal?hLibModule?As?Long)?As?Long
'?----------------未公開(kāi)函數(shù)--------------------------------------
Public?Declare?Sub?InitializeLpkHooks?Lib?"user32"?(lpProcType?As?Any)
Type?LpkHooksSetting
????lpHookProc_LpkTabbedTextOut?As?Long
????lpHookProc_LpkPSMTextOut?As?Long
????lpHookProc_LpkDrawTextEx?As?Long
????lpHookProc_LpkEditControl?As?Long
End?Type
'?-------------------------------
Public?DLLhwnd?As?Long,?DLLFunDre?As?Long
Public?LpkHooksInfo?As?LpkHooksSetting
Public?Function?GetLocalProcAdress(ByVal?lpProc?As?Long)?As?Long
GetLocalProcAdress?=?lpProc
End?Function
Function?HookProc1(ByVal?a1?As?Long,?ByVal?a2?As?Long,?ByVal?a3?As?Long,?ByVal?a4?As?Long,?ByVal?a5?As?Long,?ByVal?a6?As?Long,?ByVal?a7?As?Long,?ByVal?a8?As?Long,?ByVal?a9?As?Long,?ByVal?a10?As?Long)?As?Long
HookProc1?=?0
End?Function
運(yùn)行一下看看,是不是窗體中標(biāo)題欄和按鈕上的文字都沒(méi)有了,因?yàn)槲覀儼押瘮?shù)LpkDrawTextEx替換成自己的函數(shù)HookProc1了。這個(gè)函數(shù)有10個(gè)參數(shù),其中幾個(gè)好像是字符串指針,似乎可以用來(lái)截獲窗體要顯示的文字,然后改成另一種語(yǔ)言的文字,我猜想,也許就是這個(gè)用途吧。哈哈,純屬猜測(cè)。以上就是函數(shù)InitializeLpkHooks的用法了。
以上就是全部。?
本文所有示例代碼的下載地址是:?http://www.pen88.com/download/imehook.rar
????注入DLL是做全局鉤子或者攔截類軟件都有可能用到的技術(shù),如果做外掛的話我們也有可能需要注入一個(gè)DLL到游戲進(jìn)程中去干點(diǎn)什么“壞事”。?但我們知道現(xiàn)在要注入DLL是越來(lái)越難了。場(chǎng)景1:制作火星文輸入法外掛,原理是利用API?HOOK攔截并修改輸入法相關(guān)函數(shù),需要注入一個(gè)DLL到所有進(jìn)程中,但是后來(lái)發(fā)現(xiàn),在開(kāi)啟了瑞星的帳號(hào)保險(xiǎn)箱后,用戶將不能在QQ中輸入火星文。原因是瑞星保護(hù)了QQ進(jìn)程,禁止對(duì)其注入DLL,解決方法是提示用戶關(guān)閉帳號(hào)保險(xiǎn)箱?-_-|??確實(shí)是很降低用戶體驗(yàn)的一個(gè)不是辦法的辦法。場(chǎng)景2:制作某游戲外掛,需要注入一個(gè)DLL到游戲進(jìn)程中去直接調(diào)用游戲函數(shù)完成某一功能。結(jié)果發(fā)現(xiàn)該游戲有NP保護(hù),OpenProcess打不開(kāi),創(chuàng)建遠(yuǎn)程線程也不行,試用其它方法也一一失敗。遇到上面的情況,高手們自然是轉(zhuǎn)到Ring0下面去,使用驅(qū)動(dòng)之類的辦法來(lái)對(duì)付啦,不過(guò)吾等菜鳥(niǎo)可就是酒井沒(méi)法子了?-_-|?
????不過(guò)也別太灰心,凡事總會(huì)有辦法的。我想我們需要一種持久的、穩(wěn)定的、不容易被安全軟件屏蔽的DLL注入方法,后來(lái)發(fā)現(xiàn),輸入法程序就是能完成這一任務(wù)的理想人選。輸入法程序程序到底是什么?它沒(méi)有自己的進(jìn)程,并且在系統(tǒng)還沒(méi)有登錄時(shí)就已被加載(在歡迎界面你也可以調(diào)出輸入法),它可以在游戲中打開(kāi),也可以在控制臺(tái)程序中打開(kāi),還可以在瑞星保護(hù)下的QQ中打開(kāi),在殺軟中也可以打開(kāi),這不就是我們要找的特性嗎。那么,輸入法到底是什么呢?根據(jù)Windows的規(guī)定,輸入法其實(shí)就是一個(gè)DLL,不過(guò)它是一個(gè)特殊的DLL,它必須具有標(biāo)準(zhǔn)輸入法程序所規(guī)定的那些接口,輸入法是由輸入法管理器(imm32.dll)控制的,輸入法管理器又是由user32.dll控制的。輸入法在系統(tǒng)目錄是以IME為擴(kuò)展名的文件,當(dāng)在應(yīng)用程序中激活某個(gè)輸入法時(shí),輸入法管理器就會(huì)在那個(gè)應(yīng)用程序的進(jìn)程中加載對(duì)應(yīng)的IME文件,注意,加載IME文件跟加載普通的DLL并沒(méi)有本質(zhì)區(qū)別,所以,可以認(rèn)為,輸入法其實(shí)就是注入到應(yīng)用程序中的一個(gè)DLL文件,并且,這種“注入”是不會(huì)被殺軟和游戲NP攔截的(至少目前是)。現(xiàn)在,我們已經(jīng)有了一個(gè)注入DLL的另類方法,那就是利用輸入法。具體流程是這樣,首先制作一個(gè)標(biāo)準(zhǔn)輸入法文件,但是這個(gè)輸入法并不完成文字輸入工作,它的唯一任務(wù)就是用來(lái)注入DLL,所以稱為“服務(wù)輸入法”,然后,制作一個(gè)控制程序,來(lái)控制服務(wù)輸入法,當(dāng)然最后還需要一個(gè)用于注入的目標(biāo)DLL,這樣一共就有3個(gè)文件。開(kāi)始工作后,控制程序首先將服務(wù)輸入法安裝到系統(tǒng)中,然后傳遞幾個(gè)參數(shù)給服務(wù)輸入法,參數(shù)中包括了需要注入的DLL文件的名稱和路徑,然后,控制程序?qū)⒎?wù)輸入法設(shè)置為系統(tǒng)的默認(rèn)輸入法,這樣新的程序一打開(kāi),服務(wù)輸入法就會(huì)注入那個(gè)程序。當(dāng)然,在服務(wù)輸入法安裝之前打開(kāi)的程序不會(huì)被注入,這時(shí)需要向系統(tǒng)中的所有窗口POST一條WM_INPUTLANGCHANGEREQUEST消息,該消息可以在指定窗口中后臺(tái)激活服務(wù)輸入法,這樣,系統(tǒng)中所有擁有窗口的進(jìn)程就都被我們的服務(wù)輸入法注入了。服務(wù)輸入法注入程序之后,就會(huì)根據(jù)控制程序傳遞過(guò)來(lái)的參數(shù)加載目標(biāo)DLL,這樣目標(biāo)DLL也就隨著服務(wù)輸入法一同注入到目標(biāo)程序中了。注意服務(wù)輸入法是控制程序用WM_INPUTLANGCHANGEREQUEST消息在所有窗口中自動(dòng)激活的,如果某個(gè)窗口自動(dòng)激活失敗,你就需要在那個(gè)窗口中手工切換到服務(wù)輸入法,這樣才能注入進(jìn)去了。至于注入以后,你就可以在窗口中切換到別的輸入法,這并不會(huì)影響已經(jīng)注入進(jìn)去的DLL。我將這一套功能制作成一個(gè)完整的示例,你可以在以下地址下載:?http://www.pen88.com/download/imehook.rar??壓縮包中的第6個(gè)和第8個(gè)文件夾演示了此功能并包含所有源代碼。其中文件imedllhost09.dll就是服務(wù)輸入法,運(yùn)行時(shí)會(huì)被安裝到系統(tǒng)中,控制程序退出時(shí)會(huì)自動(dòng)卸載該輸入法,這樣用戶就不太容易察覺(jué),你還可以重新編譯該輸入法,將名稱改為“中文(中國(guó))”,這樣隱蔽性更好。文件hxwdllwx.dll是演示用的目標(biāo)DLL,你可以替換成自己的DLL,然后那個(gè)exe文件就是控制程序了。輸入法imedllhost09.dll在運(yùn)行時(shí)會(huì)被復(fù)制到系統(tǒng)目錄并更名為imedllhost09.ime,它導(dǎo)出了2個(gè)函數(shù)用于控制。在VB中的聲明為:
Public?Declare?Function?IMESetPubString?Lib?"imedllhost09.ime"?(ByVal?RunDLLStr?As?String,?ByVal?UnloadDll?As?Long,?ByVal?loadNextIme?As?Long,?ByVal?DllData1?As?Long,?ByVal?DllData2?As?Long,?ByVal?DllData3?As?Long)?As?Long
Public?Declare?Function?IMEClearPubString?Lib?"imedllhost09.ime"?()?As?Long
其中IMESetPubString用于向輸入法傳遞要注入的DLL等參數(shù)。RunDLLStr,要注入的DLL命令和完整路徑。UnloadDll,當(dāng)輸入法退出時(shí),是否同時(shí)卸載目標(biāo)DLL?0-是,1-否。loadNextIme,當(dāng)切換至該服務(wù)輸入法時(shí),是否直接切換到下一個(gè)輸入法(這樣服務(wù)輸入法就好像被跳過(guò)了,可最小限度影響用戶的輸入法順序)?0-否,1-是。DllData1,DllData2,DllData3是傳遞給目標(biāo)DLL的回調(diào)函數(shù)(函數(shù)名稱必須為RunDllHostCallBack)的參數(shù),你可以在目標(biāo)DLL中導(dǎo)出一個(gè)函數(shù),名稱為RunDllHostCallBack,這樣當(dāng)輸入法注入時(shí)會(huì)調(diào)用目標(biāo)DLL的該回調(diào)函數(shù)并向其傳遞這3個(gè)參數(shù)。函數(shù)原型為(VC):
DWORD?RunDllHostCallBack(DWORD?calldata1,?DWORD?calldata2,DWORD?calldata3);
IMEClearPubString函數(shù)用于清除輸入法的配置,清除后,輸入法將停止在新的程序中注入目標(biāo)DLL,但已注入的DLL不會(huì)卸載。
好了,利用輸入法來(lái)注入DLL基本上就是這樣了,詳細(xì)的用法大家可以看壓縮包中的第8個(gè)文件夾,其中服務(wù)輸入法是VC寫的,控制程序是VB的,代碼都是有注釋的。測(cè)試發(fā)現(xiàn)該方法能過(guò)目前所有殺軟,也能注入冰刃。當(dāng)然缺點(diǎn)還是有的,就是目標(biāo)程序如果不接受輸入法那就沒(méi)辦法了,但是現(xiàn)在一般的游戲都不會(huì)禁止玩家在里面打字吧,而且殺軟也不能禁止用戶輸入漢字吧,哈哈,所以通用性應(yīng)該還是蠻好的。
最后,我再介紹另一個(gè)注入DLL的方法,估計(jì)也很少被用到。是利用一個(gè)未公開(kāi)函數(shù)RegisterUserApiHook,可以在網(wǎng)上搜索關(guān)鍵詞“RegisterUserApiHook”,查到有人在Windows?2003下測(cè)試成功,但是我在Windows?XP測(cè)試卻失敗。后來(lái)終于找到了失效的原因。RegisterUserApiHook函數(shù)可以在系統(tǒng)中注冊(cè)一個(gè)全局鉤子,你需要在鉤子中指定一個(gè)DLL和一個(gè)回調(diào)函數(shù),然后,所有加載了user32.dll的程序就都會(huì)在啟動(dòng)時(shí)加載你指定的這個(gè)DLL。用這個(gè)函數(shù)來(lái)注入DLL也是很不錯(cuò)的。但是測(cè)試發(fā)現(xiàn)它的注入能力似乎趕不上上面提到的利用輸入法來(lái)注入的辦法,可以注入一般的程序和某些安全程序,但是對(duì)冰刃無(wú)效。而且它有一個(gè)限制,就是系統(tǒng)中只能同時(shí)存在一個(gè)這樣的鉤子。實(shí)際上這個(gè)鉤子平時(shí)是被系統(tǒng)中的Themes服務(wù)占用了,Themes服務(wù)正是利用這個(gè)鉤子HOOK了繪制窗口的相關(guān)API,所以才讓所有程序窗口變成XP主題樣式的。所以我們要用這個(gè)鉤子的話,必須先關(guān)閉Themes服務(wù),這樣在XP下也可以用了,但是這樣系統(tǒng)就變成Windows?2000的樣式了?-_-|?
RegisterUserApiHook函數(shù)的VB聲明如下:
Public?Declare?Function?RegisterUserApiHookXP?Lib?"user32"?Alias?"RegisterUserApiHook"?(ByVal?hInstance?As?Long,?ByVal?fnUserApis?As?Long)?As?Long
Public?Declare?Function?RegisterUserApiHook2003?Lib?"user32"?Alias?"RegisterUserApiHook"?(pRegInfo?As?HookAPIRegInfo2003)?As?Long
可以看到,在XP和2003下這個(gè)函數(shù)的參數(shù)是不一樣的。關(guān)于此函數(shù)的示例代碼,請(qǐng)參見(jiàn)壓縮包中的第5個(gè)文件夾。
最后的最后,再介紹一個(gè)未公開(kāi)函數(shù)InitializeLpkHooks,這個(gè)函數(shù)在網(wǎng)上能找到的資料更少,只有一個(gè)聲明而已。但是它名稱中最后那個(gè)“Hooks”誤導(dǎo)了我,我以為又是一個(gè)可以用來(lái)注入DLL的不錯(cuò)函數(shù),用OD反出來(lái)一看,原來(lái)只是個(gè)局部HOOK而已。雖然沒(méi)太大用,還是一并寫上吧,也許誰(shuí)用得著呢。InitializeLpkHooks顧名思義就是HOOK?LPK的,Windows有個(gè)lpk.dll,就是支持多語(yǔ)言包的那么個(gè)功能。測(cè)試發(fā)現(xiàn)好多程序在TextOut之前似乎是要調(diào)用lpk.dll里面的相關(guān)函數(shù)的,可能是支持多語(yǔ)言的程序就需要用這個(gè)來(lái)判斷到底要顯示那種語(yǔ)言吧。而InitializeLpkHooks,就是用來(lái)HOOK?lpk.dll里面的4個(gè)函數(shù)的,這4個(gè)函數(shù)是LpkTabbedTextOut,LpkPSMTextOut,LpkDrawTextEx,LpkEditControl。我們先打開(kāi)VB,在窗體中加入以下代碼吧:
Private?Sub?Form_Load()
DLLhwnd?=?LoadLibrary("lpk.dll")???'加載DLL
DLLFunDre?=?GetProcAddress(DLLhwnd,?"LpkDrawTextEx")???'獲取回調(diào)函數(shù)地址
LpkHooksInfo.lpHookProc_LpkTabbedTextOut?=?0
LpkHooksInfo.lpHookProc_LpkPSMTextOut?=?0
LpkHooksInfo.lpHookProc_LpkDrawTextEx?=?GetLocalProcAdress(AddressOf?HookProc1)???'設(shè)置要HOOK的LPK函數(shù)
LpkHooksInfo.lpHookProc_LpkEditControl?=?0
InitializeLpkHooks?LpkHooksInfo
End?Sub
Private?Sub?Form_Unload(Cancel?As?Integer)
LpkHooksInfo.lpHookProc_LpkTabbedTextOut?=?0
LpkHooksInfo.lpHookProc_LpkPSMTextOut?=?0
LpkHooksInfo.lpHookProc_LpkDrawTextEx?=?DLLFunDre
LpkHooksInfo.lpHookProc_LpkEditControl?=?0
InitializeLpkHooks?LpkHooksInfo
FreeLibrary?DLLhwnd
End?Sub
然后新建一個(gè)模塊,在模塊中加入以下代碼:
Public?Declare?Function?LoadLibrary?Lib?"kernel32"?Alias?"LoadLibraryA"?(ByVal?lpLibFileName?As?String)?As?Long
Public?Declare?Function?GetProcAddress?Lib?"kernel32"?(ByVal?hModule?As?Long,?ByVal?lpProcName?As?String)?As?Long
Public?Declare?Function?FreeLibrary?Lib?"kernel32"?(ByVal?hLibModule?As?Long)?As?Long
'?----------------未公開(kāi)函數(shù)--------------------------------------
Public?Declare?Sub?InitializeLpkHooks?Lib?"user32"?(lpProcType?As?Any)
Type?LpkHooksSetting
????lpHookProc_LpkTabbedTextOut?As?Long
????lpHookProc_LpkPSMTextOut?As?Long
????lpHookProc_LpkDrawTextEx?As?Long
????lpHookProc_LpkEditControl?As?Long
End?Type
'?-------------------------------
Public?DLLhwnd?As?Long,?DLLFunDre?As?Long
Public?LpkHooksInfo?As?LpkHooksSetting
Public?Function?GetLocalProcAdress(ByVal?lpProc?As?Long)?As?Long
GetLocalProcAdress?=?lpProc
End?Function
Function?HookProc1(ByVal?a1?As?Long,?ByVal?a2?As?Long,?ByVal?a3?As?Long,?ByVal?a4?As?Long,?ByVal?a5?As?Long,?ByVal?a6?As?Long,?ByVal?a7?As?Long,?ByVal?a8?As?Long,?ByVal?a9?As?Long,?ByVal?a10?As?Long)?As?Long
HookProc1?=?0
End?Function
運(yùn)行一下看看,是不是窗體中標(biāo)題欄和按鈕上的文字都沒(méi)有了,因?yàn)槲覀儼押瘮?shù)LpkDrawTextEx替換成自己的函數(shù)HookProc1了。這個(gè)函數(shù)有10個(gè)參數(shù),其中幾個(gè)好像是字符串指針,似乎可以用來(lái)截獲窗體要顯示的文字,然后改成另一種語(yǔ)言的文字,我猜想,也許就是這個(gè)用途吧。哈哈,純屬猜測(cè)。以上就是函數(shù)InitializeLpkHooks的用法了。
以上就是全部。?
本文所有示例代碼的下載地址是:?http://www.pen88.com/download/imehook.rar