代码如下:
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
#!/usr/bin/python3
#http://www.frombyte.com 张宇
import
os
import
sys
import
random
import
hashlib
import
struct
import
zlib
import
re
def
help_exit():
print
(
" 命令格式:"
)
print
(
" python3 %s <File name> <Start bytes> <Start LCN> <Start VCN>:"
%
sys.argv[
0
])
print
(
" File name:要解释的包含runlist的文件名称"
)
print
(
" Start bytes:文件中要解释runlist的起始位置"
)
print
(
" Start LCN:runlist开始的参考LCN值,如果是一段完整的runlist,这个值应为0."
)
print
(
" Start VCN:runlist开始的参考VCN值,如果是一段没有0x20的runlist,这个值多数为0."
)
print
(
" *返回值:一个二维队列,打印结果。\n"
)
exit()
#通过抛出异常判断第一个参数是否是A-F
def
is_num_by_except(s):
try
:
a
=
int
(s,
16
)
if
(a>
0
and
a<
=
16
):
return
True
else
:
return
False
except
ValueError:
return
False
if
len
(sys.argv)!
=
5
:
print
(
" ***参数数量或格式错误!"
)
help_exit()
if
sys.argv[
2
].isdigit():
spoi
=
int
(sys.argv[
2
])
if
spoi<
0
:
print
(
"***错误,起始字节位置不能取负值"
)
help_exit()
else
:
print
(
"***错误,起始字节位置应为非负整数"
)
help_exit()
if
sys.argv[
3
].isdigit():
slcn
=
int
(sys.argv[
3
])
if
slcn<
0
:
print
(
"***错误,起始LCN不能取负值"
)
help_exit()
else
:
print
(
"***错误,起始LCN应为非负整数"
)
help_exit()
if
sys.argv[
4
].isdigit():
svcn
=
int
(sys.argv[
4
])
if
svcn<
0
:
print
(
"***错误,起始VCN不能取负值"
)
help_exit()
else
:
print
(
"***错误,起始VCN应为非负整数"
)
help_exit()
def
get_i(vl,ilen):
q
=
0
for
i
in
range
(
0
,ilen):
q
=
q | ( vl[
0
][i] << i
*
8
)
#若为负数
if
vl[
0
][ilen
-
1
] >
0x80
:
q
=
q
-
(
1
<< ilen
*
8
)
return
q
f
=
open
(
"%s"
%
sys.argv[
1
],
'rb'
)
f.seek(spoi)
data
=
f.read(
1024
)
v1
=
1
i
=
0
lists
=
[[
0
for
i
in
range
(
2
)] ]
del
lists[
0
]
while
True
:
t
=
struct.unpack_from(
'B'
,data,i)
v1
=
t[
0
]
if
v1
=
=
0
:
break
v1_p
=
(v1 &
0xF0
) >>
4
v1_l
=
(v1 &
0xF
)
if
(v1_l >
=
8
)
or
(v1_p >
=
8
)
or
(v1_l
=
=
0
):
print
(
"***偏移%d:run list长度和位置字节有错误!***"
%
(i
+
spoi))
break
i
=
i
+
1
if
(i
+
8
) >
=
1024
:
break
t
=
struct.unpack_from(
'8s'
,data,i)
v1_dl
=
get_i(t,v1_l)
if
v1_dl <
0
:
print
(
"***偏移%d:run片断长度不能为负!***"
%
(i
+
spoi))
break
i
=
i
+
v1_l
if
(i
+
8
) >
=
1024
:
break
t
=
struct.unpack_from(
'8s'
,data,i)
v1_dp
=
get_i(t,v1_p)
slcn
=
slcn
+
v1_dp
lists.append([slcn,v1_dl])
i
=
i
+
v1_p
#print("%x,%x:%x,%x"%(v1_l,v1_p,v1_dl,slcn))
print
(
"Runlist(共%d个片断):"
%
len
(lists))
print
(
"%20s%20s%20s"
%
(
"VCN"
,
"LCN"
,
"LEN"
))
for
i
in
lists:
print
(
"%20d%20d%20d"
%
(svcn,i[
0
],i[
1
]))
svcn
+
=
i[
1
]
f.close()
|
执行效果如下:
root@zhangyu-VirtualBox:~/NTFS-5# python3 read_runlist.py mft_source.img
***参数数量或格式错误!
命令格式:
python3 read_runlist.py <File name> <Start bytes> <Start LCN> <Start VCN>:
File name:要解释的包含runlist的文件名称
Start bytes:文件中要解释runlist的起始位置
Start LCN:runlist开始的参考LCN值,如果是一段完整的runlist,这个值应为0.
Start VCN:runlist开始的参考VCN值,如果是一段没有0x20的runlist,这个值多数为0.
*返回值:一个二维队列,打印结果。
root@zhangyu-VirtualBox:~/NTFS-5# python3 read_runlist.py mft_source.img 5688 0 0
Runlist(共18个片断):
VCN LCN LEN
0 32212 1
1 157952 2
3 207115 3
6 244046 3
9 122523 1
10 157991 1
11 170296 3
14 40552 5
19 149853 2
21 122721 2
23 141674 1
24 145783 3
27 158109 3
30 145820 1
31 240236 1
32 154081 1
33 166379 3
36 178711 3