-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.js
109 lines (101 loc) · 3.72 KB
/
app.js
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
const fs = require('fs');
let MFT = [
'Offset to fixup array',
'Number of entries in fixup array',
'$LogFile sequence number',
'Sequence value',
'Link count',
'Offset to first attribute',
'Flags',
'Used size of MFT entry',
'Allocated size of MFT entry',
'Next attribute identifier'
]
let SECTION = [
['Attribute Type Identifier', undefined, 'int'],
['Length of Attribute', 4, 'int'],
['Non-resident flag', 4, 'short'],
['Lenght of name', 1, 'short'],
['Offset to name', 1, 'short'],
['Flags', 2, 'short'],
['Attribute Identifier', 2, 'short'],
['Empty1', 2, 'short'],
{
resident: [
['Size of content', undefined, 'int'],
['Offset to content', 4, 'short']
],
non_resident: [
['Starting Virtual Cluster Number of the runlist', undefined, 'short'],
['Ending Virtual Cluster Number of the runlist', 8, 'short'],
['Offset to the runlist', 8, 'short'],
['Compression unit size', 2, 'short'],
['unused', 2, 'short'],
['Allocated size of the attribute content', 4, 'short'],
['Actual size of attribute content', 8, 'short'],
['Initialized size of the attribute content', 8, 'short'],
]
},
['Empty1', 2, 'short']
]
class mft {
output() {
this.data = fs.readFileSync(__dirname + '/MFT.bin').slice(4)
this.offset = 0
this.header = {}
let bytes = this.getBytes(this.data); bytes[8].bytes++
console.log("----------------------------------------");
MFT.forEach((name, i) => { let buffer = bytes[i]; this.header[name] = this.getData(buffer.offset, buffer.bytes); })
Object.keys(this.header).reduce((name, key) => {
console.log(key +': ' + this.header[key] )}, 11)
console.log("----------------------------------------");
this.attributes = this.getAttribytes(this.header['Offset to first attribute'])
}
getAttribytes(length) {
let attributes = []
let identifier
while (this.data.length) {
identifier = this.getData(length - this.offset, 4)
length = this.getData(2, 2) - 2 + this.offset
if (isNaN(length) || length - this.offset <= 0) break
attributes.push(this.getAttribyte(identifier, length - this.offset))
console.log("----------------------------------------");
}
return attributes;
}
getAttribyte(identifier, length) {
let getType = str => ({ 'short': 1, 'int': 2, 'long': 4 }[str])
let attribute = {}
attribute[SECTION[0][0]] = identifier
attribute[SECTION[1][0]] = length
SECTION.slice(2, 8).forEach(([name, offset, type]) => attribute[name] = this.getData(offset, getType(type)))
Object.keys(attribute).reduce((name, offset, type) => {console.log(offset +': ' + attribute[offset] )
}, 11)
return attribute
}
getData(offset, bytes) {
this.offset += offset
let data = this.data.slice(0, offset)
this.data = this.data.slice(offset)
return parseInt(data.slice(-bytes).reverse().toString('hex'), 16)
}
getBytes(mft) {
let res = []
let bytes = 0, offset = 0
for (let i = 0; i < mft.length; i++) {
offset++
if (mft[i] != 0) bytes++
else {
if (bytes != 0) {
res.push({ offset: offset - 1, bytes })
bytes = 0
offset = 1
}
}
}
return res
}
toString = () => ({ header: this.header, attribytes: this.attributes })
}
let test= new mft();
test.output();