mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6mobile wallpaper 7
890 字
3 分钟
好靶场逆向入门
2026-05-27

1.strings快捷键shift+f12#

2.反转#

shift+f12发现一个乱序的flag

观察发现是4个字母一反

加上下面的} 3

处理后得到:

flag{2927995c2b46419b9fcfd5056ec49fc3}

3.xor异或#

这边个人能力比较弱 本质彩笔 看了wp晓得是通过对前5个字符进行单字节异或爆破

拿到flag flag{e6c6934573f24d70963b0574ed1e0ddc}

4.伪代码,小端序#

描述:有人写了个石头剪刀布的 Windows 小程序,说赢了五局三胜就给 flag—— 但你信吗?真有人会把正经 flag 放在游戏胜利的弹窗里?还是单字节异或,你会f5反编译看伪代码吗

有一个明文flag 但是交了不对 符合描述

题目提示单字节异或 f5反编译看伪代码

看到一个get_real_flag

int get_real_flag()
{
__int64 v1[3]; // [rsp+20h] [rbp-30h]
_QWORD v2[2]; // [rsp+38h] [rbp-18h]
unsigned int i; // [rsp+4Ch] [rbp-4h]
v1[0] = 0xA06044854525F55LL;
v1[1] = 0x5106035002025207LL;
v1[2] = 0x2520B5656070756LL;
v2[0] = 0x555700010A0556LL;
*(_QWORD *)((char *)v2 + 6) = 0x4E01570703070055LL;
for ( i = 0; i <= 0x25; ++i )
putchar(*((_BYTE *)v1 + (int)i) ^ 0x33);
return putchar(10);
}

丢给ai分析后得到flag{7594a11c05be44ee8a1e6923df3404d2}

自己也要分析一下原理:

参考wp: “先要记住数字异或为0,不同为1:1110^0100=1010(注意这里例子中的结果) 对于异或的计算,异或可以想象成一个三角形的关系 C语言中最经典的用法 a = a ^ b; b = a ^ b; a = a ^ b; 在加密解密、免杀等场景下,经常会用到异或 还是上面的例子 1010^1110=0100 1010^01100=1110 是不是有点晕,没关系,这里举个例子:你可以把其中一个当作是密钥,任意一个都可以,你把密钥拿掉后,你给你朋友剩下的两个中的一个,这时候,你朋友需要密钥才可以知道你手里的是什么数字,可以这样理解”

wp
int get_real_flag()
{
__int64 v1[3]; // [rsp+20h] [rbp-30h]
_QWORD v2[2]; // [rsp+38h] [rbp-18h]
unsigned int i; // [rsp+4Ch] [rbp-4h]
v1[0] = 0xA06044854525F55LL;
v1[1] = 0x5106035002025207LL;
v1[2] = 0x2520B5656070756LL;
v2[0] = 0x555700010A0556LL;
*(_QWORD *)((char *)v2 + 6) = 0x4E01570703070055LL;
for ( i = 0; i <= 0x25; ++i )
putchar(*((_BYTE *)v1 + (int)i) ^ 0x33);
return putchar(10);
}
这一段就是函数的伪代码,我们可以看到关键的异或运算符 ^ ,猜测这里的密钥就是0x33
分析伪代码
v1[0] = 0x570B044854525F55i64; // 8 字节
v1[1] = 0x100555550000703i64; // 8 字节(注意只有 7 字节有效)
v1[2] = 0x557515251070701i64; // 8 字节
v2[0] = 0x515752030A03550Bi64; // 8 字节
*(_QWORD *)((char *)v2 + 6) = 0x4E55020101005157i64; // 从 v2+6 开始写入 8 字节
这里要注意的一个点是十六进制在内存中是小端序,什么意思呢
就是说 0x570B044854525F55 在内存中排序为,55 5F 52 54 48 04 0B 57 就是从后往前按字节顺序拍,一般我们使用的电脑都是小端序的,只要记住这样排可以了
*(_QWORD *)((char *)v2 + 6) = 0x4E55020101005157至于这一行代码的意思是,对内存扩充,QWORD是8字节,也就是上面的 0x570B044854525F55
char* 表示指针,可以按1个字节来操作
+6 表示对v2进行扩充,将原先的8字节的基础上再去加6个字节
但是 0x4E55020101005157 这里是8个字节,所以在操作的时候会对最开始的两个字节进行舍去,也就是舍去了57 51刚好跟v2的最后两个字节重叠在一起 大概就是这样:
> 0B 55 03 0A 03 52 57 51 > 57 51 00 01 01 02 55 4E
0B 55 03 0A 03 52 57 51 00 01 01 02 55 4E 最后得到这个结果 大概的代码逻辑分析清楚了,接着就是解密了,这里我直接用AI写脚本了...

