论坛: 编程破解 标题: [原创]比泰软件防盗版战士2005JV1.00脱壳 复制本贴地址    
作者: yongmin [yongmin]    论坛用户   登录
下载页面: http://www.skycn.com/soft/10178.html
软件大小: 1052 KB
软件语言: 简体中文
软件类别: 国产软件 / 试用版 / 加密工具
应用平台: Win9x/NT/2000/XP
加入时间: 2005-01-10 15:14:20
下载次数: 2982
推荐等级: ****
开 发 商: http://WWW.bittide.com
软件介绍: 比泰软件防盗版战士(BS-APC),是比泰科技(?2002-2005)出品的一个软件加密保护产品系列(含L版、A版、J版等产品线),它们为商业软件提供可靠的防盗版保护并支持数字化发行。|它采用比泰公司世界领先的“执行代码抽取加密”技术,软硬件结合,以“认证技术”保证软件“对象安全”、以“功能相关法”保证软件“入口安全”、以具有唯一性的计算机(物理)特征数据作为身份认证指纹,并以软件用户计算机本身的运算能力进行防盗版保护。|具有64位以上,到128位的加密安全强度。安全强度远胜传统的外壳加密式加密狗、API内嵌式加密狗,软件保护的功能范围及运行效率超过智能狗,且无须学习加密狗编程,不引入附加硬件维护问题。|适合对C/MFC/Visual C++(VC++)/Borland C++ Builder(BCB)、Delphi/Object Pascal、Power Builder(PB)、Authorware、Director等开发工具所编译程序的保护。|因为它是对真实指令进行代码抽取加密,因此暂不保护伪编译程序,如VB、VFP、C#、JAVA。
       
【作者声明】:只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
       
【调试环境】:WinXP、OllyDBG V1.10、PEiD、LordPE、ImportREC
       
―――――――――――――――――――――――――――――――――
【脱壳过程】:
     
     
比泰软件防盗版战士是国产壳,有些特色。
壳首先通过ShareDll.dll对EXE主程序解码,包括重新定位IAT。
ShareDll.dll就是这个壳的特征!IAT处理有点繁琐。
OEP就是壳的EP,呵呵,不必寻找了。
简单写一下脱壳过程,希望作者能够继续完善这个壳,成长为新的猛壳。 
―――――――――――――――――――――――――――――――――
一、两次Second段内存断点定位输入表处理部分
       
   
1、预处理
   
设置Ollydbg忽略所有异常选项。设置Ollydbg暂停在系统断点。
老规矩:用IsDebug 1.4插件去掉Ollydbg的调试器标志。



CODE:[Copy to clipboard]7C921231  C3                retn
//进入Ollydbg后暂停在系统断点
Alt+B 察看断点窗口,会发现Ollydbg默认在BSLicense.exe的EP处设置了断点
点右键,删除这个断点,否则会导致解码出错!

现在Alt+M 显示内存窗口,在第2个区段00401000段“设置内存写入断点”。
F9运行,中断下来,取消断点。Ctrl+F9执行到返回


CODE:[Copy to clipboard]10002C83  8908          mov dword ptr ds:[eax],ecx
//中断在这里
10002C85  8B4C24 2C      mov ecx,dword ptr ss:[esp+2C]
10002C89  8950 04        mov dword ptr ds:[eax+4],edx
10002C8C  8B5424 30      mov edx,dword ptr ss:[esp+30]
10002C90  8948 08        mov dword ptr ds:[eax+8],ecx
10002C93  8950 0C        mov dword ptr ds:[eax+C],edx
10002C96  75 AA          jnz short Sharedll.10002C42
10002C98  5D            pop ebp
10002C99  5B            pop ebx
10002C9A  8D4C24 08      lea ecx,dword ptr ss:[esp+8]
10002C9E  C74424 34 FFFFFFFF mov dword ptr ss:[esp+34],-1
10002CA6  C1E7 04        shl edi,4
10002CA9  E8 D2E4FFFF      call Sharedll.10001180
10002CAE  8B4C24 2C      mov ecx,dword ptr ss:[esp+2C]
10002CB2  8BC7          mov eax,edi
10002CB4  5F            pop edi
10002CB5  5E            pop esi
10002CB6  64:890D 00000000  mov dword ptr fs:[0],ecx
10002CBD  83C4 30        add esp,30
10002CC0  C2 1000        retn 10
//或者直接F4至这里
――――――――――――――――――――――――
2、第二次Second段内存断点定位输入表处理部分

