使用ntfs_study探寻hardlink的本质

在推出ntfs_study的博文中,我谈到过要用一些例子来简单介绍这个工具的用法,本文就算是这个工具的使用介绍以及hardlink在ntfs文件系统底层的简单探讨。

MSDN中写到,hardlink是在文件系统中,用多个在同一个卷的路径表示同一个文件的方法。那么在ntfs格式中这些被link的文件是怎么存在的呢?下面进行一些简单的探讨。

首先,我们需要去创建hardlink的文件。
20130312202150

图中,第一个命令,在target_file.txt的同目录下,创建了hardlink文件link_file.txt。第二个命令,在不同目录(otherdir)下创建了第二个hardlink文件,link_file_in_otherdir.txt。第三个命令返回了错误,原因是我试图在不同卷里面来创建hardlink文件。失败的原因文章后面会介绍。

现在,让我们用ntfs_study来查看ntfs对这三个文件的处理到底是怎么样的。
20130312202324

在这张图中,我们可以清楚的看到,这三个文件的file reference,也就是在主文件表(MFT)的id都是一样的!有一点我们必须明白,一个文件的存在不是因为在目录里面显示了文件名,而是他在MFT中有自己的位置,另外文件名只是文件的一个属性而已,没什么特别的。这也就解释了,看似三个文件为什么会指向同一个文件,因为在目录的记录中,他们指向了同一个id。

为了更加深入的探讨这个问题,我们来看一看id为0xB4A6这个具体情况。首先看看他的file record的数据。

20130312202509

这里可以看到hardlinks的值是4!看到这里,应该就感到奇怪了,我们明明只创建了两个hardlink的文件,为什么这里写的是4呢?实际上,对于ntfs的文件而已,文件名以及他们在那个目录,这些都是属性而已,没有本体和hardlink之分,也就是说,我们原始创建的target_file.txt对于文件本身,也是一个hardlink。那么这个问题还是没解决啊,就算加上本身,最多也就是3个hardlinks,但是这里明明写的是4个!

让我们更加具体的看一看到底是什么回事吧。

20130312202536

首先,我们看到了这个文件的属性中,居然有4个文件名,其中有三个实际上我们已经能够猜到,他们应该分别是target_file,link_file和link_file_in_otherdir这三个名称,那么第四个又是什么呢?只能再进一步看了。

20130312202616

看了这幅图,估计大家就明白了,这个是为了兼容8.3文件名而产生的一个hardlink,只不过在我们现在的系统上隐藏了这个文件hardlink而已。其他三个文件名,如我们刚刚所料,就是那三个文件的名字。

现在解释下为什么hardlink只能在同一个卷里了。原因很显而易见,hardlink实际上是依赖于ntfs的MFT的,而不同的卷,会有不同的MFT,所以不能在不同卷之间创建hardlink也是理所当然的。

SysinternalsSuite中有一个工具叫做findlinks,用来找到一个文件所有的hardlink。其中实现的方法在不同的系统中有所不同,在vista以下的系统中程序调用GetFileInformationByHandle获得文件的MFT id,然后查找整个卷的文件,打开他们获得句柄,再调用GetFileInformationByHandle得到这些文件的id,与之前的id进行比对。可以说,这是非常费时的。而在vista中,这个耗时的问题得到了解决,调用FindFirstFileNameW和FindNextFileNameW就能够文件所有的hardlinks了。

我也计划过两天写一个find_links_study。

NTInternals

access_enum_study —— 仿AccessEnum的工具

access_enum_study 是我逆向AccessEnum所写的程序。写这个逆向加上写这个程序大概用了1个多星期的时间吧。不过说实话,逆向算法还是比较麻烦的事情,所以这个程序里面有一些算法是我自己想的。不过果然不出我所料,效率比起Mark的正牌工具差了不少。这下,真的只能当作玩具玩玩了。

20130309230748

下载access_enum_study

NTInternals

ntfs_info_study —— 仿NtfsInfo工具

ntfs_info_study 这个工具可以显示ntfs卷的一些信息。主要也是学习NtfsInfo的功能,而仿造的一个小工具。ntfs_info_study能显示的信息包括卷大小,扇区数量,簇数量,扇区字节数,簇字节数,主文件表每条记录字节数以及主文件表的一些信息。当然它还可以显示部分NTFS系统文件的信息,例如:$Volume。

