二进制逆向题目解析
ctf2—-Input flag
用ida打开这个文件,进入流程图模式:
使用Shift+12调出字符串表,寻找有效字符串:
这里的字符串很少,我们可以在下面看到一个”Flag is right”,点击进去可以进入汇编代码区:
点击红色区域,进入流程图模式,F5则可以进入汇编代码段,我们可以得到下面一串代码:
int __cdecl main()
{
char s; // [esp+10h] [ebp-110h]
printf("Input flag:");
sub_80485A0(&s, 0x100u);
if ( (unsigned __int8)sub_8048630(&s) )
puts("Flag is right.");
else
puts("Flag is wrong.");
return 0;
}
观察代码,想要得到”Flag is right.”,我们要想先知道sub_8048630是什么,点击进去,我们可以看到另外一串代码:
int __cdecl sub_8048630(char *s)
{
size_t v1; // eax
int v3; // edx
if ( s )
{
v1 = strlen(s);
if ( v1 )
{
if ( v1 == 29 )
{
v3 = 0;
while ( s[v3] == byte_8049AE0[(unsigned __int8)((unsigned __int8)byte_8049B15[v3] / 3u - 2)] )
{
if ( ++v3 == 29 )
return 1;
}
}
}
}
return 0;
}
两个代码结合,我们知道,上面这个必须返回值为1,那我们就看怎么令它为1,:
v1 = strlen(s);
if ( v1 )
{
if ( v1 == 29 )
{
v3 = 0;
while ( s[v3] == byte_8049AE0[(unsigned __int8)((unsigned __int8)byte_8049B15[v3] / 3u - 2)] )
{
if ( ++v3 == 29 )
return 1;
}
}
}
v1是s的字符串长度,当v1=29时,才能向下运行,所以字符串s的长度为29,向下运行,v3=0,
while ( s[v3] == byte_8049AE0[(unsigned __int8)((unsigned __int8)byte_8049B15[v3] / 3u - 2)] )
{
if ( ++v3 == 29 )
return 1;
当v3加到29时,才能返回1,所以while循环进行了29次,我们把 byte_8049AE0点进去发现了一串字符串:
这串字符串为:lk2j9Gh}AgfY4ds-a6QW1#k5ER_T[cvLbV7nOm3ZeX{CMt8SZo]U
再把byte_8049B15点进去:
会得到一串十六进制数,用shift+E快捷键以字符串数组把它们提取出来,得到:
{
0x48, 0x5D, 0x8D, 0x24, 0x84, 0x27, 0x99, 0x9F, 0x54, 0x18,
0x1E, 0x69, 0x7E, 0x33, 0x15, 0x72, 0x8D, 0x33, 0x24, 0x63,
0x21, 0x54, 0x0C, 0x78, 0x78, 0x78, 0x78, 0x78, 0x1B
}
而byte_8049B15[v3] / 3u - 2)
这一句的意思是以v3作为下标来取byte_8049B15
这里的数,取出来的数除以3,再减去2,得到另一个数,再以最后得到的这个数为下标去byte_8049AE0
里面的字符,放到s下表为v3的里面,所以,我们大概理清思路,就可以写程序,获得flag,
以下是python程序:
a=[0x48,0x5D,0x8D,0x24,0x84,0x27,0x99,
0x9F,0x54,0x18,0x1E,0x69,0x7E,0x33,0x15,
0x72,0x8D,0x33,0x24,0x63,0x21,0x54,0x0C,
0x78,0x78,0x78,0x78,0x78,0x1B]
b=[]
c='lk2j9Gh}AgfY4ds-a6QW1#k5ER_T[cvLbV7nOm3ZeX{CMt8SZo]U'
flag=''
for i in range(len(a)):
b.append(int(a[i]/3-2))
for j in range(len(b)):
flag+=c[b[j]]
print (flag)
得到的flag:
kctf{YoU_hAVe-GOt-fLg_233333}
链接:c库函数strlen函数