现在再次在00401000段“设置内存写入断点”。F9运行,中断后取消断点。
OK,我们就来到了ShareDll.dll中对EXE主程序输入表的处理部分了。

下面这段可能看着比较郁闷,你可以比较一下加壳程序运行流程和下面修改后的运行流程,这样容易理解点。


CODE:[Copy to clipboard]10002A0B  8B4424 0C      mov eax,dword ptr ss:[esp+C]
10002A0F  C606 E9        mov byte ptr ds:[esi],0E9
//中断在这里,我们要在这里Patch,否则壳会把输入表搞的乱七八糟。
//修改为:jmp 10009900 ★ 跳到Patch代码
10002A12  2BC6          sub eax,esi
10002A14  83C0 FB        add eax,-5
10002A17  8946 01        mov dword ptr ds:[esi+1],eax
10002A1A  8B5424 14      mov edx,dword ptr ss:[esp+14]
10002A1E  8B4424 20      mov eax,dword ptr ss:[esp+20]
//[esp+20]保存的是命令类型 ★
10002A22  3D 2D8B0000      cmp eax,8B2D
//分支①、8B2D ★
10002A27  893A          mov dword ptr ds:[edx],edi
10002A29  0F8F 9C000000    jg Sharedll.10002ACB
10002A2F  0F84 86000000    je Sharedll.10002ABB
10002A35  3D 158B0000      cmp eax,8B15
//分支②、8B15 ★
10002A3A  7F 68          jg short Sharedll.10002AA4
10002A3C  74 38          je short Sharedll.10002A76
10002A3E  3D A1000000      cmp eax,0A1
//分支③、A1 ★
10002A43  74 1B          je short Sharedll.10002A60
10002A45  3D 0D8B0000      cmp eax,8B0D
//分支④、8B0D ★
10002A4A  0F85 D9000000    jnz Sharedll.10002B29
10002A50  8B4C24 10      mov ecx,dword ptr ss:[esp+10]
10002A54  8D46 06        lea eax,dword ptr ds:[esi+6]
10002A57  C601 8B        mov byte ptr ds:[ecx],8B
10002A5A  C641 01 0D      mov byte ptr ds:[ecx+1],0D
10002A5E  EB 24          jmp short Sharedll.10002A84
10002A60  8B4C24 10      mov ecx,dword ptr ss:[esp+10]
10002A64  8D46 05        lea eax,dword ptr ds:[esi+5]
10002A67  C601 A1        mov byte ptr ds:[ecx],0A1
10002A6A  8B5424 14      mov edx,dword ptr ss:[esp+14]
10002A6E  8951 01        mov dword ptr ds:[ecx+1],edx
10002A71  83C1 05        add ecx,5
10002A74  EB 18          jmp short Sharedll.10002A8E
10002A76  8B4C24 10      mov ecx,dword ptr ss:[esp+10]
10002A7A  8D46 06        lea eax,dword ptr ds:[esi+6]
10002A7D  C601 8B        mov byte ptr ds:[ecx],8B
10002A80  C641 01 15      mov byte ptr ds:[ecx+1],15
10002A84  8B5424 14      mov edx,dword ptr ss:[esp+14]
10002A88  8951 02        mov dword ptr ds:[ecx+2],edx
10002A8B  83C1 06        add ecx,6
10002A8E  2BC1          sub eax,ecx
10002A90  C601 E9        mov byte ptr ds:[ecx],0E9
10002A93  83E8 05        sub eax,5
10002A96  5F            pop edi
10002A97  8941 01        mov dword ptr ds:[ecx+1],eax
10002A9A  5E            pop esi
10002A9B  33C0          xor eax,eax
10002A9D  5B            pop ebx
10002A9E  83C4 10        add esp,10
10002AA1  C2 0C00        retn 0C
10002AA4  3D 1D8B0000      cmp eax,8B1D
//分支⑤、8B1D ★
10002AA9  75 7E          jnz short Sharedll.10002B29
10002AAB  8B4C24 10      mov ecx,dword ptr ss:[esp+10]
10002AAF  8D46 06        lea eax,dword ptr ds:[esi+6]
10002AB2  C601 8B        mov byte ptr ds:[ecx],8B
10002AB5  C641 01 1D      mov byte ptr ds:[ecx+1],1D
10002AB9  EB C9          jmp short Sharedll.10002A84
10002ABB  8B4C24 10      mov ecx,dword ptr ss:[esp+10]
10002ABF  8D46 06        lea eax,dword ptr ds:[esi+6]
10002AC2  C601 8B        mov byte ptr ds:[ecx],8B
10002AC5  C641 01 2D      mov byte ptr ds:[ecx+1],2D
10002AC9  EB B9          jmp short Sharedll.10002A84
10002ACB  3D 15FF0000      cmp eax,0FF15
//分支⑥、FF15 ★
10002AD0  7F 3D          jg short Sharedll.10002B0F
10002AD2  74 2C          je short Sharedll.10002B00
10002AD4  2D 358B0000      sub eax,8B35
10002AD9  74 15          je short Sharedll.10002AF0
10002ADB  83E8 08        sub eax,8
10002ADE  75 49          jnz short Sharedll.10002B29
10002AE0  8B4C24 10      mov ecx,dword ptr ss:[esp+10]
10002AE4  8D46 06        lea eax,dword ptr ds:[esi+6]
10002AE7  C601 8B        mov byte ptr ds:[ecx],8B
10002AEA  C641 01 3D      mov byte ptr ds:[ecx+1],3D
10002AEE  EB 94          jmp short Sharedll.10002A84
10002AF0  8B4C24 10      mov ecx,dword ptr ss:[esp+10]
10002AF4  8D46 06        lea eax,dword ptr ds:[esi+6]
10002AF7  C601 8B        mov byte ptr ds:[ecx],8B
10002AFA  C641 01 35      mov byte ptr ds:[ecx+1],35
10002AFE  EB 84          jmp short Sharedll.10002A84
10002B00  8B4C24 10      mov ecx,dword ptr ss:[esp+10]
10002B04  8D46 06        lea eax,dword ptr ds:[esi+6]
10002B07  C601 FF        mov byte ptr ds:[ecx],0FF
10002B0A  E9 71FFFFFF      jmp Sharedll.10002A80
10002B0F  3D 25FF0000      cmp eax,0FF25
//分支⑦、FF25 ★
10002B14  75 13          jnz short Sharedll.10002B29
10002B16  8B4C24 10      mov ecx,dword ptr ss:[esp+10]
10002B1A  8D46 06        lea eax,dword ptr ds:[esi+6]
10002B1D  C601 FF        mov byte ptr ds:[ecx],0FF
10002B20  C641 01 25      mov byte ptr ds:[ecx+1],25
10002B24  E9 5BFFFFFF      jmp Sharedll.10002A84
10002B29  5F            pop edi
10002B2A  C743 04 15270000  mov dword ptr ds:[ebx+4],2715
10002B31  5E            pop esi
10002B32  83C8 FF        or eax,FFFFFFFF
10002B35  5B            pop ebx
10002B36  83C4 10        add esp,10
10002B39  C2 0C00        retn 0C
――――――――――――――――――――――――
3、Patch 处理:搞定输入表

