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 是不是有点晕,没关系,这里举个例子:你可以把其中一个当作是密钥,任意一个都可以,你把密钥拿掉后,你给你朋友剩下的两个中的一个,这时候,你朋友需要密钥才可以知道你手里的是什么数字,可以这样理解”
wpint 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字节,也就是上面的 0x570B044854525F55char* 表示指针,可以按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 4E0B 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。
📌 详细步骤解析
- 数据定义
<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>原有数据的一部分。
- 内存布局(小端序)
所有整数按 小端字节序(低位字节在低地址)放置。最终形成连续的字节数组(前 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 个字节)。 - 异或解密
每个字节<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>
由于异或运算的可逆性,原文 = 密文 ⊕ 密钥。 - 最终结果
对 38 个字节依次异或后得到可读字符,拼接即得 flag:
<font style="background-color:rgba(255, 255, 255, 0);">flag{7594a11c05be44ee8a1e6923df3404d2}</font>
🔧 手工验证示例(前几个字节)
| 地址偏移 | 存储值(hex) | 异或0x33 | ASCII |
|---|---|---|---|
| 0 | 0x55 | 0x66 | f |
| 1 | 0x5F | 0x6C | l |
| 2 | 0x52 | 0x61 | a |
| 3 | 0x54 | 0x67 | g |
| 4 | 0x48 | 0x7B | { |
| … | … | … | … |
| 37 | 0x4E | 0x7D | } |
这样便得到了完整的 flag。
5.base64

打开看到这个东西

进入这个函数


这段在干什么
- 把常量直接塞进寄存器
- 再写到栈上
- 本质是在拼字符串
也就是把 Base64 串拆成很多 8 字节块存起来
把 movabs 里的值翻成字符串
6B74335A68786D5Ah3267544E34635459h304D7A596B565459h6A46544F79636A59h3551544E6952324Dh7845444E78635459h3D303359784544h按字节拆分 去掉h 比如
6B74335A68786D5Ah 变成
6B 74 33 5A 68 78 6D 5A
注意小端序 要倒过来
变成5A 6D 78 68 5A 33 74 6B
换成ASCII
ASCII5A = Z6D = m78 = x68 = h5A = Z33 = 374 = t6B = k得到ZmxhZ3tk
依次处理
base64ZmxhZ3tkYTc4NTg2YTVkYzM0YjcyOTFjM2RiNTQ5YTcxNDExY30=解码:

flag{da78586a5dc34b7291c3db549a71411c}
如果这篇文章对你有帮助,欢迎分享给更多人!
部分信息可能已经过时












