一般来说,逆向分析并不是对那些庞大的程序进行完整的逆向,只是分析特定位置的一个或几个函数。
1、程序加载详解#
打开菜单上的 VIEW-OPEN SUBVIEW-SEGMENTS,可以看到已经自动加载的程序区块。
在区段的名称(NAME)
一列后面,是区段起始(START)
和终点(END)
的地址。
RWX 这一列显示初始状态下这个区段是否有读READ(R)
、写WRITE(W)
以及执行EXECUTION(X)
权限。
后面的D
和L
两列分别对应于DEBUGGER(调试器)
和LOADER(加载器)
。
第一列 (D) 为空,只有程序在调试模式时才会填充已经加载的区段,L 这一列显示了加载器创建的区段,其他列的内容不是那么重要。
2、查看关键字符串#
尝试打开 exe 程序
在 help-register 处可输入 name 和 serial。
随意输入字符,提示 No luck there,mate!
查看字符串,快捷键 shift + F12。
可以看到和程序一样的提示。
双击上图中的字符,跳转到如下位置
在 0x00402169 地址上保存了这条字符串,在该地址上按D键
可以查看具体的字节。
再一次按 A 键可以恢复显示字符串,按 X 键更好的显示右边的引用。
3、查找关键函数#
上图中,有两个不同的函数引用了这条字符串。一个是sub_401362
,另一个是sub_40137E
。
之所以是两个不同的函数,因为 IDA 显示引用都是 functions + XXXX 这种方式,如果他们属于同一个函数,那么只有 XXXX 这个值会改变,而前面的部分不变,但是 sub_后的地址是不一样的。
sub_401362
sub_40137E
目前已经找到所有显示注册不成功信息的位置。
回到sub_401362函数,如图所示,这里调用了 messagebox API 函数来显示 NO LUCK THERE MATE 这样的消息。这个 API 函数接收 NO LUCK 字符串作为窗口标题,NO LUCK THERE MATE 字符串作为显示的文本。
sub_40137E也一样,意味着在两个地方都会触发注册不成功的消息。有可能是处理不同的信息。如果要显示注册成功的消息,这两处都要绕开。
接下来按 X 键查看程序对sub_401362函数的引用如下图所示,只有一处引用。
转到这个引用之前,重命名一下sub_401362 函数,比如说 CARTEL_ERROR。在函数地址上按N键
,然后填写这个新的名字。
来到引用了 CARTEL_ERROR 函数处
在调用 CARTEL_ERROR 函数之前又一个 jz 跳转,为了区分成功 / 失败的代码块,可以给这些代码块加上颜色),点击代码块右上角颜色选择器,如下图所示。
续在 0x40124c 处按回车键,进入被调用的函数 0x40134d。
0x40134D 函数
将0x40134D 函数改成 CARTEL_BUENO 名称。
将引用他们的代码块变成绿色。
4、标记指令位置#
继续来到 0x401243 代码处的 jz 命令,打开菜单 JUMP-MARK POSITION(快捷键 alt + m),将其命名位 DECISION_FINAL,之后就能轻松回到这个位置。
打开菜单 Jump-Jump to marked position。
就可以轻松跳转到对应的位置。
5、修改指令#
按照之前的分析,如果把 0x401243 处的 JZ 改成 JNZ,那么输入一个非法密码的时候,程序也会执行注册成功这条路径。
注:keypatch
由于 7.6 版本没有 keypatch 这个插件,尝试安装也没能安装上,所以换了个 ida 7.7 的绿色汉化版。
当前指令处右键,选择keypatch-patch
(快捷键:ctrl + alt + k)。
打开如下窗口:
修改内容如下:
修改后,点击 patch,返回如下内容,后面的注释告诉你修改了内容。
再一次右键点击patching-apply patch to...
,保存修改后的内容
保存为 exe 文件。
运行 crackme.exe 程序,随意输入内容,一共弹出两个窗口,一个成功提示,一个失败提示。
综上,需要修改两处的内容,才能绕过注册。
如上图所示,这里显示了另一处注册失败的消息,同时红色代码块上方有一个 cmp 指令,比较用户输入的用户名的字符是否小于 0x41,也就是字符 A。如果小于 0x41,则提示注册失败。
之前运行 crackme.exe 注册时,输入的时 111(0=30,1=31),显然小于 0x41,所以当程序检测到包含数字的时候,就显示注册失败。这里就不能把 jb 改成 jnb 了,不然输入字符又会报错了。
上图中的虚线,显示了程序将跳转到这里就报错,所以如果将跳转指令改成 nop,程序就不会跳转了,而是继续执行下一条指令,而不执行这里的报错。
切回图形化显示。
修改后整体界面混乱。
上图可以看到修改后的 nop 字节,报错信息也被孤立了。
重新保存修改后的文件。
测试完成后,支持任意字符输入了。