老鸟请飘过~
初识文件系统相关驱动的时候,卷的概念比较模糊,有分区了,为啥还得有个卷……当初认为一个分区就是一个卷,后来发现,这是不准确的。
卷:卷是扇区的逻辑集合,这些扇区可能位于一个磁盘上,也可能来自多个磁盘。一个物理磁盘上的扇区可以划分成多个分区(partition),每个分区包含一组连续的扇区;而卷负责管理一个或多个分区中的扇区。在windows中,卷有两种,简单卷和多分区卷。
文件系统;是卷内部的一种逻辑结构,允许用户以文件(数据流)方式来访问和组织数据。
卷与文件系统:给卷分配一个驱动器字母并不等于该卷就有了对应的文件系统;卷上的数据是以扇区来管理的,而文件系统则为扇区中的数据定义了结构信息。为了能以文件和目录的方式来方访问一个卷上的数据,该卷必须被关联上一个文件系统,此过程称为卷识别。
文件系统驱动程序识别一个卷的依据是,检查该卷的引导扇区,看是否符合该文件系统所要求的必要条件,包括一些标识字符串和关键结构信息。识别通过后,文件系统驱动程序会创建这个卷的文件系统实例(即:一个文件系统设备对象)并设置好设备对象的相关属性。
从上述信息,我们可以粗略的认为,在一个空白卷上构造一个文件系统,就是在该卷的引导扇区中写入文件系统关联的各种数据。
写引导扇区,可以调用系统接口来完成,也可以自行填充相关的数据(符合格式规定就行,Ramdisk例子中有FAT的引导扇区格式)。以前弄的那个文件保险箱,格式化的时候,是调用系统的外壳(shell32.dll)的函数SHFormatDrive,弹出一个对话框,再进行格式化操作。真正执行格式化的并非是这个外壳函数,真正执行格式化的操作函数应该在这个对话框的窗口过程中。用OD跟进去瞧瞧。(PS:有啥不对或者,不足,欢迎拍砖
)
push esi ; dwInitParam
push offset sub_7D668179 ; lpDialogFunc
push [ebp+hWndParent] ; hWndParent
push 7000h ; lpTemplateName
push hInstance ; hInstance
call sub_7D6103B1
在IDA中,看了一下,很明显,上面是一个创建对话框函数,跟进对话框过程函数(lpDialogFunc)。
push edi ; lpThreadId
push edi ; dwCreationFlags
push esi ; lpParameter
push offset sub_7D667FA1 ; lpStartAddress
push edi ; dwStackSize
push edi ; lpThreadAttributes
call ds:CreateThread
在窗口过程函数中,上面这段代码比较显眼,因为那界面上有个进度条,驱动进度条而又不使得界面卡死,通常使用线程,(在加密界面 第三版 的那个壳里面 也是这么弄的),跟进线程函数。
在线程函数中,首先就看到文件系统相关的东西:
loc_7D668029: ; "FAT32"
mov [ebp+var_4], offset aFat32
jmp short loc_7D668042
mov [ebp+var_4], offset aExfat ; "exFAT"
jmp short loc_7D668042
loc_7D668032: ; "NTFS"
mov [ebp+var_4], offset aNtfs
jmp short loc_7D668042
loc_7D66803B: ; "FAT"
mov [ebp+var_4], offset aFat
格式化的函数应该离这里不远了,继续往下,一些获取句柄,发送消息,处理外壳通知的一些地方直接跳过,真正格式化的函数的的名字并没有出现在地图中。不过有两个CALL,是通过函数指针来调用的。
第一个:
push dword ptr [esi+60h]
lea eax, [esi+64h]
push [ebp+var_C]
push eax
push [ebp+var_4]
push [ebp+var_10]
push ebx
call dword ptr [esi+14h]
第二个:
loc_7D668110:
lea eax, [esi+48h]
push eax
push dword ptr [esi+4]
push dword ptr [esi+28h]
call dword ptr [esi+2Ch]
接下来跑OD,瞧瞧这两个函数指针指向哪个函数。
对话框函数执行后,立马蹦出了那个格式化对话框。跳转到窗口过程,在创建线程附近下断。然后设置格式化相关选项,开始格式化……
(格式化警告)
7D6683E5 68 31000100 PUSH 0x10031
7D6683EA 33FF XOR EDI,EDI
7D6683EC 57 PUSH EDI
7D6683ED 68 16700000 PUSH 0x7016
7D6683F2 FF75 08 PUSH DWORD PTR SS:[EBP+0x8]
7D6683F5 FF35 A4F5797D PUSH DWORD PTR DS:[0x7D79F5A4] ; shell32.7D590000
7D6683FB E8 274C1000 CALL shell32.ShellMessageBoxW ; 弹框函数
在提示线程函数时,OD会出现一种假死现象,F8按下,程序状态变为运行了,没断下来……解决方法:在之前按F8的地方,往后一句代码上,F2设个断点,暂停程序,再回复运行(OD工具栏上的)。就可以断下来了。继续F8,如果卡了,重复上述步骤@_@,直到哪两个函数指针的位置。
(线程函数中)
第一个函数指针调用代码
7D6680F3 68 4B71667D PUSH shell32.7D66714B ; CallBackFunction
7D6680F8 75 16 JNZ SHORT shell32.7D668110
7D6680FA FF76 60 PUSH DWORD PTR DS:[ESI+0x60] ; 2048
7D6680FD 8D46 64 LEA EAX,DWORD PTR DS:[ESI+0x64]
7D668100 FF75 F4 PUSH DWORD PTR SS:[EBP-0xC] ;
7D668103 50 PUSH EAX ; L"Text"
7D668104 FF75 FC PUSH DWORD PTR SS:[EBP-0x4] ; L"NTFS"
7D668107 FF75 F0 PUSH DWORD PTR SS:[EBP-0x10] ; 0xC
7D66810A 53 PUSH EBX ; L"Z:\\"
7D66810B FF56 14 CALL DWORD PTR DS:[ESI+0x14] ; fmifs.FormatEx
第二个函数指针调用代码:
7D668110 8D46 48 LEA EAX,DWORD PTR DS:[ESI+0x48]
7D668113 50 PUSH EAX
7D668114 FF76 04 PUSH DWORD PTR DS:[ESI+0x4]
7D668117 FF76 28 PUSH DWORD PTR DS:[ESI+0x28]
7D66811A FF56 2C CALL DWORD PTR DS:[ESI+0x2C]
瞧瞧ESI结构里是啥:
dd ESI:
00185280 00000002 //+0
00185284 00000019 //+4
00185288 0000FFFF //+8
0018528C 00000001 //+c
00185290 696D0000 fmifs.696D0000 //+10
00185294 696D1EDF fmifs.FormatEx //+14
00185298 696D27A5 fmifs.QuerySupportedMedia //+18
0018529C 696D2743 fmifs.EnableVolumeCompression//+1c
001852A0 696D33E0 fmifs.ChkdskEx //+20
001852A4 696D2BED fmifs.QueryDeviceInformation+//+24
001852A8 6CFE0000 diskcopy.6CFE0000 //+28
001852AC 6CFE2FC8 diskcopy.#1 //+2c
最后,找到两个模块 fmifs.dll (FormatEx函数)和 diskcopy.dll,用PEditor瞧瞧,这两个模块有啥导出函数。
diskcopy.dll
fmifs.dll
接着就是弄清里面的函数怎么用了。貌似FormatEx未文档话,上百度,果然有结果。A下来,改改,能用了
,FormatEx回调里面,貌似信息量很多,没仔细调,而且容量小的磁盘,没有进度信息貌似没有。(整个外壳包装一下)
Src:
FormatDisk.rar
打完收工
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法