序列号型CrackMe逆向之IDA技巧篇

    前面我们探讨了用OD来定位验证逻辑位置,现在我们来探讨下如何使用IDA来定位验证逻辑位置~

控件ID搜索法

    如果一个windows程序使用了rc资源(把程序往Resrouce Hacker一拖,能看到对话框之类的资源的说明就使用了rc资源),并且控件的ID比较特殊的,就是搜索不容易出现大量重复指令的ID,就可以使用搜索立即数的方式定位对应验证逻辑,方法如下(这边使用crackme.chm的figugegl.1.exe作为演示用例)~

    将程序载入IDA,然后搜索立即数101或102,找到指令格式为PUSH 0x65(101的十六进制格式)并且注释为nIDDlgItem的指令(有些时候可能没有注释,但是指令的格式必须是PUSH的),指令所在的地址就是我们要找的程序验证逻辑,这边两个函数都有这种指令,还需要进一步分析,请见下


    我们先看双击跟进第一个指令所在的地址,然后使用F5查看对应的C代码,发现这个是窗口样式初始化的代码,并不是我们要找的验证逻辑(看到SetClassLongA就知道了)

    我们来看第二条指令所在的地址,F5仔细分析下程序逻辑基本可以断定这就是我们要找的程序验证逻辑,验证算法这边就不分析了

搜索虚表

    如果按钮的控件ID不够特殊,并且当验证按钮的控件ID为1或0的时候,这个时候只能通过找虚函数的方式来定位验证逻辑了,这个情况比较少见。控件ID为1或0的时候对应的处理函数比较特殊,它默认处理函数是OnOK和OnCancel,而这两个都是虚函数,具体操作如下(这边使用crackme.chm的noos.1.exe作为演示用例,这边搜索EDIT的控件ID值1001或1002定位更快,仅为演示而演示)

    首先找到一个CDialog的虚函数,如果用户同时重载了OnOK和OnCancel那么就找DoModel,否则要么找OnOK或OnCancel,然后单击函数的交叉引用转到虚表

    下面的1、2、3分别是DoModel、OnOK、OnCancel,如果被用户重载了,那么就会变成sub_xx的字样,所以我们可以知道2就是我们要找的验证函数OnOK


F5分析失败处理方法

    F5功能用过的都说好啊,但是有时候F5会失败,虽然可以直接看汇编,但是总是不太爽滴,能看C代码还是尽量看C代码,这样程序框架比较容易理清,比如下面这个程序(实验程序下载链接:传送门)

    产生这个问题的原因就是IDA对有些函数的栈平衡方式分析出了问题,如果函数是_stdcall方式,栈由函数自己来平衡,但是如果是_cdecl方式,则由调用者来平衡,如果IDA对函数的调用方式分析出的问题,那么就会导致栈不平衡,这个时候就会出现上面的错误,解决办法就是修正报错所在地址的栈值,这个栈值要修正成什么样子呢?函数在一开始的时候会有太高栈顶和保存寄存器值的动作,在完成这些动作后的栈顶值就是函数执行过程中的“标准栈值”,就是如果函数中因为要调用其他库函数压参数入栈,那么在函数调用完成后需要再恢复到“标准值”

    由于函数开头保存寄存器有时候可能是后面函数调用的输入参数,所以通过分析开头来确定“标准栈值”不太方便,这边我是习惯找出错地址前分析正常的Call调用,因为IDA这个时候没分析错,那么Call调用后恢复的栈顶值肯定就是标准值,当然可以多找几个Call来验证,因为有时候在release版本下,可能在连续调用几个函数后才统一平衡堆栈,最常见的例子就是printf,release下会在连续几个printf后使用add esp,xx的方式平衡,这个时候就add指令之后栈顶值就是标准值,所以stdcall方式和cdecl方式确认标准值的方式是不同的

    在出错地址处按下ALT+K呼出栈顶值调整窗口,Current SP value表示当前指令执行前的栈顶值,old and new SP表示是当前指令执行完成后栈顶值的变化值,两者相加就是指令执行完成后的栈顶值

    由于前面的call ds:__imp_mfc100_10007应该是一个stdcall调用,所以在这个call调用上按下ALT+K,可以得出标准栈顶值为-0x22C(可以多找几个Call调用来验证),所以我们只要将上面的栈顶值也调整成-0x22C就可以了,就是编辑框的0x21C改成0即可

    修改完成后你会发现又能神奇的F5啰~

交叉引用

    IDA作为静态分析的利器,它的交叉引用是一个非常强大的功能,通过数据交叉引用,我们能够知道一些全局变量在代码中的使用情况,比如有些CrackMe程序它使用全局变量来保存字符串,并且的字符串获取在一个函数,验证在另外一个函数,我们通过控件ID很容易定位到字符串获取函数,验证函数我们就可以通过对保存字符串的Buffer的交叉引用来定位了(这边使用crackme.chm的Cruehead.1.exe作为演示用例)~

    使用IDA搜索立即数1000,定位字符串获取代码位置

    接下来我们查询String的数据交叉引用就能找到对应的验证逻辑了,因为验证当然要读取字符串,肯定还会引用String变量的,双击变量进入数据段,然后单击数据的交叉引用,是不是很快就找到验证逻辑了呢?


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值