2025-11-5-cute_fake_code

2025-11-5-cute_fake_code

十一月 05, 2025

cute fake code

可爱的伪代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
v23 = __readfsqword(0x28u); // 栈保护机制:读取 FS 段寄存器的 0x28 偏移值,这是 Linux 下的栈保护金丝雀值,用于检测栈溢出。

qmemcpy(v15, "Iodl>Qnb(ocy", 12); // 将字符串 "Iodl>Qnb(ocy" 的前12个字符复制到数组 v15
v15[12] = 127; // 在第13个位置(索引12)设置值为 127(0x7F)

qmemcpy(v16, "y.i", 3); // 复制 "y.i" 的前3个字符到 v16
v16[3] = 127; // 在第4个位置设置值为 127

qmemcpy(v17, "d`3w}wek9{iy=~yL@EC", sizeof(v17)); // 将字符串 "d`3w}wek9{iy=~yL@EC" 完整复制到 v17 数组

memset(&v18, 0, 0x20uLL); // 将 v18 开始的 0x20(32)字节内存清零
sub_4406E0(0LL, &v18, 37LL);
// 一般看到这个内存清零了 后面又调用个什么参数
// 多半就是输入

LODWORD(v0) = sub_424BA0(&v18); // 调用 sub_424BA0 进行验证,参数是用户输入 &v18
// LODWORD 取低32位结果到 v0

复杂的len 实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
int __fastcall sub_424BA0(const __m128i *a1)
{
unsigned int v1; // edx
__m128i *v2; // rax
__m128i v3; // xmm1
__m128i v4; // xmm2
__m128i v5; // xmm3
__int64 v6; // rdx
unsigned __int64 v7; // rdx

if ( ((unsigned __int16)a1 & 0xFFFu) <= 0xFCFuLL )
{
v1 = _mm_movemask_epi8(_mm_cmpeq_epi8(_mm_loadu_si128(a1), (__m128i)0LL));
if ( v1 )
{
_BitScanForward((unsigned int *)&v2, v1);
return (int)v2;
}
v3 = _mm_cmpeq_epi8((__m128i)0LL, *(__m128i *)(((unsigned __int64)a1 & 0xFFFFFFFFFFFFFFF0LL) + 0x10));
v4 = _mm_cmpeq_epi8((__m128i)0LL, *(__m128i *)(((unsigned __int64)a1 & 0xFFFFFFFFFFFFFFF0LL) + 0x20));
v5 = _mm_cmpeq_epi8((__m128i)0LL, *(__m128i *)(((unsigned __int64)a1 & 0xFFFFFFFFFFFFFFF0LL) + 0x30));
v2 = (__m128i *)((unsigned __int64)a1 & 0xFFFFFFFFFFFFFFC0LL);
v6 = (__int64)((((unsigned int)_mm_movemask_epi8(v4) | ((unsigned __int64)(unsigned int)_mm_movemask_epi8(v5) << 16)) << 32) | ((unsigned __int64)(unsigned int)_mm_movemask_epi8(v3) << 16)) >> ((unsigned __int8)a1 & 0xF0u ^ (unsigned __int8)a1);
if ( !v6 )
goto LABEL_8;
LABEL_5:
_BitScanForward64((unsigned __int64 *)&v2, v6);
return (int)v2;
}
v2 = (__m128i *)((unsigned __int64)a1 & 0xFFFFFFFFFFFFFFC0LL);
v6 = (__int64)((((unsigned int)_mm_movemask_epi8(
_mm_cmpeq_epi8(
(__m128i)0LL,
*(__m128i *)(((unsigned __int64)a1 & 0xFFFFFFFFFFFFFFC0LL) + 0x20))) | ((unsigned __int64)(unsigned int)_mm_movemask_epi8(_mm_cmpeq_epi8((__m128i)0LL, *(__m128i *)(((unsigned __int64)a1 & 0xFFFFFFFFFFFFFFC0LL) + 0x30))) << 16)) << 32) | (unsigned int)_mm_movemask_epi8(_mm_cmpeq_epi8((__m128i)0LL, *(__m128i *)((unsigned __int64)a1 & 0xFFFFFFFFFFFFFFC0LL))) | ((unsigned __int64)(unsigned int)_mm_movemask_epi8(_mm_cmpeq_epi8((__m128i)0LL, *(__m128i *)(((unsigned __int64)a1 & 0xFFFFFFFFFFFFFFC0LL) + 0x10))) << 16)) >> ((unsigned __int8)a1 & 0xC0u ^ (unsigned __int8)a1);
if ( v6 )
goto LABEL_5;
v3 = 0LL;
v4 = 0LL;
v5 = 0LL;
LABEL_8:
while ( !_mm_movemask_epi8(_mm_cmpeq_epi8(_mm_min_epu8(_mm_min_epu8(_mm_min_epu8(_mm_load_si128(v2 + 4), v2[5]), v2[6]), v2[7]), v5)) )
{
v2 += 8;
if ( _mm_movemask_epi8(_mm_cmpeq_epi8(_mm_min_epu8(_mm_min_epu8(_mm_min_epu8(_mm_load_si128(v2), v2[1]), v2[2]), v2[3]), v5)) )
goto LABEL_12;
}
v2 += 4;
LABEL_12:
_BitScanForward64(
&v7,
(((unsigned int)_mm_movemask_epi8(_mm_cmpeq_epi8(v4, v2[2])) | ((unsigned __int64)(unsigned int)_mm_movemask_epi8(_mm_cmpeq_epi8(v5, v2[3])) << 16)) << 32) | (unsigned int)_mm_movemask_epi8(_mm_cmpeq_epi8((__m128i)0LL, *v2)) | ((unsigned __int64)(unsigned int)_mm_movemask_epi8(_mm_cmpeq_epi8(v3, v2[1])) << 16));
LODWORD(v2) = v7 + (_DWORD)v2 - (_DWORD)a1;
return (int)v2;
}

