UFSOFT应该算是中国的财务ERP软件的老大了, 最近发布了最新的861版, 加密狗更换为最新的深思四, 破解难度加大了不少, 看来UFSOFT公司开始重视软件的盗版行为,开始花大力气在加密上花功夫了. 小弟使用了UFSOFT软件近七年时间,真正是从DOS版用到现在的8.51版, 同时做用友解密分析也做了四五年, 在此与各位分享一下其中的经验与感受.
先从UFSOFT最早的WINDOWS平台的7.2版本来讲起吧(UFSOFT公司已经出了861了, 现在公布一下这么旧的版本的破解心得, 想必UFSOFT也不会要告我吧:)
好,言归正传.
破解工具: TRW2000 W32DSM8.93修改版 ULTRAEDIT 11
环境: WIN98(因为这个版本只能在WIN98 ME环境上运行,上不了XP)
通过分析,发现其读狗文件有两个: MSMGV.DLL(单机版用) MSMGVN.DLL(网络版用)
通过W32DSM 反汇编单机版的MSMGV.DLL, 发现在EXPORT 段有这样的字样:
+++++++++++++++++++ EXPORTED FUNCTIONS ++++++++++++++++++
Number of Exported Functions = 0035 (decimal)
Addr:10001670 Ord: 1 (0001h) Name: CCwfxNetMain
Addr:10001680 Ord: 2 (0002h) Name: CCwfxNetStation
Addr:10001660 Ord: 3 (0003h) Name: CCwfxPc
Addr:100016A0 Ord: 4 (0004h) Name: CGdzcNetMain
Addr:100016C0 Ord: 5 (0005h) Name: CGdzcNetNumber
Addr:100016B0 Ord: 6 (0006h) Name: CGdzcNetStation
Addr:10001690 Ord: 7 (0007h) Name: CGdzcPc
Addr:100016F0 Ord: 8 (0008h) Name: CGzNetMain
Addr:10001710 Ord: 9 (0009h) Name: CGzNetNumber
Addr:10001700 Ord: 10 (000Ah) Name: CGzNetStation
Addr:100016E0 Ord: 11 (000Bh) Name: CGzPc
Addr:10001640 Ord: 12 (000Ch) Name: CLdcxNetMain
Addr:10001650 Ord: 13 (000Dh) Name: CLdcxNetStation
Addr:10001630 Ord: 14 (000Eh) Name: CLdcxPc
Addr:10001810 Ord: 15 (000Fh) Name: CPjNetMain
Addr:10001820 Ord: 16 (0010h) Name: CPjNetStation
Addr:10001800 Ord: 17 (0011h) Name: CPjPc
Addr:100017E0 Ord: 18 (0012h) Name: CRJNetMain
Addr:100017F0 Ord: 19 (0013h) Name: CRJNetStation
Addr:100017D0 Ord: 20 (0014h) Name: CRJPc
Addr:10001610 Ord: 21 (0015h) Name: CUfowNetMain
Addr:10001620 Ord: 22 (0016h) Name: CUfowNetStation
Addr:10001600 Ord: 23 (0017h) Name: CUfowPc
Addr:10001790 Ord: 24 (0018h) Name: CXxsmNetMain
Addr:100017A0 Ord: 25 (0019h) Name: CXxsmNetStation
Addr:10001780 Ord: 26 (001Ah) Name: CXxsmPc
Addr:10001740 Ord: 27 (001Bh) Name: CZjjxNetMain
Addr:10001760 Ord: 28 (001Ch) Name: CZjjxNetNumber
Addr:10001750 Ord: 29 (001Dh) Name: CZjjxNetStation
Addr:10001730 Ord: 30 (001Eh) Name: CZjjxPc
Addr:100015E0 Ord: 31 (001Fh) Name: CZwNetMain ----> 哈哈,根据英文猜测应该是总账模块的主站点
Addr:100015F0 Ord: 32 (0020h) Name: CZwNetStation ---->总账模块的工作站端(即客户端)以此类推
Addr:100015D0 Ord: 33 (0021h) Name: CZwPc ------>单机版的意思
Addr:100017C0 Ord: 34 (0022h) Name: OaClient
Addr:100017B0 Ord: 35 (0023h) Name: OaServer ------>强啊, 那个时候竟然都有OA 模块了, UFSOFT公司真是牛,不过真正却根本就没发
现这个模块, 吹牛啊....
在此说明一下, UFSOFT 的7.2版的加密狗是分服务器端和客户端的,即每台电脑都要插狗的,只是狗的功能不同,不像现在一个狗那么方便.
好, 我们就拿这个CZWPC 即总账单机版开刀, 去看看到底有什么好东西看. GO
Exported fn(): CZwPc - Ord:0021h
:100015D0 686A020000 push 0000026A
:100015D5 6A00 push 00000000
:100015D7 E8F4FEFFFF call 100014D0
:100015DC 83C408 add esp, 00000008
:100015DF C3 ret
Exported fn(): CZwNetMain - Ord:001Fh
:100015E0 68CE020000 push 000002CE
:100015E5 6A01 push 00000001
:100015E7 E8E4FEFFFF call 100014D0
:100015EC 83C408 add esp, 00000008
:100015EF C3 ret
Exported fn(): CZwNetStation - Ord:0020h
:100015F0 6832030000 push 00000332
:100015F5 6A02 push 00000002
:100015F7 E8D4FEFFFF call 100014D0
:100015FC 83C408 add esp, 00000008
:100015FF C3 ret
嗯, 根据以上分析, 那个 100014D0肯定有问题, 好,跟进去:
* Referenced by a CALL at Addresses:
|:100015D7 , :100015E7 , :100015F7 , :10001607 , :10001617
|:10001627 , :10001634 , :10001644 , :10001657 , :10001667
|:10001677 , :10001687 , :10001694 , :100016A7 , :100016B7
|:100016CA , :100016E4 , :100016F7 , :10001707 , :1000171A
|:10001737 , :10001747 , :10001757 , :1000176A , :10001787
|:10001797 , :100017A7 , :100017B7 , :100017C7 , :100017D7
|:100017E7 , :100017F7 , :10001807 , :10001817 , :10001827
|
:100014D0 56 push esi
:100014D1 E88AFCFFFF call 10001160 -----> 有问题, 跟进去看看(见下面)
:100014D6 83F85E cmp eax, 0000005E ----->EAX是否为5E, 不是就跳,这个5E是什么意思, 我开始也不明白,后来问做代
理的朋友借了个狗后才知道, 原来这个5E 其实就是代理用的通用加密狗的意思, 50个用户,所以,这里绝对不能跳的, 可以直接将下面的JNE改
为9090, 就可以成功解掉狗了, 如果跳了的话就表示现在的狗不是通狗, 是普通加密狗, 再进行多步的读狗与校验, 相当麻烦,所以不在这次讨论的范围. 我们再分析一下那个 10001160是什么东西吧
:100014D9 7506 jne 100014E1
:100014DB 8B44240C mov eax, dword ptr [esp+0C]
:100014DF 5E pop esi
:100014E0 C3 ret
进入CALL 10001160程序段:
* Referenced by a CALL at Address:
|:100014D1
|
:10001160 81EC88000000 sub esp, 00000088
:10001166 33C0 xor eax, eax
:10001168 6689442400 mov word ptr [esp], ax
:1000116D 56 push esi
:1000116E 6689442406 mov word ptr [esp+06], ax
:10001173 57 push edi
:10001174 6804040000 push 00000404
:10001179 6810150210 push 10021510
:1000117E E88D7A0000 call 10008C10
:10001183 6810150210 push 10021510
:10001188 E8E37A0000 call 10008C70
:1000118D 6809580000 push 00005809
:10001192 6810150210 push 10021510
:10001197 E8247D0000 call 10008EC0
:1000119C 8D442408 lea eax, dword ptr [esp+08]
:100011A0 50 push eax
:100011A1 6A0B push 0000000B
:100011A3 6810150210 push 10021510
:100011A8 E8337F0000 call 100090E0
:100011AD 8D44240A lea eax, dword ptr [esp+0A]
:100011B1 50 push eax
:100011B2 6A0C push 0000000C
:100011B4 6810150210 push 10021510
:100011B9 E8227F0000 call 100090E0
:100011BE E8DDA60000 call 1000B8A0
:100011C3 8D442410 lea eax, dword ptr [esp+10]
:100011C7 50 push eax
:100011C8 E803A60000 call 1000B7D0
:100011CD 8D442414 lea eax, dword ptr [esp+14]
:100011D1 83C404 add esp, 00000004
:100011D4 50 push eax
:100011D5 E856A50000 call 1000B730
:100011DA 8D442410 lea eax, dword ptr [esp+10]
:100011DE 83C404 add esp, 00000004
:100011E1 50 push eax
:100011E2 E839A40000 call 1000B620
:100011E7 8D442410 lea eax, dword ptr [esp+10]
:100011EB 83C404 add esp, 00000004
:100011EE 50 push eax
:100011EF E85CA20000 call 1000B450
:100011F4 83C404 add esp, 00000004
:100011F7 8BF8 mov edi, eax
:100011F9 8D442410 lea eax, dword ptr [esp+10]
:100011FD 57 push edi
到此为止上面全部都是读加密狗的语句, 不用理会, 不改狗的话就不用那么深入了吧:)
* Possible StringData Ref from Data Obj ->"%Y"
|
:100011FE 688CF00110 push 1001F08C
:10001203 6880000000 push 00000080
:10001208 50 push eax
:10001209 E822970000 call 1000A930
:1000120E 8D442420 lea eax, dword ptr [esp+20]
:10001212 83C410 add esp, 00000010
:10001215 50 push eax
:10001216 E805970000 call 1000A920
:1000121B 83C404 add esp, 00000004
:1000121E 8BF0 mov esi, eax
:10001220 8D442410 lea eax, dword ptr [esp+10]
:10001224 57 push edi
* Possible StringData Ref from Data Obj ->"%m" ------好关键开始了.
|
:10001225 6888F00110 push 1001F088
:1000122A 6880000000 push 00000080
:1000122F 50 push eax
:10001230 E8FB960000 call 1000A930
:10001235 83C410 add esp, 00000010
:10001238 8D442410 lea eax, dword ptr [esp+10]
:1000123C 50 push eax
:1000123D E8DE960000 call 1000A920
:10001242 8B4C240C mov ecx, dword ptr [esp+0C]
:10001246 83C404 add esp, 00000004
:10001249 81E1FFFF0000 and ecx, 0000FFFF
:1000124F 3BF1 cmp esi, ecx
:10001251 7F1E jg 10001271 ---->注意啦, 这里绝对不能跳, 一跳的话EAX就成了0D啦,不是5E就会让上面的比较语句100014D6发生跳跃, 所以不能跳.
:10001253 750E jne 10001263 ----->哈哈, 这里一跳EAX就是真正的5E啦, 一定要跳.
:10001255 8B4C240A mov ecx, dword ptr [esp+0A]
:10001259 81E1FFFF0000 and ecx, 0000FFFF
:1000125F 3BC8 cmp ecx, eax
:10001261 7C0E jl 10001271
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10001253(C)
|
:10001263 B85E000000 mov eax, 0000005E
:10001268 5F pop edi
:10001269 5E pop esi
:1000126A 81C488000000 add esp, 00000088
:10001270 C3 ret
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:10001251(C), :10001261(C)
|
:10001271 B80D000000 mov eax, 0000000D
:10001276 5F pop edi
:10001277 5E pop esi
:10001278 81C488000000 add esp, 00000088
:1000127E C3 ret
从上面所看, EAX的值一定要变成5E才是通狗, 如果改上面跳转的话就要改两处地方, 小弟我偷了个懒, 直接将10001271那的MOV EAX,0000000D改为MOV EAX,0000005E, 嘿嘿,我无论你如何跳,最终的EAX值都是5E, 至此破解成功.
总结: 小弟第一次在看雪论坛上写破解文章, 所以思路可能会有点混乱, 还请各位高手多多包涵. UFSOFT 7.2的加密可算是相当简单的, 但在当时的环境由于小弟没有W32DSM等反汇编利器, 只能用TRW2000一步步跟踪, 好在有狗,才搞清楚其基本流程. 个人觉得UFSOFT软件一直到8.60版本之前,都没用什么心机在加密方式, 最简单的证明是一个加密狗可以用共享器给两台电脑共享用(指并口狗), 软件程序只在进入的时候测一下有没狗, 既没用到狗的数据做重要变量, 也不会在程序进入后还不定期读狗, 加密相当宽松(直到8.52版都是这样的情况,看来做加密的人一直没换), 真到8.60版本开始在加密上下了点功夫,但也只是增加了读狗文件的校验, 增加了点破解的难度, 延长了破解时间而已. 最主要的还是没有将重要变量数据等放到狗中, 没有在程序中使用狗内的数据, 只是检测有没狗, 这样无论狗多么强,都可以爆破. 就像大老说的,无论狗多么厉害, 使用狗的人不厉害, 也还是没用, 呵呵!
下一次小弟将对UFSOFT 7.2的下一个版本: UFSOFT 8.11A行政版做破解分析.
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课