【目 标】:Security Officer for Windows 6.7.1.1
【工 具】:flyodbg1.1、LORDPE、ImportREC,WinHex
【任 务】:脱壳、修复
【操作平台】:Windows XP sp2
【作 者】: mirrormask
【相关链接】: google
【简要说明】:老婆经常偷玩游戏,近日又迷上英雄无敌,荒废学业。某天突发奇志,要金盆洗手,要我找一用户控制软件,功能要求是在她的用户界面下,只能进入学习资料文件夹。于是找到一名为Security Officer for Windows的冬冬,方便之处不能细数。可是只有30天试用期。想我也在看雪受诸位高手熏陶多时,向老婆夸下海口,要在30天内解除软件限制,使她的学习环境得到保证.找来高手文章,边学边练,12日后,神功初成,软柿子涅扁。
【详细过程】:
peid:ASProtect 2.1x SKE -> Alexey Solodovnikov
od,大概32次异常后下code段内存断点,shift-f9,断下
00529D3C 55 push ebp ;这里
00529D3D 8BEC mov ebp,esp
00529D3F 83C4 F0 add esp,-10
00529D42 B8 4C975200 mov eax,wso.0052974C
00529D47 E8 88CFEDFF call wso.00406CD4 做了一个只有32 个esto 的odscript脚本(别的指令不会)。简陋,但方便。
无stolen code,窃喜。
1、iat初步分析
粗跟一下,会看到call进入壳里了。
00406C10 E8 EB93DA00 call 011B0000 ;可能是其他数值 搜索命令 call 011B0000,发现从 40123c开始,类似
/*40123C*/ jmp dword ptr ds:[530***]
形式的语句,他们本应整齐排列,530***就应是iat位置。但被call 011B0000这类指令打断,api调用被加密。d 530000,发现从5301b4到5309a0处是iat表,但是iat表被加密,比如:
005301F0 *5C B4 FB 1B AD 9C 80 7C *C8 2D E7 47 11 03 81 7C \贷???缜?
*处就是加密后的iat
2、找到api解密代码位置
通过学习loveboom的《ASPROTECT 2.x 脱壳系列》,知道api解密后call 011B0000会被修改,在
00406C10 E8 EB93DA00 call 011B0000
下内存写入断点
00FC5CEE 8902 mov dword ptr ds:[edx],eax ;断在这里
00FC5CF0 EB 01 jmp short 00FC5CF3
对00FC5CEE 以上几个call分析(见loveboom文一)
00FC5C9E 8D4D E0 lea ecx,dword ptr ss:[ebp-20]
00FC5CA1 8B45 F4 mov eax,dword ptr ss:[ebp-C]
00FC5CA4 8B40 3C mov eax,dword ptr ds:[eax+3C]
00FC5CA7 8B55 FC mov edx,dword ptr ss:[ebp-4] ;
00FC5CAA E8 D1130000 call 00FC7080 ;edi中为api地址。
跟进
00FC7080 55 push ebp
00FC7081 8BEC mov ebp,esp
00FC7083 83C4 E4 add esp,-1C
00FC7086 53 push ebx
00FC7087 56 push esi
00FC7088 57 push edi
00FC7089 894D F4 mov dword ptr ss:[ebp-C],ecx
00FC708C 8955 F8 mov dword ptr ss:[ebp-8],edx
00FC708F 8945 FC mov dword ptr ss:[ebp-4],eax
00FC7092 33C0 xor eax,eax
00FC7094 8945 F0 mov dword ptr ss:[ebp-10],eax
00FC7097 B8 00070000 mov eax,700
00FC709C E8 A3B4FDFF call 00FA2544
跟进
00FA2544 85C0 test eax,eax
00FA2546 74 0A je short 00FA2552
00FA2548 FF15 1890FC00 call dword ptr ds:[FC9018] ;;edi中为api地址。
loveboom说,此处下断点不会被检测到,就拿此处开刀!
3、还原iat
重新加载wso.ese,到达oep后,把
00FA2548 FF15 1890FC00 call dword ptr ds:[FC9018]
改为 call 0e000033
先申请一块内存(用od插件memory manage):
地址=0E000000
大小=00010000 (65536.) 写下如下代码:
0E000000 mov dword ptr ds:[E001000],532D40 ;532D40开始,原iat所在区块是连续空白区,下一个区块也是空白,作为预留空间,存放解密后api地址
0E00000A mov edx,401000 ;搜索“call 11b0000“的起始地质
0E00000F cmp byte ptr ds:[edx],0E8 ;是否为call指令?
0E000012 jnz short 0E000028 ;继续搜索
0E000014 mov eax,dword ptr ds:[edx+1] ;计算调用地址
0E000017 add eax,edx
0E000019 add eax,5
0E00001E cmp eax,11B0000 ;调用地址=11b0000?(11b0000可变)
0E000023 jnz short 0E000028 ;继续搜索
0E000025 pushad ;保存堆栈,观察堆栈变化
0E000026 jmp edx ;执行call 11b0000,进入api解密.如0E000033处下代码断点
0E000028 inc edx
0E000029 cmp edx,52A000 ;代码段结束?
0E00002F ^jb short 0E00000F ;继续搜索
0E000031 -jmp short 0E000031 ;方便dump
0E000033 mov ecx,dword ptr ds:[E001000] ;中断在此处,[E001000]中是为iat预留的地址
0E000039 nop
... ; 39~~~~6c之间为nop,,
0E00006c nop
0E00006D mov dword ptr ds:[ecx],edx ; edx中是api解密后地址,放入预留的iat中
0E00006F add dword ptr ds:[E001000],4 ;下一个iat地址
0E000076 mov dword ptr ds:[E002000],ecx ;保存ecx
0E00007C add esp,12C ;与0E000025处pushad对应的堆栈地址,12c可变
0E000082 popad
0E000083 mov ebx,dword ptr ds:[E002000] ;恢复ecx
0E000089 mov dword ptr ds:[edx+2],ebx ;修改api调用地址为解密后地址
0E00008C mov word ptr ds:[edx],25FF ;修改calll 011b0000为jmp ********形式
0E000091 mov ebx,dword ptr ds:[E001000]
0E000097 mov dword ptr ds:[ebx],0 ;iat保存后,下一dword填充00000000
0E00009D nop
0E00009E add dword ptr ds:[E001000],4 ;下一个iat预留地址
0E0000A5 ^jmp short 0E000028
二进制码为:
C7 05 00 10 00 0E 40 2D 53 00 BA 00 10 40 00 80 3A E8 75 14 8B 42 01 03 C2 05 05 00 00 00 3D 00
00 1B 01 75 03 60 FF E2 42 81 FA 00 A0 52 00 72 DE EB FE 8B 0D 00 10 00 0E 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 89 11 83 05 00 10 00 0E 04 89 0D 00 20 00 0E 81 C4 30 01
00 00 61 8B 1D 00 20 00 0E 89 5A 02 66 C7 02 FF 25 8B 1D 00 10 00 0E C7 03 00 00 00 00 90 83 05
00 10 00 0E 04 EB 81
代码是参照syscom <ASProtect.SKE.2.11 高速??+(?示) >中示范代码编写的,由于iat加密,进行了调整,将解密后api直接放入为其预留的iat空间,同时
0E000091 mov ebx,dword ptr ds:[E001000]
0E000097 mov dword ptr ds:[ebx],0 ;解密api地址保存为之后面填充00000000
为了使imprec不出现误报,每一api解密后iat填充00000000
代码编写完毕后,使eip=0e000000,f9,片刻,f12暂停。
dump wso.exe 。
imprec抓取iat,oep=00129D3C,rva=130000,size=4000,get,cut无效指针
fix it,不能正常运行,od载入继续跟踪发现:
004012F4 - FF25 0C025300 jmp dword ptr ds:[53020C]
004070F0 - FF25 F4035300 jmp dword ptr ds:[5303F4] 两处均是GetProcAddress,imprec修正.
可以运行,但有点问题 4、暗桩修复
先来去掉日期提示nag:
0052947C . /7E 1E jle short wso.0052949C ;修改为jmp short wso.0052949C
0052947E . |A1 38CF5200 mov eax,dword ptr ds:[52CF38]
00529483 . |8B00 mov eax,dword ptr ds:[eax]
00529485 . |8B10 mov edx,dword ptr ds:[eax]
00529487 . |FF92 EC000000 call dword ptr ds:[edx+EC] ;nag窗口
0052948D . |83F8 02 cmp eax,2 ;按try,eax=1;按quit,eax=2
00529490 . |75 0A jnz short wso.0052949C 再来去掉about的异常
把00FA0000-00FD3000 区块(位置可能会变化,od跟踪确定) 用lordpe dump,装配进修复好的wso.exe.rebuild pe.过程如下:
先打开lordpe,选wso.exe进程,点右键,区域脱壳,选00FA0000-00FD3000 区块,保存00FA0000-00FD3000.dmp文件。
再用用lordpe的pe编辑器打开已修复的wso.exe,然后查看区段,在区段表最后一条点右键“从硬盘载入区段”,载入00FA0000-00FD3000.dmp文件。
在新增区段上点右键,“编辑区段头”将虚拟地址改为ba0000
保存,rebuild pe,ok
在把about的unregistered改一下,和正式版一样:)得到老婆夸奖,还将syscom,loveboom,fly等诸位大牛大大的敬仰了一把。:)
收功之后,英雄无敌目录locked,设置password,以为老婆学业从此蒸蒸日上,与时俱进,再无30日之忧。谁知某日凌晨醒来,惨叫之声不绝于耳,老婆的大天使正在斩妖除魔。不可能阿,我的防护天衣无缝,只有我才能进入游戏目录。老婆见我惊愕,羞涩的嫣然一笑,惭愧而又骄傲的告诉我“下次吧密码设复杂点儿“。
兄弟们,牢记教训阿。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)