【文章标题】: 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
  
  此乃入口……一看就是忽悠人来的,像ASPack的嘛……
  
  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
  
  
  停在这里了……当然你地址可能跟我的不一样……我SP3的……
  
  甭管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
  
  我指的当然是这一句……为什么呢?众所周知吧……VB一上来第一句就是Push ********某某某……Push的东西呢……当然就是一串字符串VB5!什么什么的,这个是VB运行库的版本……
  在这一句上右键,反汇编窗口中跟随,这样就来到了程序的领空了
  
代码:
  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
  
  
  虽然EIP还不在这里……然后下一步是找入口点,方法很简单,VB的入口点上面是什么?当然都是输入表了……所以到达这里以后呢……Ctrl+B搜索 FF 25,一下子就到这里了:
  
代码:
  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这个地址咯……
  
  汇编一下 Push  0045A0BC
  第二句就是跳到上面去
  
代码:
  0040124C  - FF25 A4104000   jmp     dword ptr [4010A4]               ; MSVBVM60.ThunRTMain 
  
  这里嘛,汇编一下 Call 0040124C
  
  二进制复制一份,以备用
  68 BC A0 45 00 E8 EE FF FF FF
  
  
代码:
  00401254    68 BCA04500     push    0045A0BC
  00401259    E8 EEFFFFFF     call    0040124C                         ; jmp 到 MSVBVM60.ThunRTMain
  
  
  这是还原后的入口……当然你要是想这样就Dumper出来那你的程序可是跑不起来的……为啥?我是菜鸟……这个问题我也不知道……
  呃……到这里还有一步需要做,打开ImportREC然后附加到这个进程,OEP填00001254,然后自动查找IAT,获取输入表……这一步先做到这里……最小化吧,关了就不是我的错了……
  
  
  下一步,重新载入,然后直接Alt+M打开内存镜像,在LPK这个地方的Text段下内存断点,就是F2一下,当然你要是能直接在程序的领空内下内存断点我也没意见……不过你得下得去……SVKP的驱动保护可不是吃白饭的……
  
代码:
  Memory map, 条目 28
   地址=62C21000
   大小=00005000 (20480.)
   属主=LPK      62C20000
   区段=.text
   包含=代码,输入表,输出表
   类型=Imag 01001002
   访问=R
   初始访问=RWE
  
  忽略所有异常,直接F9运行,Shift+F9 忽略队列边界
  
代码:
  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
  
  
  
  看起来挺熟悉的,这不就是刚才抽了代码的OEP嘛,可是上面那些东西咋回事?不是刚才都好好的嘛,怎么成这个样了?
  当然是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
  
  
  然后LordPE伺候……直接Dumper出来……剩下的问题就是要修复了……我刚才不是叫你开着ImportREC的嘛,如果你要是关了就不是我的问题了……
  为了不增加脱壳文件的大小,我们就把输入表写道程序已有的区段内……当然你要是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
上传的附件 SVKP_VB.rar [附件去原帖下载:http://bbs.pediy.com/showthread.php?t=59807]