# Space Pirates
根据附件逆向写脚本即可
1 | `target = [ 0x5A, 0x3D, 0x5B, 0x9C, 0x98, 0x73, 0xAE, 0x32, 0x25, 0x47,` |
# Are You Pylingual?
首先对题目所给的 pyc 文件进行反编译得到 python 原文件:
1 | Decompiled with PyLingual (https://pylingual.io) |
通过分析可知 flag 被分成了两部分,再结合题目给的 output.txt 文件编写脚本即可:
1 | output = [-90, -42, -39, -42, -39, -39, -39, -42, -39, -42, -39, -42, -39, -42, -39, -90, -90, -39, -48, -13, -52, -39, -42, -39, -42, -39, -42, -39, -42, -90, -42, -39, -42, -39, -90, -90, -42, -39, -39, -39, -39, -42, -39, -90, -90, -39, -39, -42, -105, -90, -90, -42, -39, -39, -91, -90, -90, -39, -91, -39, -42, -39, -42, -39, -39, -39, -39, -42, -39, -42, -39, -39, -39, -42, -39, -42, -34, -39, -39, -42, -39, -42, -39, -42, -39, -42, -39, -90, -90, -39, -39, -123, -13, -39, -42, -39, -42, -39, -42, -39, -90, -90, -39, -39, -115, -39, -42, -90, -90, -90, -39, -39, -39, -42, -39, -42, -90, -42, -39, -42, -39, -42, -90, -90, -90, -39, -90, -90, -90, -42, -39, -42, -90, -39, -42, -39, -39, -39, -39, -42, -39, -42, -90, -90, -90, -42, -39, -42, -90, -90, -90, -42, -39, -42, -90, -42, -39, -42, -39, -42, -68, -42, -39, -42, -39, -13, -42, -90, -42, -39, -42, -90, -42, -39, -42, -90, -42, -90, -90, -90, -90, -90, -42, -39, -39, -42, -90, -90, -105, -90, -90, -42, -90, -90, -90, -90, -90, -42, -42, -90, -90, -90, -90, -42, -42, -90, -42, -39, -39, -39, -39, -39, -91, -90, -90, -90, -102, -42, -90, -90, -90, -90, -90, -42, -91, -90, -90, -90, -90, -42, -90, -90, -90, -90, -90, -42, -39, -39, -13, -39, -39, -39, -39, -39, -85, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -128, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -119, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -13, -39, -39, -39, -39, -90, -90, -90, -90, -90, -90, -90, -39, -39, -39, -39, -90, -115, -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, -39, -13, -39, -39, -39, -42, -39, -90, -90, -90, -90, -42, -39, -123, -39, -39, -42, -56, -42, -39, -90, -90, -90, -90, -42, -39, -90, -90, -39, -91, -13, -39, -39, -42, -39, -90, -90, -42, -39, -39, -123, -39, -123, -39, -42, -106, -42, -39, -90, -90, -42, -39, -42, -39, -42, -90, -42, -39, -42, -13, -39, -42, -39, -42, -90, -90, -90, -39, -39, -123, -39, -123, -42, -73, -42, -39, -42, -90, -90, -90, -42, -39, -90, -43, -39, -90, -42, -39, -13, -42, -90, -90, -90, -90, -90, -42, -39, -39, -123, -90, -90, -124, -42, -90, -90, -90, -90, -90, -42, -90, -42, -39, -123, -90, -123, -39, -39, -13, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -13, -38, -38, -118, -38, -91, -91, -38, -38, -91, -91, -91, -91, -91, -91, -38, -38, -38, -91, -91, -91, -91, -91, -38, -91, -91, -91, -91, -38, -38, -91, -103, -38, -38, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -38, -38, -38, -91, -91, -91, -91, -91, -91, -91, -91, -114, -16, -38, -38, -38, -43, -38, -38, -122, -43, -38, -38, -43, -38, -38, -38, -122, -38, -43, -38, -91, -91, -91, -43, -43, -38, -91, -91, -100, -90, -43, -38, -122, -38, -43, -38, -43, -38, -91, -91, -91, -91, -43, -38, -91, -91, -91, -91, -43, -38, -38, -43, -38, -38, -91, -43, -127, -91, -91, -91, -43, -16, -38, -38, -43, -38, -43, -122, -91, -43, -38, -43, -38, -43, -122, -38, -122, -38, -90, -91, -91, -38, -90, -43, -107, -43, -38, -43, -38, -43, -38, -38, -122, -43, -38, -43, -38, -43, -38, -38, -38, -43, -38, -43, -38, -38, -38, -38, -38, -38, -38, -43, -104, -43, -38, -90, -91, -91, -38, -90, -38, -16, -38, -43, -38, -43, -38, -38, -43, -38, -43, -38, -91, -91, -91, -38, -122, -91, -91, -91, -68, -38, -43, -38, -43, -91, -43, -38, -43, -38, -43, -122, -38, -38, -43, -38, -43, -91, -91, -91, -43, -38, -43, -91, -91, -91, -38, -38, -113, -91, -43, -38, -43, -38, -91, -91, -91, -43, -38, -43, -38, -16, -43, -91, -43, -38, -38, -43, -91, -43, -91, -43, -38, -38, -122, -91, -119, -91, -91, -91, -91, -43, -90, -91, -91, -91, -91, -43, -91, -43, -38, -122, -91, -43, -90, -91, -91, -91, -91, -43, -90, -91, -91, -91, -103, -43, -38, -38, -43, -91, -91, -91, -43, -43, -91, -91, -91, -91, -43, -38, -38, -16, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -50, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -114, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, -16, -38, -38, -91, -91, -91, -91, -109, -91, -91, -91, -38, -38, -91, -91, -91, -91, -91, -91, -91, -91, -38, -38, -38, -91, -91, -91, -91, -38, -38, -91, -91, -91, -91, -91, -54, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, -38, -38, -38, -91, -91, -91, -91, -91, -91, -91, -91, -38, -38, -38, -38, -91, -108, -38, -38, -91, -91, -91, -91, -91, -91, -38, -16, -38, -43, -91, -38, -38, -91, -91, -43, -38, -43, -38, -43, -38, -43, -38, -91, -91, -91, -91, -43, -38, -38, -43, -38, -91, -91, -38, -45, -43, -38, -91, -91, -91, -91, -43, -38, -91, -91, -91, -43, -91, -38, -38, -91, -91, -109, -38, -38, -43, -38, -91, -91, -91] |
# Space Pirates 2
通过附件可知是一个 rust 源文件,但也不难,直接逆向写脚本即可:
1 | target = [ |
# Space Pirates 3
1 | target = [ |
# Vorpal Masters
1 | def find_valid_license_key(): |
# ReadMyNote
通过在 main 函数中查找 "2025" 从而定位到
1 | *(__m128 *)Str = _mm_xor_ps( |
然后就知道 Flag 的前 16 个字符 = [数据 A] XOR [数据 B] XOR [数据 C]。
所以需要去 IDA 里找到这三个 xmmword_... 对应的数据,这就是 flag 的第一部分。
然后再通过
1 | qmemcpy(v2115, "5R!Z=6g3a=`2", 12); // 硬编码的字符串 |
可知第二部分是将字符串 "5R!Z=6g3a=2" 和 0x0578 的每个字节都异或 5`。
因此脚本为:
1 | import struct |
# Entropy Discord
在字符串搜索栏中找到字符串 "\n [+] Transformation check passed!\n", 从而通过交叉引用定位到函数 sub_6ED0,然后通过观察伪代码定位到:
1 | LABEL_8: |
发现这里有反调试,因此需要将其对应的汇编代码 nop 掉:
1 | .text:0000000000006FEF lea rsi, handler ; handler |
在 nop 的时候要注意后面的:
1 | .text:000000000000703F ud2 |
这些占位符都要 nop 掉,然后 ucp 得到完整伪代码:
1 | void sub_6ED0() |
看代码末尾的 LABEL_444(成功分支):
1 | // 1. 初始化 v250 为 v294 (v294 是输入文件的哈希值) |
可以知道
v294 是解密的钥匙。
v294 是根据我们的输入文件 (flag) 计算出来的(通过 FNV-1a 哈希算法)。
因此需要构造一个输入文件,使得它自然通过 v258 的检查。只有这样,生成的 v294 才是作者预期的那个正确的密钥
目标方程:
程序要求 v258 == 0xCAFEBABE13371337
v258 的计算公式在代码里是:
1 | v258 = 0x9E3779B97F4A7C15LL * (__ROL8__(v90, 13) ^ 0xDEADBEEFLL); |
我们需要逆推 v90,然后把 v90 的各个字节填回输入文件。
现在我们需要通过脚本做两件事:
(1)数学逆向:算出能通过检查的完美字节,写入 flag 文件。
(2)自动 Patch:读取原始程序,把 /dev/urandom 修改为 flag,并保存为一个新程序。
1 | import os |