青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆-60  評(píng)論-262  文章-1  trackbacks-0
====================================================================
以下為轉(zhuǎn)帖

操作被占用的文件-unlocker機(jī)理分析
*[標(biāo)題]: 操作被占用的文件-unlocker機(jī)理分析
*[作者]: gz1X [gz1x(at)tom(dot)com]
            EagleNet [hklt594(at)163(dot)com]
*[來(lái)自]: 中國(guó)黑客聯(lián)盟 [CHU]
*[原始鏈接]: http://blog.china-pub.com/more.asp?name=zzs0405&id=41832

[前言]
——————————————————————
之前給原作者發(fā)過(guò)郵件, 不過(guò)沒(méi)能得到unlocker的源代碼, 所以自己逆向了一份;
逆向的很匆忙, 因?yàn)榻鼇?lái)事情太多, 而且unlocker本身也是版權(quán)所有, 所以不好做的太露骨;
本人也還有不少地方不是很明白, 有機(jī)會(huì)和我聯(lián)系, 一起探討 :-)
感謝EagleNet的討論.


[關(guān)于unlocker]
——————————————————————
Unlocker是一個(gè)免費(fèi)的工具, 原作者的網(wǎng)站是: http://ccollomb.free.fr/unlocker
當(dāng)使用者發(fā)現(xiàn)有某個(gè)文件或目錄無(wú)法刪除時(shí), 只要按下鼠標(biāo)右鍵中的"Unlocker",
程序會(huì)顯示出是哪一些程序占用了該目錄或文件, 接著只要按下"Unlock"就能夠?yàn)槟愕奈募怄i.


==============================Here we start=================================

[大致流程]
——————————————————————
主程序Unlocker.exe通過(guò)ZwQuerySystemInformation查詢當(dāng)前系統(tǒng)的所有句柄信息, 然后調(diào)用OpenProcess獲取目標(biāo)進(jìn)程句柄,
遍歷當(dāng)前所有進(jìn)程, 根據(jù)進(jìn)程ID, 得到此進(jìn)程打開(kāi)的所有句柄信息, 接下來(lái)用DuplicateHandle復(fù)制Handle到本地進(jìn)程,
然后把文件句柄發(fā)給驅(qū)動(dòng)UnlockerDriver5.sys進(jìn)行名字的查詢, sys將返回文件句柄對(duì)應(yīng)的內(nèi)核文件對(duì)象的完整名字.
確定文件名后, 如果要?jiǎng)h除文件, 則調(diào)用OpenProcess與DuplicateHandle關(guān)閉句柄, 然后ZwDeleteFile刪除文件.


[UnlockerAssistant.exe]
[UnlockerHook.dll]
——————————————————————
UnlockerAssistant.exe主要是實(shí)現(xiàn)系統(tǒng)托盤(pán)等輔助功能, 同時(shí)安裝鉤子:
.text:00403AC9           public start
.text:00403AC9 start:
//...
.text:00403AD5           call   sub_40391E
跟進(jìn), 能看到主要的實(shí)現(xiàn)代碼:
.text:00403925           call   sub_402E83
//...
.text:00403944           push   offset LibFileName ; "UnlockerHook.dll"
.text:00403949           call   ds:LoadLibraryA
//...
.text:0040398A           push   offset ProcName ; "HookInstall"
.text:00403994           call   edi ; GetProcAddress
注冊(cè)窗口消息, 初始化控件, 安裝鉤子;

.text:00403A1A           call   ds:Shell_NotifyIconA
.text:00403A20           call   sub_40359E   ;RegOpenKeyExA...
設(shè)置托盤(pán)圖標(biāo), 寫(xiě)入注冊(cè)表啟動(dòng)項(xiàng);

.text:00403A69           push   offset s_Hookuninstall ; "HookUninstall"
卸載鉤子.

當(dāng)然也有綠化版本只寫(xiě)入右鍵, 這些大家自己看反匯編的代碼, 詳細(xì)的鉤子過(guò)程反匯編UnlockerHook.dll, 也不再做糾纏.
我們只看UnlockerHook.dll里一處:
.text:10001102 sub_10001102   proc near           ;
//...
.text:10001181           call   ds:GetModuleFileNameW
.text:1000118E           call   ds:PathRemoveFileSpecW
//...
.text:100011A7           push   offset s_SUnlocker_exe ; "\"%s\\Unlocker.exe\""
//...
.text:100011E0           call   ds:ShellExecuteExW
呼出主程序, 進(jìn)行文件處理.


[UnlockerDriver5.sys分析]
——————————————————————
反匯編驅(qū)動(dòng)文件, 跳到入口點(diǎn):
INIT:00402000 ; int __stdcall start(PDRIVER_OBJECT DriverObject,int)
INIT:00402000           public start
INIT:00402000 start       proc near
//...
INIT:0040203D           call   ds:IoCreateDevice
//...
INIT:004020E3           call   ds:IoCreateSymbolicLink
//...
上面就是DriverEntry了. 注意這一段:
INIT:004020AB           mov   dword ptr [ecx], offset loc_401000
INIT:004020B1           mov   dword ptr [esi+40h], offset loc_401000
INIT:004020B8           mov   dword ptr [esi+44h], offset sub_401090
INIT:004020BF           mov   dword ptr [esi+48h], offset loc_401020
INIT:004020C6           mov   dword ptr [esi+34h], offset sub_401240
經(jīng)典的, 處理MajorFunction[IRP_MJ_DEVICE_CONTROL*(sizeof PVOID)]等等.

