【文章标题】: SVKP1.43 之VB [含抽取代码]
【文章作者】: yangjt
【作者邮箱】: yangjietao123@163.com
【作者QQ号】: 325002492
【软件名称】: 体重指标获取程序
【软件大小】: 加壳前736 KB
【下载地址】: 我同学写的程序啦~~从我这里下载就好了
【加壳方式】: SVKP 1.43
【使用工具】: OllyICE,LordPE个人版,ImportREC,CFF Explorer
【操作平台】: Windows XP SP3[正版,非爱国版^_^]
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
昨天下午俺们班同学给我传过来一个他用VB写的程序……我就顺便用SVKP1.43给他加了个壳,下面是脱壳的步骤,脱完壳油化后竟然能和加壳前程序一般大小,看来SVKP对VB的保护也是有心无力啊……
废话不多说……来看程序
代码:
004B8000 > 60 pushad 004B8001 E8 00000000 call 004B8006 004B8006 5D pop ebp 004B8007 81ED 06000000 sub ebp, 6 004B800D EB 05 jmp short 004B8014 004B800F B8 49DCF466 mov eax, 66F4DC49 004B8014 64:A0 23000000 mov al, byte ptr fs:[23] 004B801A EB 03 jmp short 004B801F 004B801C C784E8 84C0EB03>mov dword ptr [eax+ebp*8+3EBC084], 7> 004B8027 67:B9 49000000 mov ecx, 49 004B802D 8DB5 C5020000 lea esi, dword ptr [ebp+2C5] 004B8033 56 push esi 004B8034 8006 44 add byte ptr [esi], 44 004B8037 46 inc esi 004B8038 ^ E2 FA loopd short 004B8034
PEiD扫描过……SVKP 1.3x -> Pavol Cerven,可惜我用的是1.43版本的……看来PEiD不可信哦……
干嘛干嘛……又没说要用OD直接把程序跑起来……别那么着急嘛,先把刚才那个OD给关掉……你要是不关废内存又不是我家的…… ^_^
先把加壳程序运行起来……然后打开一个空的OD,然后附加SVKP加过壳的那个进程
代码:
7C92120F C3 retn 7C921210 8BFF mov edi, edi 7C921212 > CC int3 7C921213 C3 retn 7C921214 8BFF mov edi, edi 7C921216 8B4424 04 mov eax, dword ptr [esp+4] 7C92121A CC int3 7C92121B C2 0400 retn 4 7C92121E > 64:A1 18000000 mov eax, dword ptr fs:[18] 7C921224 C3 retn 7C921225 > 57 push edi
甭管SP几,停到这里以后Alt+F9 返回一次……
代码:
7C92E4F4 > C3 retn 7C92E4F5 8DA424 00000000 lea esp, dword ptr [esp] 7C92E4FC 8D6424 00 lea esp, dword ptr [esp] 7C92E500 > 8D5424 08 lea edx, dword ptr [esp+8] 7C92E504 CD 2E int 2E 7C92E506 C3 retn 7C92E507 90 nop 7C92E508 > 55 push ebp 7C92E509 8BEC mov ebp, esp 7C92E50B 9C pushfd
代码:
0012FE7C 77D19418 返回到 USER32.77D19418 0012FE80 733AD756 返回到 MSVBVM60.733AD756 来自 USER32.WaitMessage 0012FE84 FFFFFFFF 0012FE88 03C2373C 0012FE8C 00000000 0012FE90 00020A9A 0012FE94 0000000F 0012FE98 00000000 0012FE9C 00000000 0012FEA0 014B4B57 0012FEA4 0000009E 0012FEA8 00000085 0012FEAC 03C20000 0012FEB0 00000000 0012FEB4 03C21E94 0012FEB8 /0012FEFC 0012FEBC |7339A627 返回到 MSVBVM60.7339A627 来自 MSVBVM60.7339A632 0012FEC0 |FFFFFFFF 0012FEC4 |03C23764 0012FEC8 |03C20000 0012FECC |03C2375C 0012FED0 |7339A5C9 返回到 MSVBVM60.7339A5C9 0012FED4 |03C2373C 0012FED8 |FFFFFFFF 0012FEDC |03C23834 0012FEE0 |03C2375C 0012FEE4 |FFFFFFFF 0012FEE8 |03C23834 0012FEEC |FFFFFFFF 0012FEF0 |000005CC 0012FEF4 |00000001 0012FEF8 |00000000 0012FEFC \733AA3B8 MSVBVM60.733AA3B8 0012FF00 7339A505 返回到 MSVBVM60.7339A505 来自 MSVBVM60.7339A51B 0012FF04 03C23834 0012FF08 FFFFFFFF 0012FF0C 000005CC 0012FF10 FFFFFFFF 0012FF14 FFFFFFFF 0012FF18 03C237FC 0012FF1C 7339A4D0 返回到 MSVBVM60.7339A4D0 0012FF20 03C23760 0012FF24 03C23834 0012FF28 FFFFFFFF 0012FF2C 000005CC 0012FF30 00000000 0012FF34 7349E470 MSVBVM60.7349E470 0012FF38 0012FFB8 0012FF3C 7FFDE000 0012FF40 73393644 返回到 MSVBVM60.73393644 来自 MSVBVM60.7339A4AA 0012FF44 FFFFFFFF 0012FF48 00000000 0012FF4C 00000010 0012FF50 7FFDE000 0012FF54 03C21FA4 0012FF58 00000044 0012FF5C 00154A48 0012FF60 00154C38 ASCII "WinSta0\Default" 0012FF64 00154C50 0012FF68 00000000 0012FF6C 00000000 0012FF70 00000000 0012FF74 00000000 0012FF78 00000000 0012FF7C 00000000 0012FF80 00000000 0012FF84 00000401 0012FF88 00000001 0012FF8C 00000000 0012FF90 00000000 0012FF94 00010001 0012FF98 00000000 0012FF9C 00000000 0012FFA0 0012FF48 0012FFA4 0012FFB0 0012FFA8 0012FFE0 指向下一个 SEH 记录的指针 0012FFAC 7347BAFD SE处理程序 0012FFB0 733A97D0 MSVBVM60.733A97D0 0012FFB4 00000000 0012FFB8 0012FFF0 0012FFBC 037CF5E1 返回到 037CF5E1 来自 MSVBVM60.ThunRTMain 0012FFC0 0045A0BC SVKP_.0045A0BC 0012FFC4 7C817067 返回到 kernel32.7C817067 0012FFC8 00000000 0012FFCC 00000010 0012FFD0 7FFDE000 0012FFD4 8054C6ED 0012FFD8 0012FFC8 0012FFDC 8523D538 0012FFE0 FFFFFFFF SEH 链尾部 0012FFE4 7C839AC0 SE处理程序 0012FFE8 7C817070 kernel32.7C817070 0012FFEC 00000000 0012FFF0 00000000 0012FFF4 00000000 0012FFF8 004B8000 offset SVKP_.<模块入口点> 0012FFFC 00000000
其实直接拉到最下面就能看到最熟悉的东西了……
代码:
0012FFC0 0045A0BC SVKP_.0045A0BC
在这一句上右键,反汇编窗口中跟随,这样就来到了程序的领空了
代码:
0045A0BC 56 push esi //返回到这里了 0045A0BD 42 inc edx 0045A0BE 35 21F01F76 xor eax, 761FF021 0045A0C3 6236 bound esi, qword ptr [esi] 0045A0C5 6368 73 arpl word ptr [eax+73], bp 0045A0C8 2E: prefix cs: 0045A0C9 64:6C ins byte ptr es:[edi], dx 0045A0CB 6C ins byte ptr es:[edi], dx 0045A0CC 0000 add byte ptr [eax], al 0045A0CE 0000 add byte ptr [eax], al 0045A0D0 2A00 sub al, byte ptr [eax] 0045A0D2 0000 add byte ptr [eax], al 0045A0D4 0000 add byte ptr [eax], al 0045A0D6 0000 add byte ptr [eax], al
代码:
0040111D BE 4500FF25 mov esi, 25FF0045 00401122 48 dec eax 00401123 1040 00 adc byte ptr [eax], al 00401126 - FF25 68104000 jmp dword ptr [401068] ; MSVBVM60.__vbaExceptHandler 0040112C - FF25 78104000 jmp dword ptr [401078] ; MSVBVM60.__vbaFPException 00401132 - FF25 38104000 jmp dword ptr [401038] ; MSVBVM60._adj_fdiv_m16i 00401138 - FF25 2C104000 jmp dword ptr [40102C] ; MSVBVM60._adj_fdiv_m32 0040113E - FF25 8C104000 jmp dword ptr [40108C] ; MSVBVM60._adj_fdiv_m32i 00401144 - FF25 18104000 jmp dword ptr [401018] ; MSVBVM60._adj_fdiv_m64 0040114A - FF25 A0104000 jmp dword ptr [4010A0] ; MSVBVM60._adj_fdiv_r 00401150 - FF25 40104000 jmp dword ptr [401040] ; MSVBVM60._adj_fdivr_m16i 00401156 - FF25 9C104000 jmp dword ptr [40109C] ; MSVBVM60._adj_fdivr_m32 0040115C - FF25 90104000 jmp dword ptr [401090] ; MSVBVM60._adj_fdivr_m32i 00401162 - FF25 70104000 jmp dword ptr [401070] ; MSVBVM60._adj_fdivr_m64 00401168 - FF25 58104000 jmp dword ptr [401058] ; MSVBVM60._adj_fpatan
代码:
0040123A - FF25 64104000 jmp dword ptr [401064] ; MSVBVM60.EVENT_SINK_QueryInterface 00401240 - FF25 4C104000 jmp dword ptr [40104C] ; MSVBVM60.EVENT_SINK_AddRef 00401246 - FF25 5C104000 jmp dword ptr [40105C] ; MSVBVM60.EVENT_SINK_Release 0040124C - FF25 A4104000 jmp dword ptr [4010A4] ; MSVBVM60.ThunRTMain //很熟悉的地方…… 00401252 0000 add byte ptr [eax], al 00401254 90 nop //SVKP抽代掉的代码总是喜欢用Nop命令代替,所以这里理所当然的入口点 00401255 90 nop 00401256 90 nop 00401257 90 nop 00401258 90 nop 00401259 90 nop 0040125A 90 nop 0040125B 90 nop 0040125C 90 nop 0040125D 90 nop 0040125E 0000 add byte ptr [eax], al 00401260 0000 add byte ptr [eax], al 00401262 0000 add byte ptr [eax], al 00401264 3000 xor byte ptr [eax], al 00401266 0000 add byte ptr [eax], al 00401268 3800 cmp byte ptr [eax], al 0040126A 0000 add byte ptr [eax], al 0040126C 0000 add byte ptr [eax], al 0040126E 0000 add byte ptr [eax], al
找到理所当然的入口点了,该要还原代码了……一共被抽掉2句代码,这第一句嘛,还记得上面找到的那个
代码:
0012FFC0 0045A0BC SVKP_.0045A0BC
汇编一下 Push 0045A0BC
第二句就是跳到上面去
代码:
0040124C - FF25 A4104000 jmp dword ptr [4010A4] ; MSVBVM60.ThunRTMain
二进制复制一份,以备用
68 BC A0 45 00 E8 EE FF FF FF
代码:
00401254 68 BCA04500 push 0045A0BC 00401259 E8 EEFFFFFF call 0040124C ; jmp 到 MSVBVM60.ThunRTMain
呃……到这里还有一步需要做,打开ImportREC然后附加到这个进程,OEP填00001254,然后自动查找IAT,获取输入表……这一步先做到这里……最小化吧,关了就不是我的错了……
下一步,重新载入,然后直接Alt+M打开内存镜像,在LPK这个地方的Text段下内存断点,就是F2一下,当然你要是能直接在程序的领空内下内存断点我也没意见……不过你得下得去……SVKP的驱动保护可不是吃白饭的……
代码:
Memory map, 条目 28 地址=62C21000 大小=00005000 (20480.) 属主=LPK 62C20000 区段=.text 包含=代码,输入表,输出表 类型=Imag 01001002 访问=R 初始访问=RWE
代码:
62C23D92 > 8BFF mov edi, edi //停在这里 62C23D94 55 push ebp 62C23D95 8BEC mov ebp, esp 62C23D97 FF75 08 push dword ptr [ebp+8] 62C23D9A FF15 4810C262 call dword ptr [<&GDI32.GetLayout>] ; GDI32.GetLayout 62C23DA0 8B4D 14 mov ecx, dword ptr [ebp+14] 62C23DA3 C1E9 08 shr ecx, 8 62C23DA6 33C1 xor eax, ecx 62C23DA8 A8 01 test al, 1 62C23DAA 75 78 jnz short 62C23E24 62C23DAC 803D C460C262 0>cmp byte ptr [62C260C4], 1 62C23DB3 75 6F jnz short 62C23E24 62C23DB5 837D 18 00 cmp dword ptr [ebp+18], 0 62C23DB9 75 58 jnz short 62C23E13 62C23DBB 8B4D 0C mov ecx, dword ptr [ebp+C] 62C23DBE 8B55 10 mov edx, dword ptr [ebp+10] 62C23DC1 32C0 xor al, al 62C23DC3 83C1 08 add ecx, 8 62C23DC6 4A dec edx 62C23DC7 56 push esi 62C23DC8 83FA 08 cmp edx, 8 62C23DCB 77 07 ja short 62C23DD4 62C23DCD FF2495 2A3EC262 jmp dword ptr [edx*4+62C23E2A] 62C23DD4 0A41 01 or al, byte ptr [ecx+1]
此时程序运行需要的所有代码已经强行解压完毕,当然除了抽取掉的代码……现在直接Ctrl+G来到上面找到的入口点:00401254
代码:
0040122E - FF25 24104000 jmp dword ptr [401024] ; MSVBVM60.733B5427 00401234 - FF25 54104000 jmp dword ptr [401054] ; MSVBVM60.734727C1 0040123A - FF25 64104000 jmp dword ptr [401064] ; MSVBVM60.7346677C 00401240 - FF25 4C104000 jmp dword ptr [40104C] ; MSVBVM60.733AD86F 00401246 - FF25 5C104000 jmp dword ptr [40105C] ; MSVBVM60.733BE385 0040124C - FF25 A4104000 jmp dword ptr [4010A4] ; MSVBVM60.7339DE3E 00401252 0000 add byte ptr [eax], al 00401254 90 nop ////到这里 00401255 90 nop 00401256 90 nop 00401257 90 nop 00401258 90 nop 00401259 90 nop 0040125A 90 nop 0040125B 90 nop 0040125C 90 nop 0040125D 90 nop
当然是SVKP对输入表的处理把他们搞成这个样子的……你就不用管那么多了,还原入口点的代码,剩下的交给ImportREC做就可以了……
直接还原入口点代码
代码:
00401240 - FF25 4C104000 jmp dword ptr [40104C] ; MSVBVM60.733AD86F 00401246 - FF25 5C104000 jmp dword ptr [40105C] ; MSVBVM60.733BE385 0040124C - FF25 A4104000 jmp dword ptr [4010A4] ; MSVBVM60.7339DE3E 00401252 0000 add byte ptr [eax], al 00401254 68 BCA04500 push 0045A0BC 00401259 E8 EEFFFFFF call 0040124C
为了不增加脱壳文件的大小,我们就把输入表写道程序已有的区段内……当然你要是RVA填1000,ImportREC肯定不买你的帐……那就加1000呗,反正都在Text段里……
不选中添加一个新的节RVA填2000然后修复转储文件修复好了……运行起来看看……挺正常的嘛…… ^_^
下面就是优化咯……下面有请CFF Explorer上场……载入脱壳后文件点到Section Headers 这边来……然后在.svkp这一节上右键,选择Delete Section(Header And Data)然后保存,直接运行……挺正常的……收工咯……
看看大小……736 KB跟加壳前程序一模一样……
--------------------------------------------------------------------------------
【经验总结】
看来SVKP对于VB程序的保护也是有心无力……竟然脱壳优化以后跟加壳前程序大小一模一样……
对于SVKP对VB程序的保护,只要记得这几点:运行,附加,返回,找FF 25,还原入口点,二进制备份入口点字节,
ImportREC,重新载入……下断点……还原入口点,Dumper,修复……优化……
这样一个由SVKP1.43加壳的VB程序就处理完成了……
不过一定要记得那个ImportREC在修复时一定不要关……还有就是如果RVA填2000ImportREC也不买你的帐……那就填3000,
以此类推……
呵呵……第一次写这么长的文章……还望大家多多指教。 ^_^
文章很长……感谢你看完……嘻嘻
附件里有加壳程序和脱壳优化后的程序
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2008年02月18日 14:34:04