Ring3下注入DLL的另類方法,能過殺軟和遊戲NP(源碼) (教學文章)
最近在用VB做線上遊戲的外掛,發現openprocess 無法使用,會被NP擋下來
找到以下文章,應該可以好好利用
原文出處 http://hi.baidu.com/ypns/blog/item/abe813df267f2c1a62279806.html
Ring3下注入DLL的另類方法,能過殺軟和遊戲NP(源碼) 注 入DLL是做全局鉤子或者攔截類軟件都有可能用到的技術,如果做外掛的話我們也有可能需要注入一個DLL到遊戲進程中去幹點什麼「壞事」。 但我們知道現在要注入DLL是越來越難了。場景1:製作火星文輸入法外掛,原理是利用API HOOK攔截並修改輸入法相關函數,需要注入一個DLL到所有進程中,但是後來發現,在開啟了瑞星的帳號保險箱後,用戶將不能在QQ中輸入火星文。原因是 瑞星保護了QQ進程,禁止對其注入DLL,解決方法是提示用戶關閉帳號保險箱 -_-| 確實是很降低用戶體驗的一個不是辦法的辦法。場景2:製作某遊戲外掛,需要注入一個DLL到遊戲進程中去直接調用遊戲函數完成某一功能。結果發現該遊戲有 NP保護,OpenProcess打不開,創建遠程線程也不行,試用其它方法也一一失敗。遇到上面的情況,高手們自然是轉到Ring0下面去,使用驅動之 類的辦法來對付啦,不過吾等菜鳥可就是酒井沒法子了 -_-|
不過也別太灰心,凡事總會有辦法的。我想我們需要一種持久的、穩定的、不容易被安全軟件屏蔽的DLL注入方法,後來發現,輸入法程序就是能完成這一任務的 理想人選。輸入法程序程序到底是什麼?它沒有自己的進程,並且在系統還沒有登錄時就已被加載(在歡迎界面你也可以調出輸入法),它可以在遊戲中打開,也可 以在控制台程序中打開,還可以在瑞星保護下的QQ中打開,在殺軟中也可以打開,這不就是我們要找的特性嗎。那麼,輸入法到底是什麼呢?根據Windows 的規定,輸入法其實就是一個DLL,不過它是一個特殊的DLL,它必須具有標準輸入法程序所規定的那些接口,輸入法是由輸入法管理器 (imm32.dll)控制的,輸入法管理器又是由user32.dll控制的。輸入法在系統目錄是以IME為擴展名的文件,當在應用程序中激活某個輸入 法時,輸入法管理器就會在那個應用程序的進程中加載對應的IME文件,注意,加載IME文件跟加載普通的DLL並沒有本質區別,所以,可以認為,輸入法其 實就是注入到應用程序中的一個DLL文件,並且,這種「注入」是不會被殺軟和遊戲NP攔截的(至少目前是)。現在,我們已經有了一個注入DLL的另類方 法,那就是利用輸入法。具體流程是這樣,首先製作一個標準輸入法文件,但是這個輸入法並不完成文字輸入工作,它的唯一任務就是用來注入DLL,所以稱為 「服務輸入法」,然後,製作一個控制程序,來控制服務輸入法,當然最後還需要一個用於注入的目標DLL,這樣一共就有3個文件。開始工作後,控制程序首先 將服務輸入法安裝到系統中,然後傳遞幾個參數給服務輸入法,參數中包括了需要注入的DLL文件的名稱和路徑,然後,控制程序將服務輸入法設置為系統的默認 輸入法,這樣新的程序一打開,服務輸入法就會注入那個程序。當然,在服務輸入法安裝之前打開的程序不會被注入,這時需要向系統中的所有窗口POST一條 WM_INPUTLANGCHANGEREQUEST消息,該消息可以在指定窗口中後台激活服務輸入法,這樣,系統中所有擁有窗口的進程就都被我們的服務 輸入法注入了。服務輸入法注入程序之後,就會根據控制程序傳遞過來的參數加載目標DLL,這樣目標DLL也就隨著服務輸入法一同注入到目標程序中了。注意 服務輸入法是控制程序用WM_INPUTLANGCHANGEREQUEST消息在所有窗口中自動激活的,如果某個窗口自動激活失敗,你就需要在那個窗口 中手工切換到服務輸入法,這樣才能注入進去了。至於注入以後,你就可以在窗口中切換到別的輸入法,這並不會影響已經注入進去的DLL。我將這一套功能製作 成一個完整的示例,你可以在以下地址下載: http://www.pen88.com/download/imehook.rar 壓縮包中的第6個和第8個文件夾演示了此功能并包含所有源代碼。其中文件imedllhost09.dll就是服務輸入法,運行時會被安裝到系統中,控制 程序退出時會自動卸載該輸入法,這樣用戶就不太容易察覺,你還可以重新編譯該輸入法,將名稱改為「中文(中國)」,這樣隱蔽性更好。文件 hxwdllwx.dll是演示用的目標DLL,你可以替換成自己的DLL,然後那個exe文件就是控制程序了。輸入法imedllhost09.dll 在運行時會被覆制到系統目錄並更名為imedllhost09.ime,它導出了2個函數用於控制。在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等參數。RunDLLStr,要注入的DLL命令和完整路徑。UnloadDll,當 輸入法退出時,是否同時卸載目標DLL 0-是,1-否。loadNextIme,當切換至該服務輸入法時,是否直接切換到下一個輸入法(這樣服務輸入法就好像被跳過了,可最小限度影響用戶的輸 入法順序) 0-否,1-是。DllData1,DllData2,DllData3是傳遞給目標DLL的回調函數(函數名稱必須為 RunDllHostCallBack)的參數,你可以在目標DLL中導出一個函數,名稱為RunDllHostCallBack,這樣當輸入法注入時會 調用目標DLL的該回調函數並向其傳遞這3個參數。函數原型為(VC):
DWORD RunDllHostCallBack(DWORD calldata1, DWORD calldata2,DWORD calldata3);
IMEClearPubString函數用於清除輸入法的配置,清除後,輸入法將停止在新的程序中注入目標DLL,但已注入的DLL不會卸載。
好了,利用輸入法來注入DLL基本上就是這樣了,詳細的用法大家可以看壓縮包中的第8個文件夾,其中服務輸入法是VC寫的,控制程序是VB的,代碼都是有 註釋的。測試發現該方法能過目前所有殺軟,也能注入冰刃。當然缺點還是有的,就是目標程序如果不接受輸入法那就沒辦法了,但是現在一般的遊戲都不會禁止玩 家在裡面打字吧,而且殺軟也不能禁止用戶輸入漢字吧,哈哈,所以通用性應該還是蠻好的。
最後,我再介紹另一個注入DLL的方法,估計也很少被用到。是利用一個未公開函數RegisterUserApiHook,可以在網上搜索關鍵詞 「RegisterUserApiHook」,查到有人在Windows 2003下測試成功,但是我在Windows XP測試卻失敗。後來終於找到了失效的原因。RegisterUserApiHook函數可以在系統中註冊一個全局鉤子,你需要在鉤子中指定一個DLL和 一個回調函數,然後,所有加載了user32.dll的程序就都會在啟動時加載你指定的這個DLL。用這個函數來注入DLL也是很不錯的。但是測試發現它 的注入能力似乎趕不上上面提到的利用輸入法來注入的辦法,可以注入一般的程序和某些安全程序,但是對冰刃無效。而且它有一個限制,就是系統中只能同時存在 一個這樣的鉤子。實際上這個鉤子平時是被系統中的Themes服務佔用了,Themes服務正是利用這個鉤子HOOK了繪製窗口的相關API,所以才讓所 有程序窗口變成XP主題樣式的。所以我們要用這個鉤子的話,必須先關閉Themes服務,這樣在XP下也可以用了,但是這樣系統就變成Windows 2000的樣式了 -_-|
RegisterUserApiHook函數的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下這個函數的參數是不一樣的。關於此函數的示例代碼,請參見壓縮包中的第5個文件夾。
最後的最後,再介紹一個未公開函數InitializeLpkHooks,這個函數在網上能找到的資料更少,只有一個聲明而已。但是它名稱中最後那個 「Hooks」誤導了我,我以為又是一個可以用來注入DLL的不錯函數,用OD反出來一看,原來只是個局部HOOK而已。雖然沒太大用,還是一併寫上吧, 也許誰用得著呢。InitializeLpkHooks顧名思義就是HOOK LPK的,Windows有個lpk.dll,就是支持多語言包的那麼個功能。測試發現好多程序在TextOut之前似乎是要調用lpk.dll裡面的相 關函數的,可能是支持多語言的程序就需要用這個來判斷到底要顯示那種語言吧。而InitializeLpkHooks,就是用來HOOK lpk.dll裡面的4個函數的,這4個函數是 LpkTabbedTextOut,LpkPSMTextOut,LpkDrawTextEx,LpkEditControl。我們先打開VB,在窗體中 加入以下代碼吧:
Private Sub Form_Load()
DLLhwnd = LoadLibrary("lpk.dll") '加載DLL
DLLFunDre = GetProcAddress(DLLhwnd, "LpkDrawTextEx") '獲取回調函數地址
LpkHooksInfo.lpHookProc_LpkTabbedTextOut = 0
LpkHooksInfo.lpHookProc_LpkPSMTextOut = 0
LpkHooksInfo.lpHookProc_LpkDrawTextEx = GetLocalProcAdress(AddressOf HookProc1) '設置要HOOK的LPK函數
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
然後新建一個模塊,在模塊中加入以下代碼:
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
' ----------------未公開函數--------------------------------------
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
運行一下看看,是不是窗體中標題欄和按鈕上的文字都沒有了,因為我們把函數LpkDrawTextEx替換成自己的函數HookProc1了。這個函數有 10個參數,其中幾個好像是字符串指針,似乎可以用來截獲窗體要顯示的文字,然後改成另一種語言的文字,我猜想,也許就是這個用途吧。哈哈,純屬猜測。以 上就是函數InitializeLpkHooks的用法了。
以上就是全部。
本文所有示例代碼的下載地址是: http://www.pen88.com/download/imehook.rar
如有錯誤 歡迎指正