我們跟蹤這兩個(gè)函數(shù), 先跟sub_401240, 如下:
PAGE:0040124D           call   ds:RtlInitUnicodeString
//...
PAGE:00401257           call   ds:IoDeleteSymbolicLink
//...
PAGE:00401265           call   ds:IoDeleteDevice
很明顯的DriverUnload函數(shù);

接著跟sub_401090, 這個(gè)函數(shù)就是類似于DispatchControl(IRP_MJ_DEVICE_CONTROL)了;
我們挑關(guān)鍵的看, RtlInitUnicodeString函數(shù)填充UNICODE_STRING結(jié)構(gòu)就不多做糾纏:
PAGE:004010FA           call   ds:ObReferenceObjectByHandle
獲取由句柄描述的對(duì)象的指針, 也就是獲取FILE_OBJECT對(duì)象;
這里, 想想內(nèi)核級(jí)文件的Read和Write, 通過(guò)HANDLE執(zhí)行就要先用ObReferenceObjectByHandle函數(shù)來(lái)獲得Handle對(duì)應(yīng)的FileObject,
然后我們?cè)俳oFileObject發(fā)送IRP進(jìn)行實(shí)質(zhì)操作.

略過(guò)分配內(nèi)存, 接著往下走:
PAGE:00401158           call   ds:ObQueryNameString
這個(gè)函數(shù)將獲取設(shè)備名, 然后和FILE_OBJECT的FileName構(gòu)成完整的名字返回(應(yīng)用層在注冊(cè)表中保存設(shè)備名+目錄名);

PAGE:00401214           call   ds:ObfDereferenceObject
再一次調(diào)用ObfDereferenceObject, 將對(duì)象的引用計(jì)數(shù)器恢復(fù)到先前的值, 防止泄漏;

PAGE:0040122D           call   ds:IofCompleteRequest
MajorFunction[IRP_MJ_CLOSE*(sizeof PVOID)], 完成操作.

回頭看看這個(gè)驅(qū)動(dòng), 實(shí)際上是很經(jīng)典也很簡(jiǎn)單的驅(qū)動(dòng)程序, 實(shí)現(xiàn)的功能也很簡(jiǎn)單:
返回文件句柄對(duì)應(yīng)的內(nèi)核文件對(duì)象的完整名字, 傳給主程序進(jìn)行文件"刪除""移動(dòng)"等操作.


[Unlocker.exe分析]
——————————————————————
直接跳到入口點(diǎn):
.text:004135FB           public start
.text:004135FB start       proc near
//...
.text:00413607           call   sub_412EDC
跟進(jìn)去, 挑重點(diǎn):

.text:00412EEF           call   sub_40D1FF     ; 命令行用法說(shuō)明
.text:00412EFC           call   sub_40D78C     ; 查詢注冊(cè)表
.text:00412F0C           push   offset Caption ; "Unlocker 1.8.5"
.text:00412F11           call   sub_413DEF     ; 創(chuàng)建線程, 網(wǎng)絡(luò)升級(jí), 在線輔助
//...
.text:00412F1C           mov   ecx, eax
.text:00412F1E           call   sub_40FA79     ; 這里開(kāi)始!

=============================================================================
我把sub_40FA79列出來(lái)(有省略), 如下:
.text:0040FA79 sub_40FA79     proc near           ; CODE XREF: sub_412EDC+42 p
.text:0040FA79           push   ebx
.text:0040FA7A           push   esi
.text:0040FA7B           push   offset LibFileName ; "ntdll.dll"
.text:0040FA82           call   ds:LoadLibraryA
//...
.text:0040FA8E           push   edi
.text:0040FA8F           mov   edi, ds:GetProcAddress
.text:0040FA95           push   offset ProcName ; "ZwQuerySystemInformation"
.text:0040FA9D           push   offset s_Zwqueryobject ; "ZwQueryObject"
.text:0040FAA7           push   offset s_Zwdeletefile ; "ZwDeleteFile"
.text:0040FAB2           push   offset s_Rtlinitunicod ; "RtlInitUnicodeString"
.text:0040FABD           push   offset s_Rtladjustpriv ; "RtlAdjustPrivilege"
.text:0040FAC8           push   offset s_Ntloaddriver ; "NtLoadDriver"
.text:0040FAD3           push   offset s_Ntunloaddrive ; "NtUnloadDriver"
.text:0040FAD8           push   ebx         ; hModule
.text:0040FAD9           mov   [esi+14h], eax
.text:0040FADC           call   edi ; GetProcAddress

這一段的代碼是unlocker的重點(diǎn)部分, 獲取ntdll.dll地址后, 調(diào)用其中的函數(shù):
1)ZwQuerySystemInformation函數(shù)獲得系統(tǒng)當(dāng)前所以進(jìn)程的所建立的句柄及其相關(guān)信息;
2)ZwQueryObject獲取句柄所代表對(duì)象信息, 查出目標(biāo)文件(設(shè)備名+目錄名);
3)ZwDeleteFile刪除目標(biāo)文件;
4)NtLoadDriver加載驅(qū)動(dòng), 當(dāng)然還需要后面的注冊(cè)表修改;
===========================================================================

再往下:
.text:00412F9E           call   ds:PathRemoveFileSpecW
.text:00412FAB           push   offset s_SUnlocker_cfg ; "%s\\Unlocker.cfg"
.text:00412FB5           call   ds:wsprintfW
//...
.text:00412FC2           call   sub_40D3F4
跟進(jìn)sub_40D3F4函數(shù), 發(fā)現(xiàn)作用是將驅(qū)動(dòng)信息寫(xiě)入注冊(cè)表;

