-
-
[原创] 第四题:达芬奇密码
-
发表于: 2019-6-21 13:15 3684
-
简单地说,本题核心验证逻辑是佩尔方程+数组实现128 bit数的运算。
使用xspy,或者IDA搜索unicode字符串"Wrong"再查找交叉引用,都可以找到关键函数sub_401EA0,事实上是按钮check的响应函数,内存地址0xAE1EA0(每次运行不一定一样)
函数sub_401EA0中可以看到输入字符串长度应该为16。
函数sub_4010E0作为本题关键的验证函数在运行过程中被修改了,是通过函数VirtualProtect和qmemcpy配合使用实现的。我选择dump内存后使用IDA打开:
函数sub_4010E0,也就是内存中的sub_AE10E0,其实是简单地实现了2**128以内的大数运算,有乘法、减法、判断相等。怎么看出来的呢?
首先观察该函数的几个数组之间的关系,也就是观察数据流
判等只有一处。理解大数运算之后发现原来是不定方程。
随后从一个比较简单的部分开始读,这里选择的是v61得到v46的部分。思考这段代码如何求逆,发现它完全类似于乘法进位的方法,相当于v61乘7得v46。于是猜测整个函数内都是大数运算。由此重新阅读以上函数就可以理解整个验证过程。
于是验证过程的核心问题是一个数学问题:
其实程序当中还有一些约束条件,我暂时把这些当作次要部分:
尝试使用z3求解问题,跑了十多分钟没有出结果,估计是在暴力,然而暴力法2**32以上都接受不了,此时显然只能放弃。于是开始寻求数学方法。
如果看成一个数学问题,上面这个核心问题还需要简化,因为搜索了解了一些不定方程的知识以后,发现若不考虑取余数运算,则为一种佩尔方程(pell)。于是猜想此处取余数运算没有用。
于是需要求解以下问题。
佩尔方程有一种递推解的方法,可以用一组特解产生多组解,于是可以尝试是否能恰好找到符合p,q上下界的解,果然找到了。数学过程大致如下:
以上,取d=7,k=8,式1特解a=8,b=3,式3特解x3=6,y3=2,带入式4迭代14次即可。说明一下我用numpy然后溢出了,好像numpy不支持128 bit整数。于是手动写了一个很难看的代码……
然后从p,q逆推回去,细心一点,注册码为L3mZ2k9aZ0a36DMM
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
- [原创] 第九题:绝地逃生 2934
- [原创] 第二题:沉睡的敦煌 2809
- [原创] 第三题:金字塔的诅咒 2904
- [原创] 第四题:达芬奇密码 3685
- [原创] 第六题:消失的岛屿 2883