Cris.Q

Back

记一杯花茶的逆向工程Blur image

(本文是新手 re 同学的学习笔记,所以可能比较啰唆,见谅~)

审题#

审题可知,flower 代表花指令,tea 代表加密算法是 TEA 或者某种 TEA 的衍生算法。

分析加密算法#

首先导航到 Strings 发现一个很明显的 base 64 编码数据 bTRwbGUxc3hubg==,解密后发现 主席是男娘 得到了 m4ple1sxnn,猜想应该是密钥。

查看字符串

再使用 FindCrypt 插件查看是否有明显的常见加密算法迹象:

查看可能的加密

没有看到有用信息,重新根据 Strings 中保留的字符串,定位到跳转点。整理后代码如下(其中包含对我的一些疑问点的注释,感谢 GPT 5 的解答):

于是我们清理 sub_1400018CA (在上述清理过的代码中为 xxtea_encrypt )代码:

可知:

  1. 使用 m4ple1sxnn 作为密钥材料(16 字节,因此填 0)
  2. 对用户输入的flag进行加密(通过sub_1400016DC函数)
  3. 将加密结果与预存的数据进行比较

花指令处理#

于是定位到 sub_1400016DC 函数,发现是一个跳转。显然这里 JUMPOUT 出的地址才是真正的实现函数。但是由于它没有被 IDA 识别为函数,我们只能强行看汇编了。

void __fastcall encrypt_impl(__int64 a1, unsigned __int64 a2)
{
  if ( a2 > 1 && 0x34 / (unsigned int)a2 != -6 )
    JUMPOUT(0x140001744LL);
}
c

(AI 注释: 你不一定要把 JUMPOUT 目标当“新函数”看。 JUMPOUT 往往只是跳到一个代码块(可能在同一函数里,或落在别的函数的中间/尾块),反编译器因此不把它认作函数入口。先把它当作“落点基本块”去读即可;若你确认那儿才是一个独立入口,再手动建函数。 )

; 噪音 / 误解码(建议当作 db)
; xor     eax, [rcx+4514F845h]
; adc     [rax], eax
; xor eax, [rcx+4514F845h] 带巨大的位移,对未定义的 RCX 取内存;adc [rax], eax 会对 EAX 指向的地址写内存,若 EAX 未设定几乎必崩——它们既不保存现场也不建立栈框,和后续“规整的逻辑”断层。
; loc_14000174B  ← 以这里作为代码起点更合理
mov     eax, [rbp+var_8]      ; eax = sum !!!注意,这里是读取sum的地方!!初始的Sum就是我们需要的Delta
shr     eax, 2
and     eax, 3                ; eax = (sum >> 2) & 3  → e ∈ {0,1,2,3}
mov     [rbp+var_18], eax     ; e
mov     [rbp+var_C], 0        ; i = 0
jmp     loc_140001806         ; 进入主循环
asm

如果我们将上面两条花指令 NOP 掉,其实可以看见部分 XXTEA 的实现(Delta 累加部分被更多花指令隐藏掉了):

进入主循环(太长了不贴),可以发现是一个标准的”判断是主循环还是尾循环,并执行符合 XXTEA 规则的轮加密”的函数。自此我们确定了该函数是 XXTEA 加密。(这一步需要有密码学基础,至少得熟悉常见的对称加密的代码实现,可以选择问AI)下一步就是找 Delta 了。

然而,上面 FindCrypt 的结果已经指出:TEA 类算法中经典的 Delta 值(0x9E3779B9)并没有出现在我们的程序中(表现为检测不出 TEA 类算法),于是我们猜测该程序有自定义的 Delta 值。结合上述内容可知 Delta 被花指令隐藏,该部分处理比较困难,于是考虑通过动态调试获取之(由于笔者使用 Linux 环境,这里使用 winedbg + gdb,选用x64dbg 等亦可):

动态调试#

首先,我们需要解决一个问题:去哪找?

根据上述内容,注意到:

mov     eax, [rbp+var_8]      ; eax = sum !!!注意,这里是读取sum的地方!!初始的Sum就是我们需要的Delta
asm

这里就是我们需要的函数,它的地址在 IDA 中可以发现是 0x14000174b,于是启动 gdb 并下断:

pwndbg>  winedbg --gdb another_flower_tea.exe
(Some Output)
pwndbg>  b *0x14000174b # 下断点
pwndbg>  c # continue,表示执行程序到断点
# 等待程序停在断点处,中间可能需要按照源程序要求执行输入操作,随便输入些东西即可
pwndbg>  set $sum_addr = $rbp - 8 # 源程序显示采用的是负偏移,所以我们先提前算出负偏移的 offset
pwndbg> x/wx $sum_addr
0x21fd68:	0x00114514
bash

好了!我们拿到了初始的 Delta——0x00114514,一个非常符合网安学长精神状态的数。于是根据标准的 XXTEA 加密过程,可以开始写解密脚本了。

写出解密脚本如下(可以求助 AI 或翻阅 Github 现成实现并修改 Delta 值):

记一杯花茶的逆向工程
https://crisq.top/blog/another_flower_tea_wp
Author Cris.Q
Published at 2025年8月25日
Comment seems to stuck. Try to refresh?✨