安全中国首页 > 文章中心 > 加密算法
 
安全中国网友投稿专用上传FTP空间:
Ftp服务器:download.anqn.com
Ftp端口:21
用户名:anqn
密 码:anqn.com
 

谜----同益起名大师3.36注册算法分析

更新时间:2008-1-3 0:34:48
责任编辑:高远
热 点:
【软件名称】:同益起名大师 V3.36 
【下载页面】:http://www.skycn.com/soft/109.html
【软件简介】:是一个专业的起名测名软件。
【调试环境】:WinXP、flyODBG、regedit、Windows自带的计算器
【作者声明】:只为技术而破解,试图探讨一下此类软件的解密方法。失误之处敬请诸位大侠赐教!            
-------------------------------------------------------
【1. 脱壳】

    壳为ACProtect,脱壳方法见fly的文章,感谢fly大侠提供脱壳:http://bbs.pediy.com/showthread.php?s=&threadid=13137         

【2. 寻找切入点】

    脱壳后的程序中关于注册的关键代码段还是带壳的(这就是SDK?),要想爆破,还得把这部分代码脱出来。可这个程序又是多点校验,想要把所有的关键段都脱出来,可不是件容易事。因此破解它还是要跟注册码。注册信息保存在下面注册表项下:

HKEY_LOCAL_MACHINE\SOFTWARE\GoodSoft\GoodName

    其中有一项"Appid",程序在发现有人为对注册表改动后,会把"Appid"的值改为"4D",然后程序就不能注册了,发生这种情况后可以用regedit手动把这一项改为0,就又可以注册了。设置OD忽略所有异常,载入程序后,先下断:

bp RegQueryValueExA

    然后运行程序,中断后看堆栈第三行,不出现"Appid"就F9运行,出现"Appid"后,关闭RegQueryValueExA这个断点,Alt+F9返回,再经过两个ret,来到这里:

005735C6  mov edx,UnPacKed.00573AE0           ; ASCII "Appid"
005735CB  mov eax,dword ptr ss:[ebp-14]
005735CE  call UnPacKed.0043D0EC  
005735D3  mov dword ptr ss:[ebp-8],eax  <====返回这里
005735D3  mov dword ptr ss:[ebp-8],eax
005735D6  lea ecx,dword ptr ss:[ebp-C]
005735D9  mov edx,UnPacKed.00573AF0              ; ASCII "Serial"
005735DE  mov eax,dword ptr ss:[ebp-14]
005735E1  call UnPacKed.0043D060
005735E6  lea ecx,dword ptr ss:[ebp-10]
005735E9  mov edx,UnPacKed.00573B00              ; ASCII "FName"
005735EE  mov eax,dword ptr ss:[ebp-14]
005735F1  call UnPacKed.0043D060
005735F6  lea edx,dword ptr ss:[ebp-24]
005735F9  mov eax,dword ptr ss:[ebp-10]
005735FC  call UnPacKed.00408B60  <====从执行前后内存中数据可以看出,这个call是复制字符串

    这里就是启动的验证段,但这里没有对注册码的完整的校验,在点击“注册”以后有完整的校验,因此要找到点击“注册”以后的代码。算注册码的时候离不开复制字符串的操作,因此下断:bp 00408B60,可是调用得太多,仔细观察了一下,发现其它调用点一般都在00500000以下,所以把00408B60的断点加上条件:[esp]>00500000,找到了点“注册”以后的代码段:

0055A090  lea edx,dword ptr ss:[ebp-20]
0055A093  mov eax,dword ptr ss:[ebp-4]
0055A096  mov eax,dword ptr ds:[eax+32C]
0055A09C  call UnPacKed.004569A8  取序列号
0055A0A1  mov eax,dword ptr ss:[ebp-20]
0055A0A4  lea edx,dword ptr ss:[ebp-1C]
0055A0A7  call UnPacKed.00408B60  复制序列号
0055A0AC  mov eax,dword ptr ss:[ebp-1C]
0055A0AF  call UnPacKed.00404584  查序列号位数
0055A0B4  cmp eax,0A      这里要求序列号大于10位
0055A0B7  jge short UnPacKed.0055A0C1
.............
0055A2F2  mov eax,dword ptr ss:[ebp-4]
0055A2F5  call UnPacKed.005565EC  跟进后有解压缩代码,估计是关键代码。

    跟进call UnPacKed.005565EC,经过下面一段后,就是解压缩啦,压缩方式仍然是ACProtect,施展跟踪ACProect的本领来跟吧:

00556616  call UnPacKed.004767E8  这里不用解压,可在此处下一个断点
0055661B  pushad

