本文共 3423 字,大约阅读时间需要 11 分钟。
代码如下:
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