VB 调试之分析 N-Code(一)
使用工具
分析思路
首先运行软件,了解一下程序:
O, No!
首先是一个
NAG 窗口
:NAG 窗口
:软件未注册或软件的试用版经常会弹出一些提示窗口要求注册,这些窗口被称为 nag 窗口,也叫烦人的窗口;然后才是软件窗口,要求输入注册码;
输入随机字符点击 OK,一个奇怪的弹窗,应该是 No? Thanks?
将
CrackMe
倒入OD
,开始分析:首先,第一件事儿是去掉
烦人的窗口
:既然是弹窗,那么它肯定调用了
MessageBox
这个 API,不过,VB 有专有的 APIrtcMsgBox
:调用一个消息框,类似于 Windows 里的 MessageBox/A/EXA,此之前一定有个 PUSH 命令将要在消息框中显示的数据压入椎栈;既然已经知道了它调用的 API,那还等什么,给
rtcMsgBox
设置断点:按下
Ctrl + G
输入rtcMsgBox
,然后点击确定,程序会跳转到rtcMsgBox
函数的行首,然后双击该行设置断点,并做好备注;设置好断点后,
F9
运行程序,程序会中断在断点位置,然后在堆栈窗口
跟踪调用位置:来到
反汇编窗口
,这个时候函数rtcMsgBox
已经调用完成,既然找到了调用位置,那怎么能去掉烦人的窗口
呢?设置好断点,重载并运行程序后,程序中断在预先设置好的断点位置,而下面一行的
CALL
就是调用rtcMsgBox
的位置,如果把这个调用NOP
了,是不是就没有NAG 窗口
了,听起来蛮靠谱,试一试:NOP
了调用rtcMsgBox
的CALL
后,继续运行程序,但并没有按照预期显示程序主窗口,而是程序结束了,这是怎么回事儿呢?按下
-
减号键,返回上层位置,把修改的内容保存下来试试:双击运行保存的程序,没有任何反应,em ~~ 看来程序被玩坏了,此路不通;
重载并运行程序,重新来到
反汇编窗口
,既然把直接调用函数NOP
了不行,那就只能继续运行程序,看看它的上一级调用:来到上级调用的返回位置,上一行的
CALl
就是刚才整段代码的调用位置,如果把这个CALl
干掉,那么弹窗也就没有了,试一试,但愿程序不被玩儿坏;在这个
CALl
的参数的上一行设置断点,重载并运行程序;程序中断在预定位置,选择下面
CALl
和它的参数用NOP
填充:继续运行程序,啊哈,期待已久的程序主窗口终于出现了:
主程序出现,说明这个方法可行;
为了后面找码方便,把修改后的程序另存为一个新的程序:终于要和
烦人的窗口
说拜拜了,至于保存的方法,上面已经说明,不再赘述;运行修改的程序,嗯,没有
NAG 窗口
,直接出现程序主窗体,一切 OK;
搞定
NAG 窗口
后,是时候寻找一下注册码了:把修改后的程序倒入
OD
,然后运行程序,主窗体出现:输入随机注册码,但不要点 OK,但不要点 OK,但不要点 OK,重要的事情说三遍:
接着到
内存窗口
,在CODE 段
设置内存访问断点
,然后到程序中点击 OK;点击 OK 后,程序中断:
这里的代码看不大懂,不过没关系,也没有找到需要的信息;
继续运行程序,直到看到了随机输入的注册码和字符串比较函数:
随机输入的字符作为字符串比较函数的参数,那另一个参数毋庸置疑,肯定是真实的注册码;
不过遗憾的是,由于这个软件是西欧字符软件,好多字符无法正确显示,找到了真实的注册码也无法输入,复制也不行,因为系统字符集中没有某些字符:
既然无法输入真实注册码,那就只能让任意字符成为注册码了:
首先,字符串比较函数的返回结果非 0,说明两个参数不相等,继续向下分析;
把比较的结果从 EAX 拷贝到 EDI 中,然后进行了一系列的操作,然而,如果 EDI 为 0,则这些操作没有任何意义,至于中间夹杂的其他操作可以忽略了,因为没有涉及到 EDI:
这里有一个 JE 跳转,上一行代码是
TEST DI, DI
,如果 EDI 自身为 0,则TEST DI, DI
影响 ZF 标志位,ZF 置 1,反之为 0,而恰恰 JE 根据 ZF 标志位跳转,可以看到,程序运行到了这里,ZF 依然为 0,则间接说明了输入的注册码不正确;既然这个跳转根据比较的结果进行跳转,那就可以确定它是关键跳,如果将 JE 修改为 JMP,是否就能满足
让任意字符成为注册码
?值得一试:修改 JE 为 JMP 后,取消内存访问断点,然后
F9
运行程序,It’s OK,终于看到了成功弹窗,不过由于字符集的原因,部分字符无法显示;保存修改到文件,然后输入任意字符:
成功的弹窗是 Yes? Thanks?