直接bp GetDlgItemTextA,定位到关键点后,进入IDA分析
下面这段代码,主要是验证输入的key必须满足一定的条件才能进行下一步的验证
通过后面的代码可知nFlag 必须等于0,否则验证失败。也就是说
key_len >= 12
key[0] != 'A' && key[1] != 'A'
key[5] == 'V' && key[11] == 'V'
第二部分验证是在这里
有一个全局的数组g_word_buf
判断g_word_buf[key[i]] & 0x107 结果,决定是否置位nFlag。
这里是验证输入的key的每个字符的合法性
来到下面的部分,看来还是F5清晰
其中W_402297()是一个查表类的加密,后来验证是RSA,算法不及格,也不知道该怎么描述这部分,先放在这里,后面逆推key时还会用到
W_40231E()这个又把加密后的结果给还原回来了,并且还在后面调用memcpy()进行比较
通过几次验证发现,只要是sub_4024E1()返回2就是验证成功
那么重点就看看这个函数的内部实现
进入sub_4024E1()
其实一开始我根本也不知道它是啥玩意,是含泪一步一步肛的,看F5是在是看不懂,太乱了,就大致的还原了一下C逻辑
搞了几个后发现是大数据的计算
我就开始尝试着猜了……,慢慢的就都猜出来了
先说一下对象结构,大致是下面这个东西,我也不知道是不是作者使用的大数库,还是他自己写的
大致流程如上图所示,这里就从后往前看了,先看sub_4021A7(obj[2]);
该函数返回2才会注册成功,还原后的类C代码
该函数的返回值,还会由sub_4011A9(obj)来决定,也就是只有sub_4011A9(obj)返回值小于0x20才可能注册成功
再次进入sub_4011A9(obj);
首先一个循环从后向前验证obj.buf[]中第一个不为0的元素
然后取出该元素进行移位处理
最终可以推算出i = 0, j = 31 ---》 nNum = 2/-2 = obj[0]
也就是obj[0]只能是2或-2
再来看看sub_4020F1(obj[2], obj[1], nNum1, obj[0]);这个函数
该函数实际上是计算:obj[2] = obj_1^nNum % obj_0
明显是一个RSA的运算
经过几次尝试发现nNum和obj_0是固定的,obj_1与我们输入的key相关,最终计算出来的结果obj[2].buf[0]只能是2或-2
将上面的结果整理成公式,也就是下面这个样子
X^0x53 % 0x41CD66ACC237B22681A18067 = 0xFFFFFFFE
X^0x53 % 0x41CD66ACC237B22681A18067 = 0x2
其中X与我们输入有关,0x53就是上面的nNum,0x41CD66ACC237B22681A18067是上面的obj_0
整理成RSA相关参数
c=0xFFFFFFFE / 2
n=0x41CD66ACC237B22681A18067
e=0x53
p=?
q=?
D=?
m=?
那么就是分解n的问题了,使用在线大数分解http://factordb.com,注意输入只能是10进制,悲催的是有好多,如何找到那个符合我们条件的?
通过上面的大数分解结果可知:
0x41CD66ACC237B22681A18067=3*5*7*11*13*17*19*23*29*31*37*41*43*47*53*59*61*67*71*73
这是一个组合数的问题…………
也就是之前高中学的20个数,任取几个有多少种组合的问题,算了数学不好,还是上网上A算法牛的代码吧…
代码也记不清是A的谁的了,在这里说声谢谢
自己加上大数库,改一改就出来了
最终计算出p=0x26AB4AE3、q=1B3A11F1BC8BC97AD
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2019-3-29 14:37
被kanxue编辑
,原因: