首页
社区
课程
招聘
[原创]简单分析R3磁盘格式化的函数
发表于: 2013-7-7 23:51 7964

[原创]简单分析R3磁盘格式化的函数

2013-7-7 23:51
7964
老鸟请飘过~

 初识文件系统相关驱动的时候,卷的概念比较模糊,有分区了,为啥还得有个卷……当初认为一个分区就是一个卷,后来发现,这是不准确的。

    卷:卷是扇区的逻辑集合,这些扇区可能位于一个磁盘上,也可能来自多个磁盘。一个物理磁盘上的扇区可以划分成多个分区(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虚拟机自动化脱壳的方法

上传的附件:
收藏
免费 5
支持
分享
最新回复 (7)
雪    币: 113
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
下载学习...
2013-7-8 02:56
0
雪    币: 154
活跃值: (91)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
3
fmifs啊,看导出表貌似好东西啊
2013-7-8 03:08
0
雪    币: 8865
活跃值: (2379)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
4
主要是那个chkdskEx很好用,其他还有一些好用的功能~~
2013-7-8 08:41
0
雪    币: 328
活跃值: (154)
能力值: ( LV12,RANK:310 )
在线值:
发帖
回帖
粉丝
5
大神飘过,膜拜一下~
2013-7-8 09:31
0
雪    币: 71
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
感谢共享

谢谢
2013-7-8 11:41
0
雪    币: 90
活跃值: (91)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
小手一抖,积分拿走
2013-7-8 14:47
0
雪    币: 10845
活跃值: (17236)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
来了解一下卷和分区的详细区别啊,多谢楼主分享经验
2013-7-8 23:13
0
游客
登录 | 注册 方可回帖
返回
//