软编码寻找序列号(二)
使用工具
- OllyDbg 1.10原版,简称
OD
; OD
汉化
和插件
均来自互联网;- CrackMe来自互联网,仅供学习使用;
- 文中特殊数字均是
HEX
,为了书写方便采用DEC
;
逆向思路
首先,打开软件到处点点,逆向一个软件起码要会用吧,不会用就没必要说逆向了:
有点意思,输入内容之后没有任何提示,看来只有输入正确的序列号才会有提示;
倒入
OD
开始分析:首先按下
Ctrl + A
让OD
分析一下代码;既然界面没有按钮,那就得先猜测它的工作原理了,如果它会在输入正确之后提示的话,那么它就是实时获取我们输入的内容并进行判断,这样的话,有用的应该就是
内存断点
了;说干就干,既然要去内存中找我们输入的内容,那输入就一定得个性一点,起码不是内存中常见的,不然一找一大堆就无从下手了:
然后去
内存窗口
按下Ctrl + B
或者右键选择查找
,输入我们的序列号点击确定开始查找,记得勾选区分大小写
:输入的还算奇葩,只找到了两个,选择第二个吧,虽然第一个是独立的,但它在内存中的范围不太像:
设置
内存访问断点
,长度随意,看心情,我就选 5 个字节了;然后去程序界面再输入一个字符后,发现程序中断了:
不过中断的地方好像没什么用,我们输入的内容在
EDX
中,下面的代码段并没有操作它,F9
继续运行程序;刚一进程序领空就发现了亮点,这里好像就是比较了:
分析一番之后发现,逻辑很常规:
首先,假码 和 可疑字符串 的前 4 个字节的机器码进行比较,不相等跳转到下一步;
接着,假码 和 可疑字符串 的第 1 个字节的机器码进行比较,不相等跳转到下一步
最后,恢复寄存器的内容并
RETN
,然后就杳无音讯了;
至于正确的序列号,当然就是那串可疑字符串了,那这串字符是怎么来的呢,不能每次都这么找吧:
我们都知道
RETN
返回的是调用位置的下一行,那跟着RETN
去看看:按照程序的流程走,既然这里是判断,那上面的就是获取和处理了,上面有好几个
CALL
,哪一个才是我们想要的那个呢,按照先获取后处理的流程来看,离我们最近的那个CALL
应该是处理用的,那么这个CALL
上面那两行代码应该就是它的参数,在参数上设置断点,看看参数是什么就知道这个CALL
的用途了:设置断点,重载程序并运行后,程序中断了,但重点不在
反汇编窗口
,而是在堆栈窗口
,我们发现了可疑字符串也就是正确的序列号,如果我们设置断点的这个CALL
是处理函数的话,那么它还没运行怎么会出现正确的序列号呢?取消断点,在它上面那个CALL
的参数上设置断点;和上面的情况一样,程序中断后,在
堆栈窗口
,我们又发现了正确的序列号,再次取消断点,给它上面那个CALL
设置断点:这次就好多了,虽然没发现有用的数据但正确的序列号也没有出现,那这个
CALL
很可能就是生成序列号的函数了,F7
跟进去看看,结果很丧气,它也不是;那就接着往上呗,终于,在设置好断点,重载并运行程序之后有了欣喜的收获,用户名当作参数传递了:
虽然还没有运行代码,但信息窗口已经告诉我们它是什么了;
果断
F7
跟进去看看,都失败那么多次了,不差这一次:进来只有四行代码,但内容非常令人兴奋:这几行代码在检测有没有输入用户名;这就是一个好的开始,因为要操作数据的时候才会检测数据有没有输入;
从这个
CALl
里出来的窗口很熟悉,因为我们在这里已经操作了 3 次了,也失败了 3 次,这次将会是最后一次了:这手灯下黑玩儿的漂亮,它一直在眼皮子底下计算序列号:
这就完了?那序列号呢?嘿嘿,在这里:
是的,运算结束后,虽然数据保存到了
EBP-C
的位置,但我们并没有弹栈,所以EAX
没有被覆盖,双击EAX
试试,对啦,将运算结果转为 10 进制就是这个用户名对应的序列号;
序列号的算法:
- 用户名最少两位;
- 用户名的下标从 1 开始;
- 取用户名每个字节和它对应的下标进行异或运算;
- 所有字节异或后的结果累加在一起;
- 取最后一个字节的机器码,与对应下标进行异或运算后,循环左移 C 位;
- 然后把左移的结果和所有字节异或后累加的结果相加;
- 最后把最终结果转换成 10 进制就是这个用户名对应的注册码;
无图无真相
例如:用户名
feng
对应的机器码是66 65 6E 67
;用户名的下标从 1 开始;
每个字节分别与它对应的下标进行异或运算
xor 66, 1 >> 67
,xor 65, 2 >> 67
,xor 6E, 3 >> 6D
,xor 67, 4 >> 63
;异或后的结果累加
67 + 67 + 6D + 63 >> 19E
;取最后一个字节的机器码,与对应下标进行异或运算后,循环左移 C 位
xor 67, 4 >> 63
,ROL 63, C >> 63000
;然后把左移的结果和所有字节异或后累加的结果相加
63000 + 19E >> 6319E
;转换成 10 进制
6319E >> 405918
;