.text:00413008           push   dword ptr [eax+8] ; lpFileName
.text:0041300B           call   sub_410E28
//...
.text:004133E8           call   ds:QueryDosDeviceA
//...
.text:004134B7           push   offset s_DeviceLanmanr ; "\\Device\\LanmanRedirector"
.text:004134BC           push   eax         ; LPWSTR
.text:004134BD           mov   [ebp+lpSrch], eax
.text:004134C0           call   ds:wsprintfW
遍歷查詢DOS設(shè)備, 進(jìn)行重定向;

.text:00413504           mov   esi, ds:DialogBoxParamA     
.text:0041350A           mov   edi, ds:GetModuleHandleA
//...
.text:00413529           call   sub_411A59   //--->getfullname
創(chuàng)建一個(gè)對(duì)話框窗口, 顯示所有枚舉出的相關(guān)進(jìn)程;
sub_411A59函數(shù)將獲取對(duì)象文件的完整名, 并返回, 我們跟進(jìn)去:

.text:00411F63           push   dword ptr [esi] ; dwProcessId
.text:00411F65           mov   edi, ds:OpenProcess
.text:00411F6B           push   ebx         ; bInheritHandle
.text:00411F6C           push   450h         ; dwDesiredAccess
.text:00411F71           call   edi ; OpenProcess
之前是進(jìn)程和模塊遍歷, 找到相關(guān)聯(lián)的所有進(jìn)程和模塊, OpenProcess打開(kāi)需要操作的文件;

.text:00411F93           call   ds:GetCurrentProcess
//...
.text:00411FA2           call   ds:DuplicateHandle
獲取本地進(jìn)程, 將對(duì)象進(jìn)程的句柄復(fù)制到本地進(jìn)程(句柄進(jìn)程相關(guān));

.text:00411FBB           push   offset s_?Unlockerdriv ; "\\\\?\\UnlockerDriver5"
.text:00411FC0           call   ds:CreateFileW
//...
將句柄發(fā)送給驅(qū)動(dòng)程序, 驅(qū)動(dòng)將返回文件句柄對(duì)應(yīng)的內(nèi)核文件對(duì)象的完整名字;


[文件操作選擇]
——————————————————————
現(xiàn)在退出sub_411A59函數(shù)返回主線, 我們走到這里:
.text:00413536           cmp   byte ptr [eax+3], 0
.text:0041353A           jz     short loc_41357B
.text:0041353A
.text:0041353C           mov   eax, cInitial
.text:00413541           test   eax, eax
.text:00413543           jz     short loc_413571   ; "移動(dòng)"或者"重命名"操作;
.text:00413543
.text:00413545           xor   ebx, ebx
.text:00413547           test   eax, eax
.text:00413549           jbe   short loc_41355F   ; "刪除"操作
這里將進(jìn)行文件處理的選擇, 是無(wú)動(dòng)作? 刪除? 還是移動(dòng)? 重命名?

.text:0041353A           jz     short loc_41357B
//...
.text:0041357B           xor   ebx, ebx
.text:0041357D           cmp   cInitial, ebx
.text:00413583           jz     short loc_4135AE
cInitial存放的值代表當(dāng)前的窗口是否為初始窗口;

a)
我們先看是派生窗口時(shí)的處理, loc_4135AE:
.text:004135B5           push   offset sub_412D62 ; lpDialogFunc
//...
.text:00412DA4           push   [esp+800h+hDlg] ; hDlg
.text:00412DAB           call   sub_412371   //-->toMoveFile
生成一個(gè)瀏覽對(duì)話框供選擇路徑保存文件:
.text:004123AB           call   sub_410064
//--->
.text:00410082           call   ds:CoInitialize
.text:004100D6           call   ds:SHBrowseForFolderW
.text:004100E4           call   ds:SHGetPathFromIDListW
.text:004100F4           call   ds:CoUninitialize
//<---
.text:004123DE           call   ds:PathIsDirectoryW
.text:0041242C           call   ds:GetSaveFileNameW
.text:00412451           call   sub_4115AE     //-->inject

實(shí)際上查看sub_412371這個(gè)函數(shù)的交叉引用(實(shí)際上你不用看引用也很容易就會(huì)發(fā)現(xiàn)), 會(huì)發(fā)現(xiàn):
.text:00412478 sub_412478     proc near     //-->GuiControlDeal
這里是一個(gè)對(duì)話框, 也就是我們右鍵unlocker時(shí)產(chǎn)生的界面, 它將生成unlocker的主界面,
也將處理各種用戶操作的消息, 發(fā)給各個(gè)子程序去處理;

回到:
.text:004135C7           call   esi ; DialogBoxParamA
.text:004135CF           call   sub_410F86   //-->MoveFile
由于cInitial值為0, 所以此時(shí)必定是用戶選擇了"移動(dòng)"或"重命名";

=========================================================================
跟進(jìn)sub_410F86, 看到:
.text:00410F96           jnz   loc_4110C2     ; 重命名
//...
.text:00411145           call   esi ; wsprintfW
//...
.text:00411173           call   edi ; SHFileOperationW
//...
.text:00411166           mov   [ebp+FileOp.wFunc], 4   ;ReName
text:00411217             call   edi ; SHFileOperationW
調(diào)用wsprintfW格式化路徑后, 填充SHFILEOPSTRUCT結(jié)構(gòu), 由SHFileOperationW來(lái)重命名, 完成后調(diào)用MessageBoxA通知完成;

否則就是"移動(dòng)"操作:
.text:00411048           call   sub_410BB2   //-->getdirfile
//--->
.text:00410C20           call   ds:FindFirstFileW
.text:00410C95           call   ds:FindNextFileW
//<---
.text:00411064           call   ds:MoveFileExW
.text:00411076           jnz   short loc_41105F ; 循環(huán)移動(dòng)目錄下的所有文件
.text:00411093           jb     loc_410FBF     //-->deleteDir
//...
.text:004113E4           push   eax         ; int
.text:004113E5           mov   eax, lpSrch
.text:004113EA           push   [ebp+var_8]   ; int
.text:004113ED           add   eax, esi
.text:004113EF           push   eax         ; lpExistingFileName
.text:004113F0           call   sub_410462   //-->movefile
到這里就完成了這兩項(xiàng)功能, 不過(guò)注意函數(shù)里壓棧時(shí)的參數(shù):

.text:00411281           call   getdirfile
//...
.text:00411302           push   4           ; MOVEFILE_DELAY_UNTIL_REBOOT
.text:00411304           lea   eax, [ebp+NewFileName]
.text:0041130A           push   eax         ; lpNewFileName
.text:0041130B           push   dword ptr [edi] ; lpExistingFileName
.text:0041130D           call   ds:MoveFileExW
這段代碼的意思是, 如果暫時(shí)處理不了用戶請(qǐng)求的文件操作, 那就在系統(tǒng)重新啟動(dòng)時(shí)實(shí)行操作;
========================================================================

接著:
.text:004135DE           cmp   [ebp+var_9], 0
.text:004135E2           jnz   loc_413514
返回, 重新獲取文件的完整名, 重繪主窗口;

.text:004135E8           call   sub_40D51D
.text:004135ED           call   sub_413B8F
ds:GlobalFree釋放內(nèi)存后, 調(diào)用了sub_40D51D, 它刪除了注冊(cè)表里的sys服務(wù), 然后sub_413B8F休眠, 繼續(xù)等待操作觸發(fā);

b)
現(xiàn)在我們回到a)處, 考慮另一種情況, cInitial==1:

.text:00413586           push   offset GuiControlDeal ; lpDialogFunc
.text:00413596           call   esi ; DialogBoxParamA
//...
.text:00413568           push   [ebp+hMem]
.text:0041356B           call   sub_41178F   //--->CloseFileHandle
此時(shí)的文件操作是"刪除"(或者"無(wú)動(dòng)作");

sub_41178F函數(shù)的作用就是實(shí)現(xiàn)刪除文件, 我們看:

.text:004117FB           call   ds:OpenProcess
//...
.text:0041180D           call   ds:TerminateProcess
//...
.text:00411819           cmp   eax, 0FFFFFFFFh
.text:0041181C           jnz   loc_4119F8
判斷目標(biāo)文件是哪種類型文件, exe還是dll? 是exe則跳到loc_4119F8處;

.text:0041182E           call   ds:OpenProcess
//...
.text:00411868           call   GetModuleFileNameExW
//...
.text:00411873           push   offset s__dll   ; ".DLL"
.text:00411878           push   eax         ; pszPath
.text:00411879           call   sub_40FC27
文件是dll類型, 獲取其路徑;

.text:0041189F           push   offset s_SUS   ; "/s /u \"%s\""
//...
.text:004118B3           mov   [ebp+ExecInfo.lpVerb], offset s_Open ; "open"
.text:004118BA           mov   [ebp+ExecInfo.lpFile], offset s_Regsvr32_exe ; "regsvr32.exe"
//...
.text:004118DA           call   ds:ShellExecuteExW
先將模塊注銷掉, 使用regsvr32.exe /s /u實(shí)現(xiàn);

.text:00411944           push   offset s_Freelibrary ; "FreeLibrary"
//...
.text:00411966           push   offset s_Closehandle ; "CloseHandle"
然后通過(guò)FreeLibrary來(lái)釋放, 調(diào)用GetModuleHandleW查詢句柄后, 用CloseHandle將其關(guān)閉;

注意這一段代碼:
.text:00411888           push   0Eh
.text:0041188A           pop   ecx
也就是說(shuō)循環(huán)將進(jìn)行0EH(14)次, FreeLibrary也將執(zhí)行14次直到dll被釋放;

.text:00411921           call   esi ; WriteProcessMemory
.text:00411933           call   edi ; VirtualAllocEx
.text:004119A8           call   esi ; WriteProcessMemory
.text:004119B5           call   ds:CreateRemoteThread
想必您已經(jīng)注意到了這些代碼, 對(duì), 思路就是用線程注入到目標(biāo)進(jìn)程去調(diào)用FreeLibrary來(lái)釋放dll;

現(xiàn)在我們來(lái)到loc_4119F8處, 也就是上文提到的如果文件是exe文件時(shí)的處理方法:
.text:00411A07           call   ds:OpenProcess
.text:00411A1B           call   ds:GetCurrentProcess
.text:00411A28           call   ds:DuplicateHandle
.text:00411A3C           call   ds:CloseHandle
還是先打開(kāi)文件, 然后調(diào)用DuplicateHandle, 但是這里傳遞的參數(shù)是DUPLICATE_CLOSE_SOURCE標(biāo)志, 將強(qiáng)制關(guān)閉句柄;

===========================EOF===But to be modified========================