实际上ntfs_info_study稍微修复了NtfsInfo的一个问题。原来的NtfsInfo已经无法显示NTFS系统文件的信息了。原因是这个工具调用FindFirstFile这样的函数来查找NTFS系统文件。我不知道什么版本的Windows可以这么做,至少现在Windows 7上,这个方法是行不通的。所以在我从写的工具里,是先打开系统文件,然后查询文件信息,但是普通的CreateFile是打不开这些文件的,这里我的方法是调用OpenFileById。不过实际上,我还没找到正规而且完美显示所有NTFS系统文件的方法,因为部分系统文件在打开的时候会提示访问拒绝。

当然不正规的但是却比较完美的查看NTFS系统文件的方法也有,就是直接打开卷,解析NTFS文件系统数据结构。这个功能已经在ntfs_study中实现了,具体可以移步这个链接

20130227235402

以上是一副对比图,其他功能是一样的,唯一的区别就是最后一项中,ntfs_info_study能够显示部分NTFS系统文件信息。

Usage: ntfs_info_study.exe

使用方法自然也不必说明了,有兴趣的各位可以下载玩玩。

下载ntfs_info_study

NTInternals

pipe_list_study —— 仿PipeList的小工具

昨天在家看完笑傲江湖,没事可做,看了sysinternals的一个很简单的小工具PipeList,然后逆了下,山寨了一个,并且加按照管道名筛选的功能。工具很简单,一共也就200行代码。使用方法如下:

1
2
3
4
Usage: pipe_list_study.exe [search_pipe_name]
search_pipe_name  ---  List the pipes that has search_pipe_name in the pipe name string.
                       Without this argument pipe_list_study will list all pipes.

20130221114347

下载pipe_list_study

NTInternals

又是总结和展望:没有世界末日,生活还要继续

今天总算是有时间,有心情写一篇总结去年生活,展望今年的文章了。

过去的2012年对我来说并不是末日,恰恰相反,他更像是一个新的开始。年初加入新公司,感觉选择还是比较正确的。在新的公司工作,工作不算忙,考勤也比较人性化,环境也还不错。主要是新同事们都还不错,别的不说,侃大山的能力还是很让人钦佩的。所以工作之余也非常娱乐。他们负责娱,我负责乐就行了,哈哈哈哈。刚刚说到工作不算忙,说起来本人也确实在这个环境中挺酱油的,不过俺也不是偷懒,主要是工作上合适我的活不算多。我去小组之后,发现本来打打杀杀的软件,现在要做良民了,不过其实这个做产品的思路是正确的,我也落得点清闲,实在不错。

当然了,本人实际上不甘于清闲。没事的时候还是跟哥们研究了许多编译器和系统底层的机制。除此之外,今年最大的一个收获是把COM这套东西了解一下,这样不仅对今后的工作有所帮助,而且自己本身对代码应该如何写方面也有一些收获。了解了COM当然要了解ATL,因为ATL过于强大,大部分代码我也没有去读,现在而言主要停留在能合理的使用,对于这点我也比较满意,实际上没打算把ATL搞得太清楚。至于编译器,学的也不多,刚刚把语法分析那块弄得一知半解吧。系统底层倒是一直在研究,尤其是文件系统,注册表等。关于系统底层这些,可以看我去年发的几篇blog,都是一些研究后自己写的工具。包括ntfs文件系统学习工具,注册表格式学习工具,pdb的解析工具等等。

回头再看看去年定的目标。。。我只能说“呵呵”。。。没有一个完成的啊有木有!!!果然奇迹没有发生啊有木有!!!那么,我又要给今年定目标了。。。

1.写一个study系列的工具,可以从山寨sysinternals的工具开始做起。

没了,对!就这一条!!!我就不信这一条我也搞不定!!!!!

