题目:
IDA打开,先找到main函数,再F5查看伪代码
逻辑很好懂,想要得到congratulations,就是得想办法跳出while循环,从while(1)这里看无法直接跳出,只能寻找break语句,刚好在第二个if那里发现了break,也就是,只要输入的内容经过sub_4012F0函数处理后,也满足if后面的三行判断就可以了。
同时为了方便,将类似scanf函数里面的dword_404390的名字修改为str
开始分析if里面三条语句的含义
关键是搞明白这个off_404018是在干什么,双击查看,
再双击打开sub_401080
前面的循环是分别对str1[i]异或i,最后strncmp(Str1, "pvlg", 5u) == 0是比较str1和”pvlg
的前五位,如果相同就返回0,这样==0成立,整个函数就返回1,即true,这样就可以保证if条件的第一个为真了,所以输入个条件就是前五位分别异或0,1,2,3,4后是pvlg`,
也就是说str[0] ^ 0 == 112, str[1] ^ 1 == 118, str[2] ^ 2 == 108, str[3] ^ 3 == 103, str[4] ^ 4 == 96
即flag的前五位是p,w,n,d,d
同样的操作,再看if中的第二个条件对应的函数
很容易可以得到,for循环的作用是交换a1[i]和a1[3-i]的值,很典型的不用临时变量交换两个数据的方法。然后v2是strcmp(a1,”evoL”)函数的返回值,然后下面的if语句,就是当v2等于0时不执行,当v2不等于零时进行一个赋值操作,根据前面的分析可以知道,这个函数返回值必须为真,即在return那里,v2==0必须成立,所以就是strcmp函数的返回值必须为0。也就是说flag的6-9位是L,o,v,e
再看if中的第三个函数
首先看for循环之后的内容,发现是和4010F0最后的一模一样的也就是说strcmp(a1,”ZELDA”)函数的返回值必须是0,也就是说经过for循环处理过后的a1得是“ZELDA“
最后的问题就是搞明白for循环对a1进行了怎样的操作
还是为了方便观察,把qword_4043B0名字修改一下,就是last_one吧
同时注意到,修改变量名后,main函数发生了变化,
多出来的LODWORD查阅资料,发现是宏定义
也就是说,下面的输入函数,橙色字体那里相当于是last_one的,也就是说后面%lld输入的内容实际上是存储在这个last_one里面的
a1[0]=last_one右移32位,得到90,说明last_one的第32位左边的数字是1011010;
a1[1]=last_one剩下的31位右移24位,得到69,即last_one的24-32位是69,即1000101
同理可得到a1[2],a1[3],a1[4]分别为1001100,1000100,1000001所以
last_one为0101 1010 0100 0101 0100 1100 0100 0100 0100 0001,转化为十进制就是387,709,682,753,这就是last_one的值
也就是说flag最后的数字部分就是387,709,682,753
同时观察这个输入函数,输入字符串和数字之间有个空格
这样解出来的flag实际上就是pwnddLove 387709682753;