[后語(yǔ)]
——————————————————————
突然發(fā)現(xiàn)沒(méi)結(jié)尾, 被老大姐罵了, 補(bǔ)充一個(gè)吧.
unlocker最主要的功能實(shí)現(xiàn)都在unlocker.exe和一個(gè).sys驅(qū)動(dòng)里, 值得關(guān)注的是它怎么實(shí)現(xiàn)的關(guān)閉句柄和刪除文件.
關(guān)鍵的函數(shù) (部分也是未公開(kāi)的API) , 比如:
ZwQuerySystemInformation、 ZwQueryObject、ZwDeleteFile、ObReferenceObjectByHandle、ObQueryNameString、 SHFileOperationW、MoveFileExW、DuplicateHandle.
這里尤其是DuplicateHandle和MoveFileExW比較有意思.
詳細(xì)的界面構(gòu)造沒(méi)有去研究, 就是這句:
.text:00412478 sub_412478     proc near     //-->GuiControlDeal
跟進(jìn)去分析就是界面的相關(guān)操作了, 太煩, 本人時(shí)間有限, 如果有人愿意繼續(xù), 記得把結(jié)果分享一份給我, 謝謝.



*[參考資料]:
——————————————————————
1. Windows平臺(tái)內(nèi)核級(jí)文件訪問(wèn)   baiyuanfan
2. unlocker1.8.5       http://ccollomb.free.fr/unlocker
3. Kmd教程-全功能的驅(qū)動(dòng)程序分析   羅云彬

4. http://forum.sysinternals.com/forum_posts.asp?TID=7974

==========================================================================

另一篇: http://windknown.spaces.live.com/blog/cns!627D8DB6EC5BD4A7!435.entry

April 07
UnLocker帶來(lái)的思考
    這幾個(gè)禮拜已經(jīng)是忙得焦頭爛額了, 這2天還偏偏和unlocker這個(gè)軟件耗上了, 我的睡眠時(shí)間啊~~
    UnLocker是一款可以用來(lái)刪除已被占用文件的軟件, http://ccollomb.free.fr/unlocker/
    通常的刪除文件是通過(guò)調(diào)用win32 api的DeleteFile來(lái)執(zhí)行的, 該函數(shù)會(huì)檢查是否有引用該文件的句柄, 因此若有進(jìn)程打開(kāi)了該文件是無(wú)法刪除的. 另外說(shuō)一下該api的執(zhí)行過(guò)程, 打開(kāi)文件-〉設(shè)置為刪除-〉關(guān)閉文件, 此時(shí)系統(tǒng)會(huì)自動(dòng)刪除該文件. 設(shè)置是通過(guò)主控制號(hào)為IRP_MJ_SET_INFORMATION的IRP進(jìn)行的, IO 棧的Parameters.SetFile.FileInformationClass值為 FileDispositionInformation, AssociatedIrp.SystemBuffer指向結(jié)構(gòu) FILE_DISPOSITION_INFORMATION, 其成員DeleteFile設(shè)置為T(mén)RUE. 于是乎, 如果在自己的文件過(guò)濾驅(qū)動(dòng)里過(guò)濾該 IRP, 只需要改為FASLE就可以防止文件被刪除了.
    說(shuō)一下另一種刪除文件的方法, 也就是unlocker使用的, ntdll導(dǎo)出的ZwDeleteFile, 該函數(shù)的原理沒(méi)有細(xì)究, 但是同樣也是會(huì)檢查句柄的.
    因此, 要?jiǎng)h除文件的關(guān)鍵是需要關(guān)閉打開(kāi)的文件句柄, 而句柄是與進(jìn)程相關(guān)的. 今天仔細(xì)逆向了一下unlocker, 包括主程序和一個(gè)sys文件.
    sys文件的作用是返回文件句柄對(duì)應(yīng)的內(nèi)核文件對(duì)象的完整名字, 例如: \Device\HarddiskVolum1\mytest.doc,  \Device\HarddiskVolum1就是C:這個(gè)卷的設(shè)備名. 大致流程就是調(diào)用ObReferenceObjectByHandle通過(guò)對(duì)象獲取FILE_OBJECT對(duì)象, 然后通過(guò)ObQuerNameString查詢FILE_OBJECT中的DeviceObject指針獲取設(shè)備名, 再與 FILE_OBJECT的FileName構(gòu)成完整的名字返回.
    主程序是通過(guò) ZwQuerySystemInformation 查詢 handle 信息, 類型為 SystemHandleInformation, 然后調(diào)用 OpenProcess 獲取目標(biāo)進(jìn)程句柄, 再用 DuplicateHandle 復(fù)制 Handle 為本進(jìn)程, 再通過(guò)驅(qū)動(dòng)查詢名字, 確定文件名. 一定記住句柄是進(jìn)程相關(guān)的, MSDN里描述, 例如在DriverEntry中打開(kāi)的句柄是在system進(jìn)程下, 因此在驅(qū)動(dòng)DispatchFunction中不可用, 因?yàn)镈ispatchFunction的進(jìn)程上下文為與驅(qū)動(dòng)通信的進(jìn)程. 當(dāng)要?jiǎng)h除文件時(shí), 對(duì)于打開(kāi)的文件, unlocker仍然是通過(guò)OpenProcess與DuplicateHandle, 只是指定了 DUPLICATE_CLOSE_SOURCE標(biāo)志, 真是大開(kāi)眼界阿, 如此便關(guān)閉了句柄, 高. 而對(duì)于dll就沒(méi)有那么方便了, unlocker會(huì)用線程注入到目標(biāo)進(jìn)程去調(diào)用FreeLibrary來(lái)釋放dll, 因此可能不夠穩(wěn)定, 而且逆向時(shí)發(fā)現(xiàn)注入的代碼只嘗試0x10次Free, 呵呵我load20次自己就可以搞定撈.
    然后看MSDN過(guò)程中發(fā)現(xiàn)了另一個(gè)nb函數(shù), SetHandleInformation, 設(shè)置這個(gè)標(biāo)志 HANDLE_FLAG_PROTECT_FROM_CLOSE , 那么 unlocker 調(diào)用 DuplicateHandle 也關(guān)不掉你的句柄了, 試驗(yàn)了一下, 果然說(shuō)刪不了撈, hoho
    整這些鳥(niǎo)東西弄了我一天時(shí)間, 唉, 許久不逆向, 生疏了不少~~而且因?yàn)樵谔摂M機(jī)里調(diào)試, 老破機(jī)器這個(gè)卡啊~~睡覺(jué)去!
    順便一提, 今天發(fā)現(xiàn)國(guó)內(nèi)搞安全的兄弟們共享精神不如國(guó)外阿, 唉, 環(huán)境使然, 人嗎首先還是要自己生存的. 想想自己也快畢業(yè)了, 有點(diǎn)迷惘, 畢業(yè)了干啥工作去捏……生存阿生存