【3. 代码粗跟踪】

    跟踪ACProtect,大家可以各显其才。我提供一种方法供参考,其实这是我刚发现的方法,我在一开始跟踪时也不知道这个方法,我跟踪时用的方法要比这个费劲得多。
    这个软件嵌入的解码有个特点,都有一次int3异常,这使得硬件断点不能直接使用。但也不是绝对地不能用,要在发生int3异常以后再用才行。对于此例,到达00556616处,esp=12f8b8。设置OD不忽略“int3中断”和“同时忽略以下指定的异常或者异常范围”,其余全忽略。F9运行程序,在00558058处发生异常,这时下:hr 12f8b4,F9运行,第3次中断时解码完毕,断下后取消硬件断点。其余地方可按此法处理,不再赘述。

    对点“注册”以后的代码粗跟踪如下:

00559AEC  call UnPacKed.0050A150  根据系统算出申请码
........................
00559B5B  mov edx,dword ptr ss:[ebp-38]  对话框中的申请码
00559B5E  mov eax,dword ptr ss:[ebp-C]  根据系统算出的申请码
00559B61  call UnPacKed.004046D0  两个申请码比较
00559B66  jnz UnPacKed.00559ED7
................
00559C41  lea eax,dword ptr ss:[ebp-70]
00559C44  push eax
00559C45  lea edx,dword ptr ss:[ebp-74]
00559C48  mov eax,dword ptr ss:[ebp-C]
00559C4B  call UnPacKed.00408B60  复制申请码
00559C50  lea eax,dword ptr ss:[ebp-74]
00559C53  mov edx,UnPacKed.00559FD8           ; ASCII "        "
00559C58  call UnPacKed.0040458C  申请码后面加空格
00559C5D  mov eax,dword ptr ss:[ebp-74]
00559C60  mov ecx,8
00559C65  mov edx,1
00559C6A  call UnPacKed.004047E4  取前8位
00559C6F  lea eax,dword ptr ss:[ebp-70]
00559C72  push eax
00559C73  lea edx,dword ptr ss:[ebp-7C]
00559C76  mov eax,dword ptr ds:[esi+300]
00559C7C  call UnPacKed.004569A8  从对话框中取姓
00559C81  mov eax,dword ptr ss:[ebp-7C]
00559C84  lea edx,dword ptr ss:[ebp-78]
00559C87  call UnPacKed.00408B60  复制姓
00559C8C  mov edx,dword ptr ss:[ebp-78]
00559C8F  pop eax
00559C90  call UnPacKed.0040458C  把姓连在申请码之后
00559C95  mov eax,dword ptr ss:[ebp-70]
00559C98  lea edx,dword ptr ss:[ebp-6C]
00559C9B  call UnPacKed.004E00B8  加密(每位和1F异或)
00559CA0  mov edx,dword ptr ss:[ebp-6C]
00559CA3  mov eax,dword ptr ds:[57F108]
00559CA8  call UnPacKed.00404318  保存加密后申请码的地址
00559CAD  lea edx,dword ptr ss:[ebp-8C]
00559CB3  mov eax,dword ptr ds:[esi+32C]
00559CB9  call UnPacKed.004569A8  取序列号
00559CBE  mov eax,dword ptr ss:[ebp-8C]
00559CC4  lea edx,dword ptr ss:[ebp-88]
00559CCA  call UnPacKed.00408B60  复制序列号
00559CCF  mov eax,dword ptr ss:[ebp-88]
00559CD5  lea edx,dword ptr ss:[ebp-84]
00559CDB  call UnPacKed.00513FFC  序列号调位
00559CE0  mov eax,dword ptr ss:[ebp-84]
00559CE6  lea edx,dword ptr ss:[ebp-80]
00559CE9  call UnPacKed.004E00B8  加密(每位和1F异或)
00559CEE  mov edx,dword ptr ss:[ebp-80]
00559CF1  mov eax,dword ptr ds:[57EB9C]  保存地址
00559CF6  call UnPacKed.00404318
00559CFB  lea edx,dword ptr ss:[ebp-C]
00559CFE  mov eax,dword ptr ds:[57F108]
00559D03  mov eax,dword ptr ds:[eax]
00559D05  call UnPacKed.004FBC54  对由申请码和姓字符串变换f1()得一字符串A
00559D0A  lea eax,dword ptr ss:[ebp-94]
00559D10  push eax
00559D11  lea edx,dword ptr ss:[ebp-98]
00559D17  mov eax,dword ptr ds:[57EB9C]
00559D1C  mov eax,dword ptr ds:[eax]
00559D1E  call UnPacKed.004E00B8  对序列号的变换结果再变换,即还原出序列号
00559D23  mov eax,dword ptr ss:[ebp-98]  
00559D29  mov ecx,5
00559D2E  mov edx,17      从17H=23位开始取5位
00559D33  call UnPacKed.004047E4  
00559D38  mov eax,dword ptr ss:[ebp-94]
00559D3E  lea edx,dword ptr ss:[ebp-90]
00559D44  call UnPacKed.004ED010  对23~26位变换f2(),得到B
00559D49  mov edx,dword ptr ss:[ebp-90]  B
00559D4F  mov eax,dword ptr ss:[ebp-C]  正确值A
00559D52  call UnPacKed.004046D0  比较
00559D57  jnz UnPacKed.00559ED7    关键之一
00559D5D  lea eax,dword ptr ss:[ebp-A0]
00559D63  push eax
00559D64  lea edx,dword ptr ss:[ebp-A4]
00559D6A  mov eax,dword ptr ds:[57EB9C]
00559D6F  mov eax,dword ptr ds:[eax]
00559D71  call UnPacKed.004E00B8
00559D76  mov eax,dword ptr ss:[ebp-A4]
00559D7C  mov ecx,5
00559D81  mov edx,17
00559D86  call UnPacKed.004047E4
00559D8B  mov eax,dword ptr ss:[ebp-A0]
00559D91  lea edx,dword ptr ss:[ebp-9C]
00559D97  call UnPacKed.004ED010
00559D9C  mov edx,dword ptr ss:[ebp-9C]
00559DA2  mov eax,dword ptr ss:[ebp-C]
00559DA5  call UnPacKed.004046D0  比较之二,与比较之一相同
00559DAA  jnz UnPacKed.00559E6A
00559DB0  lea eax,dword ptr ss:[ebp-A8]
00559DB6  push eax
00559DB7  lea edx,dword ptr ss:[ebp-AC]
00559DBD  mov eax,dword ptr ds:[57EB9C]
00559DC2  mov eax,dword ptr ds:[eax]
00559DC4  call UnPacKed.004E00B8
00559DC9  mov eax,dword ptr ss:[ebp-AC]
00559DCF  mov ecx,3
00559DD4  mov edx,1D
00559DD9  call UnPacKed.004047E4  取29~31位
00559DDE  mov eax,dword ptr ss:[ebp-A8]
00559DE4  call UnPacKed.004E9BE0  对29~31位变换
00559DE9  mov ebx,eax
00559DEB  lea eax,dword ptr ss:[ebp-B0]
00559DF1  push eax
00559DF2  lea edx,dword ptr ss:[ebp-B4]
00559DF8  mov eax,dword ptr ds:[57EB9C]
00559DFD  mov eax,dword ptr ds:[eax]
00559DFF  call UnPacKed.004E00B8
00559E04  mov eax,dword ptr ss:[ebp-B4]
00559E0A  mov ecx,1C
00559E0F  mov edx,1
00559E14  call UnPacKed.004047E4  取1~28位
00559E19  mov eax,dword ptr ss:[ebp-B0]
00559E1F  call UnPacKed.004F0748  对1~28位变换
00559E24  cmp ebx,eax      关键比较之三
00559E26  jnz UnPacKed.00559ED7
00559E2C  mov eax,UnPacKed.00559FF8                ;  ASCII "111"
00559E31  call UnPacKed.00506940  关键之四,校验17~22位
00559E36  mov byte ptr ss:[ebp-1],al
00559E39  cmp byte ptr ss:[ebp-1],0
00559E3D  je short UnPacKed.00559E4C
00559E3F  lea eax,dword ptr ss:[ebp-C]
00559E42  mov edx,UnPacKed.00559FF8                ;  ASCII "111"
00559E47  call UnPacKed.0040435C
00559E4C  cmp byte ptr ss:[ebp-1],0
00559E50  je UnPacKed.00559ED7
00559E56  mov eax,dword ptr ss:[ebp-C]
00559E59  mov edx,UnPacKed.00559FF8                ;  ASCII "111"
00559E5E  call UnPacKed.004046D0
00559E63  jnz short UnPacKed.00559E6A
00559E65  call UnPacKed.00503320  关键之五,校验1~16位

    跟踪时发现,根据系统计算申请码时用到了cpuid这个API,可是在我的电脑上多次运行这个API,返回值中ebx的值是在两个值中变的,因此算出的申请码也有两种,程序发现两个申请码不同也会通不过注册,因此跟踪时要注意一下00559B66这个地方。我觉得这也算是软件的一个BUG。
    对注册码验证前先对注册码调位,调用点如00559CDB。调位的方法是第1、4位互换,第5、8位互换,4*i+1位和4*(i+1)位互换,i=0,1,2,...,末尾不足4位时,最后两位互换。以下所讲的除非特别说明的以外,均是调位以后的注册码,程序把注册码分成四段进行校验。

1 2 3 下一页

 
相关文章
一日一文章
 
一日一软件
一日一动画