PE 覆盖层从文件偏移 0x54600 开始,即 PyInstaller 归档数据。归档末尾(偏移 0x717f0b)存放 PyInstaller Cookie(魔数 MEI\x0c\x0b\x0a\x0b\x0e),记录了包长度、TOC 偏移、Python 版本(313)等元信息。
归档包含 21 个条目:
使用 Python 3.13 的 marshal 模块反序列化 main 条目的字节码,结果如下:
完整反汇编:
co_consts = (0, None),co_names = ('sys', 'exit'),无嵌套代码对象。
主脚本仅执行 sys.exit(0),不包含任何挑战逻辑。 这是一个障眼法,引导逆向分析者误以为程序什么也不做。
PYZ 归档包含 112 个模块,全部为 Python 3.13 标准库模块(__future__、argparse、base64、email.*、importlib.*、json.*、zipfile.* 等)。
对所有 112 个模块的解压数据进行全文搜索:
PYZ 归档中不含任何用户代码或挑战逻辑。
对 PyInstaller 归档中的全部 21 个条目(包括 DLL、PYD 等二进制文件)解压后搜索 my_function,在 python313.dll 中发现命中:
python313.dll 的解压数据是 Python 3.13 的完整 DLL 二进制。my_function 出现在 DLL 内部的冻结模块(frozen module)数据区域中。
以 <module> 字符串为线索,在 python313.dll 中搜索冻结模块的代码对象起点。最终在偏移 5046496 (0x4CA770) 处成功用 marshal.loads() 加载出一个模块级代码对象:
挑战代码被注入到了 <frozen os> 模块中。 os 是 Python 标准库的核心模块,作为冻结模块编译进 python313.dll。作者在标准 os 模块代码末尾(第 1188 行之后)追加了挑战代码。
由于 os 模块在 Python 启动过程中被自动导入,这段附加代码在 main.py 的 sys.exit(0) 执行之前就已运行。
标准 os 模块的最后一个函数是 process_cpu_count(第 1173 行)。从第 1183 行起是注入的挑战代码。模块的 co_names 在标准名称之后追加了以下条目:
模块的 co_consts 在标准常量之后追加了以下关键条目:
注入的 my_function 代码对象如下:
反汇编确认:
co_code(26 字节):
co_consts:(None, 666)
程序运行时显示的提示由 const[145] 中的 8 段 16 字节密文逐段 XOR 0x55 后拼接得到:
解码结果(UTF-8):
程序读取用户输入的 6 字符 key 后,执行两轮 XOR 解密:
第一轮——还原 co_consts 中的字符串值:
第二轮——还原 co_code(验证用):
随后通过 Python 的运行时字节码替换机制修改 my_function:
提示文本直接展示了目标代码 print("恭喜成功!"),因此明文字符串已知。
目标字符串 "恭喜成功!" 的 UTF-8 编码为 15 字节:
与密文 const[151](同样 15 字节)逐字节异或:
密钥为 6 字节循环:y b 6 t c r
用密钥 "yb6tcr" 对 const[149](26 字节)做 XOR,结果与原始 co_code 完全一致:
用密钥 "yb6tcr" 对 const[151](15 字节)做 XOR,结果为 "恭喜成功!" 的 UTF-8 编码:
还原后的 my_function 反汇编:
传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!!
最后于 14小时前
被V1NKe编辑
,原因: