UndercoverBoy833 Posted April 12 Posted April 12 (edited) I really need help with Asphalt Legends UNITE PC version unknown files because I really wanted to dump the game files using BigChillGhost's python script and manifest.map but this script only supports v3.6.3a Android version and my sample file is v24.5.130.0 PC version (the latest version) because there's even more unicorn cars i wanted to rip. Is there anyone who can help me with it? The process on how to rip all assets from separate apks using both manifest.map and the python script (For Android version of Asphalt 9 Legends Unite) was: I) put both manifest.map and the python file in the dump folder with encrypted files II) run the python script. It'll rename all the filenames contained in the manifest.map manifest.7z restoreFileHierarchy.py Asphalt 9 PC sample.7z In the meantime, I'll also link my other topic relating to Asphalt 9/Legends Unite jmodel: Edited April 13 by UndercoverBoy833 Linking my other link related to it + the steps of extracting unknown files
wq223 Posted April 18 Posted April 18 On 2025/4/12 at PM4点55分, UndercoverBoy833 said: 我急需《狂野飙车:联合》PC 版未知文件的帮助,因为我真的很想用 BigChillGhost 的 Python 脚本和 manifest.map 转储游戏文件,但这个脚本只支持 v3.6.3a 安卓版本,而我的示例文件是 v24.5.130.0 PC 版(最新版本),因为里面还有更多独角兽车我想提取。有谁能帮我吗? 使用 manifest.map 和 python 脚本(针对 Android 版 Asphalt 9 Legends Unite)从单独的 apk 中提取所有资产的过程如下: I) 将 manifest.map 和 python 文件放入包含加密文件的 dump 文件夹中 II) 运行 python 脚本。它将重命名 manifest.map 中包含的所有文件名 清单.7z 207.24 千字节 · 1 次下载 恢复文件层次结构.py 796 B · 1 次下载 狂野飙车9 PC 样本.7z 1.89 MB · 2 次下载 与此同时,我还将链接与 Asphalt 9/Legends Unite jmodel 相关的其他主题: Some of the files you provide contain zstd compression File Type 1:89 6A 74 65 78 20 78 0D Compression position is 0x5B But there are 22 bytes of additional data before this These additional data need to be added to the compressed file at the same time and skipped when decompressed 4 bytes - extra data + total compressed data size 4 bytes - unknown, very close to the size of the compressed data 4 bytes - Decompressed size (correct) File Type 2:89 6A 6D 6F 78 0D 0A 01 The example of this file starts after 510 bytes Because two unknowns need to be read, four compression sizes and four decompressed sizes File Type 3:02 AF EA 61 6E 67 69 65 79 EC DC 47 The verification is too small, and I haven't seen whether there is compression for the time being, I'm not sure For the first two data, I wrote a script to decompress the compressed data inside and directly extract binary data of unknown structures. All research is based on guessing from existing files, if a more complete script is needed, you may need to add features based on more files, because I can't guarantee that the offsets displayed by each file are the same import os import struct import pyzstd import random import string from pathlib import Path def random_filename(length=16, extension='.bin'): chars = string.ascii_letters + string.digits return ''.join(random.choice(chars) for _ in range(length)) + extension def process_first_format(f): extracted_data = [] f.seek(69) while True: position = f.tell() size_bytes = f.read(4) if len(size_bytes) < 4: break data_size = struct.unpack('<I', size_bytes)[0] remaining_size = data_size - 4 data = f.read(remaining_size) if len(data) < remaining_size: print(f"Insufficient data @ {position}") break full_data = size_bytes + data processed_data = full_data[22:] if len(full_data) > 22 else full_data if len(processed_data) >= 4 and processed_data[:4] == bytes.fromhex('28 B5 2F FD'): try: extracted_data.append(pyzstd.decompress(processed_data)) except Exception as e: print(f"Decompression failed: {e}") extracted_data.append(processed_data) else: extracted_data.append(processed_data) return extracted_data def process_second_format(f): extracted_data = [] f.seek(510) while True: position = f.tell() unknown = f.read(2) if len(unknown) < 2: break compression_info = f.read(8) if len(compression_info) < 8: break compressed_size = struct.unpack('<I', compression_info[:4])[0] compressed_data = f.read(compressed_size) if len(compressed_data) < compressed_size: print(f"Insufficient data @ {position}") break if len(compressed_data) >= 4 and compressed_data[:4] == bytes.fromhex('28 B5 2F FD'): try: extracted_data.append(pyzstd.decompress(compressed_data)) except Exception as e: print(f"Decompression failed: {e}") extracted_data.append(compressed_data) else: extracted_data.append(compressed_data) return extracted_data def process_single_file(input_file, output_dir): try: with open(input_file, 'rb') as f: header = f.read(8) if header == bytes.fromhex('89 6A 74 65 78 20 78 0D'): print(f"Processing {input_file} (Format 1)") results = process_first_format(f) elif header == bytes.fromhex('89 6A 6D 6F 78 0D 0A 01'): print(f"Processing {input_file} (Format 2)") results = process_second_format(f) else: print(f"Skipping {input_file} (Unknown format)") return for i, data in enumerate(results, 1): output_path = Path(output_dir) / random_filename() with open(output_path, 'wb') as out_file: out_file.write(data) print(f"Saved block {i} from {input_file}") except Exception as e: print(f"Error processing {input_file}: {e}") def process_directory(input_dir, output_dir): Path(output_dir).mkdir(parents=True, exist_ok=True) for entry in os.scandir(input_dir): if entry.is_file(): process_single_file(entry.path, output_dir) if __name__ == '__main__': import sys if len(sys.argv) != 3: print("Usage: python asphalt.py <input_directory> <output_directory>") sys.exit(1) process_directory(sys.argv[1], sys.argv[2]) 1
Engineers shak-otay Posted April 19 Engineers Posted April 19 (edited) Skipping this additional data may do the trick. A9tool (which comes with libzstd.dll, btw, if user cared for BigChillghosts post more carefully) gives me this: a9tool c.jtex Error: missing configuration file! Default settings have been used! Processing c.jtex... 1048576, 262144, 65536, 16384, 4096, 1024, 256,finished (Where c.jtex is renamed 000C022A608FF242 for easier handling on command line.) The resulting c.jtex.pvr doesn't show a valid tex, so I'll recompile libzstd asap, with taking the additional data into acount. Thanks for the hint. (I'd like to check your python code, but module pyzstd is not standard (haha) on Windows systems.) Edited April 19 by shak-otay
wq223 Posted April 19 Posted April 19 (edited) This work is done on other systems, because I can't install pyzstd on Windows system, it may be a problem with my python version, maybe some alternatives can be used Edited April 19 by wq223
Engineers shak-otay Posted April 21 Engineers Posted April 21 (edited) I got your script running under windows after python -m pip install pyzstd==0.15.3 and 11 bins where created from the c.jtex mentioned here. I compared the biggest bin file (1 MB) to the c.jtex.pvr (from offset 0x34) created by A9tool and the data is identical (apart from the fact that c.jtex.pvr is bigger). So far so good. But why then doesn't the pvr contain a valid texture? Edited April 21 by shak-otay
UndercoverBoy833 Posted April 21 Author Posted April 21 34 minutes ago, shak-otay said: I got your script running under windows after python -m pip install pyzstd==0.15.3 and 11 bins where created from the c.jtex mentioned here. I compared the biggest bin file (1 MB) to the c.jtex.pvr (from offset 0x34) created by A9tool and the data is identical (apart from the fact that c.jtex.pvr is bigger). So far so good. But why then doesn't the pvr contain a valid texture? probably different format, also have you tried getting into game memory for any file format type in the PC version (Windows Store) of this game? If not, then it's probably that.
Engineers shak-otay Posted April 21 Engineers Posted April 21 (edited) How should "getting into game memory" help? I guess it's another problem because the biggest decompressed block has some structures: edit: I have a working file, car_Lamborghini_Terzo_Millennio_details_mk.tga.jtex, which provides a valid pvr, so I think I need to understand the .jtex headers. What I found is that the above shown pvr picture has the pixelformat ASTC_5x5x5, while the valid pvr has ETC2 RGB. Edited April 21 by shak-otay
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now