现在我们要找2个地方
1、Patch代码存放地址 选择Patch代码存放的地址时候要小心,其他地方会引发异常。可以用playar兄弟的MemoryManage插件申请一段临时内存。一般在ShareDll.dll第2区段的末尾处可以存放临时数据。
2、跳转表存放地址  这里的地址要保证是空白处,我选择放在00430660处。


CODE:[Copy to clipboard]10009900  53            push ebx
10009901  3E:8B5C24 70    mov ebx,dword ptr ds:[esp+70]; kernel32.7C800000
//[esp-70]处保存的是处理DLL的基址 ★
10009906  3B1D 00064300    cmp ebx,dword ptr ds:[430600]; kernel32.7C800000
//提前在[430600]处写入当前处理DLL的基址 ★
1000990C  74 0D          je short Sharedll.1000991B
//这样比较前后2次处理的函数是否是同一个DLL的
1000990E  891D 00064300    mov dword ptr ds:[430600],ebx
10009914  8305 04064300 04  add dword ptr ds:[430604],4
//提前在[430604]处写入准备放跳转地址的地址00430660 ★ 呵呵,有点拗口了
1000991B  3B3D 08064300    cmp edi,dword ptr ds:[430608]; ntdll.RtlReAllocateHeap
//第一个函数过后在[430608]处写入第一个函数的地址
10009921  74 0D          je short Sharedll.10009930
//这个壳把一个相同函数放好几个地方,比较烦
//比较前后2次处理的函数是否相同 ★
10009923  893D 08064300    mov dword ptr ds:[430608],edi
//保存不同函数地址的值
10009929  8305 04064300 04  add dword ptr ds:[430604],4
//跳转地址+4
10009930  3E:8B5C24 24    mov ebx,dword ptr ds:[esp+24]
//[esp+24]是壳放置的命令类型代码! ★
10009935  81FB A1000000    cmp ebx,0A1
//有一个单字节的,所以需要单独提出来
1000993B  74 11          je short Sharedll.1000994E
1000993D  86FB          xchg bl,bh
//前后位调换
1000993F  891E          mov dword ptr ds:[esi],ebx
//写入主程序
10009941  8B1D 04064300    mov ebx,dword ptr ds:[430604]; BSLicens.00430660
10009947  893B          mov dword ptr ds:[ebx],edi
//正确函数写入 ★
10009949  895E 02        mov dword ptr ds:[esi+2],ebx
//跳转地址写入 ★
1000994C  EB 0D          jmp short Sharedll.1000995B
1000994E  891E          mov dword ptr ds:[esi],ebx
10009950  8B1D 04064300    mov ebx,dword ptr ds:[430604]; BSLicens.00430660
10009956  893B          mov dword ptr ds:[ebx],edi
10009958  895E 01        mov dword ptr ds:[esi+1],ebx
1000995B  5B            pop ebx
1000995C  E9 B990FFFF      jmp Sharedll.10002A1A
//跳回去继续流程
从Ollydbg中“二进制复制”如下:


