roking 发表于 2008-1-20 03:10:10

VB程序之特征码搜寻方式定位NAG窗口(提供脚本)、注册表操作

人有天生的惰性,拿着别人写的破解分析,自己先做时,总想着“偷看”一下,结果思维被束缚住了,而且一些真金白银的东西,自己却不知道应该去重视他,收获甚少。

    看了n多的文章教材后,感觉好像领悟了不少真功夫,对那些初级的crackme练习开始嗤之以鼻(其实至今我还没有完整的做过一个),就想着拿商业软件练刀,结果我被一次次碰得头破血,自信心丧失殆尽,还好我有个好习惯,不对自己和别人发泄情绪,因为我有一个绝密武器---香烟!用它燃烧我的生命来安宁我的灵魂,才能让我脑袋清醒的坐下来总结一下失败过程中拾到的点点收获,为我的从头来过留些帮助。虽然对高手来说不值一提,但这是我辛苦后的收获,也许我能更深的记住它。不足之处请大家斧正。

    进入正题,这里仅讨论VB程序。由于VB编写的程序与微软的MSVBVM虚拟机相关模块关系紧密,没有对MSVBVM机理的一定了解的话,跟踪分析起来很容易就跑出程序领空回不来,还不容易理清流程(我很菜,这是我的感受),动态调试时如何快速定位感兴趣的代码段是我想学习的。对于程序运行的大致流程、窗体事件及控件事件处理入口的快速定位,一般常用SmartCheck、VBExplorer等VB专用工具就可搞定。可是对于我等菜鸟来说,通过入口进入后,分析里面的代码也是件头疼的事,下面主要把我收获的在OD中定位Nag窗口代码、VB注册表操作的经验与新手们分享讨论。

一、特征码搜寻方式定位及消除NAG窗口
VB程序的Nag窗口一般有两种实现方式,一种是通过MsgBox()方法显示NAG对话框,一种是采用窗体(form)显示模态NAG窗口。对于MsbBox()方式,我们当然可以直接OD中用“bp rtcMsgBox”下断来断下来,然后跟几步会回到应用程序代码空间。或“bpx rtcMsgBox”直接在所有调用上下断直接断在目标程序领空的调用处,这些方法教材上常说,大家也常用,这里就不说了。
针对窗体(form)方式的NAG窗口,本人初菜,没找到可方便下断的函数(谁要是知道,一定告诉我!!),于是用VB写了个最最简单的双form程序,一个主窗体,一个NAG窗体,编译后进行OD跟踪,想提取出些特征码,嘿嘿,让我找到了个:
00401D1F|.FF97 B0020000   CALL DWORD PTR DS:        ;这个就是调用窗体显示的

我拿它的机器码“FF97 B0020000”作为特征码,去其它程序上试验,竟然没有找到,然后用“B0020000”却找到一大堆,发现其中和窗体显示相关的有“FF91 B0020000”、“FF92 B0020000”、“FF96 B0020000”等等,于是我们可以总结出VB窗体调用的特征码为“FF??B0020000”,这里??是通配符,OD的二进制查找里允许用通配符的:),有了这个,我们就可以在目标程序领空事先搜索所有符合通配符的地方下断,跑起程序来,断下来时,不是NAG窗体的就取消对应的断点,直到找到正确的调用,接下来就是我们的关键操作,直接NOP它!我发现这种方法找到的地方可以安全的直接NOP掉,因为VB程序与MSVBVM虚拟机的紧密联系,有时不好找NOP的关键点,有时地方错了,调用堆栈会不平衡导致崩溃。而这一点经我测试是安全的(没有理论支撑,不一定对!)。这样的话就可以直接去掉此NAG窗口。后面我用一个实战例子说明。另外出现NAG窗口调用的附近同时也常常是一个注册标志验证点,这对于分析注册验证算法、逆行根踪算法入口有帮助(本人汇编差,对算法不通)。

