攻防世界逆向高手题之Reversing-x64Elf-100
继续开启全栈梦想之逆向之旅~
这题是攻防世界逆向高手题的Reversing-x64Elf-100
照例扔入exeinpefo中查看信息,然后扔入对应IDA中查看伪代码:
64位ELF文件,无壳,扔入64位IDA中,有主函数从主函数开始:(PS:这里犯下第一个错误,我一开始以为没有主函数,跳到start函数中去分析了,结果有个栈指针错误,但是我还不会调,迷惘了,后来一看才发现原来有主函数)
跟踪进入判断函数并分析代码:
__int64 __fastcall sub_4006FD(__int64 a1)
{
int i; // [rsp+14h] [rbp-24h]
__int64 v3[4]; // [rsp+18h] [rbp-20h]
v3[0] = (__int64)"Dufhbmf"; //这里犯下第二个错误,我以为是普通字符串,在内存中应该小端顺序反序才对,结果是数组,数组的话从首地址开始的确是正序的了,吸取经验,以后要是不确定是不是反序就直接双击跟踪看内存即可。
v3[1] = (__int64)"pG`imos";
v3[2] = (__int64)"ewUglpt";
for ( i = 0; i <= 11; ++i )
{
if ( *(char *)(v3[i % 3] + 2 * (i / 3)) - *(char *)(i + a1) != 1 ) //这里犯下第三个错误,一开始没看见最左边的取地址符*的范围是一整个(char *)(v3[i % 3] + 2 * (i / 3)),搞到脚本编写出来障碍,这里应该这样理解,(char *)(v3[i % 3]取这v3[0]、v3[1]、v3[2]、中的第几个完整数组,+ 2 * (i / 3)是为了在确定的v3[0]、v3[1]、v3[2]中继续深入取对应数组的字符进行操作,这里的逆向逻辑也简单,就是*(char *)(v3[i % 3] + 2 * (i / 3)) - 1 = *(char *)(i + a1)
return 1LL;
}
return 0LL;
}
分析完毕,脚本:
key1="Dufhbmf"
key2="pG`imos"
key3="ewUglpt"
flag=""
key4=[key1,key2,key3]
for i in range(12):
flag+=chr(ord(key4[i%3][(2*int(i/3))]) -1)
print(flag)
补充一下,这道题一开始以为是与用户输入无关的存储型flag,本来想断点调试直接输出flag的,结果IDA远程和linux的GDB都不行,想起前面的栈指针错误,应该和调试不了有关吧~ 不过后来想了想,是不能通过动态调试获取的,因为return是嵌入在循环中的:
也就是有一个不对就跳出循环,就没办法读出完整的flag了,所以这应该是与用户输入有关的生成型flag。
总结:
1:
这里犯下第一个错误,我一开始以为没有主函数,跳到start函数中去分析了,结果有个栈指针错误,但是我还不会调,迷惘了,后来一看才发现原来有主函数
2:
这里犯下第二个错误,我以为是普通字符串,在内存中应该小端顺序反序才对,结果是数组,数组的话从首地址开始的确是正序的了,吸取经验,以后要是不确定是不是反序就直接双击跟踪看内存即可。
3:
这里犯下第三个错误,一开始没看见最左边的取地址符*的范围是一整个(char *)(v3[i % 3] + 2 * (i / 3)),搞到脚本编写出来障碍,这里应该这样理解,(char )(v3[i % 3]取这v3[0]、v3[1]、v3[2]、中的第几个完整数组,+ 2 * (i /3)是为了在确定的v3[0]、v3[1]、v3[2]中继续深入取对应数组的字符进行操作,这里的逆向逻辑也简单,就是(char *)(v3[i % 3] + 2 * (i / 3)) - 1 = *(char *)(i + a1)
解毕!敬礼!