--- categories: Original date: 2025-01-18T00:00:00Z tags: - 信息技术 - 逆向工程 slug: unpack-cheat-engine title: 提取并还原 Cheat Engine 导出的可执行文件 --- ## 处理可执行文件并获取`CETRAINER` XML [cetrainer-unpacker](https://github.com/AlexAltea/cetrainer-unpacker) [Rust 版本](https://www.unknowncheats.me/forum/general-programming-and-reversing/649970-cheat-engine-trainer-unpacker-decryptor.html) [Mirror](./cetrainer-unpacker-v1.0.0_[unknowncheats.me]_.zip) ## 读取`CETRAINER`中的`Ascii85` [unpack_ce_trainer.py](https://gist.github.com/0x1F9F1/3744179f47e190cbbf35dac34e048c66) ```python import base64 import json import os import struct import xml.etree.ElementTree as ET import zlib ce_base85_char_map = dict( zip( "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%()*+,-./:;=?@[]^_{}", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~", ) ) def decode_ce_base85(data): return base64.b85decode("".join(ce_base85_char_map[v] for v in data)) def decrypt_ce_trainer(data): for j in range(2, len(data)): data[j] ^= data[j - 2] for j in reversed(range(0, len(data) - 1)): data[j] ^= data[j + 1] key = 0xCE for j in range(len(data)): data[j] ^= key key = (key + 1) & 0xFF assert data[0:5].decode("ascii") == "CHEAT", "Invalid Trainer" return zlib.decompress(data[5:], -zlib.MAX_WBITS)[4:] def read_pascal_string(data, offset): length = data[offset] offset += 1 result = data[offset : offset + length].decode("ascii") offset += length return result, offset def read_form_raw_data(data): offset = 0 (data_length,) = struct.unpack_from("