import os
import struct
import lzma
import hashlib
DEBUG = False
BASE_ADDRESS = 0x00120200
class Base:
def __init__(self):
self.startFilePos = 0
self.data = bytearray(0x15C8)
class SingleFileData:
def __init__(self):
self.fileInt = [0, 0]
self._dataSize = 0
self.fileData = bytearray()
self.nextSingleFileData = None
class SingleFile:
def __init__(self):
self.startFilePos = 0
self.data = bytearray(0x194)
self._times = 0
self._isFolder = False
self._fileSize = 0
self.firstFileData = None
def read_base(file):
file.seek(BASE_ADDRESS)
base = Base()
base.startFilePos = file.tell()
base.data = bytearray(file.read(0x15C8))
return base
def read_next_file(file, need_data):
single_file = SingleFile()
single_file.startFilePos = file.tell()
single_file.data = bytearray(file.read(0x194))
single_file._isFolder = (single_file.data[200] == -1)
single_file._times = single_file.data[0x190]
first_file_data = None
for i in range(single_file._times):
file_data = SingleFileData()
file_data.fileInt = struct.unpack('<2I', file.read(8))
single_file._fileSize += file_data.fileInt[0]
if not single_file._isFolder:
if not DEBUG:
file_data.fileData = bytearray(file.read(file_data.fileInt[0]))
else:
file.seek(file_data.fileInt[0], os.SEEK_CUR)
if first_file_data is None:
single_file.firstFileData = file_data
first_file_data = file_data
else:
first_file_data.nextSingleFileData = file_data
first_file_data = file_data
return single_file
def extract_file(f, output_folder):
filename = re.sub(r'[^\w\-_. ]', '', f.data.decode("utf-16le").replace("\x00", ""))
path = os.path.join(output_folder, filename)
os.makedirs(os.path.dirname(path), exist_ok=True)
with open(path, "wb") as file_handle:
file_data = f.firstFileData
while file_data is not None:
if file_data.fileData is not None:
file_handle.write(file_data.fileData)
file_data = file_data.nextSingleFileData
return path
def calculate_md5(file_path):
hasher = hashlib.md5()
with open(file_path, "rb") as file:
for chunk in iter(lambda: file.read(4096), b""):
hasher.update(chunk)
return hasher.hexdigest()
def main():
output_folder = r"F:\The couers of He predecessor\The fourth lesson\data"
with open("F:/The couers of He predecessor/The fourth lesson/MeiqiaWinLatest.exe", "rb") as f:
base = read_base(f)
print(f"baseStartPos: {base.startFilePos:0x}")
while True:
file = read_next_file(f, not DEBUG)
if file._fileSize <= 0:
break
extracted_file_path = ""
if not DEBUG:
extracted_file_path = extract_file(file, output_folder)
md5 = ""
if extracted_file_path:
md5 = calculate_md5(extracted_file_path)
print(f"fileStartPos: {file.startFilePos:0x}\t\tisFolder: {file._isFolder}")
print(f"fileName: {file.data.decode('utf-16le')}\t\tfileZipSize: 0x{file._fileSize:0x}\n")
print(f"MD5: {md5}\n")
if __name__ == "__main__":
main()