去年写了总结后,同学们说我生活上的写的太少了,好吧那我简单总结下生活上的开心事!最开心的是,哥开始健身了!!!每周固定和一哥们去三次健身房,每次25分钟跑4k多米,并且锻炼腹肌和肱二头肌。现在人感觉就像回到高中状态。更让人欣慰的事情是能看到一点点腹肌了!另外精神方面,更多的相信“念念不忘,必有回响”,也有称这个为宇宙神秘力量的,不是迷信,而是一种信念,是一种相信只要你不断努力,不断追求就一定能达到目标的执念。不过可惜,我一直念念不忘年会大奖,可惜大宇宙送了我两个字——“呵呵”。。。关于练字,总是断断续续,貌似没啥进步。关于英语,嗯,没了。关于更八卦的生活详情~呵呵~你们以为我会写么!

那么今年生活上的目标呢?!还是健身,练字,英语和嘿嘿~~~

最后还是送祝福时间:祝福我的家人,朋友和我自己,新春快乐,健康平安,家庭和睦温馨!!!

proc_study —— 仿PsList的进程查看工具

proc_study 是我通过逆向PsList而写出来的小工具,如果在本地查看进程,这个工具和pslist没有任何区别。因为实现查看进程的方式也是和pslist一模一样的。另一方面,他缺乏pslist的查看远程计算机的进程的功能。没有实现这个并不是不知道怎么实现,是我半天也没搭建出这样的一个远程环境,真够郁闷的。这个应该是年前的最后一个study系列的工具了。期待蛇年有时间山寨更多工具,嘿嘿~~~

20130204204101

这个工具的使用方法和命令行参数可以直接参看PsList的。因为整个Usage我都是直接山寨过来的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Usage: proc_study [-d][-m][-x][-t][name|pid]
-d      Show thread detail.
-m     Show memory detail.
-x      Show processes, memory information and threads.
-t       Show process tree.
name Show information about processes that begin with the name
specified.
-e      Exact match the process name.
pid Show information about specified process.
All memory values are displayed in KB.
Abbreviation key:
Pri Priority
Thd Number of Threads
Hnd Number of Handles
VM Virtual Memory
WS Working Set
Priv Private Virtual Memory
Priv Pk Private Virtual Memory Peak
Faults Page Faults
NonP Non-Paged Pool
Page Paged Pool
Cswtch Context Switches

下载proc_study

NTInternals

hive_study —— 注册表文件格式解析工具

这几天又写了个小工具,刚下班就在这发了算了。

hive_study 是一个注册表文件格式解析工具。功能也比较的简单,主要是dump出注册表里面的数据信息。例如显示子项,子键,显示键值以及他们的安全描述符。当然了,还是那样,注册表的hive文件实际上是不可读的,因为内核独占他了。想要获得可以读的hive文件,可以用ntfsstudy把hive文件dump出来,然后去读这个新的hive文件。以下是他的Usage。

1
2
3
4
5
6
7
8
9
Usage : hive_study.exe -f hive_path [-options]
Options:
[-k key_path] Specifies key path (e.g.: -k "ControlSet001\Control\Session Manager")
[-v value_name] Specifies value name (e.g.: -v BootExecute)
[-l] List subkeys information
[-e] List values information
[-s] Show key security description information
[-w output_file] Dump attribute to a file

20130123181723

下载hive_study

NTInternals

分享自己打造的BugReporter

这份代码应该是将近一年前写的吧,应该是去年年初了。不像ntfsstudy和dia_study,这个工具应该比较的实用吧,实用场合可以比较多。所以也把源代码发出来。看工具名称基本上已经知道了是报告bug用的。其实这种工具倒是挺多的。不过我个人感觉自己写一个用起来顺手,而且代码量小,容易修改自定义。

工具代码有三个工程,分别是minidump_generator,dump_minidump,BugReporter。
minidump_generator是一个dll,当然也可以编译成静态库,他需要加入到你想使用BugReporter的工程里面。
dump_minidump是一个dump文件的解析库,他是BugReporter工程的依赖库。
BugReporter是一个窗口程序,在你融合了minidump_generator的程序崩溃的时候会弹出窗口。就像图中那样。

20130120193015

勾选send bug report并且点击ok,窗口里的完整log和dump文件会打包为zip文件储存,储存的地方可以由程序指定,也可以写注册表键值,reporter会去都键值然后存储到相应的位置。具体什么键值,看源代码吧。不完整和遗憾的地方也有,就是还没有http上传到提交dump收集服务器的代码。因为确实不会写php啥的。另外这个工程也用了不少开源代码,这里也感谢一下,其中包括反汇编引擎和ZIP代码。

