安装包逆向2

本文档详细描述了一个Python程序,用于从名为MeiqiaWinLatest.exe的文件中读取基地址数据,解析单个文件及其子文件,提取文件内容,并计算文件MD5。程序包含类定义和相关函数,如读取文件、提取文件数据以及验证文件完整性。
摘要由CSDN通过智能技术生成
import os
import struct
import lzma
import hashlib

DEBUG = False  # 调试标志
BASE_ADDRESS = 0x00120200  # 基地址偏移量

# Base类,用于存储基地址的数据
class Base:
    def __init__(self):
        self.startFilePos = 0  # 基地址在文件中的起始位置
        self.data = bytearray(0x15C8)  # 存储基地址的数据

# SingleFileData类,用于存储单个文件的数据
class SingleFileData:
    def __init__(self):
        self.fileInt = [0, 0]  # 存储文件的大小和其他属性
        self._dataSize = 0  # 文件数据的大小
        self.fileData = bytearray()  # 文件数据
        self.nextSingleFileData = None  # 下一个文件数据节点的引用

# SingleFile类,用于存储单个文件的信息
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):
    # 创建SingleFile对象来存储文件信息
    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()  # 创建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

# 计算文件MD5值的函数
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)  # 计算文件的MD5值

            # 打印文件信息和MD5值
            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()


在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Back~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值