easistRe

  1. [SWPU2019]EasiestRe

[SWPU2019]EasiestRe

根据运行时的输出找到主函数,发现是个双进程保护

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
char sub_B08A40()
{
char v1; // [esp+0h] [ebp-140h]
char v2; // [esp+0h] [ebp-140h]
int v3[62]; // [esp+8h] [ebp-138h] BYREF
char Str[56]; // [esp+100h] [ebp-40h] BYREF
size_t v5; // [esp+138h] [ebp-8h]

v5 = 0;
j__memset(Str, 0, 0x32u);
v3[52] = 2;
v3[53] = 3;
v3[54] = 7;
v3[55] = 14;
v3[56] = 30;
v3[57] = 57;
v3[58] = 120;
v3[59] = 251;
j__memset(v3, 0, 0xC8u);
sub_B01497((int)"Please Input Flag:\n", v1);
sub_B01956("%s", (char)Str);
v5 = j__strlen(Str);
__debugbreak();
sub_B01497((int)"you are too short!", v2);
return 0;
}

发现一个反调试,查看汇编发现有一个int3指令

INT3指令是专门用来支持调试的一条指令,它对应的机器码是0xCC。当cpu执行到这条指令是会产生异常并调用相应的异常处理程序(3号中断)进行进一步的处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if ( NumberOfBytesRead[0] )
{
for ( i = 1; i < 35 && (unsigned __int8)Buffer[i] == 144; ++i )
;
}
if ( i == 1 )
v8 = 0;
if ( v8 )
{
switch ( i )
{
case 4:
Context.ContextFlags = 65543;
hThread = OpenThread(0x1FFFFFu, 0, DebugEvent.dwThreadId);
if ( !GetThreadContext(hThread, &Context) )
goto LABEL_31;
++Context.Eip;

分析这一段代码,根据i的值进入不同的分支,而i的取值决定于buff[i]是否等于144,即0x90,对应着nop指令,所以i就是记录nop指令的个数+1(int3),继续分析知道了v16就是用于修改这里int3和后面六个nop的,直接patch,得到新的函数

使用idapython来修改比较方便

1
2
3
4
5
a = [0x90, 0x83, 0x7D, 0xF8, 0x18, 0x7D, 0x11]
b = 0x408AF8
for i in range(7):
#idc.PatchByte(b + i, a[i])
ida_bytes.patch_byte(b + i, a[i])
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
char sub_B08A40()
{
char v1; // [esp+0h] [ebp-140h]
char v2; // [esp+0h] [ebp-140h]
int v3[52]; // [esp+8h] [ebp-138h] BYREF
int v4[10]; // [esp+D8h] [ebp-68h] BYREF
char Str[56]; // [esp+100h] [ebp-40h] BYREF
int v6; // [esp+138h] [ebp-8h]

v6 = 0;
j__memset(Str, 0, 0x32u);
v4[0] = 2;
v4[1] = 3;
v4[2] = 7;
v4[3] = 14;
v4[4] = 30;
v4[5] = 57;
v4[6] = 120;
v4[7] = 251;
j__memset(v3, 0, 0xC8u);
sub_B01497((int)"Please Input Flag:\n", v1);
sub_B01956("%s", (char)Str);
v6 = j__strlen(Str);
if ( v6 >= 24 )
{
sub_B0247D(Str, (int)v4, (int)v3);
sub_B0384B((int)v3);
return 1;
}
else
{
sub_B01497((int)"you are too short!", v2);
return 0;
}
}

然后就得到了加密的函数,是个背包加密

脚本解密即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
iv=0x1234
inv=12
rflag=[0x3d1,0x2f0,0x52,0x475,0x1d2,0x2f0,0x224,0x51c,0x4e6,0x29f,0x2ee,0x39b,0x3f9,0x32b,0x2f2,0x5b5,0x24c,0x45a,0x34c,0x56d,0xa,0x4e6,0x476,0x2d9]
key=[2,3,7,14,30,57,120,251]
flag=[]
for i in range(24):
tem = rflag[i] * inv % 491
b=''
for j in range(8):
if key[7-j] > tem:
b += '0'
else:
b += '1'
tem -= key[7-j]
flag.append(int(b[::-1],2))
print(chr((flag[0]^0x1234)&0xff),end='')
for i in range(1,24):
print(chr((flag[i]^rflag[i-1])&0xff),end='')

#swpuctf{y0u_@re_s0_coo1}

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 3049155267@qq.com

💰

×

Help us with donation