-
Notifications
You must be signed in to change notification settings - Fork 27
/
zip.nail
92 lines (88 loc) · 3.91 KB
/
zip.nail
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
!LITTLE-ENDIAN
// https://users.cs.jmu.edu/buchhofp/forensics/formats/pkzip.html
file_flags = {
encrypted uint1 | [0]
compression1 uint1 | [0]
compression2 uint1 | [0]
datadesc uint1 | [0]
enhanced_deflation uint1 | [0]
compressed_patch uint1 | [0]
strong_encrypted uint1 | [0]
uint4 = 0
utf8 uint1
uint1 = 0
maskheader uint1 | [0]
uint2 = 0
}
internal_attr = {
ascii uint1
uint1 = 0
control uint1 | [0]
uint13 = 0
}
fileentry(@crc32 uint32,@compression_method uint16,@compressed_size uint32, @uncompressed_size uint32) = {
uint32 = 0x04034b50
version uint16
flags file_flags
@compression_method_local uint16
mtime uint16 //TODO: Extend dependencies for duplicated data
mdate uint16
@crc32_local uint32
@compressed_size_local uint32
@uncompressed_size_local uint32
@filename_len uint16
@extra_len uint16
filename n_of @filename_len uint8
extra n_of @extra_len uint8
$compressed transform size_u32 ($current @compressed_size)
$uncompressed transform zip_compression ($compressed @compression_method @uncompressed_size)
transform crc_32 ($uncompressed @crc32)
contents apply $uncompressed many uint8
transform uint16_depend (@compression_method_local @compression_method)
transform uint32_depend (@crc32_local @crc32)
transform uint32_depend (@compressed_size_local @compressed_size)
transform uint32_depend (@uncompressed_size_local @uncompressed_size)
}
dir_fileheader($filestream) = { //TODO: we need to make the filename depend
uint32 = 0x02014b50
os uint16
pkzip_version uint16
flags file_flags
@compression_method uint16
mtime uint16
mdate uint16
@crc32 uint32
@compressed_size uint32
@uncompressed_size uint32
@file_name_len uint16
@extra_len uint16
@comment_len uint16
disk uint16 | [0] // TODO: We need to do multidisk
internal internal_attr
external_attr uint32
@off uint32
filename n_of @file_name_len uint8
extra_field n_of @extra_len uint8
comment n_of @comment_len uint8
$contentstream transform offset_u32 ($filestream @off)
contents apply $contentstream fileentry(@crc32,@compression_method,@compressed_size, @uncompressed_size)
}
end_of_directory($filestream) = {
uint32 = 0x06054b50
disks uint16 | [0]
directory_disk uint16 | [0]
@this_disk_directory_records uint16
@total_directory_records uint16
@directory_size uint32 // Byte size
@directory_start uint32
$dirstr1 transform offset_u32 ($filestream @directory_start) //TODO: how can we get the offset properly
$directory_stream transform size_u32 ($dirstr1 @directory_size)
@comment_length uint16
comment n_of @comment_length uint8
files apply $directory_stream n_of @total_directory_records dir_fileheader($filestream)
transform uint16_depend (@this_disk_directory_records @total_directory_records)
}
zip_file = {
$filestream, $end_directory transform zip_end_of_directory ($current)
contents apply $end_directory end_of_directory($filestream)
}