Guest User

DragonQuest_XI.bms v3

a guest
Sep 13th, 2018
2,930
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.86 KB | None | 0 0
  1. # Unreal Engine 4 - Unreal Tournament 4 (*WindowsNoEditor.pak) (script 0.4.20a)
  2. # script for QuickBMS http://quickbms.aluigi.org
  3.  
  4. # Modified for Dragon Quest XI by infogram :) (version 3)
  5. # NOTE: ONLY FOR DRAGON QUEST XI! Other UE4 games will be incompatible with this script!
  6.  
  7. math NO_TAIL_INFO = 0 # set it to 1 for archives with corrupt/missing tail information
  8.  
  9. quickbmsver "0.8.4"
  10.  
  11. math TOC_FILE = 0
  12.  
  13. # set your AES_KEY here as text or C string ("\x11\x22...") or umodel hex (0x1122...)
  14. set AES_KEY binary "JACK-NE-KEY-1QaZ2WsX3EdC4RfV5TgB"
  15. putarray 10 -1 "KIWIKIWIKIWIKIWIKIWIKIWIKIWIKIWI" # first beta of Street Fighter V
  16. putarray 10 -1 "_aS4mfZK8M5s5KWC2Lz2VsFnGKI7azgl" # current version of Street Fighter V
  17. putarray 10 -1 "bR!@nbR0wnc@rychR!$d@nd@v3d3R3kj!mj0$hk3v!nm!ch@3lm!k3s3@nst3v3t!m" # Victory: The Culling
  18. putarray 10 -1 "casd#55@#$%323!$^#b%05sa5W|hhaf4365s52ss51|55m!|{55s^@@36f233|-|0w@%3g8hssDk35/!Nm|_|%ds23%a32d5&23as3%12p|-|y$t3ds562d23fav3c@dyw38#49" # Victory: The Culling
  19. putarray 10 -1 "C8C4847F3B4FA52D4AAD57A52358CDBC" # Injustice 2 (iOS)
  20. putarray 10 -1 "k14z0ZLR8a7jNm49uyBzxXYY9LpTHcehLSNiC3jAkzBsffPuy8YsTa72RLD9KWIn" # Gal*Gun VR
  21. putarray 10 -1 "E7@[dZfoYCW;+YWR;0JK^{9tt:yU0_T&" # Marvel VS Capcom - Infinite
  22. putarray 10 -1 "E1A1F2E4AA066C54BD5090F463EDDF58D01684243672B3CE809FF47FF473B04A" # OverHit
  23. putarray 10 -1 "I0vV6wr0TFbg3m23QuSIwnYC1sI0AIDq" # Fernbus
  24. putarray 10 -1 "y298qjSb115NqQ3Agad30DWn2QYrTI8CT6aP05l2PBV9Qe92S94PdoVCCy06A38L" # Fortnite
  25. putarray 10 -1 "b9uW0RKNY91be8HN3Lemi68j6Xsi2l7fQJYsp5oR4al4C4c9kY5E0l90411l9P3L" # Dragonball FighterZ
  26. putarray 10 -1 "45DD15D6DD2DA50AEB71CE7A5284CF8EA498B2EC3D52B7E336F3EA0071CE44B3"
  27. putarray 10 -1 "MRZpemumg6t2AXExrMQs6TSoZRG+YSABK338oc6F8kTXu4k6QffJgYAzKl65Tk2L"
  28. putarray 10 -1 "0x9D8C9A4A4FA082F213EED604B6E756237181685EEDA82216437617D7AA5231AF"
  29. putarray 10 -1 ""
  30. math AES_KEY_IS_SET = 0
  31.  
  32. math ALTERNATIVE_MODE = 0
  33.  
  34. get ARCHIVE_NAME basename
  35. get ARCHIVE_PATH FILEPATH
  36.  
  37. math VERSION = 0
  38.  
  39. math CHUNK_OFFSET_ABSOLUTE = -1 # default, enabled
  40.  
  41. # 1 = HIT
  42. math WORKAROUND = 0
  43.  
  44. if NO_TAIL_INFO != 0
  45. get OFFSET asize
  46. math ALTERNATIVE_MODE = 1
  47. else
  48. goto -0x2c
  49. get MAGIC long #idstring "\xe1\x12\x6f\x5a" # 0x5a6f12e1
  50. endian guess MAGIC # 0x5a6f12e1:le, 0xe1126f5a:be
  51. if MAGIC == 0x1233a # HIT game
  52. math WORKAROUND = 1
  53. elif MAGIC == 0x1066a # OverHit
  54. math WORKAROUND = 1
  55. elif MAGIC == 0x13aed # OverHit
  56. math WORKAROUND = 1
  57. elif ARCHIVE_NAME & "OverHit"
  58. math WORKAROUND = 1
  59. elif ARCHIVE_NAME == "0" # HIT
  60. math WORKAROUND = 1
  61. elif ARCHIVE_PATH & "Gears of War 4"
  62. math WORKAROUND = 2
  63. endif
  64. get VERSION long
  65. get OFFSET longlong
  66. get SIZE longlong
  67. getdstring HASH 20
  68. if WORKAROUND == 1
  69. math VERSION = 3
  70. endif
  71.  
  72. if VERSION >= 3
  73. goto -0x2d
  74. get ENCRYPTED byte
  75. if ENCRYPTED != 0
  76. callfunction SET_AES_KEY 1
  77. log MEMORY_FILE10 OFFSET SIZE
  78. encryption "" ""
  79. math TOC_FILE = -10 # MEMORY_FILE10 is -10
  80. endif
  81. endif
  82.  
  83. goto OFFSET # don't use TOC_FILE
  84. callfunction GET_NAME 1
  85. endif
  86.  
  87. if ALTERNATIVE_MODE == 0
  88. get FILES long TOC_FILE
  89. else
  90. math FILES = 0x7fffffff
  91. math MAX_OFF = OFFSET
  92. goto 0
  93. set NAME string ""
  94. endif
  95.  
  96. math CHUNK_SIZE = 0x10000 # just in case...
  97. for i = 0 < FILES
  98. if ALTERNATIVE_MODE == 0
  99. callfunction GET_NAME 1
  100. if NAMESZ == 0 # lame work-around for Conan Exiles
  101. callfunction GET_NAME 1
  102. endif
  103. endif
  104. savepos TMP_OFF # no need to use TOC_FILE in savepos/goto
  105.  
  106. get OFFSET longlong TOC_FILE
  107. if WORKAROUND == 2
  108. get ZSIZE long TOC_FILE
  109. get SIZE long TOC_FILE
  110. get ZIP byte TOC_FILE
  111. else
  112. get ZSIZE longlong TOC_FILE
  113. get SIZE longlong TOC_FILE
  114. get ZIP long TOC_FILE
  115. endif
  116. if WORKAROUND == 1
  117. getdstring HASH 20 TOC_FILE
  118. elif VERSION <= 1
  119. get TSTAMP longlong TOC_FILE
  120. endif
  121. if WORKAROUND == 2
  122. else
  123. getdstring HASH 20 TOC_FILE
  124. endif
  125. math CHUNKS = 0
  126. math ENCRYPTED = 1
  127. if VERSION >= 3
  128. if ZIP != 0
  129. get CHUNKS long TOC_FILE
  130. for x = 0 < CHUNKS
  131. get CHUNK_OFFSET longlong TOC_FILE
  132. get CHUNK_END_OFFSET longlong TOC_FILE
  133. putarray 0 x CHUNK_OFFSET
  134. putarray 1 x CHUNK_END_OFFSET
  135. next x
  136. endif
  137. if WORKAROUND == 2
  138. else
  139. get ENCRYPTED byte TOC_FILE
  140. endif
  141. get CHUNK_SIZE long TOC_FILE
  142. endif
  143. math ENCRYPTED = 0
  144. if WORKAROUND == 1
  145. if ARCHIVE_NAME == "0" # HIT game only!
  146. math ENCRYPTED = 0
  147. endif
  148. endif
  149. if ALTERNATIVE_MODE != 0
  150. savepos TMP_OFF
  151. math OFFSET + TMP_OFF
  152. endif
  153.  
  154. comtype copy # for AES
  155. if ZIP & 1
  156. comtype zlib
  157. elif ZIP & 2
  158. comtype gzip
  159. elif ZIP & 4
  160. comtype snappy
  161. if VERSION >= 6
  162. comtype oodle
  163. endif
  164. if WORKAROUND == 2
  165. comtype lz4
  166. endif
  167. elif ZIP & 0x10
  168. comtype oodle
  169. endif
  170. if ZIP == 3 # JoyfunRPG / Faith of Danschant
  171. comtype oodle
  172. endif
  173.  
  174. if CHUNKS > 0
  175. log NAME 0 0
  176. append
  177. math TMP_SIZE = SIZE
  178. if CHUNK_OFFSET_ABSOLUTE < 0 && OFFSET != 0
  179. getarray CHUNK_OFFSET 0 0
  180. if CHUNK_OFFSET u< OFFSET
  181. math CHUNK_OFFSET_ABSOLUTE = 0
  182. else
  183. math CHUNK_OFFSET_ABSOLUTE = 1
  184. endif
  185. endif
  186. for x = 0 < CHUNKS
  187. getarray CHUNK_OFFSET 0 x
  188. getarray CHUNK_END_OFFSET 1 x
  189. math CHUNK_ZSIZE = CHUNK_END_OFFSET
  190. math CHUNK_ZSIZE - CHUNK_OFFSET
  191. if ENCRYPTED != 0
  192. callfunction SET_AES_KEY 1
  193. math CHUNK_ZSIZE x 16
  194. endif
  195.  
  196. if TMP_SIZE u< CHUNK_SIZE
  197. math CHUNK_SIZE = TMP_SIZE
  198. endif
  199. if CHUNK_OFFSET_ABSOLUTE == 0
  200. math CHUNK_OFFSET + OFFSET
  201. endif
  202.  
  203. # DQXI: data gets XOR'd with DEADFADEBEEFCAFE, then NOT'd (in other words, XOR'd with 0xFF)
  204. # so we do it in reverse: NOT the data we read, then XOR with DEADFADE
  205. # do this by telling QBMS to XOR all files reads using "filexor", then tell it to XOR writes using "encryption xor"
  206. # so it'll: read -> filexor -> encryptionxor -> write
  207.  
  208. encryption xor "\xDE\xAD\xFA\xDE\xBE\xEF\xCA\xFE"
  209.  
  210. # DQXI: only compressed files have the compressed data NOT'd for some reason
  211. # uncompressed files don't, so make sure not to enable filexor for uncompressed files
  212. if ZIP != 0
  213. filexor 0xFF
  214. endif
  215.  
  216. clog NAME CHUNK_OFFSET CHUNK_ZSIZE CHUNK_SIZE
  217.  
  218. filexor "" # disable filexor
  219.  
  220. math TMP_SIZE - CHUNK_SIZE
  221. next x
  222. append
  223. else
  224. # the file offset points to an entry containing
  225. # the "same" OFFSET ZSIZE SIZE ZIP HASH ZERO fields,
  226. # just an additional backup... so let's skip them
  227. savepos BASE_OFF
  228. math BASE_OFF - TMP_OFF
  229. math OFFSET + BASE_OFF
  230. if ENCRYPTED != 0
  231. callfunction SET_AES_KEY 1
  232. math ZSIZE x 16
  233. endif
  234. clog NAME OFFSET ZSIZE SIZE
  235. endif
  236. encryption "" ""
  237.  
  238. if ALTERNATIVE_MODE != 0
  239. math OFFSET + ZSIZE
  240. goto OFFSET
  241. if OFFSET == MAX_OFF
  242. break
  243. endif
  244. if VERSION >= 4
  245. padding 0x800 # necessary for WitchIt
  246. endif
  247. endif
  248. next i
  249.  
  250. startfunction SET_AES_KEY_ASK
  251. math AES_KEY_IS_SET = 1
  252. print "The archive is encrypted, select the number of the key to use or type yours:"
  253. for z = 0
  254. getarray KEY 10 z
  255. if KEY == ""
  256. break
  257. endif
  258. print "%z%: %KEY%"
  259. next z
  260. print "%z%: press RETURN for no encryption (Lineage 2 Revolution)"
  261. set KEY unknown "???"
  262. strlen TMP KEY
  263. if KEY == ""
  264. math AES_KEY_IS_SET = -1
  265. set AES_KEY string "no key, encryption disabled"
  266. elif TMP <= 2
  267. getarray AES_KEY 10 KEY
  268. if AES_KEY strncmp "0x"
  269. string AES_KEY << 2
  270. string AES_KEY h AES_KEY
  271. endif
  272. elif KEY strncmp "0x"
  273. string KEY << 2
  274. string AES_KEY h KEY
  275. else
  276. set AES_KEY binary KEY
  277. endif
  278. print "KEY: %AES_KEY%"
  279. endfunction
  280.  
  281. startfunction SET_AES_KEY
  282. if AES_KEY_IS_SET == 0
  283. callfunction SET_AES_KEY_ASK 1
  284. endif
  285. if AES_KEY_IS_SET > 0
  286. encryption aes AES_KEY "" 0 32
  287. endif
  288. endfunction
  289.  
  290. startfunction GET_NAME
  291. get NAMESZ signed_long TOC_FILE
  292.  
  293. if NAMESZ >= 0
  294. if NAMESZ > 0x200
  295. math ALTERNATIVE_MODE = 1
  296. else
  297. getdstring NAME NAMESZ TOC_FILE
  298. endif
  299. else
  300. math NAMESZ n NAMESZ
  301. if NAMESZ > 0x200
  302. math ALTERNATIVE_MODE = 1
  303. else
  304. math NAMESZ * 2
  305.  
  306. # DQXI: filename xor key is DEADFADEBEEFCAFE, 0x00 spaces between the key because only the upper byte of the unicode char gets xor'd
  307. filexor "0xDE 0x00 0xAD 0x00 0xFA 0x00 0xDE 0x00 0xBE 0x00 0xEF 0x00 0xCA 0x00 0xFE 0x00"
  308.  
  309. getdstring NAME NAMESZ TOC_FILE
  310. set NAME unicode NAME
  311.  
  312. string NAME - 2 # DQXI: after XORing an extra gibberish char is added, this'll remove it
  313. filexor ""
  314. endif
  315. endif
  316. endfunction
Add Comment
Please, Sign In to add comment