百度云链接:https://pan.baidu.com/s/1OVHaQdDduI5NEWLMx75-lQ
提取码:v6ac
把exe文件丢进64位IDA,使用F5大法
v17 = __readfsqword(0x28u);
printf("Please input your flag:", argv, envp);
scanf("%s", &v7);
*v8 = 0LL;
memset(&v9, 0, 0x58uLL);
v10 = 0;
*v11 = 0LL;
memset(&v12, 0, 0x58uLL);
v13 = 0;
*v14 = 0LL;
memset(&v15, 0, 0x58uLL);
v16 = 0;
_substr666(v8, &v7, 0, 6);
_substr666(v11, &v7, 7, 6);
v3 = &v7;
_substr666(v14, &v7, 6, 1);
v4 = 0;
if ( _0x233333(v8) )
{
v3 = &v6;
if ( _0x666666(v11, &v6) )
{
if ( _0x8048000(v14) )
v4 = 1;
}
}
if ( v4 )
printf("Unbelievable! Congratualation!", v3);
else
printf(aSorryTryAgain, v3);
我们可以知道v7是我们的flag
往下看_substr666()这个函数出现了很多次,我们点进去看看
__int64 __fastcall _substr666(char *a1, char *a2, int a3, int a4)
{
int v4; // eax
int v6; // [rsp+20h] [rbp-8h]
int i; // [rsp+24h] [rbp-4h]
v6 = 0;
for ( i = a3; a4 + a3 > i; ++i )
{
v4 = v6++;
a1[v4] = a2[i];
}
return 0LL;
}
我们可以看出666这个函数就是把字符串a2从下标a3开始,数a4位数放到a1里。
_substr666(v8, &v7, 0, 6);//把v7从下标0开始把6位数放到v8
_substr666(v11, &v7, 7, 6);//把v7从下标7开始把6位数放到v11
_substr666(v14, &v7, 6, 1);//把v7[6]放到v14
如果v4为真则正确,那么
_0x233333(v8) ,_0x666666(v11, &v6)和_0x8048000(v14) 为真。
点进去233333函数
_BOOL8 __fastcall _0x233333(char *a1)
{
//此处省略某些不重要的定义
v7 = __readfsqword(0x28u);
*s2 = 0LL;
memset(&v5, 0, 0x58uLL);
v6 = 0;
_substr666(s2, str, 7, 6);
for ( i = 0; i < strlen(a1); ++i )
s1[i] = (a1[i] + 4) ^ 2;
return strcmp(s1, s2) == 0;
}
把从str[7]开始数六位放进s2,那么str是什么呢,点进去是一堆字符vosng%_Ngemkt,要使s1,s2相同,那么v8通过简单的异或加密可得到s1。
回到上一级,点进去666666函数
BOOL8 __fastcall _0x666666(char *a1, char *a2)
{
//此处省略某些不重要的定义
v11 = __readfsqword(0x28u);
v3 = 0;
*s = 0LL;
memset(&v9, 0, 0x58uLL);
v10 = 0;
_substr666(s, str, 0, 6);
for ( i = 0; i < strlen(s); ++i )
a2[i] = s[i];
for ( j = 0; j < strlen(s); ++j )
v7[j] = a1[j] + j - 1;
for ( k = 0; k < strlen(s); ++k )
{
if ( v7[v3] == a2[v3] )
++v3;
}
return v3 == strlen(s);
}
再次使用666函数 _substr666(s, str, 0, 6);//把从str[0]开始数6位放入s,再放入a2,让a1即v11经过这一步“v7[j] = a1[j] + j - 1;”后与a2相等
_0x8048000(v14)函数就更简单了
_BOOL8 _fastcall 0x8048000(char *a1)
{
return strcmp(a1, "") == 0;//v14就是''
}
综上所述,flag分为三段,前6位对应v8,中间是v14即‘_’,后六位对应v11
脚本如下
#include <iostream>
#include <string>
using namespace std;
int main()
{
char a[]={"vosng%_Ngemkt"};
for(int i=7;i<7+6;i++)
{
cout<<char((a[i]^2)-4);
}
cout<<"_";
for(int i=0;i<6;i++)
{
cout<<char(a[i]+1-i);
}
return 0;
}
image.png
flag格式为gwht{}
所以最终flag为gwht{Hacker_world!}
网友评论