打开后是一个windows下的pe文件,查壳,无壳,为32位的可执行文件,使用IDA(32)打开,f5一键反编译,发现反编译不了,显示positive sp value has been found,那就开始看汇编把!
这里需要我们输入flag,通过后面的判断可以知道,输入字符长度为24,继续往下:
,,
这里可以看出来,flag经过了两个函数,__Z5wrongPc和__Z3omgPc如下:
前者主要对flag进行一些操作,偶数位(从0开始)^i,奇数位-1,得到的结果值传入后者再与字符串unk_4030C0进行比较
这里,发现有错误的输出,但输出错误并不会影响到整个程序的进行,而且后序的传参传的仍是原来的值,所以这里是个假的flag!!!好把,做题的时候我没有发现,(把假的flag求出来后才发现是假的>~<,但不影响啦)继续,
这里,进去__Z7encryptPc函数后,什么都没有,而箭头指向的地方是个循环解密的过程,换至OD中动态调试,运行到 call 401500处,
f7单步跟踪,发现函数流程如下:
判断[ebp+0x1c](计数器,起始值为0)的值是否等于0x12,然后从input中取出对应的字符与404012处对应的字符进行异或,异或后的值再与[ebp+eax*4-0x6c]中的值相比较,相等则继续直至退出循环,若有一个不相等则退出程序, 查看[ebp+eax*4-0x6c]中的值,如图:
因此可以求出flag[0:19]的值,还剩下最后5个,往后继续,有提示"come here",因此继续往下运行,必要时更改标志寄存器的值,跳过一些判断,跳出该函数处
运行到call 40159a处,f7单步进入,函数开头为,
结尾为
函数开头将5个数,放入了[ebp-0x11]地址处,继续运行至0x401617处,发现就是将flag的第一个字符与开头的第一个字符相比较,若相等则输出Really???若不相等就是输出I hide the last past,但这肯定是不相等的,再结合提示猜测与最后flag的五个字符有关,因为flag最后一位为'}',故猜测flag即为开头五个字符与ord('}')-0x3a异或得到,脚本如下:
c=[0x0E,0x0D,0x09, 0x06,0x13,0x05,0x58, 0x56,0x3E,0x06,0x0C, 0x3C,0x1F,0x57,0x14, 0x6B,0x57,0x59,0xd] d=[0x25,0x74,0x70,0x26,0x3A] b='hahahaha_do_you_find_me?' print(len(a),len(b),len(c)) for i in range(19): temp=ord(b[i])^c[i] print(chr(temp),end='') for i in d: x=i^(ord('}')^0x3a) print(chr(x),end='')
得到结果即为flag!!!