forked from JokerDKha/SoS-FoMT-encrypt-code
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sosfomt_disc_zip.txt
325 lines (296 loc) · 12.5 KB
/
sosfomt_disc_zip.txt
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
# script for QuickBMS http://quickbms.aluigi.org
set ZIP_PASSWORD binary "\x97\x71\xE0\x75\x93\x9B\x99\xC2\xE7\x82\xE6\x89\x81\xE8\x82\x91\xE1\x59\x8D\xD8\x55\x9E\x98\xE0\xB7\x8B\x95\xE7\x5F\x91\xA0\x82\xC7\x9A\xB8\x9F\xC7\x4E\x96\x7D\x99\x5C\x93\x4F\xE8\x62\x9C\xCF\x89\x97\x97\x80\x8E\xC2\x8E\x56\x97\xA6\x82\xDC\x9A\xDD\x89\x55\x99\xFC\x89\xF9\x9D\xFB\x9D\xEB\x99\xF1\x9B\xB0\x53\x89\xA9\xE7\xC0\x93\x8E\x8F\x4E\xE2\x4B\xE3\x5B\x9D\xC8\x93\xAD\x9A\xAB\x94\x92\x83\x70\x9E\x67\x9D\x66\x9D\x5B\xE0\xE2\x4F\x95\x50\x8F\x41\xE7\x84\xE1\xB1\x96\x8C\x9E\xF0\x91\x63\x99\x77\x83\x94\xE8\x52\xE4\x81\xE0\xE5\x82\xC2\xE0\x63\xE2\xB0\x96\xE8\x8F\x7A\xEA\x9E\x91\x6B\x82\xEC\x9F\x47\x89\x64\xD4\x9B\x89\x9D\x53\x89\x40\x95\x81\x82\x58\x9F\x62\xE9\x47\x90\x77\xE9\xA1\x8C\x50\x8A\xBC\x9A\xD1\x99\xA4\x81\x8E\x97\xA6\x98\x6C\xE2\x77\xE9\x57\xE1\xD4\x94\xBB\xE0\x97\x9F\xD1\x83\x4D\x89\xD2\xE3\xD8\xE8\xC1\x99\x63\x8F\x8D\x93\xC7\xE1\x5C\x95\x8C\x8B\xF2\x94\xBF\xE1\x80\x8D\xC1\xE2\xE4\x82\xAC\x9A\xB6\xE4\x9C\x94\x9E\x84\x5A\x8E\x5A\x8B\xCF\x6A\xE8\x79\x9D\xD8\xE3\xA9\xEA\x86\xE1\xDE\xE1\x5C\x9B\xD9"
quickbmsver "0.7.4"
get EXE_SIGN long
goto 0
if EXE_SIGN == 0x00905a4d
get EXT extension
if EXT == "exe" || EXT == "dll"
findloc OFFSET string "PK\x03\x04"
goto OFFSET
endif
elif EXE_SIGN == 0x02014b50
findloc OFFSET binary "\x50\x4b\x03\x04"
goto OFFSET
endif
savepos OFFSET
set ZIP_SIGN short 0x0403
goto OFFSET
getdstring ZIP_CENTRAL_SEARCH 6 # PK_sign + sign + ver
goto OFFSET
get DUMMY short
get ZIP_SIGN short
math ALTERNATIVE_MODE = 0 # in reality this is the real correct mode to read the ZIP archives
math FIRST_FILE = 1
goto OFFSET
get zip_filesize asize
for offset = offset < zip_filesize
#idstring "PK\x03\x04"
get PK_sign short # so it works also with modified ZIP files!
get sign short
if sign == ZIP_SIGN # Local file header
get ver short
get flag short
get method short
get modtime short
get moddate short
get zip_crc long
get comp_size long
get uncomp_size long
get name_len short
get extra_len short
getdstring name name_len
getdstring extra extra_len
savepos offset
if FIRST_FILE != 0
math FIRST_FILE = 0
if flag & 8
if zip_crc == 0
if comp_size == 0
#if uncomp_size == 0 # needs to be commented out
goto -0x16
get PK_sign short
idstring "\x05\x06"
get disk_num short
get disk_start short
get central_entries short
get central_entries short
get central_size long
get central_offset long
get comm_len short # let's think it's zero
getdstring comment comm_len
math ALTERNATIVE_MODE = 1
math ALTERNATIVE_OFFSET = central_offset
math ALTERNATIVE_comp_size = 0
math ALTERNATIVE_uncomp_size = 0
math ALTERNATIVE_zip_crc = 0
set NAME string "/" # skip this file
math uncomp_size = 0 # skip this file
#endif
endif
endif
endif
endif
if ALTERNATIVE_MODE != 0
math comp_size = ALTERNATIVE_comp_size
math uncomp_size = ALTERNATIVE_uncomp_size
math zip_crc = ALTERNATIVE_zip_crc
endif
# zip64
if extra_len >= 20
getvarchr extra_id extra 0 short
if extra_id == 0x0001
if comp_size == 0xffffffff
getvarchr uncomp_size 4 longlong
getvarchr comp_size 12 longlong
endif
endif
endif
# possible lame tricks used by games
if comp_size & 0x80000000 # < 0
if comp_size u> zip_filesize
math comp_size ^= 0xffffffff
math uncomp_size ^= 0xffffffff
endif
endif
if name_len & 0x80000000 # < 0
math name_len ^= 0xffffffff
endif
if extra_len & 0x80000000 # < 0
math extra_len ^= 0xffffffff
endif
if flag & 1
if ZIP_PASSWORD == ""
print "the file is encrypted, you must set ZIP_PASSWORD in the script!"
#cleanexit
endif
math method_backup = method
if method == 99
getvarchr AES_EXTRA1 extra 0 short # Extra field header ID (0x9901)
getvarchr AES_EXTRA2 extra 2 short # Data size (currently 7, but subject to possible increase in the future)
getvarchr AES_EXTRA3 extra 4 short # Integer version number specific to the zip vendor
getvarchr AES_EXTRA4 extra 6 short # 2-character vendor ID
getvarchr AES_EXTRA5 extra 8 byte # Integer mode value indicating AES encryption strength
getvarchr AES_EXTRA6 extra 9 short # The actual compression method used to compress the file
math method = AES_EXTRA6
if AES_EXTRA5 == 0x01
math AES_KEY_SIZE = 8
set AES_ALGO string "ZIP_AES128"
elif AES_EXTRA5 == 0x02
math AES_KEY_SIZE = 12
set AES_ALGO string "ZIP_AES192"
elif AES_EXTRA5 == 0x03
math AES_KEY_SIZE = 16
set AES_ALGO string "ZIP_AES256"
else
print "Error: invalid AES_EXTRA5 %AES_EXTRA5%"
cleanexit
endif
getdstring AES_SALT AES_KEY_SIZE
xmath offset "offset + (AES_KEY_SIZE + 2)"
xmath comp_size "comp_size - (AES_KEY_SIZE + 2 + 10)"
strlen ZIP_PASSWORD_LEN ZIP_PASSWORD
encryption AES_ALGO ZIP_PASSWORD AES_SALT 0 ZIP_PASSWORD_LEN # long story short, set the password length or use "Set binary"
else
encryption zipcrypto ZIP_PASSWORD 1
endif
endif
if method == 0
Log name offset comp_size # was uncomp_size before AES
else
if method == 8
ComType deflate
elif method == 1
ComType shrink
elif method == 2
ComType reduce1
elif method == 3
ComType reduce2
elif method == 4
ComType reduce3
elif method == 5
ComType reduce4
elif method == 6
ComType pkware # ???
elif method == 9
ComType deflate64
elif method == 10
ComType pkware # ???
elif method == 12
ComType bzip2
elif method == 13
ComType XMemDecompress
elif method == 14
ComType lzmaefs
elif method == 18
ComType terse # ???
elif method == 21
ComType XMemDecompress
elif method == 34
ComType brotli
elif method == 64
ComType darksector
elif method == 95
comtype LZMA2_EFS0
getdstring XZ_MAGIC 6
get XZ_FLAGS0 byte
get XZ_FLAGS byte
get XZ_CRC32 long
xmath DUMMY "1 << ((((XZ_FLAGS & 0xf) - 1) / 3) + 2)"
getdstring DUMMY DUMMY
savepos tmp
xmath comp_size "comp_size - (tmp - offset)"
math offset = tmp
elif method == 96 # compressed jpeg
ComType copy
math uncomp_size = comp_size
string name + ".jpg"
elif method == 97 # wavpack
ComType copy
math uncomp_size = comp_size
string name + ".wv"
elif method == 98
ComType ppmd
elif method == 99
ComType lzfse
else
print "unsupported compression method %method%"
cleanexit
endif
CLog name offset comp_size uncomp_size
endif
if flag & 1
encryption "" ""
if method_backup == 99
math offset += 10
endif
endif
math offset += comp_size
goto offset
if ALTERNATIVE_MODE != 0
goto ALTERNATIVE_OFFSET
endif
elif sign == 0x0806 # Archive extra data record
get extra_len long
getdstring extra extra_len
elif sign == 0x0201 # Central directory structure
get ver_made short
get ver_need short
get flag short
get method short
get modtime short
get moddate short
get zip_crc long
get comp_size long
get uncomp_size long
get name_len short
get extra_len short
get comm_len short
get disknum short
get int_attr short
get ext_attr long
get rel_offset long
getdstring name name_len
getdstring extra extra_len
getdstring comment comm_len
if ALTERNATIVE_MODE != 0
math ALTERNATIVE_comp_size = comp_size
math ALTERNATIVE_uncomp_size = uncomp_size
math ALTERNATIVE_zip_crc = zip_crc
savepos ALTERNATIVE_OFFSET
goto rel_offset
endif
elif sign == 0x0505 # Digital Signature
get sign_len long
getdstring sign sign_len
elif sign == 0x0606 # Zip64 end of central directory record
get dir_record longlong
get ver_made short
get ver_need short
get num_disk long
get num_disk2 long
get tot_entries longlong
get tot_entries2 longlong
get central_size longlong
get central_offset longlong
print "Error: zip64 extensible data sector not implemented, contact me"
cleanexit
elif sign == 0x0706 # Zip64 end of central directory locator
get start_central long
get end_central longlong
get disks long
elif sign == 0x0605 # End of central directory record
get disk_num short
get disk_start short
get central_entries short
get central_entries short
get central_size long
get central_offset long
get comm_len short
getdstring comment comm_len
elif sign == 0x0807 # Data Descriptor
get zip_crc long
get comp_size long
get uncomp_size long
elif sign == 0x3030 # disk spanning
# nothing?
else
# A ZIP archive should be read from the end and not sequentially because in some rare cases
# we may have some "gaps" between the various directories, this is a basic way to guess
# the beginning of the next directory
# ZIP_CENTRAL_SEARCH contains zeroes that will not be considered, not a problem
print "...search ZIP signature..."
findloc NEW_OFFSET binary ZIP_CENTRAL_SEARCH ""
if NEW_OFFSET == ""
xmath COVERAGE "offset / (zip_filesize / 100)" # "(offset*100)/zip_filesize" may go in overflow on 32bit
set COVERAGE_OK string "not fully covered, lot of data remaining"
if COVERAGE >= 90
set COVERAGE_OK string "fully covered, probably no remaining data"
endif
print "\nError: unknown ZIP signature %sign|x% at offset %offset|x%\n if the other files have been extracted correctly it's all ok,\n maybe this is just the end of file:\n\n OFFSET %offset|x%\n ZIP SIZE %zip_filesize|x%\n COVERAGE %COVERAGE% / 100 (%COVERAGE_OK%)"
cleanexit
endif
goto NEW_OFFSET
endif
savepos offset
next