CODE:[Copy to clipboard]53 3E 8B 5C 24 70 3B 1D 00 06 43 00 74 0D 89 1D 00 06 43 00 83 05 04 06 43 00 04 3B 3D 08 06 43
00 74 0D 89 3D 08 06 43 00 83 05 04 06 43 00 04 3E 8B 5C 24 24 81 FB A1 00 00 00 74 11 86 FB 89
1E 8B 1D 04 06 43 00 89 3B 89 5E 02 EB 0D 89 1E 8B 1D 04 06 43 00 89 3B 89 5E 01 5B E9 B9 90 FF
FF
―――――――――――――――――――――――――――――――――
二、OEP+完成脱壳


Ctrl+S在“整个段块”搜索命令序列:


CODE:[Copy to clipboard]
add esp,4
xor eax,eax
pop edi
pop esi
pop ebp
pop ebx
add esp,230
retn 4



CODE:[Copy to clipboard]10002963  85C0          test eax,eax
10002965  7C 0A          jl short Sharedll.10002971
10002967  43            inc ebx
10002968  83C6 04        add esi,4
//找到这里
1000296B  3BDF          cmp ebx,edi
1000296D  7C DE          jl short Sharedll.1000294D
1000296F  33C0          xor eax,eax
10002971  5F            pop edi
10002972  5E            pop esi
10002973  5D            pop ebp
10002974  5B            pop ebx
10002975  C2 0C00        retn 0C
//这里下断,F9运行,中断后取消断点
当我们中断在10002975处后,输入表已经处理完毕了。

OEP就是壳的EP,我们可以直接G壳的EP。
还是再次使用Second段内存断点大法吧!
Alt+M 显示内存窗口,在第2个区段00401000段“设置内存访问断点”。
F9运行,直接中断在OEP!


CODE:[Copy to clipboard]0040F1A8  55            push ebp
//用LordPE完全Dump这个进程
0040F1A9  8BEC          mov ebp,esp
0040F1AB  6A FF          push -1
0040F1AD  68 60BC4200      push BSLicens.0042BC60
0040F1B2  68 3C314100      push BSLicens.0041313C
0040F1B7  64:A1 00000000    mov eax,dword ptr fs:[0]
0040F1BD  50            push eax
0040F1BE  64:8925 00000000  mov dword ptr fs:[0],esp
0040F1C5  83EC 58        sub esp,58
0040F1C8  53            push ebx
0040F1C9  56            push esi
0040F1CA  57            push edi
0040F1CB  8965 E8        mov dword ptr ss:[ebp-18],esp
0040F1CE  FF15 F8074300    call dword ptr ds:[4307F8]    ; kernel32.GetVersion
运行ImportREC,选择这个进程。OEP不用修改,点IT AutoSearch,Get Import得到输入表,现在所有的函数都是有序有效的,FixDump,正常运行!

地主 发表时间: 06-10-22 11:02

回复: jhkdiy [jhkdiy]   版主   登录
学习了,谢谢发帖。

B1层 发表时间: 06-10-22 13:23

论坛: 编程破解

20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon

粤ICP备05087286号