joker
当我看到这题的名叫joker的时候,我就知道,这题很美好,没好了。但是为了线下赛,我哭着下载了题目,然后,然后我就真哭了。
老规矩,拿到题目先查壳:
拿到有用信息,32位,无壳,gcc编译。
用ida看一下程序大体结构:
这里你会发现,按下f5会报错
这里是堆栈的问题,解决连接如下: https://blog.csdn.net/xiangshangbashaonian/article/details/81950110
反编译主函数:
发现整体思路很清晰吖,输入长度为24,接下来就是一堆函数,我们跟着看一下:
wrong:
一个简单的分奇偶加密,下一位:
omg:
简单的比较,看提示好像马上出flag了?很简单吗!
然后飞速写了解密脚本,得到flag: flag{fak3_alw35_sp_me!!}
???这一看就是假的啊,我心态崩了!
幸好下面还有两个函数,跟进去看看
?
?
这两个函数一看就不正常啊!双重打击。。。
encrypt这个函数可以看出来是被加密的,写个idapy解密:
sea = ScreenEA()
c = 1
for i in range(0,186):
c = Byte(sea+i)^0x41
PatchByte(sea+i,c)
但解密之后又会发现新的报错。。。
在安利一篇文章解决问题: https://blog.csdn.net/lixiangminghate/article/details/78820388
其实这里直接读汇编也是很简单的,我这里放一下最后的反汇编:
encrypt:
finally:
这回总该是最后的结果了吧。
encrypt的解密脚本很好写,一个异或:
#include<stdio.h>
int main()
{
int str[] = { 0xe,0xd,9,6,0x13,0x5,0x58,0x56,0x3e,0x6,0xc,0x3c,0x1f,0x57,0x14,0x6b,0x57,0x59,0xd,0};
char a[] = "hahahaha_do_you_find_me?";
for (int i = 0; i <= 18; ++i)
{
for (int l = 32; l <= 127; l++)
{
if ((l ^ a[i]) == (str[i]))
{
printf("%c", l);
break;
}
}
}
得到: flag{d07abccf8a410c
诶,不对啊,记得flag要24位啊,而且你这}也没有啊,你在逗我???
急急忙忙看了一眼最后的函数(一个下午都在研究这个函数。。。),啥也没干啊?可以得到 得到%tp&: 五个字符,但看了后面干的事情,和flag开头字符比较?有卵用啊,然后我记得那天下午。。。
我tm心态崩了啊!
答案是盲猜真的是搞,最后一位一定是},根据这个展开想象,}与:的异或为G,把其他的字符也异或一下G
最后flag就是 flag{d07abccf8a410cb37a}
总结:这种题之前的还好,要用到idapy和调节sp之类的,但最后这个加密真的是鬼,纯靠天马行空的想象,最后看看就好