二、VB程序的注册表操作的提醒

    这里不涉及VB以直接调用系统API方式操作注册表的内容,而是讨论通过VB自带的SaveSetting()、GetSetting()方式读写注册表的情况,使用这种方式时,VB程序会把信息固定的写到注册表的“下面。所以在OD中使用“bpx rtcSaveSetting”及“bpx rtcGetSetting”后再检查程序领空中的断点信息,就可以判断是否使用了此种方式访问了注册表,并且使用了的话,能直接断在目标领空的关键代码处。记下“[HKEY_CURRENT_USER\Software\VB and VBA Program Settings\”这个位置,适时的查看相关注册表项有助于分析理解关键代码。


三、实战例子

    目标软件是:Power RM AVI MPG VCD WMV Converter,一款未加壳的VB写的多种视频格式互转软件,1.15日从华军down下来的3.0.21版,还没搞完,1.18就更新到4.02了:(,4.0.2支持的视频格式更多,但试用版仅能转50%长度的文件,我算法不行,那个50%我搞不定。这里用3.0.21版做例子,迅雷搜可以搜到。

    就像开篇提到的,我基础还没打扎实,拿来一个软件搞的头破血流,最终没有完全搞定。不过让我第一次写了上面总结。回过头想想,破解之路没有尽头,可能连到达哪一个层次的标志也是很模糊的,一个孤立的软件的完美破解不应该是个目标,也不象征着什么(加密技术也有难易之分),之前太注重结果导致心气不好,后果很严重(离开电脑就心不在焉:炒菜放了两遍盐、抽烟发呆裤子又烧个洞...),现在才体会到有了收获才是重要的,当然基础不踏实让我走了许多弯路,今后要踏踏实实好好领会前辈们的心血之作。言归正传:

【破文标题】 VB程序特征码(FF??B0020000)搜寻方式定位NAG窗口实战
【破文作者】 roking
【破解工具】 OD
【破解平台】 WindowsXP SP2
【目标软件】 Power RM AVI MPG VCD WMV Converter 3.0.21
【原版下载】 老版本程序,迅雷搜可以搜到
【保护方式】 试用次数、NAG、功能限制(一次仅处理1个文件、不能拖放操作)

    事先说明,此程序我没有本事把它完美破解。这里演示上面提到的内容。达到的效果是可处理多个文件、无限使用次数、去除了NAG,但是拖放限制没有去掉:(,注册机就更别提了,属于爆破且不完美的典型。

    先体验一下程序功能:一启动就提示只能用14次,试用后一次仅处理1个文件,而且文件转换过程中多次出现讨厌的NAG窗口。

我们OD载入,隐藏一下OD,忽略所有异常,Crtl+A分析一下代码

动手之前先考虑下步骤,14次就不能用了,得赶紧先把这个限制去掉,省得过期后调试起来麻烦。那它是在哪里保存使用次数的呢?无外乎注册表或文件,这个程序我们在OD里这样检查:

OD命令行下参考断点“bpx rtcSaveSetting”和“bpx rtcGetSetting”,然后ALT+B检查断点信息,看到新加了4个断点,是读写注册表的。

shift+F9执行程序,断在了00440FF5这里:00440FCD   .8BC4          MOV EAX,ESP                                       ; |
00440FCF   .8B4D BC       MOV ECX,DWORD PTR SS:                     ; |
00440FD2   .8908          MOV DWORD PTR DS:,ECX                        ; |
00440FD4   .8B55 C0       MOV EDX,DWORD PTR SS:                     ; |
00440FD7   .8950 04       MOV DWORD PTR DS:,EDX                        ; |
00440FDA   .8B4D C4       MOV ECX,DWORD PTR SS:                     ; |
00440FDD   .8948 08       MOV DWORD PTR DS:,ECX                        ; |
00440FE0   .8B55 C8       MOV EDX,DWORD PTR SS:                     ; |
00440FE3   .8950 0C       MOV DWORD PTR DS:,EDX                        ; |
00440FE6   .68 40FD4000   PUSH video.0040FD40                                 ; |Arg3 = 0040FD40
00440FEB   .68 34FD4000   PUSH video.0040FD34                                 ; |Arg2 = 0040FD34
00440FF0   .68 10FD4000   PUSH video.0040FD10                                 ; |Arg1 = 0040FD10
00440FF5   .FF15 14124000 CALL DWORD PTR DS:[<&MSVBVM60.#689>]                ; \rtcGetSetting   读注册表
00440FFB   .8BD0          MOV EDX,EAX根据代码提示看看调用的几个参数内容,知道,是读取下text的键值

我们F8粗跟看看,其间注意寄存器和堆栈的内容,一直来到004411AC:0044119C   .51            PUSH ECX                                          ; /Arg4
0044119D   .68 40FD4000   PUSH video.0040FD40                                 ; |Arg3 = 0040FD40
004411A2   .68 34FD4000   PUSH video.0040FD34                                 ; |Arg2 = 0040FD34
004411A7   .68 10FD4000   PUSH video.0040FD10                                 ; |Arg1 = 0040FD10
004411AC   .FF15 08104000 CALL DWORD PTR DS:[<&MSVBVM60.#690>]                ; \rtcSaveSetting                写注册表通过检查调用参数看到往注册表里写入的内容,一堆编码过的字符,根据F8粗跟寄存器内容的分析及我们先前的试用体验,应该能够猜到,每使用一次,次数加1,编码后存入注册表,那么只要我们不让它保存新的数值或让他一直保存某个固定值就可以延长试用次数了。同时我们应该能够想假设我们已经注册成功,那我们从注册表里会读到啥呢,程序又会跳到哪里去呢?那我们就注意跟一下,那些没有实现的向下的单向跳转(向上的跳转一般都是循环用的),到了未实现得跳转就在未实现的分支入口处鼠标右键“在此新建EIP”,注意一直用F8粗跑,每次更改跳转分支时,在纸上记录一下位置和是否修改了分支方向,由于我们随意修改程序走向可能会导致程序异常退出,需要根据记下的中间步骤重新来过,通过这种方式尝试遍历正常试用过程中无法执行到代码,我们会发现,当来到00441665:0044165D   .FF15 08114000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaStrCmp>]   ;比较解码后的内容是否为“ok”
00441663   .85C0          TEST EAX,EAX
00441665   .0F85 32030000 JNZ video.0044199D;这里我们修改EIP到下一指令后就会直接进入主程序窗口,跳过了注册窗口
0044166B   .C745 FC 19000>MOV DWORD PTR SS:,19由于这条指令是通过我们修改EIP才执行到的,我们试试看能不能跳过所有的注册表操作,直接来到这里的下一条指令地址为0044166B(目标),在前面设的注册表读取断点

00440FF5   .FF15 14124000 CALL DWORD PTR DS:[<&MSVBVM60.#689>]    ; \rtcGetSetting   读注册表

之前的地方,我们找一个位置直接跳到我们的目标00441665去,在哪里合适呢?来看读注册表之前这一段:00440FAA   .FF15 5C124000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaStrMove>]      ;MSVBVM60.__vbaStrMove
00440FB0   .8D8D 6CFFFFFF LEA ECX,DWORD PTR SS:
00440FB6   .FF15 20104000 CALL DWORD PTR DS:[<&MSVBVM60.__vbaFreeVar>]      ;MSVBVM60.__vbaFreeVar
00440FBC   .C745 FC 04000>MOV DWORD PTR SS:,4
00440FC3   .B8 10000000   MOV EAX,10
00440FC8   .E8 D318FCFF   CALL <JMP.&MSVBVM60.__vbaChkstk>
00440FCD      8BC4          MOV EAX,ESP                                                                                                                                                ;就从这里开跳!!!
00440FCF      8B4D BC       MOV ECX,DWORD PTR SS:
00440FD2      8908          MOV DWORD PTR DS:,ECX
00440FD4      8B55 C0       MOV EDX,DWORD PTR SS:
00440FD7   .8950 04       MOV DWORD PTR DS:,EDX                        ; |
00440FDA   .8B4D C4       MOV ECX,DWORD PTR SS:                     ; |
00440FDD   .8948 08       MOV DWORD PTR DS:,ECX                        ; |
00440FE0   .8B55 C8       MOV EDX,DWORD PTR SS:                     ; |
00440FE3   .8950 0C       MOV DWORD PTR DS:,EDX                        ; |
00440FE6   .68 40FD4000   PUSH video.0040FD40                                 ; |Arg3 = 0040FD40
00440FEB   .68 34FD4000   PUSH video.0040FD34                                 ; |Arg2 = 0040FD34
00440FF0   .68 10FD4000   PUSH video.0040FD10                                 ; |Arg1 = 0040FD10
00440FF5   .FF15 14124000 CALL DWORD PTR DS:[<&MSVBVM60.#689>]                ; \rtcGetSetting你可能回问为啥选这里,看一下MSVBVM60.rtcGetSetting调用的参数个数为7个(Ctrl+N查一下就知道),这样我起码知道从00440FCD开始为MSVBVM60.rtcGetSetting准备参数了,之前的代码是干啥的我不管了反正是完整的,我不去破坏它,之后的读注册表操作的代码我们将不再用它了,所以就从这里改代码是安全的,改为:

00440FCD   /E9 99060000   JMP 0044166B

保存所有修改,我们重新执行一下看看,跳过了注册窗口提示,也没有了试用次数限制。

进入主窗口后我们先来看看如何去掉视频转换过程中频繁出现的窗体形式的NAG,就要使用前面提到的“FF??B0020000”了

在汇编窗口里Ctrl+G,输入00401000,来到目标领空的起始位置,按Ctrl+B搜索二进制字符串,注意不要勾选“整个块”,最下面输入HEX值“FF??B0020000”,每找到一个就在上面F2设一个断点,然后Ctrl+L找一个,直到全部找完。此程序有十几个地方,这里有些是显示NAG窗体的,全部设置完断点后shift+F9跑起程序来,进行各种操作,等程序跑出NAG窗体时就会断下来,直接把断点处指令NOP掉即可。一共3处,都处理完后,取消所有断点并保存修改。此时窗体形式的NAG窗口都已经去除了,但程序中还是有MsgBox形式的注册提醒。

我们也来去掉它。OD命令行里输入“bpx rtcMsgBox”下参考断点,跑起程序来,等对话框即将出现时断下了。断下来后向上翻看代码检查一下rtcMsgBox的调用参数或试着F8一步,看是不是NAG提示,是的话,回来分析代码流程,改关键跳,由于此文目的主要介绍去除窗体方式的NAG,而不是这个软件的详细破文,再说最终我也没找到注册算法,因此就不详细说了,给出结果,改两处就可以取消仅能处理1个文件的限制:

第一处:
      00425145   /0F84 86000000 JE video.004251D1
      改为:
      00425145   /E9 87000000   JMP video.004251D1

第二处:
      004253EA      B9 04000280   MOV ECX,80020004                        
      改为:
      004253EA   /EB 67         JMP SHORT video.00425453
      
就暂时总结到这里吧,这个目标软件的注册算法的代码位置搞得我很郁闷:(
本来写完了,觉得手工搜特征码对于大一些的程序效率太低,想起来脚本是不是能自动搞这个,就翻开资料教程看到看雪精华8里有OllyHTML脚本的教程,现学现卖,这里给个批量下断的脚本。使用方法:OD的插件菜单-->OllyHTML-->load-->html 打开脚本就行了。

[ 本帖最后由 roking 于 2008-3-17 18:08 编辑 ]

roking 发表于 2008-1-20 03:43:09

/:L /:L /:L
刚上网百度了一下“FF??B0020000”,第一条就是“VB快速逆向法”一篇博客,是转自看雪的:

http://bbs.pediy.com/showthread.php?threadid=12133

看了下,里面总结的比我的全面多了,看来我得改进下学习方法了。

/:L /:L /:L

magic659117852 发表于 2008-1-20 09:27:27

/:001 不懂。。。学习/:good

hnld 发表于 2008-1-20 10:24:27

向楼主学习,总结经验是一个好的习惯。值得我学习。我也正在流血。

pw2000 发表于 2008-1-20 10:34:12

文章很详细,学习一下。

asd98 发表于 2008-1-21 01:57:19

多谢,慢慢看了,正在学习,/:018

puti67 发表于 2008-1-22 09:54:48

还不大懂呀,学习中!!!!

ttt0001 发表于 2008-1-22 20:10:24

确实是好文章,学习了!谢谢!很是详细!

hzh686 发表于 2008-3-9 19:02:21

不错,学习了,谢谢

scgycxzzc 发表于 2008-3-12 20:37:42

潞细学习一隆:time: :time:
页: [1]
查看完整版本: VB程序之特征码搜寻方式定位NAG窗口(提供脚本)、注册表操作