这谁看了不迷糊啊?

1
2
LODWORD(v0) = sub_424BA0(&v18);
if ( v0 == 36 )

由此推出,密码长度是36

1
if ( (unsigned __int8)(v18.m128i_i8[i] ^ i) != v15[i] )

令人迷茫,啥是 m128i_i8 我直接(i_i)

后面看了一下

1
2
3
4
5
6
7
8
00000000 m128i_i8        db 16 dup(?)
00000000 m128i_i16 dw 8 dup(?)
00000000 m128i_i32 dd 4 dup(?)
00000000 m128i_i64 dq 2 dup(?)
00000000 m128i_u8 db 16 dup(?)
00000000 m128i_u16 dw 8 dup(?)
00000000 m128i_u32 dd 4 dup(?)
00000000 m128i_u64 dq 2 dup(?)

哦,int 8

那我估计就是 让每个字符转成 int8 然后和 i XOR 并 == v15[i]

那么可以解密了

继续往下走

1
2
3
4
memset(v21, 0, sizeof(v21));
v22 = 0;
sub_4406E0(0LL, v21, 64LL);
v21[2].m128i_i8[7] = 0;

何意味?

  • v21 是一个 __m128i 类型的数组
  • v21[2] 是数组的第3个元素(索引从0开始)
  • m128i_i8[7] 表示将该128位向量视为8位有符号整数数组

__m128i 是128位(16字节)的SIMD向量:

1
2
3
字节索引: 0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
m128i_i8: [0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15]

v21[2].m128i_i8[7] = 0; 表示:

  • v21 数组的第3个128位向量
  • 的第8个字节(索引7)
  • 设置为0

666 搞这么复杂就这

也就是从0开始数第7位是0 呗

1
2
LODWORD(v3) = sub_424BA0(v21);
if ( v3 == 39 )

然后第二轮,密码长度是39吗

1
2
3
4
5
6
7
8
9
10
v5 = sub_400E44(v21);
v6 = sub_400E44(v5);
v7 = sub_400E44(v6);
v8 = sub_400E44(v7);
v9 = sub_400E44(v8);
v10 = sub_400E44(v9);
v11 = sub_400E44(v10);
v12 = sub_400E44(v11);
v13 = sub_400E44(v12);
v14 = sub_400E44(v13);

然后惊险神秘代码