下载源代码:BugReporter

以下是完整的dump log:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
SYSTEM INFORMATIONS
---------------
ProcessorArchitecture : x86
Number Of Processors : 16
OS Version : 6.1
BuildNumber : 7600
CSDVersion :
Platform : Windows Server 2003, Windows XP, or Windows 2000
EXCEPTION INFORMATIONS
---------------
Thread id : 5744
ExceptionCode : c00000fd
ExceptionFlags : 00000000
ExceptionRecord : 0000000000000000
ExceptionAddress : 0000000000dea637
ExceptionInformation0 = 0000000000000000
ExceptionInformation1 = 0000000000102000
Thread Context :
EAX = 00102000 ECX = 00102050 EDX = 5eea2408 EBX = 7efde000
ESP = 00103120 EBP = 00103128 ESI = 001ff9c8 EDI = 00104210
EFLAGS = 00010206
MODULE INFORMATIONS
---------------
Base Size Name FileVersion ProductVersion
0000000000de0000 0001a000 D:\crashme\Debug\crashme.exe 0 0
00000000772b0000 00180000 C:\Windows\SysWOW64\ntdll.dll 600011db040af 600011db040af
0000000075ef0000 00100000 C:\Windows\SysWOW64\kernel32.dll 600011db04001 600011db04001
00000000750f0000 00046000 C:\Windows\SysWOW64\KERNELBASE.dll 600011db04001 600011db04001
000000005ed90000 00124000 C:\Windows\winsxs\x86_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.30729.4148_none_2a4cbfc25558bcd3\msvcr90d.dll 9000078091034 9000078091034
0000000074330000 000eb000 C:\Windows\System32\dbghelp.dll 600011db04001 600011db04001
0000000076e00000 000ac000 C:\Windows\SysWOW64\msvcrt.dll 700001db04001 6000121be4001
0000000076d10000 000f0000 C:\Windows\SysWOW64\rpcrt4.dll 600011db04001 600011db04001
0000000074e20000 00060000 C:\Windows\SysWOW64\sspicli.dll 600011db04064 600011db04064
0000000074e10000 0000c000 C:\Windows\SysWOW64\CRYPTBASE.dll 600011db04001 600011db04001
00000000761e0000 00019000 C:\Windows\SysWOW64\sechost.dll 600011db04001 600011db04001
00000000763e0000 000a0000 C:\Windows\SysWOW64\advapi32.dll 600011db04001 600011db04001
000000006e810000 00025000 C:\Windows\System32\powrprof.dll 600011db04001 600011db04001
00000000768e0000 0019d000 C:\Windows\SysWOW64\setupapi.dll 600011db04001 600011db04001
0000000074f70000 00027000 C:\Windows\SysWOW64\cfgmgr32.dll 600011db04001 600011db04001
0000000076c80000 00090000 C:\Windows\SysWOW64\gdi32.dll 600011db04001 600011db04001
0000000076a80000 00100000 C:\Windows\SysWOW64\user32.dll 600011db04001 600011db04001
0000000077280000 0000a000 C:\Windows\SysWOW64\lpk.dll 600011db04001 600011db04001
0000000075140000 0009d000 C:\Windows\SysWOW64\usp10.dll 102721db04001 102721db04001
0000000076150000 0008f000 C:\Windows\SysWOW64\oleaut32.dll 600011db04001 600011db04001
0000000075ff0000 0015c000 C:\Windows\SysWOW64\ole32.dll 600011db04001 600011db04001
0000000074fa0000 00012000 C:\Windows\SysWOW64\devobj.dll 600011db04001 600011db04001
0000000074f10000 00060000 C:\Windows\System32\imm32.dll 600011db04001 600011db04001
0000000075020000 000cc000 C:\Windows\SysWOW64\msctf.dll 600011db04001 600011db04001
000000006fa00000 0003e000 C:\Program Files (x86)\Sophos\Sophos Anti-Virus\sophos_detoured.dll 900000000235f 9000000000000
00000000763d0000 00005000 C:\Windows\SysWOW64\psapi.dll 600011db04001 600011db04001
Crash IP Disasm :
test dword ptr [eax], eax

Debugging

Dia_study —— PDB查看工具

