Created
October 15, 2021 06:27
-
-
Save jessy-lua/d080b7bf499d72d2911f9bb15d9f2fc5 to your computer and use it in GitHub Desktop.
New World oodle preset for QuickBMS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ZIP files example 0.4.11 | |
# more info: http://www.pkware.com/documents/casestudies/APPNOTE.TXT | |
# note that with some archives like those created by Stuff-it on MacOSX is | |
# not possible to use this script because they are wrongly built, practically | |
# they set the comp_size and uncomp_size fields of the "Local file header" at | |
# 0 and they set them only in the relative "Central directory structure" which | |
# means that it's necesary to read this one first for extracting the files | |
# contained in the local header... senseless and stupid | |
# script for QuickBMS http://quickbms.aluigi.org | |
# put the password here, it supports both ZipCrypto and AES | |
set ZIP_PASSWORD string "" | |
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 == 15 | |
ComType oodle | |
elif method == 18 | |
ComType terse # ??? | |
elif method == 21 | |
ComType XMemDecompress | |
elif method == 28 | |
ComType lz4f | |
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 |
@jessy-lua do you happen to remember the source of the compression methods that aren't in either APNOTE or the infozip equivalent.
In particular,
- 13 ComType XMemDecompress
- 14 lzmaefs
- 15 oodle
- 21 XMemDecompress
- 28 lz4f
- 34 brolti
- 64 darksector
@jessy-lua do you happen to remember the source of the compression methods that aren't in either APNOTE or the infozip equivalent.
In particular,
- 13 ComType XMemDecompress
- 14 lzmaefs
- 15 oodle
- 21 XMemDecompress
- 28 lz4f
- 34 brolti
- 64 darksector
I even don't know what this means, sorry 🤷♂️
No worries.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
During the Reimport xml file there is an error that the modified file is larger than the original, although this is not true.
The console shows that the original compressed file weighs 1895 bytes, while the new file is only compressed to 2410 bytes and also "Error: zip64 extensible data sector not implemented, contact me".
Bad compression method or what is the problem?