Armadillo 1.xx - 2.xx脱壳讨论
【软件名称】:Rida.exe 软件版本:1.002
【软件大小】:1.63 MB
【下载地址】:http://www.micromedical.co.uk/update/download.asp
【软件简介】:该软件是医疗行业软件,用于测定小气道阻力,配有专门的肺功能仪。
【软件限制】:30天试用
【破解声明】:这是医院买的正版软件,有安装序列号及注册码,脱壳只为汉化及学习,失误之处敬请诸位大侠赐教
【破解工具】:W32dasm8.93+、OD1.10、resscope1.94
―――――――――――――――――――――――――――――――――――――――――――
【破解过程】:
Armadillo 1.xx - 2.xx标准方式加壳的脱壳过程,大家看了论坛精华后相信再熟悉不过了,此处就简单带过:
1.找OEP:我用最笨笨的方法,一直按F8,直到出现启动界面,看一下是哪个Call,下次G 地址,直接到这个Call后,F7跟入,继续上述步骤,至最后看到的Call是Call edi,即为OEP,完全是体力活,简单吧?
2.找Magic Jump:以前的精华有各种断点,随便选一种方法均可,因为大家不可能找到这个版本的程序验证,略过。
3.跳过Magic Jump,到达OEP,用LordPE dump程序,ImportRec获得IAT,所有指针有效,FIX刚才DUMP出的程序,可正常运行。原程序1.63M脱壳后接近4M。
4.用LordPE删除程序section的text1以下4个段,rebuild一下,体积减小到1.87M,试运行有效,至此脱壳完成。
经以上处理后的程序运行时有NAG窗口,先提示“Is the program protected?”,当然按“确定”啦,又提示“You have day(s) left”,再次“确定”,才进入主程序。
拿出W32asm反汇编,查找串式参考“Is the ”,共有两处,经分析,一处是启动时提示,另一处为调出注册界面时提示,看一下代码:
* Possible StringData Ref from Data Obj ->"DAYSLEFT" <=======取剩余试用时间
|
:00454E18 6874594E00 push 004E5974
:00454E1D FF1594DB4F00 call dword ptr [004FDB94]
:00454E23 85C0 test eax, eax
:00454E25 751B jne 00454E42 <========此处可跳过第一个NAG
:00454E27 6A10 push 00000010
* Possible StringData Ref from Data Obj ->"Error!" <=====没取到,看样子被脱壳!
|
:00454E29 6880594E00 push 004E5980
* Possible StringData Ref from Data Obj ->"Is the program protected?" <====难道没保护了吗?
|
:00454E2E 6888594E00 push 004E5988
:00454E33 8B8DFCFEFFFF mov ecx, dword ptr [ebp+FFFFFEFC]
:00454E39 E8197C0400 call 0049CA57
:00454E3E 33C0 xor eax, eax
:00454E40 EB27 jmp 00454E69
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00454E25(C)
|
:00454E42 8D9500FFFFFF lea edx, dword ptr [ebp+FFFFFF00]
:00454E48 52 push edx
把:00454E25 处 jne 00454E42 改成jmp 即可跳过,但还有第二个NAG,查找对话框ID后,可用类似方法解决,
* Referenced by a CALL at Address:
|:0046046A
|
:00454D20 55 push ebp
:00454D21 8BEC mov ebp, esp
:00454D23 6AFF push FFFFFFFF
:00454D25 68D5174C00 push 004C17D5
:00454D2A 64A100000000 mov eax, dword ptr fs:[00000000]
:00454D30 50 push eax
:00454D31 64892500000000 mov dword ptr fs:[00000000], esp
:00454D38 51 push ecx
:00454D39 894DF0 mov dword ptr [ebp-10], ecx
:00454D3C 8B4508 mov eax, dword ptr [ebp+08]
:00454D3F 50 push eax
* Possible Reference to Dialog: DialogID_00A5 <======此处可用resscope查看ID为165,即16进制A5
|
:00454D40 68A5000000 push 000000A5
向上查找到0046046A:
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00460389(C)
|
:00460462 6A00 push 00000000
:00460464 8D8D54FDFFFF lea ecx, dword ptr [ebp+FFFFFD54]
:0046046A E8B148FFFF call 00454D20
还要向上00460389:
* Possible StringData Ref from Data Obj ->"EXPIRED"
|
:0046037C 68CC654E00 push 004E65CC
:00460381 FF1594DB4F00 call dword ptr [004FDB94]
:00460387 85C0 test eax, eax
:00460389 0F84D3000000 je 00460462 <======就在这里,条件跳转
:0046038F 6AFF push FFFFFFFF
:00460391 6A00 push 00000000
* Possible Reference to String Resource ID=00141: "The trial period for this software has expired.
Unable to l"
|
:00460393 688D000000 push 0000008D
显然00460389处为判断时间,如果过期则不跳,提示过期,在试用期内则跳转,还是跳不过NAG,再向上看:
:004602E6 8B8D6CFCFFFF mov ecx, dword ptr [ebp+FFFFFC6C]
:004602EC E83E110000 call 0046142F
:004602F1 85C0 test eax, eax
:004602F3 0F85DB010000 jne 004604D4 <======这个跳过所有判断,爽!
:004602F9 68FF000000 push 000000FF
:004602FE 8D85CCFEFFFF lea eax, dword ptr [ebp+FFFFFECC]
:00460304 50 push eax
* Possible StringData Ref from Data Obj ->"CLOCKBACK" <=====时间后调?
|
:00460305 68B0654E00 push 004E65B0
:0046030A FF1594DB4F00 call dword ptr [004FDB94]
:00460310 8BF0 mov esi, eax
:00460312 68FF000000 push 000000FF
:00460317 8D8DCCFEFFFF lea ecx, dword ptr [ebp+FFFFFECC]
:0046031D 51 push ecx
* Possible StringData Ref from Data Obj ->"CLOCKFORWARD" <=====时间前调?
|
:0046031E 68BC654E00 push 004E65BC
:00460323 FF1594DB4F00 call dword ptr [004FDB94]
:00460329 0BF0 or esi, eax
:0046032B 85F6 test esi, esi
:0046032D 7441 je 00460370 <======改过系统时间?否则跳过
:0046032F 6AFF push FFFFFFFF
:00460331 6A00 push 00000000
* Possible Reference to String Resource ID=00140: "There are anomalies with the internal clock.
Cannot load R"
|
:00460333 688C000000 push 0000008C
:00460338 E89A6F0400 call 004A72D7
:0046033D C78590FCFFFF00000000 mov dword ptr [ebp+FFFFFC90], 00000000
:00460347 C645FC00 mov [ebp-04], 00
:0046034B 8D8DC8FEFFFF lea ecx, dword ptr [ebp+FFFFFEC8]
:00460351 E844E90300 call 0049EC9A
:00460356 C745FCFFFFFFFF mov [ebp-04], FFFFFFFF
:0046035D 8D4DCC lea ecx, dword ptr [ebp-34]
:00460360 E84A5E0500 call 004B61AF
:00460365 8B8590FCFFFF mov eax, dword ptr [ebp+FFFFFC90]
:0046036B E9D2020000 jmp 00460642
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0046032D(C)
|
:00460370 68FF000000 push 000000FF
:00460375 8D95CCFEFFFF lea edx, dword ptr [ebp+FFFFFECC]
:0046037B 52 push edx
* Possible StringData Ref from Data Obj ->"EXPIRED" <======如果系统时间正确,判断试用是否过期
经过以上两处修改,应该可以了吧,运行,OK,界面马上出来了,耶!!!
点击“New Examination”,程序不声不响退出,我倒!看来还有暗桩,仔细看看,上面的判断都有一个函数调用call dword ptr [004FDB94],动态跟踪看看,找到地址再静态分析,原来是调用armaccess.dll内的判断函数,在W32dasm中查找串式参考armaccess.dll,共有3处,经分析,一处为输入注册码时使用,一处为程序启动时,一处为程序启动后,点击各个菜单时要先检验。
* Referenced by a CALL at Address:
|:00455B7E <========只有一处调用
|
:00461790 55 push ebp
:00461791 8BEC mov ebp, esp
:00461793 83EC10 sub esp, 00000010
:00461796 894DF0 mov dword ptr [ebp-10], ecx
:00461799 C645F400 mov [ebp-0C], 00
* Possible StringData Ref from Data Obj ->"ArmAccess.DLL"
|
:0046179D 68CC664E00 push 004E66CC
:004617A2 FF1574DB4F00 call dword ptr [004FDB74]
:004617A8 8945FC mov dword ptr [ebp-04], eax
:004617AB 837DFC00 cmp dword ptr [ebp-04], 00000000
:004617AF 7504 jne 004617B5
:004617B1 33C0 xor eax, eax
:004617B3 EB3C jmp 004617F1
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004617AF(C)
|
* Possible StringData Ref from Data Obj ->"CheckCode" <=========检验Code,当然是注册时啦
|
:004617B5 68DC664E00 push 004E66DC
因为脱壳后,已没必要注册,此处不需修改
第二处,程序运行时调用:
* Referenced by a CALL at Address:
|:00461620
|
:004617F7 55 push ebp
:004617F8 8BEC mov ebp, esp
:004617FA 83EC10 sub esp, 00000010
:004617FD 894DF0 mov dword ptr [ebp-10], ecx
* Possible StringData Ref from Data Obj ->"ArmAccess.DLL" <=====调用
|
:00461800 68E8664E00 push 004E66E8
:00461805 FF1574DB4F00 call dword ptr [004FDB74]
:0046180B 8945F8 mov dword ptr [ebp-08], eax
:0046180E 837DF800 cmp dword ptr [ebp-08], 00000000
:00461812 7502 jne 00461816
:00461814 EB5A jmp 00461870
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00461812(C)
|
* Possible StringData Ref from Data Obj ->"SetDefaultKey" <=====设置环境变量
|
:00461816 68F8664E00 push 004E66F8
:0046181B 8B45F8 mov eax, dword ptr [ebp-08]
:0046181E 50 push eax
:0046181F FF1578DB4F00 call dword ptr [004FDB78]
:00461825 8945F4 mov dword ptr [ebp-0C], eax
:00461828 837DF400 cmp dword ptr [ebp-0C], 00000000
:0046182C 7502 jne 00461830
:0046182E EB40 jmp 00461870
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0046182C(C)
|
:00461830 FF55F4 call [ebp-0C]
:00461833 25FF000000 and eax, 000000FF
:00461838 85C0 test eax, eax
:0046183A 7502 jne 0046183E
:0046183C EB32 jmp 00461870
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0046183A(C)
|
* Possible StringData Ref from Data Obj ->"UpdateEnvironment" <=========设置环境变量
|
:0046183E 6808674E00 push 004E6708
:00461843 8B4DF8 mov ecx, dword ptr [ebp-08]
:00461846 51 push ecx
:00461847 FF1578DB4F00 call dword ptr [004FDB78]
:0046184D 8945FC mov dword ptr [ebp-04], eax
:00461850 837DFC00 cmp dword ptr [ebp-04], 00000000
:00461854 7502 jne 00461858
:00461856 EB18 jmp 00461870
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00461854(C)
|
:00461858 FF55FC call [ebp-04]
:0046185B 25FF000000 and eax, 000000FF
:00461860 85C0 test eax, eax
:00461862 7502 jne 00461866
:00461864 EB0A jmp 00461870
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00461862(C)
|
:00461866 8B55F8 mov edx, dword ptr [ebp-08]
:00461869 52 push edx
:0046186A FF157CDB4F00 call dword ptr [004FDB7C]
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00461814(U), :0046182E(U), :0046183C(U), :00461856(U), :00461864(U)
|
:00461870 8BE5 mov esp, ebp
:00461872 5D pop ebp
:00461873 C3 ret
取消先前所作的跳转修改,根据动态调试结果,该调用应返回1,故004617F7处开始,改为
xor eax,eax
inc eax
ret
第三处,为运行程序功能菜单时调用
* Referenced by a CALL at Addresses:
|:00415B26 , :00415DA4
|
:00461874 55 push ebp
:00461875 8BEC mov ebp, esp
:00461877 6AFF push FFFFFFFF
:00461879 6897214C00 push 004C2197
:0046187E 64A100000000 mov eax, dword ptr fs:[00000000]
:00461884 50 push eax
:00461885 64892500000000 mov dword ptr fs:[00000000], esp
:0046188C 81EC48020000 sub esp, 00000248
:00461892 57 push edi
:00461893 898DACFDFFFF mov dword ptr [ebp+FFFFFDAC], ecx
:00461899 A0DC894F00 mov al, byte ptr [004F89DC]
:0046189E 8885ECFEFFFF mov byte ptr [ebp+FFFFFEEC], al
:004618A4 B93F000000 mov ecx, 0000003F
:004618A9 33C0 xor eax, eax
:004618AB 8DBDEDFEFFFF lea edi, dword ptr [ebp+FFFFFEED]
:004618B1 F3 repz
:004618B2 AB stosd
:004618B3 66AB stosw
:004618B5 AA stosb
:004618B6 8D8DE8FEFFFF lea ecx, dword ptr [ebp+FFFFFEE8]
:004618BC E82F0AFAFF call 004022F0
:004618C1 C745FC00000000 mov [ebp-04], 00000000
* Possible StringData Ref from Data Obj ->"ArmAccess.DLL"
|
:004618C8 681C674E00 push 004E671C
:004618CD FF1574DB4F00 call dword ptr [004FDB74]
:004618D3 8945EC mov dword ptr [ebp-14], eax
:004618D6 837DEC00 cmp dword ptr [ebp-14], 00000000
:004618DA 7527 jne 00461903
:004618DC C785CCFDFFFF01000000 mov dword ptr [ebp+FFFFFDCC], 00000001
:004618E6 C745FCFFFFFFFF mov [ebp-04], FFFFFFFF
:004618ED 8D8DE8FEFFFF lea ecx, dword ptr [ebp+FFFFFEE8]
:004618F3 E8A2D30300 call 0049EC9A
:004618F8 8B85CCFDFFFF mov eax, dword ptr [ebp+FFFFFDCC]
:004618FE E9A9020000 jmp 00461BAC
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004618DA(C)
|
* Possible StringData Ref from Data Obj ->"UpdateEnvironment"
下面略去
经00415B26处下断点调试,此调用应返回0,故00461874处开始改为
xor eax,eax
ret
经以上处理,程序运行无误,继续完成汉化工作,也就是脱壳的最主要目的,方便我科不太懂英文的人使用。
以下为请大家指点之处:
1.在win2000下,程序“注册”菜单项为灰色,即已注册,在win98下仍可点击,并出现注册对话框,考虑是否与脱壳时系统环境有关?
2.原版在别的机子上安装,用Trial-Reset2.0在win98环境下可去除Armadillo的30天试用信息,重新开始试用,但在win2000环境下毫无作用,是本软件另设有标志,还是所有Armadillo壳都这样的?
3.http://www.micromedical.co.uk/update/download.asp有一个升级版本,为1.10版,
Rida - Rint Database (Upgrade Only, requires a valid installation of Rida)提示仅供升级,要有一个有效的安装,实际无所谓,只要安装了DAO数据引擎就可以运行了,
用PEID查壳为Armadillo 1.xx - 2.xx -> Silicon Realms Toolworks,运行后为单进程,上一版本的安装序列号及注册码仍可使用,故加壳方法是一样的,但
用精华中描述的各种方法,先找到OEP:
00DB92FE 83F9 01 cmp ecx,1
00DB9301 75 22 jnz short 00DB9325
00DB9303 FF76 04 push dword ptr ds:[esi+4]
00DB9306 FF76 08 push dword ptr ds:[esi+8]
00DB9309 6A 00 push 0
00DB930B E8 31F4FEFF call 00DA8741
00DB9310 50 push eax
00DB9311 A1 D8E6DC00 mov eax,dword ptr ds:[DCE6D8]
00DB9316 8B48 6C mov ecx,dword ptr ds:[eax+6C]
00DB9319 3348 54 xor ecx,dword ptr ds:[eax+54]
00DB931C 3348 0C xor ecx,dword ptr ds:[eax+C]
00DB931F 2BF9 sub edi,ecx
00DB9321 FFD7 call edi ; Rida.004AD8EB <=====OEP
此处F7跟进,
004AD8EB 55 push ebp
004AD8EC 8BEC mov ebp,esp
004AD8EE 6A FF push -1
004AD8F0 68 906D4F00 push Rida.004F6D90
004AD8F5 68 A0234B00 push Rida.004B23A0
004AD8FA 64:A1 0000000>mov eax,dword ptr fs:[0]
004AD900 50 push eax
004AD901 64:8925 00000>mov dword ptr fs:[0],esp
验证的确为OEP
然后找magic jump
00D9A113 FF15 CCF0DB00 call dword ptr ds:[DBF0CC] ; KERNEL32.GetModuleHandleA
00D9A119 3945 08 cmp dword ptr ss:[ebp+8],eax ; Rida.00400000
00D9A11C 75 07 jnz short 00D9A125
00D9A11E B9 583BDC00 mov ecx,0DC3B58
00D9A123 EB 51 jmp short 00D9A176
00D9A125 393D 9841DC00 cmp dword ptr ds:[DC4198],edi
00D9A12B B9 9841DC00 mov ecx,0DC4198
00D9A130 0F84 91000000 je 00D9A1C7 <======magic jump?
00D9A136 8B35 40A1DC00 mov esi,dword ptr ds:[DCA140]
00D9A13C A1 D8E6DC00 mov eax,dword ptr ds:[DCE6D8]
00D9A141 F641 08 01 test byte ptr ds:[ecx+8],1
00D9A145 74 0D je short 00D9A154
将00D9A130处改为jmp 00D9A1C7后,无法用G 004AD8EB到达OEP,且无论怎么运行后,ImportRec获得IAT,有很多指针无效,cut thunk(s)后修复dump的文件,也无法运行,哪位大虾麻烦指点一下。如要下载安装调试,可用安装序列号210 193 597,注册码是根据硬件计算的,贴出来也没用。
不知道这个贴子有没有违规,如果不行,请FLY老大删贴,千万不要ban 我的 ID,上次被警告了,好怕怕哦!
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!