没事在家翻代码,发现大半年前的一份代码,写的是一个调用DIA SDK查看PDB文件的小工具。仔细想想我觉得还有点用处,而且使用方式简单,所以现在就发到blog上来吧。

简单介绍一下这个小工具。它可以dump出pdb的函数和数据结构的信息。下面两张图分别dump的是数据结构和函数的信息。

图一中,命令行为 dia_study.exe -p xxx.pdb -n processor -t 其实 -p是指pdb路径,-n是要获得的符号(支持通配符),-t说明要看的是数据结构而不是函数。然后所有带有processor的数据结构就会dump出来了。

20130120165712

图二中,命令行为 dia_study.exe -p xxx.pdb -n processor -f 唯一的区别就是-t变成了-f。指明要dump的是函数而非数据结构。

20130120165737

ok,使用方式就是如此简单。注意一点,请自备vs2010的c runtime 以及 msdia100.dll(需要注册),否则程序无法运行。

下载 dia_study

Debugging

NtfsStudy —— ntfs磁盘格式学习工具

经过将近一个月业余时间的开发,终于完成了NtfsStudy这个小工具的第一版。

简单介绍一下这个工具,NtfsStudy这个工具是我在学习Ntfs文件系统磁盘格式的时候,为了自己更加方便快捷的查看磁盘格式而开发的工具。可以说这个工具从开始写到现在发布,实际上也是一个学习ntfs的过程。我一边研究理解这个格式,一边把理解的东西写成代码,加入这个工具,然后再用这些功能去理解新的内容。反复这样做,这个工具就也不知不觉成型了。

NtfsStudy这个工具的主要功能是:枚举目录文件,查看和dump文件属性。这些功能都没用调用windows 文件操作类的API完成,而是依靠直接读取磁盘信息,并且解析磁盘信息来完成的。例如,如果尝试去复制注册表的系统hive文件,那是一定会被系统拒绝的,这个文件是系统读写独占的,但是通过这个工具就能绕过“ntfsstudy.exe -f c:\ -r e0a2 -w 3 d:\system.hiv”, 这个命令行的意思是把volume C上的引用数为0xe0a2文件中的3号属性的内容写到d:\system.hiv文件中。其实id为3的属性正好就是data属性,也就是文件本身的内容。这样就可以dump不能读的注册表hive文件了。下面是“ntfsstudy.exe -f c:\ -r e0a2 -d 8”的结果:

ntfs_hive

更多的详细用法和例子等我有空会在blog里面写一些。

下面就是他的Usage,也是目前该工具具有的功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
NtfsStudy v1.0 - Ntfs format study tool.
Copyright (C) 2012-2013 nightxie
0CCh - www.0cch.net
Usage : NtfsStudy.exe [options] -f file_path_name
-f file_path_name Specifies the target file path to parse.
options:
[-r file_reference]   Specifies the target file reference.
NtfsStudy will parse the REFERENCE rather than the path which
Specifies by -f. NtfsStudy will just use the path root.
[-a] Show the file record information of the target file.
[-l]   List the files in the directory.
[-w attribute_id output_file_path] Write target attribute to a file.
(The attribute size must less than 128mb)
[-v attribute_type] Show detail attribute information specified by attribute_type.
[-d attribute_type [start_offset range]] Show binary information specified by attribute_type.
[-s secure_id] Show the security descriptor specified by secure_id.
[-c] Show the attributes definition columns.
About attribute type:
$STANDARD_INFORMATION         = 1
$ATTRIBUTE_LIST               = 2
$FILE_NAME                    = 3
$OBJECT_ID                    = 4
$SECURITY_DESCRIPTOR          = 5
$VOLUME_NAME                  = 6
$VOLUME_INFORMATION           = 7
$DATA                         = 8
$INDEX_ROOT                   = 9
$INDEX_ALLOCATION             = 10
$BITMAP                       = 11
$REPARSE_POINT                = 12
$EA_INFORMATION               = 13
$EA                           = 14
$LOGGED_UTILITY_STREAM        = 16
About secure id:
To get the secure id of target file.
Use '-v 1' command, secure id will displayed in STANDARD_INFORMATION.

另外我还会继续完善这个工具。如果发现bug请与我联系。

下载NtfsStudy

NTInternals