============================================================================
第三篇: http://blog.vckbase.com/windowssky/archive/2007/04/18/25565.html

小議文件保護(hù)和鎖定技術(shù)

  近1年來(lái)互連網(wǎng)上的木馬越來(lái)越多, 有的還刪除不掉, 要切換到dos才可行, 如: CNNC, 3721等, 實(shí)現(xiàn)技術(shù)也五花八門(mén), 但就文件不可刪除的實(shí)現(xiàn)技術(shù)可分三類:

  1 Attach file system; 這種技術(shù)和Filemon/sfilter查不多, 就是掛一個(gè) filter 驅(qū)動(dòng)到 fs 上, 其他函數(shù)都是 passthru 下去, 只處理 IRP_MJ_SET_INFORMATION, 當(dāng)發(fā)現(xiàn)有刪除需保護(hù)文件的 IRP, 就
Irp->IoStatus.Status = STATUS_SUCCESS;            
Irp->IoStatus.Information = 0;            
IoCompleteRequest(Irp, IO_NO_INCREMENT);
根本不讓 Fs 去處理, 從而達(dá)到文件不可刪除的作用!

有什么方法可以刪除呢? 自己寫(xiě)個(gè)驅(qū)動(dòng)自己填充 irp 包 (見(jiàn) OSR 文檔 Rolling Your Own) , 直接發(fā)送 IRP 到 File System Device 上去就 ok 啦!


  2 修改 file system 的 dispatch 函數(shù)表; 首先得到 Fs 的 DriverObject (根據(jù)驅(qū)動(dòng)名得到驅(qū)動(dòng)設(shè)備對(duì)象 (ObReferenceObjectByName(IoDriverObjectType))), pDriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = MySetInformation, 然后在 MySetInformation 中再調(diào)用原來(lái)的調(diào)度函數(shù), 類似于 HookApi; 發(fā)現(xiàn)有刪除需保護(hù)文件的 IRP, 就直接 IoCompleteRequest, 根本不讓原來(lái)的 FsSetInformation 處理!

有什么方法可以刪除呢? 自己寫(xiě)個(gè)驅(qū)動(dòng)來(lái)修復(fù) Fs 的 dispatch 函數(shù)表, 讀 Fs 的原始文件, 根據(jù) PE 文件得到 Fs 的 Entrypoint, dispatch 函數(shù)表的填充都在 EntryPoint 后面, 我們可以根據(jù) Opcode 查找, XX XX XX XX 就是我們要找的 dispatch 的原始地址; 找到后 pDriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = XX XX XX XX, 然后就能刪除文件啦!

FunOpc=MajorFunction*4+0x38
C7 46 FunOpc[<80]  XX XX XX XX  mov     dword ptr [esi+50h], offset _NtfsFsdSetInformation
C7 86 FunOpc[>=80] XX XX XX XX
C7 43 FunOpc[<80]  XX XX XX XX  mov     dword ptr [ebx+50h], offset _NtfsFsdSetInformation
C7 83 FunOpc[>=80] XX XX XX XX


  3 通過(guò) ZwCreateFile 把文件鎖定; 刪除時(shí)報(bào)告 "文件正在使用, 禁止刪除", 具體原理自己摸索吧, 反正是通過(guò) ZwCreateFile 實(shí)現(xiàn)的!

有什么方法可以刪除呢?
  step1: 通過(guò) QuerySystemInformation(SystemHandleInformation) 得到當(dāng)前系統(tǒng)的所有句柄信息
  step2: 遍歷當(dāng)前所有進(jìn)程, 根據(jù)進(jìn)程 ID, 得到此進(jìn)程打開(kāi)的所有句柄信息
  Step3: 把句柄發(fā)送給我們的驅(qū)動(dòng)程序, 驅(qū)動(dòng)程序根據(jù) ObQueryNameString 得到句柄的路徑信息, 然后再傳給我們的應(yīng)用程序
  Step4: 如果是我們要?jiǎng)h除文件的路徑, 應(yīng)用程序調(diào)用 DuplicateHandle(DUPLICATE_CLOSE_SOURCE), 句柄被關(guān)閉了, 現(xiàn)在可以刪除文件了!
  注: QuerySystemInformation 的使用說(shuō)明見(jiàn) The Undocumented Functions, 或者 http://undocumented.ntinternals.net, 第三種解除文件鎖定的方法是我反匯編 Unlocker 軟件學(xué)習(xí)到的


  最后感謝 7cat 的幫助!

====================================================================
以下為原創(chuàng)

