加密形式: 深思Ⅲ加密狗。
破解工具:Winice, Hiew, Wdasm893中文版。
作者:sworm
【破解过程】
㈠运行程序,显示“Internal Error. 软件出现致命错误,请检查加密狗是否正确!”后退出。
㈡在Wice中Bpx Messageboxa,再运行程序,显示上述信息时弹出。按F12若干次回到调用处,可见是xxxxxrx调用ACAD.acrx_abort。
㈢反汇编xxxxxrx.arx文件,得:
Exported fn(): acrxEntryPoint - Ord:0002h
:1C05CF00 8B442404 mov eax, dword ptr [esp+04]
:1C05CF04 48 dec eax
:1C05CF05 83F804 cmp eax, 00000004
:1C05CF08 0F878C000000 ja 1C05CF9A
:1C05CF0E FF2485A0CF051C jmp dword ptr [4*eax+1C05CFA0]
:1C05CF15 8B442408 mov eax, dword ptr [esp+08]
:1C05CF19 50 push eax
* Reference To: ACAD.acrxUnlockApplication, Ord:0D5Bh
|
:1C05CF1A E8BDC00800 Call 1C0E8FDC
:1C05CF1F 83C404 add esp, 00000004
:1C05CF22 E8C9AAFEFF call 1C0479F0
:1C05CF27 85C0 test eax, eax
:1C05CF29 7505 jne 1C05CF30
:1C05CF2B E8C0AAFEFF call 1C0479F0
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1C05CF29(C)
|
:1C05CF30 E84BFEFFFF call 1C05CD80
:1C05CF35 E8A6A8FEFF call 1C0477E0
:1C05CF3A E8019CFEFF call 1C046B40
:1C05CF3F A388E00F1C mov dword ptr [1C0FE088], eax
:1C05CF44 85C0 test eax, eax
:1C05CF46 7521 jne 1C05CF69
:1C05CF48 6A00 push 00000000
:1C05CF4A 6A04 push 00000004
:1C05CF4C E82FAAFEFF call 1C047980
:1C05CF51 83C408 add esp, 00000008
:1C05CF54 E807ABFEFF call 1C047A60
* Possible StringData Ref from Data Obj ->"
软件出现致命错误,请检查加密狗是否正确!"========>就在这!
|
:1C05CF59 6888560F1C push 1C0F5688
* Reference To: ACAD.acrx_abort, Ord:0D5Dh
|
:1C05CF5E E8CBBF0800 Call 1C0E8F2E
:1C05CF63 83C404 add esp, 00000004
:1C05CF66 33C0 xor eax, eax
:1C05CF68 C3 ret
㈣在显示错误前,ACAD.acrxUnlockApplication下面,有:
1C05CF22 E8C9AAFEFF call 1C0479F0-------看call 1C046B40也可
查看该处指令,见:
:1C0479F0 83EC60 sub esp, 00000060
:1C0479F3 E888FB0100 call 1C067580
:1C0479F8 85C0 test eax, eax
:1C0479FA 7507 jne 1C047A03-------------à是否为TDMD狗?
:1C0479FC B801000000 mov eax, 00000001
:1C047A01 EB31 jmp 1C047A34
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1C0479FA(C)
|
:1C047A03 66C7442404AF07 mov [esp+04], 07AF―――>应用口令
:1C047A0A 66C74424060700 mov [esp+06], 0007―――>应用口令
:1C047A11 66C74424081A00 mov [esp+08], 001A―――>应用口令
:1C047A18 66C7442402FFFF mov [esp+02], FFFF――――>开锁
:1C047A1F 8D442400 lea eax, dword ptr [esp]
:1C047A23 50 push eax
:1C047A24 E817170A00 call 1C0E9140―――――★
:1C047A29 66837C240001 cmp word ptr [esp], 0001
:1C047A2F 1BC0 sbb eax, eax
:1C047A31 83E002 and eax, 00000002
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1C047A01(U)
|
:1C047A34 83F801 cmp eax, 00000001
:1C047A37 7509 jne 1C047A42
:1C047A39 B801000000 mov eax, 00000001
:1C047A3E 83C460 add esp, 00000060
:1C047A41 C3 ret
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1C047A37(C)
|
:1C047A42 83F802 cmp eax, 00000002―――――>是否sense3狗
:1C047A45 7511 jne 1C047A58
:1C047A47 E874560100 call 1C05D0C0
:1C047A4C 663D0100 cmp ax, 0001
:1C047A50 1BC0 sbb eax, eax
:1C047A52 83C460 add esp, 00000060
:1C047A55 F7D8 neg eax
:1C047A57 C3 ret
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1C047A45(C)
|
:1C047A58 33C0 xor eax, eax
:1C047A5A 83C460 add esp, 00000060
:1C047A5D C3 ret
标志处即为sense3狗操作函数。该[esp]=0 有狗。又是一个拿生日作口令的!
㈤查看1C0E9140处程序,见:
* Referenced by a CALL at Addresses
|:1C046774 , :1C0467EA , :1C046A26 , :1C046B75 , :1C046C96
|:1C046DD6 , :1C046F16 , :1C047065 , :1C047176 , :1C0472B6
|:1C047817 , :1C047A24 , :1C047A94 , :1C05D0E9 , :1C05D10E
|:1C05D1D6 , :1C05D2B0
|
:1C0E9140 8B442404 mov eax, dword ptr [esp+04]
:1C0E9144 6A01 push 00000001
:1C0E9146 50 push eax
:1C0E9147 E864020000 call 1C0E93B0
:1C0E914C 83C408 add esp, 00000008
:1C0E914F C20400 ret 0004
由reference表,知有17处加密狗操作。
前14处均为开锁操作,第15处为关锁操作,最后两处为狗操作,必然在开锁操作之后,我们随便观察一处开锁:
* Referenced by a CALL at Addresses:
|:1C0101AA , :1C0156C0 , :1C026A29 , :1C05CF3A , :1C06D469
|:1C0720C7 , :1C0CC80A , :1C0D65DA
|
:1C046B40 83EC64 sub esp, 00000064
:1C046B43 57 push edi
:1C046B44 E8370A0200 call 1C067580
:1C046B49 85C0 test eax, eax-------------à是否为TDMD狗?
:1C046B4B 7507 jne 1C046B54
:1C046B4D B801000000 mov eax, 00000001
:1C046B52 EB31 jmp 1C046B85
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1C046B4B(C)
|
:1C046B54 66C7442408AF07 mov [esp+08], 07AF
:1C046B5B 66C744240A0700 mov [esp+0A], 0007
:1C046B62 66C744240C1A00 mov [esp+0C], 001A
:1C046B69 66C7442406FFFF mov [esp+06], FFFF
:1C046B70 8D442404 lea eax, dword ptr [esp+04]
:1C046B74 50 push eax
:1C046B75 E8C6250A00 call 1C0E9140―――sense3函数
:1C046B7A 66837C240401 cmp word ptr [esp+04], 0001
:1C046B80 1BC0 sbb eax, eax
:1C046B82 83E002 and eax, 00000002
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1C046B52(U)
|
:1C046B85 83F801 cmp eax, 00000001
:1C046B88 0F8584000000 jne 1C046C12
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1C046B88(C)
|
:1C046C12 83F802 cmp eax, 00000002―――sense3狗?
:1C046C15 753F jne 1C046C56
:1C046C17 68164C0000 push 00004C16
:1C046C1C 684B110000 push 0000114B
:1C046C21 E84A660100 call 1C05D270――――干吗的?
:1C046C26 83C408 add esp, 00000008
:1C046C29 8BC8 mov ecx, eax
:1C046C2B 81E1FFFF0000 and ecx, 0000FFFF
:1C046C31 250000FFFF and eax, FFFF0000
:1C046C36 3D0000DF00 cmp eax, 00DF0000
:1C046C3B 7512 jne 1C046C4F
:1C046C3D 81F937220000 cmp ecx, 00002237
:1C046C43 750A jne 1C046C4F
:1C046C45 B801000000 mov eax, 00000001――好狗由此返回
:1C046C4A 5F pop edi
:1C046C4B 83C464 add esp, 00000064
:1C046C4E C3 ret
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:1C046C3B(C), :1C046C43(C)
|
:1C046C4F 33C0 xor eax, eax――坏狗由此返回
:1C046C51 5F pop edi
:1C046C52 83C464 add esp, 00000064
:1C046C55 C3 ret
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1C046C15(C)
|
:1C046C56 33C0 xor eax, eax
:1C046C58 5F pop edi
:1C046C59 83C464 add esp, 00000064
:1C046C5C C3 ret
到call 1c05d270看看,到底干吗?
* Referenced by a CALL at Address:
|:1C046C21
|
:1C05D270 668B4C2404 mov cx, word ptr [esp+04]
:1C05D275 B804000000 mov eax, 00000004
:1C05D27A 66C705FEEB111C0000 mov word ptr [1C11EBFE], 0000
:1C05D283 66C70500EC111CBFB7 mov word ptr [1C11EC00], B7BF
:1C05D28C 668B542408 mov dx, word ptr [esp+08]
:1C05D291 68F0EB111C push 1C11EBF0
:1C05D296 66A3F2EB111C mov word ptr [1C11EBF2], ax
:1C05D29C 66A3FAEB111C mov word ptr [1C11EBFA], ax
:1C05D2A2 66890DFCEB111C mov word ptr [1C11EBFC], cx
:1C05D2A9 66891502EC111C mov word ptr [1C11EC02], dx
:1C05D2B0 E88BBE0800 call 1C0E9140―――>sense3函数,注意地址
:1C05D2B5 66833DF0EB111C00 cmp word ptr [1C11EBF0], 0000
:1C05D2BD 7409 je 1C05D2C8
:1C05D2BF 33C0 xor eax, eax
:1C05D2C1 66A1F0EB111C mov ax, word ptr [1C11EBF0]
:1C05D2C7 C3 ret
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1C05D2BD(C)
|
:1C05D2C8 33C0 xor eax, eax
:1C05D2CA 33C9 xor ecx, ecx
:1C05D2CC 66A106EC111C mov ax, word ptr [1C11EC06]
:1C05D2D2 C1E010 shl eax, 10
:1C05D2D5 668B0D0CEC111C mov cx, word ptr [1C11EC0C]
:1C05D2DC 0BC1 or eax, ecx
:1C05D2DE C3 ret
至此,程序的狗操作方式很清楚了。这个程序用的是码表法,且码表长度很有限。
Sense3的狗内代码执行是中看不中用的花拳绣腿。长度有限,只好完成简单的数值运算,很少有程序有经常执行的相应代码可放入,最后只好作判断狗之用。对付方法参考紫竹的大作吧。
【小结:】
先找到出错提示,由此找到最底层的sense3函数,这是关键!在反汇编代码中,由reference表,可看见所有操作。一一对此修改即可破解,不会遗漏。本例共修改44字节。
若要复制,也基本不成问题,唯一难点是代码区,一句老话,看悟性吧。我一般不复制,一则没钱买空狗(谁赞助?Kao,只接到一个鸡蛋!);二则没必要,重写sense3函数即可,如将1C0E9140重写。而本例全为判断狗的Boolean函数,连使用狗内数据都没有,无狗都可破解。
上次“废话”篇中的代码为某加密程序的狗返回值处理函数,第一条指令mov eax,[esp+4]就是将sense3data中返回标志赋给eax, 看出来了吗?
写教程很累,这是我的第二篇,以前写过一篇TDMD加钥匙盘的,都是虎头蛇尾的,抱歉了。 ========================================================================
本文将介绍软件加密锁的一些编程技巧,以及软件开发者将如何编写安全可靠的代码,如何对付各种各样的加密狗破解,编写加密程序时应该尽量避免的一些问题等等。以下是全文。
一、加密狗加密的基本原理
开发商程序通过调用硬件加密狗的接口模块对硬件加密狗操作,硬件加密狗响应该操作并通过接口模块将相应数据返回给开发商的应用程序。开发商的应用程序可以对返回值进行判定并采取相应的动作。如果返回无效的响应,表明没有正确的狗,开发商可以将应用程序终止运行,或者让应用程序以错误的方式执行。简要示意如下:
二、常用的解密方法1、反汇编后静态分析: W32Dasm、IDA Pro
2、用调试工具跟踪动态分析:SoftICE、TRW2000
3、针对各种语言的反汇编工具:VB、Delphi、Java等
4、其他监视工具:FileMon、RegMon 等
三、如何提高加密强度下面,我们以Sentinel SuperPro加密锁为例,详细介绍一下使用如何在编程的过程中提高加密强度的方法。
1、反DEBUG解密的编程方法和技巧访问狗之后不要立即做判断,判断狗不正确后,不要立即提示,或者不提示。开发商在程序各个部分插入校验算法的代码,用以增加程序代码的复杂性,防止解密者轻易跟踪发现全部的校验代码。校验代码插入程序的频率越高,破解难度越大,软件就越安全。
重要的字符串不要在程序中以明文出现,应该使用算法动态生成。
在不影响程序效率的情况下,尽量多写一些查狗的函数,彼此要有区别,使用不同的算法,多一些查狗出错的标志,让这些标志参与运算,在不同的模块中,使用不同的查狗函数。
针对某一具体查询校验,都有三步骤组成:查询得到响应串;比较响应串和查询串是否匹配;根据校验结果执行相应的步骤。建议三个步骤要延时执行。最好将三步骤相互远离些,甚至放到不同的子程序或函数中。例如:执行“查询得到响应串”后,相隔50行执行“比较响应串和查询串是否匹配”,假如程序需要调用一个函数。那么就在这个函数里执行“执行相应的步骤”。解密者在跟踪过程中,即使发现了其中一部分程序代码,但很难发现另外两部分代码和全部三部分之间的关联。程序难于被破解。
将加密锁返回的“响应串”作为程序中的参数使用。例如:算法单元返回“响应串”是“87611123”,而程序中需要使用“123”这个参数。程序中得到“响应串”后,将“响应串”减去“87611000”得到参数。如果解密者修改代码跳过查询校验加密锁部分,参数将是错误值,从而会使程序运行紊乱。
程序在验证加密算法过程中,一般情况下验证数据不正确程序就会选择退出。这样一来很容易被解密者发现代码特征,跳过查询校验部分。开发商设计查询校验部分时,如果程序校验数据不正确,程序也不退出可以继续执行一些无用的操作使程序紊乱,用以隐蔽代码迷惑解密者。
开发商的软件可能有多个模块,查狗的模块或接口不要用显而易见的名字来命名,这样会令解密者更容易找到加密点,当然也可以利用一些名字来迷惑解密者,尤其是dll,引出函数时甚至可以不用函数名。
给查狗函数加入一定的随机性,例如,随机地执行某一API函数,或者在狗的存储区中划定一小块区域作随机读写,读写地址、读写内容、读写长度都是随机取的,这样可以很好地防止那些模拟工具。
试用版与正式版要分开,试用版不提供的功能,代码已经删掉,使得不可能利用试用版破解得到正式版。
在大多数情况下,破解是通过更改exe 或 dll 文件实现的,要在程序中检查exe或dll文件的完整性,即利用某种算法计算出整个文件的校验和,在程序中比较,如果文件被更改,校验和就会变化,这类算法网上有很多,可以查得到。另外,exe和dll之间要相互认证,一方面防止dll被替换,另一方面防止非法exe访问dll。
小结:应该尽量避免的问题
1)访问狗、做判断、提示用户写在一起
2)重要的字符串在程序中以明文出现
3)在狗中存放字符串,程序中读出比较
4)调用同一函数或判断同一个全局标志查狗
5)试用版软件同正式版软件是同一份
6)查狗的模块或接口名字太明显
7)程序无随机性,每次运行执行路径都一样
8)没有检查exe 或 dll 文件的完整性,exe 和 dll 之间也没有相互认证
2、反“监听仿真”软件保护锁的编程方法1)随机查询法:开发商使用SuperPro开发工具生成大量查询、响应对,如:1000 对,并在程序中使用这些校验数据。在程序运行过程中,从1000 对查询、响应对之中,随机的抽出其中一对验证SuperPro加密算法。因为,校验数据很多,每次验证加密算法使用的“查询响应对”可能不同,“监听仿真”软件即使纪录了一部分“查询响应对”,但无法纪录全部“查询响应对”。软件每次运行时,都可能使用新的查询响应校验数据,“监听仿真”软件无法响应这些新的查询。因此,“监听仿真”也就失去了模拟、仿真SuperPro软件保护锁的作用。
2)延时法:开发商可以事先使用开发工具生成大量的校验数据,即:“查询、响应”对,比如:200000 组“查询、响应”对,开发程序过程中,开发商设计定时查询、校验加密锁的机制。在程序运行过程中,每10分钟查询并校验加密锁一次,使用过的校验数据,4年内不再重复使用。即使监听软件24小时记录数据,也需要4年才能纪录完毕。4年后,软件早已过了“热卖期”了,使用监听软件的解密者也就失去了行动意义。
3)分组、分时法:开发商可以在程序中把查询响应对分组,比如:1200 对校验数据可分为12组,每100对一组。程序在一年中的第一月使用第一组校验数据,第二月使用第二组校验数据,以此类推。监听软件就算记录了第一月的校验数据,第二个三个月以后校验数据没有纪录,在以后的时间段软件仍然无法正常使用,从而“监听仿真”失去意义。
4)随机噪声数据法:开发商可以在程序中随机产生查询数据,随机数据和真实数据混合在一起,监听软件即使记录了查询数据,也会被其随机性所迷惑,同时也无法仿真另一个次软件运行产生的随机数,加密软件也就无法破解。
注:本文部分内容来源于SafeNet(原彩虹天地)的加密锁之一Sentinel SuperPro的使用说明文档以及相关技术文档整理而成。
===============================================================================
本文介绍的是软件加密狗破解的一般思路和方法。其实做为软件开发者,研究好软件加密的确很重要,不过也很有必要多了解一些关于加密狗解密和破解的知识,加密和破解就像矛和盾一样,对于解密知识了解的越多,那么编写的加密代码就越好,要知道加密永远都比解密要容易的多,只有知己知彼,方能百战百胜。硬件加密锁,俗程“加密狗”,对于加密狗的破解大致可以分为三种方法,一种是通过硬件克隆或者复制,一种是通过SoftICE等Debug工具调试跟踪解密,一种是通过编写拦截程序修改软件和加密狗之间的通讯。
硬件克隆复制主要是针对国产芯片的加密狗,因为国产加密狗公司一般没有核心加密芯片的制造能力,因此有些使用了市场上通用的芯片,破解者分析出芯片电路以及芯片里写的内容后,就可以立刻复制或克隆一个完全相同的加密狗。不过国外的加密狗就无法使用这种方法,国外加密狗硬件使用的是安全性很好的自己研制开发的芯片,通常很难进行复制,而且现在国内加密狗也在使用进口的智能卡芯片,因此这种硬件克隆的解密方法用处越来越少。
对于Debug调试破解,由于软件的复杂度越来越高,编译器产生的代码也越来越多,通过反汇编等方法跟踪调式破解的复杂度已经变得越来越高,破解成本也越来越高,目前已经很少有人愿意花费大量精力进行如此复杂的破解,除非被破解的软件具有极高的价值。
目前加密锁(加密狗)的解密破解工作主要集中在应用程序与加密动态库之间的通讯拦截。这种方法成本较低,也易于实现,对待以单片机等芯片为核心的加密锁(加密狗)具有不错的解密效果。
由于加密锁(加密狗)的应用程序接口(API)基本上都是公开的,因此从网上可以很容易下载到加密狗的编程接口API、用户手册、和其它相关资料,还可以了解加密狗技术的最新进展。
例如,某个国内知名的美国加密狗提供商的一款很有名的加密狗,其全部编程资料就可以从网上获取到,经过对这些资料的分析,我们知道这个加密锁(加密狗)有64个内存单元,其中56个可以被用户使用,这些单元中的每一个都可以被用为三种类型之一:算法、数据值和计数器。
数据值比较好理解,数据值是用户存储在可读写的单元中的数据,就和存储在硬盘里一样,用户可以使用Read函数读出存储单元里面的数据,也可以使用Write函数保存自己的信息到存储单元。
计数器是这样一种单元,软件开发商在其软件中使用Decrement函数可以把其值减一,当计数器和某种活动的(active)算法关联时,计数器为零则会封闭(deactive)这个算法。
算法单元较难理解一些,算法(algorithm)是这样一种技术,你用Query(queryData)函数访问它,其中queryData是查询值,上述函数有一个返回值,被加密的程序知道一组这样的查询值/返回值对,在需要加密的地方,用上述函数检查狗的存在和真伪。对于被指定为算法的单元,软件上是无法读和修改的,即使你是合法的用户也是如此,我理解这种技术除了增加程序复杂性以外,主要是为了对付使用模拟器技术的破解。
此加密锁(加密狗)的所有API函数调用都会有返回值,返回值为0的时候表示成功。
因此,破解思路就出来了,就是使用我们自己的工具(如VB、VC等)重新编写构造一个和加密狗API一样的DLL动态库文件,里面也包含Read、Write等全部API中包含的函数,使用的参量及返回值和原来的函数一样,所有函数返回零。然后对Query、Read函数进行处理,返回应用软件需要的数值即可。
这个新的DLL文件编写成功后,直接替换掉原来的DLL文件,这时候再运行应用软件,软件访问加密狗的操作就全部会被拦截,拦截程序永远会返回正确的数据给软件,从而实现了模拟加密狗的运行。
以上是目前破解软件加密狗(加密锁)的一些常见思路,对于这种破解,软件开发者还是有相应的一些对策的。
==========================================================================
菜鸟破狗记
首先声明,本人不是专业破解的,也不会以此为职业。之所以干了这事完全是因为友情,之所以写下这篇文章是为了给许多我这样的菜鸟一些提示。
朋友早两天给我一个软件,当没有软件狗的时候会在软件上打上一行“注意!没有软件狗!!”的字出来,而且功能也有限制,要求我把字隐藏掉,资源都改掉,功能都开放出来。小弟之前从来没玩过破解,惟一有点沾边的事情事早两年为了跟踪微软的rdpclient,用wdasm调试,然后还是拿VC的二进制编辑器来修改的代码(呵呵,很笨吧)。不过朋友说搞软件的我只能找到你一个,小弟心软,又觉得应该还有点把握,就答应了下来。
开始我还是拿wdasm来调,结果wdasm居然告诉我这个EXE文件太大,没有反汇编完全,我倒。我想要不然先改资源好了,就拿VC的资源编辑器来改,结果一改完保存,程序干脆起不来了!我更倒。
被这么一折腾,我都有点失去信心了。就上网找了许多关于破解和软件狗的文章,疯狂的下载了一堆破解软件。比较有用的是Resource Hacker,用它终于能改资源了;odbg1.1,终于把程序反汇编完全了,对中文的支持也比较好,很多字符串都能看出来,可是用它调试这个软件,一调试就出错,把我气的...最值得一赞的是IDA PRO v4.8,这真是个超强的工具,界面专业,参考信息多,依照C语言的习惯在许多地方都有参考信息,惟一美中不足的是对汉字的支持有点问题。我后来调试都是拿这两个软件交替用,要修改代码或参考字符串的就用ODBG,要跟踪的就用IDA PRO。这两个软件都有超多的工具,不过一来本文不是介绍工具的,二来小弟用到的功能只是九牛一毛,就不乱说了。
期间小弟做了一件很蠢的事,看到很多人说对软件狗脱壳,小弟就下了一堆的脱壳工具,轮番上阵对这个软件试,搞了两天,没有一个成功的。去下了大佬的加密狗检测工具,知道它是彩虹TDSD狗,可是知道是什么狗有什么用呢?它又不会给你破解。后来我终于明白幸福还是要靠自己去寻找,不劳而获这种腐败的想法是不能有的,非常惭愧。
好了,前言太多了,言归正传。这个软件是一开始就去查有没有软件狗的,所以我想没有狗应该也能跟踪到代码。因为软件狗的资料上说是并口的,我在odbg1.1里把所有的字符串都列出来,然后查\\.\LPT,结果还真给我查到了!虽然它是\\.\LPTDI,但是直觉上我觉得应该就在这里,点击这个字符串,转到反汇编界面,原来是个CreateFile函数调用,我就在IDA PRO的这里置了个断点。紧接着它下面的是\\.\TDSD.VXD,也是被CreateFile的,我又在这儿置了个断点。
用IDA PRO调试,果然,程序开始没几个函数就走到这个断点了。这段代码如下:
6A 00 /PUSH 0 ; /hTemplateFile = NULL
68 80000000 |PUSH 80 ; |Attributes = NORMAL
6A 03 |PUSH 3 ; |Mode = OPEN_EXISTING
6A 00 |PUSH 0 ; |pSecurity = NULL
6A 07 |PUSH 7 ; |ShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE|4
68 000000C0 |PUSH C0000000 ; |Access = GENERIC_READ|GENERIC_WRITE
68 240B5300 |PUSH “\\.\LPTDI1“ ; |FileName = “\\.\LPTDI1“
FF15 60C65300 |CALL DWORD PTR DS:[<&KERNEL32.CreateFil>; \CreateFileA
83F8 FF |CMP EAX,-1
8945 FC |MOV DWORD PTR SS:[EBP-4],EAX
请原谅为了隐藏该软件的信息,我对代码作了一些处理。以下同。
因为我的机子上没有软件狗,所以返回值EAX为-1,然后它跳了跳,就跳到下面这句:
B8 BBAA0000 MOV EAX,AABB
EB 3C JMP 到本函数结尾
本函数结束,跳到调用本函数的后一条语句。
这个函数结束后,所执行的代码真是乱七八糟,给大家共享几条:
/EB 6A JMP XXX
|C745 F4 08644>MOV DWORD PTR SS:[EBP-C], ; Case 0 of switch
|EB E2 JMP XXX
|0FB706 MOVZX EAX,WORD PTR DS:[ESI]
|83E8 00 SUB EAX,0 ; Switch (cases 0..11)
|74 5C JE SHORT XXX
|48 DEC EAX
|74 26 JE SHORT XXX
|83E8 03 SUB EAX,3
|74 18 JE SHORT XXX
|83E8 0D SUB EAX,0D
|74 09 JE SHORT XXX
|C745 F4 64000>MOV DWORD PTR SS:[EBP-C],64
|EB 30 JMP SHORT XXX
|B8 37750000 MOV EAX,7537 ; Case 11 of switch
|E9 18010000 JMP XXX
|C745 F4 04000>MOV DWORD PTR SS:[EBP-C],4 ; Case 4 of switch
|EB 1D JMP SHORT XXX
这看上去像是一段正常的switch(){case}代码,可是问题在于它接连来这么几大段跟这差不多的代码。所以我觉得这些应该是花指令(果不其然,后来我才知道彩虹的花指令是比较有名的),因为如果C程序写成这个样子,那绝对是不可维护的,再笨程序员也不可能这么写。所以我没理它,直接往后跳。跳了两跳,就到本函数末尾了。
8BC3 MOV EAX,EBX
5F POP EDI
5E POP ESI
5B POP EBX
E8 22BB0100 CALL XXX
85C0 TEST EAX,EAX
75 28 JNZ SHORT XXX
A1 3CE97800 MOV EAX,DWORD PTR DS:[78E93C]
8B0D 40E97800 MOV ECX,DWORD PTR DS:[78E940]
8B15 44E97800 MOV EDX,DWORD PTR DS:[78E944]
894424 5A MOV DWORD PTR SS:[ESP+5A],EAX
A0 48E97800 MOV AL,BYTE PTR DS:[78E948]
894C24 5E MOV DWORD PTR SS:[ESP+5E],ECX
895424 62 MOV DWORD PTR SS:[ESP+62],EDX
884424 66 MOV BYTE PTR SS:[ESP+66],AL
EB 27 JMP SHORT XXX
8B0D 20E97800 MOV ECX,DWORD PTR DS:[78E920]
8B15 24E97800 MOV EDX,DWORD PTR DS:[78E924]
A1 28E97800 MOV EAX,DWORD PTR DS:[78E928]
894C24 3C MOV DWORD PTR SS:[ESP+3C],ECX
8A0D 2CE97800 MOV CL,BYTE PTR DS:[78E92C]
895424 40 MOV DWORD PTR SS:[ESP+40],EDX
894424 44 MOV DWORD PTR SS:[ESP+44],EAX
884C24 48 MOV BYTE PTR SS:[ESP+48],CL
8D5424 3C LEA EDX,DWORD PTR SS:[ESP+3C]
直觉上,我觉得应该是找到正主了。往下一瞧,果不其然,它下面是对与程序相关的文件进行处理,应该就是这里了。然后我去看彩虹的开发资料,它说如果有软件狗的话返回值是0。于是我就将这段代码的开头CALL XXX改为MOV EAX, 0,再将所有调用该函数的地方都改为MOV EAX, 0。(其实也就两个地方)
这样就完了?不,我把改后的程序运行一下,那段文字仍然出现!功能也没有开放!
我继续到这两个有CALL XXX的地方看汇编代码,结果在一个地方发现它执行完如上的代码后,下面会有一个函数对某些字符串进行比较,比较完之后的代码如下:
E8 28980500 CALL YYY
85C0 TEST EAX,EAX
7D 20 JGE SHORT ------------------------------
6A 05 PUSH 5 |
8D8B FE050000 LEA ECX,DWORD PTR DS:[EBX+5FE] |
E8 B79A0600 CALL ZZZ |
... |
6A 00 PUSH 0 <-----------------------------
8D8B FE050000 LEA ECX,DWORD PTR DS:[EBX+5FE]
E8 979A0600 CALL ZZZ
看到“push 5”和“push 0”,我一下想到会不会是SW_SHOW和SW_HIDE,然后去查winuser.h,果然,SW_SHOW=5,SW_HIDE=0。这个软件的开发者应该先把一些文字写入软件狗,读出来的时候和预定的字符串进行比较,如果不对的话仍然认为没有软件狗。
于是,最关键的一步来临了!我把所有CALL YYY的地方都改为MOV EAX, 1,然后保存,运行,哈哈!果然那段文字不出来了,功能也开放了。呵呵,菜鸟的第一次破狗之旅也结束了。从正式跟踪到破解完成,花了我近7个小时,累死我了。
说明:当然,真正的破解过程绝没有说的这么轻松,其间充满着狂热、希冀和沮丧交织的心理;同时,查找到关键点,是经过很多次跟踪才敢确定的,不可能一下子就猜到;还要查阅大量的资料,了解软件狗的一些基本原理。最后,工具的先进是个破解成功的一个主要因素,很难想像我再拿wdasm能破得出来;但是绝不要对工具产生依赖心理,靠什么都不如靠自己的努力。期间我给许多破解界的前辈发了信息,讨教经验,但是很可惜都没有人理我,这也是我写下本文的原因之一,希望能给像我一样的菜鸟一点努力的方向。
一直到现在,我还是不知道脱壳是怎么搞的,里面的函数调用和资源不会被影响到吗?有谁愿意告诉我?我后来看了彩虹的一些开发资料,这个软件应该是把软件狗代码嵌入到程序代码中的,所以我也不想什么脱壳了。