这段伪代码的原理是:
将几个 64 位整数(小端序存储)拼接成字节数组,然后对每个字节与 <font style="background-color:rgba(255, 255, 255, 0);">0x33</font> 做异或运算,最后输出明文 flag。

📌 详细步骤解析#

  1. 数据定义
    • <font style="background-color:rgba(255, 255, 255, 0);">v1[3]</font>:3 个 64 位整数,共 24 字节。
    • <font style="background-color:rgba(255, 255, 255, 0);">v2[2]</font>:2 个 64 位整数,共 16 字节。
    • 随后 <font style="background-color:rgba(255, 255, 255, 0);">*(_QWORD *)((char *)v2 + 6) = 0x4E01570703070055LL</font> <font style="background-color:rgba(255, 255, 255, 0);">v2</font> 起始地址偏移 6 字节处写入一个 64 位值,这会覆盖 <font style="background-color:rgba(255, 255, 255, 0);">v2</font> 原有数据的一部分。
  2. 内存布局(小端序)
    所有整数按 小端字节序(低位字节在低地址)放置。最终形成连续的字节数组(前 24 字节来自 <font style="background-color:rgba(255, 255, 255, 0);">v1</font>,后 16 字节来自 <font style="background-color:rgba(255, 255, 255, 0);">v2</font> 且被部分覆盖)。
    循环 <font style="background-color:rgba(255, 255, 255, 0);">for ( i = 0; i <= 0x25; ++i )</font> 会依次读取 0~37 号字节(共 38 个字节)。
  3. 异或解密
    每个字节 <font style="background-color:rgba(255, 255, 255, 0);">byte[i]</font> 与固定密钥 <font style="background-color:rgba(255, 255, 255, 0);">0x33</font> 异或:
    <font style="background-color:rgba(255, 255, 255, 0);">putchar( byte[i] ^ 0x33 )</font>
    由于异或运算的可逆性,原文 = 密文 ⊕ 密钥。
  4. 最终结果
    对 38 个字节依次异或后得到可读字符,拼接即得 flag:
    <font style="background-color:rgba(255, 255, 255, 0);">flag{7594a11c05be44ee8a1e6923df3404d2}</font>

🔧 手工验证示例(前几个字节)#

地址偏移存储值(hex)异或0x33ASCII
00x550x66f
10x5F0x6Cl
20x520x61a
30x540x67g
40x480x7B{
370x4E0x7D}

这样便得到了完整的 flag。

5.base64#

打开看到这个东西

进入这个函数

这段在干什么#

  • 把常量直接塞进寄存器
  • 再写到栈上
  • 本质是在拼字符串

也就是把 Base64 串拆成很多 8 字节块存起来

把 movabs 里的值翻成字符串#

6B74335A68786D5Ah
3267544E34635459h
304D7A596B565459h
6A46544F79636A59h
3551544E6952324Dh
7845444E78635459h
3D303359784544h

按字节拆分 去掉h 比如

6B74335A68786D5Ah 变成

6B 74 33 5A 68 78 6D 5A

注意小端序 要倒过来

变成5A 6D 78 68 5A 33 74 6B

换成ASCII#

ASCII
5A = Z
6D = m
78 = x
68 = h
5A = Z
33 = 3
74 = t
6B = k

得到ZmxhZ3tk

依次处理

base64
ZmxhZ3tk
YTc4NTg2
YTVkYzM0
YjcyOTFj
M2RiNTQ5
YTcxNDEx
Y30=

解码:

flag{da78586a5dc34b7291c3db549a71411c}

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

好靶场逆向入门
http://blog.azkanna.cn/posts/好靶场逆向入门/
作者
AzKanna
发布于
2026-05-27
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录