free2000fly 按:
unlocker 軟件真是搞的百轉(zhuǎn)千回, 還用到了驅(qū)動(dòng), 其實(shí)不必要, 在ring3是可以通過(guò)文件句柄得到文件名的, 以下是刪除已被鎖定文件的代碼:
BOOL DeleteLockedFile(DWORD dwProcessID, HANDLE hFile)
{
    TCHAR szTargetName[MAX_PATH] 
= { 0 };
    HANDLE hTargeFile 
= INVALID_HANDLE_VALUE;
    HANDLE hProcess 
= NULL;
    BOOL bResult 
= FALSE;
    
    
do 
    {
        hProcess 
= OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessID);
        
if (NULL == hProcess) {
            
break;
        }
        
        
if (FALSE == DuplicateHandle(hProcess, hFile, 
            GetCurrentProcess(), 
&hTargeFile, 
            
0, FALSE, DUPLICATE_SAME_ACCESS)) 
        {
            
break;
        }
        
        
if (INVALID_HANDLE_VALUE==hTargeFile || NULL==hTargeFile) {
            
break;
        }

        
if (FALSE == GetFilePathFromHandle(hTargeFile, 
            szTargetName, _countof(szTargetName))) 
        {
            
break;
        }

        CloseHandle(hTargeFile);
        hTargeFile 
= INVALID_HANDLE_VALUE;
        
        
if (0 == lstrlen(szTargetName)) {
            
break;
        }
        
        
if (FALSE == DuplicateHandle(hProcess, hFile, 
            GetCurrentProcess(), 
&hTargeFile, 
            
0, FALSE, 
            DUPLICATE_SAME_ACCESS
|DUPLICATE_CLOSE_SOURCE))  // 關(guān)鍵標(biāo)志
        {
            
break;
        }

        
if (INVALID_HANDLE_VALUE==hTargeFile || NULL==hTargeFile) {
            
break;
        }
        
        CloseHandle(hTargeFile);
        hTargeFile 
= INVALID_HANDLE_VALUE;

        bResult 
= DeleteFile(szTargetName);
    } 
while (FALSE);

    
if (INVALID_HANDLE_VALUE != hTargeFile && NULL != hTargeFile) {
        CloseHandle(hTargeFile);
    }
    
    
if (hProcess) {
        CloseHandle(hProcess);
    }
    
return bResult;
}
其中函數(shù) GetFilePathFromHandle 的實(shí)現(xiàn)請(qǐng)看我的 另一篇博文 " 從文件句柄得到文件路徑的函數(shù) "

PS. 最近幾天試圖實(shí)現(xiàn)枚舉已打開(kāi)所有文件的功能, 我卻一而再,再而三的在函數(shù) NtQueryObject 和 ZwQueryInformationFile 上遭遇掛起的現(xiàn)象, 這兩個(gè)函數(shù)在被調(diào)用后有可能不再返回, 軟件失去響應(yīng), 這是相當(dāng)要命的事, 后來(lái)的解決方法是, 用一個(gè)獨(dú)立的線程來(lái)調(diào)用這兩個(gè)函數(shù), 如果超時(shí)則立即返回, 但在需要講求效率的場(chǎng)合這個(gè)解決方法行不通. 查遍網(wǎng)絡(luò)才發(fā)現(xiàn)這可能算是 Windows 系列操作系統(tǒng)的一個(gè) BUG.  因此, 最后, 還是回到了必須使用驅(qū)動(dòng)的老路上去了.  2009.12.05

參考:
http://www.codeproject.com/KB/shell/OpenedFileFinder.aspx
http://www.codeproject.com/Articles/35202/GetFinalPathNameByHandle-API-Hangs.aspx
http://www.codeguru.com/forum/showthread.php?t=359606
http://bbs.pediy.com/showthread.php?t=60190

posted on 2009-07-14 02:45 free2000fly 閱讀(6677) 評(píng)論(2)  編輯 收藏 引用

評(píng)論:
# re: 操作被占用的文件-unlocker機(jī)理分析 2009-12-22 14:05 | marihees
大哥您好,小弟有一點(diǎn)不明白 DeleteLockedFile(DWORD dwProcessID, HANDLE hFile) dwProcessID這個(gè)鎖定文件的進(jìn)程ID如何獲得? hFile傳入的是?我想改成DeleteLockedFile(CString strFilePath) 該如何做呢?  回復(fù)  更多評(píng)論
  
# re: 操作被占用的文件-unlocker機(jī)理分析 2012-05-07 11:33 | 斷了的貓
強(qiáng)大 謝謝分享   回復(fù)  更多評(píng)論
  

只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲香蕉视频| 午夜免费久久久久| 亚洲人成亚洲人成在线观看图片 | 性做久久久久久久久| 免费一区视频| 伊人久久av导航| 久久综合九色欧美综合狠狠| 亚洲综合视频在线| 国产精品区二区三区日本| 一区二区三区久久| 日韩视频一区二区| 欧美人在线视频| 999在线观看精品免费不卡网站| 欧美va亚洲va香蕉在线| 久久亚洲午夜电影| 亚洲国产欧美在线| 欧美激情在线有限公司| 欧美福利视频网站| 99精品国产在热久久婷婷| 欧美激情视频一区二区三区在线播放| 美女视频一区免费观看| 亚洲精品乱码久久久久久久久| 女人色偷偷aa久久天堂| 嫩模写真一区二区三区三州| 亚洲人成人一区二区三区| 亚洲国产精品一区二区久| 欧美 日韩 国产 一区| 亚洲欧洲日产国产网站| 欧美激情 亚洲a∨综合| 欧美成人免费全部| 亚洲午夜激情网页| 亚洲一区在线直播| 国产一区视频观看| 蜜桃av噜噜一区二区三区| 欧美国产精品久久| 亚洲视频在线观看免费| 亚洲男同1069视频| 在线观看不卡| 亚洲三级视频在线观看| 国产精品三区www17con| 老司机凹凸av亚洲导航| 免费亚洲电影在线| 亚洲小视频在线| 午夜在线a亚洲v天堂网2018| 在线观看日韩国产| 亚洲裸体视频| 国产人成精品一区二区三| 欧美国产1区2区| 国产精品久久国产精麻豆99网站| 国产欧美一区二区三区另类精品| 久久久欧美精品sm网站| 欧美成人中文字幕| 亚洲国产成人av在线| 国产精品女主播一区二区三区| 欧美一区二区三区四区视频| 久久久免费精品视频| 国产精品99久久99久久久二8| 欧美伊人久久久久久午夜久久久久| 亚洲福利视频网| 亚洲午夜成aⅴ人片| 影院欧美亚洲| 亚洲在线视频一区| 亚洲国产精品一区二区久| 亚洲女女女同性video| 亚洲日本va在线观看| 亚洲欧美日韩天堂一区二区| 99re66热这里只有精品3直播 | 国产日韩一区二区| 亚洲区在线播放| 精品动漫一区二区| 亚洲欧美另类综合偷拍| 一区二区免费在线播放| 久久综合网络一区二区| 久久久久国色av免费观看性色| 欧美日韩在线大尺度| 亚洲高清视频在线观看| 国产一区二区三区四区三区四| 中文日韩欧美| 亚洲性图久久| 欧美日韩视频在线| 亚洲欧洲一区| 99国产一区二区三精品乱码| 欧美不卡视频一区发布| 老色批av在线精品| 激情综合网激情| 久久国产精品色婷婷| 久久精品国产第一区二区三区| 国产精品嫩草影院av蜜臀| 亚洲另类在线视频| 日韩亚洲欧美成人一区| 欧美成人精品福利| 亚洲国产精品美女| 亚洲欧洲精品一区二区| 蜜桃视频一区| 欧美xart系列高清| 亚洲激情欧美激情| 欧美国产日韩一区二区三区| 亚洲国产成人精品久久| 亚洲精品一区在线| 欧美日韩国产免费| 一本到高清视频免费精品| 亚洲视频在线观看网站| 国产精品v欧美精品∨日韩| 亚洲视频在线二区| 欧美在线观看一区二区三区| 国产欧美在线| 久久久精品国产99久久精品芒果| 久久久综合激的五月天| 一区二区三区在线视频免费观看| 久久亚洲图片| 亚洲精选视频在线| 亚洲欧美日韩直播| 国产欧美在线视频| 久久亚洲捆绑美女| 亚洲国产日韩一区| 一区二区三区四区在线| 国产精品一区二区三区免费观看| 欧美一区二区三区免费大片| 农村妇女精品| 国产精品99久久久久久久女警| 日韩午夜在线电影| 欧美另类亚洲| 亚洲欧美日韩一区二区在线| 久久综合免费视频影院| 亚洲精品一区在线观看香蕉| 国产精品福利网站| 久久久噜噜噜久久| 91久久在线观看| 久久精品视频导航| 亚洲国产精品免费| 国产精品久久久久久久久借妻 | 国产精品久久久91| 欧美一区亚洲| 亚洲精品1区| 久久精品免费| 99亚洲伊人久久精品影院红桃| 国产精品一区免费观看| 老司机精品视频一区二区三区| 亚洲视频导航| 亚洲福利av| 久久嫩草精品久久久久| 一本久久综合亚洲鲁鲁| 国产一区二区三区四区在线观看| 牛牛国产精品| 欧美一二区视频| 亚洲精品乱码久久久久久| 久久久人人人| 午夜精品视频| 日韩一级黄色大片| 在线观看国产一区二区| 国产精品免费小视频| 欧美福利精品| 老司机67194精品线观看| 亚洲一区日韩在线| 一本色道久久综合亚洲91| 欧美电影免费观看高清| 久久gogo国模裸体人体| 一区二区三区四区国产| 亚洲国产小视频| 亚洲成人在线免费| 国产日韩在线不卡| 欧美色中文字幕| 欧美精品在线一区| 欧美 亚欧 日韩视频在线| 久久国产免费看| 亚洲欧美美女| 亚洲欧美电影在线观看| 在线午夜精品自拍| 亚洲精品日韩在线观看| 亚洲承认在线| 欧美成人午夜激情| 美女主播精品视频一二三四| 久久精品免费看| 欧美在线3区| 欧美一区网站| 欧美在线一区二区| 香蕉乱码成人久久天堂爱免费 | 久久精品国产免费观看| 亚洲一区在线看| 在线视频免费在线观看一区二区| 日韩午夜av| 亚洲精品乱码久久久久久久久 | 99热这里只有精品8| 亚洲精品国产精品乱码不99按摩 | 美女黄色成人网| 免费观看日韩| 99精品欧美一区| 久久天天躁狠狠躁夜夜av| 久久久久久尹人网香蕉| 老牛国产精品一区的观看方式| 欧美va天堂| 日韩视频在线一区二区| 夜夜夜久久久| 午夜精品一区二区在线观看| 午夜精品久久久久| 久久久久久久久久久久久久一区| 久久夜色精品国产亚洲aⅴ| 久久综合网hezyo| 欧美日韩福利| 国产精品一二三四区|