总体结构:
首先找到main函数,结构很清晰
前半段是输入和初始化
后半段开始着手加密
最后给出相应的输出
逐步分析:
首先在liunx中运行程序(注意要使用64位版本的liunx系统,后缀是AMD64的那种)
由题目给的这些字串可以得知,我们要输入六个数据来玩一个猜数游戏
这六个数据仔细分析就会发现就是v6,v6的每个元素占据4个字节
然后跟踪v6的行踪,仔细分析与v6有关的加密代码
这里dword_601078是取了每个v6元素四个字节中的后两个字节中的值,dword_60107c则是取了每个v6元素四个字节中前两个字节的值(详细去看hidword和lodword的定义)
这里解释一下为什么dword——601078那一条语句没有lodword函数却依然和有lodword函数的结果相同,这是由于dword_601078这个变量只能存储2个字节的数据,因此在读取v6[j]时只能读取其前两个字节,那么效果其实就跟lodword一样了。
深入到sub_400686中
先观察最下面这一段:
v3的值赋值到a1地址处,v4的值赋值到a1头部之后的元素上,考虑到a1其实是dword_601078,a1的一个元素大小为4字节,那么a1[1]所指向的地址不就是dword_60107c吗?这样这段代码的意义就明了了,对输入的数据两个两个一组进行异或加密。
再看最后的判断:
其实就是要让刚刚异或加密出来的结果符合if中给出的v7各个元素的值。
一些值是等式给出来的,解个简单的方程就知道v7各个元素的值了。
得到各个元素的值后,由结果通过逆算法推输入,就可以得到正确答案了(要注意耐心写脚本,这个工作挺繁琐的)
记得最后把输入的数字变成字符才能得到flag
Flag为flag{re_is_great!}