看下sub_400E44的实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
__int64 __fastcall sub_400E44(const __m128i *a1)
{
__int64 v1; // rax
int v3; // [rsp+18h] [rbp-28h]
int v4; // [rsp+1Ch] [rbp-24h]
__int64 v5; // [rsp+20h] [rbp-20h]
__int64 v6; // [rsp+30h] [rbp-10h]
__int64 v7; // [rsp+38h] [rbp-8h]

LODWORD(v1) = sub_424BA0(a1);
v6 = v1;
if ( v1 % 3 )
v5 = 4 * (v1 / 3 + 1);
else
v5 = 4 * (v1 / 3);
v7 = sub_41EF60(v5 + 1);
*(_BYTE *)(v5 + v7) = 0;
v3 = 0;
v4 = 0;
while ( v3 < v5 - 2 )
{
*(_BYTE *)(v7 + v3) = aAbcdefghijklmn[(unsigned __int8)a1->m128i_i8[v4] >> 2];
*(_BYTE *)(v7 + v3 + 1LL) = aAbcdefghijklmn[(16 * (a1->m128i_i8[v4] & 3)) | ((unsigned __int8)a1->m128i_i8[v4 + 1] >> 4)];
*(_BYTE *)(v7 + v3 + 2LL) = aAbcdefghijklmn[(4 * (a1->m128i_i8[v4 + 1] & 0xF)) | ((unsigned __int8)a1->m128i_i8[v4 + 2] >> 6)];
*(_BYTE *)(v7 + v3 + 3LL) = aAbcdefghijklmn[a1->m128i_i8[v4 + 2] & 0x3F];
v4 += 3;
v3 += 4;
}
if ( v6 % 3 == 1 )
{
*(_BYTE *)(v3 - 2LL + v7) = 61;
*(_BYTE *)(v3 - 1LL + v7) = 61;
}
else if ( v6 % 3 == 2 )
{
*(_BYTE *)(v3 - 1LL + v7) = 61;
}
return v7;
}

疑似,base64编码操作,返回的是指向Base64编码结果的指针

~~我什么时候才能一眼确认各种函数的作用啊~~

所以 v5 是 v21进行b64编码,然后v6是v5编码…以此类推,到最下面,v14

然后就看到个神秘条件

!(unsigned int)sub_400360(v14, off_6CC090)

估计是做比较吧

1
2
3
4
5
6
7
8
9
10
11
12
13
__int64 (__fastcall *sub_422820())()
{
__int64 (__fastcall *result)(); // rax

result = sub_42F5A0;
if ( (dword_6CE7A8 & 0x10) == 0 )
{
result = sub_42E340;
if ( (dword_6CE770 & 0x200) == 0 )
return sub_422850;
}
return result;
}

以及 off_6CC090的值是

1
2
3
4
5
6
7
8
9
10
11
12
13
Vm0wd2VHUXhTWGhpUm1SWVYwZDRWVll3Wkc5WFJsbDNXa1pPVlUxV2NIcFhhMk0xV'
.rodata:00000000004A23A8 ; DATA XREF: .data:off_6CC090↓o
.rodata:00000000004A23E9 db 'mpKS1NHVkdXbFpOYmtKVVZtcEtTMUl5VGtsaVJtUk9ZV3hhZVZadGVHdFRNVTVYVW'
.rodata:00000000004A242A db '01T2FGSnRVbGhhVjNoaFZWWmtWMXBFVWxSTmJFcElWbTAxVDJGV1NuTlhia0pXWWx'
.rodata:00000000004A246B db 'ob1dGUnJXbXRXTVZaeVdrWm9hVlpyV1hwV1IzaGhXVmRHVjFOdVVsWmlhMHBZV1ZS'
.rodata:00000000004A24AC db 'R1lWZEdVbFZTYlhSWFRWWndNRlZ0TVc5VWJGcFZWbXR3VjJKSFVYZFdha1pXWlZaT'
.rodata:00000000004A24ED db '2NtRkhhRk5pVjJoWVYxZDBhMVV3TlhOalJscFlZbGhTY1ZsclduZGxiR1J5VmxSR1'
.rodata:00000000004A252E db 'ZXSlZjRWhaTUZKaFZqSktWVkZZYUZkV1JWcFlWV3BHYTFkWFRrZFRiV3hvVFVoQ1d'
.rodata:00000000004A256F db 'sWXhaRFJpTWtsM1RVaG9hbEpYYUhOVmJUVkRZekZhY1ZKcmRGTk5Wa3A2VjJ0U1Ex'
.rodata:00000000004A25B0 db 'WlhTbFpqUldoYVRVWndkbFpxUmtwbGJVWklZVVprYUdFeGNHOVhXSEJIWkRGS2RGS'
.rodata:00000000004A25F1 db 'nJhR2hTYXpWdlZGVm9RMlJzV25STldHUlZUVlpXTlZadE5VOVdiVXBJVld4c1dtSl'
.rodata:00000000004A2632 db 'lUWGhXTUZwell6RmFkRkpzVWxOaVNFSktWa1phVTFFeFduUlRhMlJxVWxad1YxWnR'
.rodata:00000000004A2673 db 'lRXRXTVZaSFVsUnNVVlZVTURrPQ==

解出来是一个网址https://bbs.pediy.com/thread-254172.htm

所以我flag呢?

可恶啊

继续找

这里是关键

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
unsigned __int64 sub_400D35()
{
unsigned __int64 result; // rax
unsigned int v1; // [rsp+Ch] [rbp-24h]
int i; // [rsp+10h] [rbp-20h]
int j; // [rsp+14h] [rbp-1Ch]
unsigned int v4; // [rsp+24h] [rbp-Ch]
unsigned __int64 v5; // [rsp+28h] [rbp-8h]

v5 = __readfsqword(0x28u);
v1 = sub_43FD20(0LL) - qword_6CEE38;
for ( i = 0; i <= 1233; ++i )
{
sub_40F790(v1);
sub_40FE60();
sub_40FE60();
v1 = sub_40FE60() ^ 0x98765432;
}
v4 = v1;
if ( ((unsigned __int8)v1 ^ byte_6CC0A0[0]) == 'f' && (HIBYTE(v4) ^ (unsigned __int8)byte_6CC0A3) == 'g' )
{
for ( j = 0; j <= 24; ++j )
sub_410E90((unsigned __int8)(byte_6CC0A0[j] ^ *((_BYTE *)&v4 + j % 4)));
}
result = __readfsqword(0x28u) ^ v5;
if ( result )
sub_444020();
return result;
}

反复试错写下exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
v15 = "Iodl>Qnb(ocy" + chr(127)

v16 = "y.i" + chr(127)

v17 = "d`3w}wek9{iy=~yL@EC"

# flag 长度为 36

v2 = 36

v15 += v16 + v17 # 凑一块长度正好够
# (v18.m128i_i8[i] ^ i) != v15[i]
# result = 4294967294LL; 估计是中断

for i in range(len(v15)):
print(chr(ord(list(v15)[i]) ^ i), end="")

flag = "Info:The first four chars are `flag`"
# 告诉我们前四个字符是flag

# 继续往下走
v21 = 0
v22 = 0

# sub_4406E0(0LL, v21, 64LL); 完全确定v21是接收输入了


# v21[2].m128i_i8[7] = 0;
# 啥玩意

# 新的key 0x98765432 但没什么用
flag_l = []
with open("ELF/flag.txt", "r") as f:
flag = f.read().replace(".data:0000000000", "").split("\n")

for i in flag:
t = (i.split("h")[0].split("db"))
if len(t) == 2:
flag = t[1].replace(" ", "")
flag_l.append(flag)

print(flag_l)
key_flag = "flag"
key = ""
for i in range(4):
key+=chr(ord(key_flag[i]) ^ int(flag_l[i], 16))
#
print(key)
for i in range(len(flag_l)):
print(chr(int(flag_l[i], 16) ^ ord(key[i % 4])), end="")

flag.txt内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
.data:00000000006CC0A0 byte_6CC0A0     db 40h                  ; DATA XREF: sub_400D35+95↑r
.data:00000000006CC0A0 ; sub_400D35+C1↑r
.data:00000000006CC0A1 db 35h ; 5
.data:00000000006CC0A2 db 20h
.data:00000000006CC0A3 byte_6CC0A3 db 56h ; DATA XREF: sub_400D35+A6↑r
.data:00000000006CC0A4 db 5Dh ; ]
.data:00000000006CC0A5 db 18h
.data:00000000006CC0A6 db 22h ; "
.data:00000000006CC0A7 db 45h ; E
.data:00000000006CC0A8 db 17h
.data:00000000006CC0A9 db 2Fh ; /
.data:00000000006CC0AA db 24h ; $
.data:00000000006CC0AB db 6Eh ; n
.data:00000000006CC0AC db 62h ; b
.data:00000000006CC0AD db 3Ch ; <
.data:00000000006CC0AE db 27h ; '
.data:00000000006CC0AF db 54h ; T
.data:00000000006CC0B0 db 48h ; H
.data:00000000006CC0B1 db 6Ch ; l
.data:00000000006CC0B2 db 24h ; $
.data:00000000006CC0B3 db 6Eh ; n
.data:00000000006CC0B4 db 72h ; r
.data:00000000006CC0B5 db 3Ch ; <
.data:00000000006CC0B6 db 32h ; 2
.data:00000000006CC0B7 db 45h ; E
.data:00000000006CC0B8 db 5Bh ; [