软编码寻找序列号(一)

使用工具

  • OllyDbg 1.10原版,简称OD
  • OD 汉化插件均来自互联网;
  • CrackMe来自互联网,仅供学习使用;
  • 文中特殊数字均是HEX,为了书写方便采用DEC

逆向思路

  1. 首先,打开软件到处点点,逆向一个软件起码要会用吧,不会用就没必要说逆向了:

    开始

  2. 倒入OD开始分析:

    • 首先按下Ctrl + AOD分析一下代码;

    • 接着按下Ctrl + N查看使用了哪些API,用的API不多,一眼就看到了GetDlgItemTextA,在GetDlgItemTextA函数上设置断点,然后去断点窗口双击断点进入反汇编窗口给断点设置备注,这是一个好的习惯,请保持;

    • 然后F9运行程序,输入用户名和注册码,点击确定;

    • 程序断下来了,在堆栈窗口选择Buffer右键数据窗口中跟随,没有数据,因为断点在行首,Ctrl + F9或者点击菜单栏调试选项,选择执行到返回,再去数据窗口中看看,有数据了,是我们输入的用户名;

    • 再次运行程序,程序再次中断,不出意外应该是获取注册码,在堆栈窗口选择Buffer右键数据窗口中跟随,没有数据,Ctrl + F9或者点击菜单栏调试选项,选择执行到返回,再去数据窗口中看看,有数据了,是我们输入的注册码;

    • 能获取到数据就是一个好的开始,F7 或 F8单步执行到程序领空,熟悉的字样映入眼帘:

      程序领空
      既有我们输入的内容,也有提示字样,应该就是这里了,那就开始分析;

    • 前面的代码是堆栈平衡和清除弹窗的代码,进CALL之后,直接ALT + F9或者点击菜单栏调试选项,选择执行到用户代码

    • 需要分析的代码来了:刚分析了两行,发现了几行特别的代码:

      发现

      这几行代码,一个push然后紧跟着一个CALL,而且 push 的是我们输入的内容,这里应该就是关键了;

    • F7进第 1 个CALL看看:

      用户名call

      • 刚进来第 1 行代码有困惑的吗?你咋知道是用户名放入ESI 寄存器

        第一行

        很简单,[ESP+4]告诉我的,ESP 寄存器永远指向堆栈的顶端,那[ESP+4]就是下一行喽,看一眼堆栈窗口,第二行的数据不正是我们输入的用户名吗?

      • 接着,出现了第 2 处令人疑惑的代码:

        疑惑1

        机器码和41比较,这到底是啥意思?刚开始我也弄不明白,而且后面的逻辑也显示和41半毛钱关系没有,直到无意中在用户名输入了数字,弹出两次注册失败,才好像明白了这里判断的是啥?我们先看看 16 进制的41到底是什么:

        41

        原来41是大写字母A,而后面的5A则是大写字母Z,那我好像明白怎么回事儿了,它应该是在判断用户名是否是英文字母;

      • 当字符的机器码大于41并且大于5A时,程序会跳转到一个新的CALL,那它干了什么呢:

        新CALL

        可以看到,这里只有 3 行代码,我们分析一下,小写字母的机器码减去20是什么,没错,是对应的大写字母,这三行代码的作用就是:将用户名转换为大写字母,然后用大写字母替换用户名中的小写字母,然后返回:

        大写

        当用户名全部转为大写字母之后,又来到了一个CALL,这个CALL又是干什么的呢,F7跟进去看看:

        新CALL

        原来,是将转换为大写字母后的用户名的每个字节的机器码累加在一起,然后和5678异或,并把异或后的结果放入EAX并返回:

        返回

    • 用户名处理完了,接下来就是注册码了:

      比较

      刚从用户名的连环CALL里出来就这么刺激吗?把用户名运算后的结果和我们输入的注册码都 push 到了这个CALL里面,这里应该就是比较了;

      注册码

      结果很打脸啊,不是验证CALL而是运算注册码的CALL,而第一行的PUSH EAX只是个入栈而已。。。

    • 验证环节

      验证

      根据CALL跳转的位置,轻松知道它的用途;

    • 注册码的计算规则:

      • 用户名必须是字母;
      • 将每个字母转为大写字母;
      • 把每个字母的 16 进制累加在一起;
      • 累加的结果与 5678 异或;
      • 异或后的结果与 1234 异或;
      • 将最后的结果转为 10 进制,注册码就出来啦;
    • 无图无真相

      • 例如:yang的大写YANG的 16 进制是59 41 4E 47

      • 加在一起是59 + 41 + 4E + 47 >> 12F

      • 12F5678异或xor 12F, 5678 >> 5757

      • 57571234异或xor 5757, 1234 >> 4563

      • 4563转为 10 进制后17763;

        上图