本帖最后由 zbnysjwsnd8 于 2017-7-19 19:23 编辑
唔。。。我也是第一次写分析文章 写的不是很好 如果有哪里错了还请大牛们指出来。 直接开始。 程序截图:
寻找按钮事件的起始地址:
从上图可以知道 注册失败的话会弹出一个MessageBox. 不妨在OD中给user32!MessageBoxA下断点 然后F9运行,输入假码试试能不能断下。
断下来了。然后F8单步 返回到程序领空
继续F8 返回到按钮事件。来到这里。
然后向上翻 找到函数头。
所以004010A1处就是按钮事件的起始地址
0x1 正式分析
在004010A1处下断,删掉MessageBoxA的断点 重新载入程序 F9运行。随便输入一串假码然后点击【注册】 会在004010A1处断下。
可以看到下面有一个call F8直接过去吧(易语言的实在没法看)过去以后 eax寄存器有变化了。
感觉有点眼熟。。。
对比一下 应该是一样的。所以这段代码的功能是获取机器码。来到这里。
这里把eax压入堆栈了 观察一下堆栈。
可以看到两个值其中 0019F38C 的值是eax的值(不用我说也知道为什么吧)然后F8步过这个call.过去以后,浮点寄存器有变化了
和178001005352对比一下 发现这个是178001005352的小数形式(精度很高)
因此这段代码是将机器码转换成了双精度小数(从文本转换成双精度小数) 继续往下。
来到这里。可以发现 这个call的地址和之前将机器码转换成双精度小数的call地址是一样的。
F8步过 看看寄存器的变化。
其中42452是0xA5D4的十进制形式 所以这段代码就是将0xA5D4转换成双精度小数的形式。
继续单步 来到这里:
从图中可知SS:[EBP - 0XC]处的值是178001005352.0000(机器码的双精度小数形式)
继续往下
从图中可知SS:[EBP - 0X14]处的值是42450.0000(0xA5D4的双精度小数形式)然后FMUL就是将这两个数据相乘 然后结果保存到ST(0)中。
这个就是结果(记为a1)。
这个00401129的指令则是将ST(0)中的寄存器弹出到SS:[EBP - 0x1C]中
有了之前的经验这段代码的意思应该很明显了:
将0x7EC6转换成双精度小数的形式;
这个则是将2转换成双精度小数的形式:
然后来到这里:
功能我已经写出来了 继续往下。
执行完这个call 观察一下寄存器
可以得知:这段代码是将a3转换成文本
转换成文本后的a3的地址(00812DD8)保存到LOCAL.16中
执行完这个call 观察一下寄存器:
其中“123”是我们输入的注册码 也就是说这段代码的意思是获取注册码
注册码的地址(0081DC70)保存到LOCAL.17中 接下来就是比较注册码:
这里这个JE实现了 如果实现的话就会提示失败 然后程序退出。
点击确定以后 程序退出。重新载入 F9运行 输入之前获取的注册码,点击【注册】 看看效果
因此 这个注册码就是正确的注册码(相对于这个机器码而言)
0x2 注册机
现在总结一下这个CM的算法:
设注册码为a,机器码为b(均为文本型)
则a = 到文本 (到数值 (b) × 42452 + 32454 ÷ 2)
有了这个算法 写出注册机就不难了。
附:注册机源代码
|