easync

进入ida分析

找到main函数按F5查看伪代码

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
//定义数据
__int64 v3; // rbx
__int64 v4; // rax
char v5; // al
char *v6; // rcx
int v8[10]; // [rsp+20h] [rbp-19h]
char v9; // [rsp+48h] [rbp+Fh]
__int128 v10[3]; // [rsp+50h] [rbp+17h] BYREF
__int16 v11; // [rsp+80h] [rbp+47h]
//初始化值
v8[0] = 167640836;
v8[1] = 11596545;
v11 = 0;
v8[2] = -1376779008;
memset(v10, 0, sizeof(v10)); // void *memset(void *str, int c, size_t n) 复制字符 c(一个无符号字符)到参数 str 所指向的字符串的前 n 个字符
v3 = 0i64;
v8[3] = 85394951;
v8[4] = 402462699;
v8[5] = 32375274;
v8[6] = -100290070;
v8[7] = -1407778552;
v8[8] = -34995732;
v8[9] = 101123568;
v9 = -7;
sub_140001064("%50s"); // scanf() 输入字符串
v4 = -1i64;
// 计算输入的字符串长度
do
++v4;(_BYTE *)
while ( *((_BYTE *)v10 + v4) ); //(_BYTE *)v10就是用于操作v10每一个byte的指针(int类型有4个byte,32位bit)
// 输入字符串每一byte数据处理后逐一和v8每一byte数据对比
if ( v4 == 41 )
{
while ( 1 )
{
v5 = (*((_BYTE *)v10 + v3) ^ 0x32) - 86;
*((_BYTE *)v10 + v3) = v5;
if ( *((_BYTE *)v8 + v3) != v5 )
break;
if ( ++v3 >= 41 ) // 两者每一位byte值都相同则flag正确
{
v6 = "you are right!";
goto LABEL_8;
}
}
v6 = "wrong!";
LABEL_8:
sub_140001010(v6);
}
return 0;
}

image-20230213182634321

v4 = -1i64;-1转化成64位写法

v7是加密结果

25行是个scanf,接受char型v9

如果看不出来scanf将flag读⼊到了哪⾥,可以双击进⼊26⾏的函数,再返回 main(快捷键esc),再按⼀次F5,就能⾃动分析了,这种情况是因为ida的分析策略⽐较懒

30行长度验证

32行循环加密:把输入的v9每一位加0i64(猜测是为了转化成64位类型)然后与0x32异或最后减86

*((_BYTE *)v9这里的*表示指针,&表示取地址

35行给指针赋新值

36行判断我们输入值加密后是否等于加密结果v7

image-20230213183402412

那么我们把v7解密就可以了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main()
{
int v7[11];
v7[0] = 167640836
v7[1] = 11596545
v7[2] = -1376779008
v7[3] = 85394951
v7[4] = 402462699
v7[5] = 32375274
v7[6] = -100290070
v7[7] = -1407778552
v7[8] = -34995732
v7[9] = 101123568
char* p = v7;
for (int i = 0; i < 41; i++)
{
putchar((p[i] + 86) ^ 0x32);
}
}

也可也配合按位与和移位操作来代替

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
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#define GET_LOW_BYTE0(x) ((x >> 0) & 0x000000ff) /* 获取第0个字节 */
#define GET_LOW_BYTE1(x) ((x >> 8) & 0x000000ff) /* 获取第1个字节 */
#define GET_LOW_BYTE2(x) ((x >> 16) & 0x000000ff) /* 获取第2个字节 */
#define GET_LOW_BYTE3(x) ((x >> 24) & 0x000000ff) /* 获取第3个字节 */
//0x12345678 & 0x00ffffff = 0x00345678

int main()
{
int v8[10];
v8[0] = 167640836;
v8[1] = 11596545;
v8[2] = -1376779008;
v8[3] = 85394951;
v8[4] = 402462699;
v8[5] = 32375274;
v8[6] = -100290070;
v8[7] = -1407778552;
v8[8] = -34995732;
v8[9] = 101123568;
char v5=0;
char v6[10];
int v3=0;
while ( v3<10)
{
printf("%c",(GET_LOW_BYTE0(v8[v3])+86)^0x32);
printf("%c",(GET_LOW_BYTE1(v8[v3])+86)^0x32);
printf("%c",(GET_LOW_BYTE2(v8[v3])+86)^0x32);
printf("%c",(GET_LOW_BYTE3(v8[v3++])+86)^0x32);
}
return 0;
}

//hgame{4ddit1on_is_a_rever5ible_0peration}