3、竟然真的能运行,让输入密码,随便输了一个,错误:
4、使用Ida反编译,果然也是个elf类型:
5、找到main函数,使用view-Open subviews-Generate pesudocode(或按快捷键F5)生成伪代码:
生成后:
6、可以看出代码逻辑:
for ( i = 1; i <= 10; ++i )
{
v3 = malloc(0x10uLL);
*(_DWORD *)v3 = i;
v3[4] = *(_DWORD *)v3 + 109;
a3 = (char **)qword_601080;
*((_QWORD *)v3 + 1) = qword_601080;
qword_601080 = (__int64)v3;
}
最后两句像极了链表,是的,应该是一个链表的插入操作,且为头插法。
注意这里,qword_601080始终指向链表的头,且第五位开始存取序号+109,前面几位存取序号
printf("Enter the password: ", a2, a3);
if ( fgets(&s, 7, stdin) )
{
if ( sub_40074D(&s, 7LL) )
{
puts("Incorrect password!");
result = 1LL;
}
else
{
puts("Nice!");
result = 0LL;
}
}
看这个是只要满足sub_40074D(&s,7LL)==0即可。
7、转入sub_40074D函数(双击进入):
for ( j = 0; j <= 5; ++j )
{
if ( *((_DWORD *)&v6 + j) != *(&v9 + j) )
return 1LL;
}
return 0LL;
}
首先要满足返回0,必须使 j从0到5满足:
*((_DWORD *)&v6 + j) == *(&v9 + j)
即v6和v9前六位相同。
8、v9和后面五位分别为527256(v9v10v11v12v13v14):
v6 = 0LL;
v7 = 0LL;
v8 = 0LL;
v9 = 5;
v10 = 2;
v11 = 7;
v12 = 2;
v13 = 5;
v14 = 6;
9、则要使v6也为527256(v6为int64类型):因为v6每次赋的为v4的值,v4每次为0,则要想使赋值,v4赋值的v5的值,满足if条件的即为v5后面每一位与a1相同,而注意的是v5的恰好是链表的地址,且为加109的,因此分别为114、111、116、111、114、115,转换为ASCII码:rotors
for ( i = 0; i <= 5; ++i )
{
v5 = qword_601080;
v4 = 0;
while ( v5 )
{
if ( *(_BYTE *)(v5 + 4) == *(_BYTE *)(i + a1) )
{
v4 = *(_DWORD *)v5;
break;
}
v5 = *(_QWORD *)(v5 + 8);
}
*((_DWORD *)&v6 + i) = v4;
}
10、可以试一下,也可以直接提交flag啦(不要带冒号)。