吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 13230|回复: 25
收起左侧

[原创] NoobyProtect SE Demo 1.6.1.0 IAT加密初探

[复制链接]
yangjt 发表于 2009-8-15 12:01
本帖最后由 yangjt 于 2009-8-15 12:15 编辑

【文章标题】: NoobyProtect SE Demo 1.6.1.0 IAT加密初探
【文章作者】: yangjt
【作者邮箱】: yangjietao123@163.com
【作者QQ号】: 325002492
【下载地址】: 附件里
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  非常感谢这两天帮助过我的所有人……特别感谢下Nooby指点,还有HyperChem和Hmily的帮助
  
首先载入壳,Demo版可以来到VirtualProtect在那里的
E8 75FFFFFF     call    VirtualProtectEx处下断点,然后看堆栈,当堆栈变成这样的时候
0012FF48   FFFFFFFF  |hProcess = FFFFFFFF
0012FF4C   00401000  |Address = 复件_未?00401000
0012FF50   00004000  |Size = 4000 (16384.)
0012FF54   00000040  |NewProtect = PAGE_EXECUTE_READWRITE
0012FF58   0012FF84  \pOldProtect = 0012FF84

再按一遍F9,这个时候代码段就已经解码了。然后取消断点,来到00401000段……因为我们的目的只是分析IAT,所以找到入口对我们来说并没有太多的作用,Ctrl+B搜索E8 ?? ?? 0A 00搜索不到就更改0A的值,增加或减少,对于这个程序是这个
可以来到这个地方:
004010C7    000D 0A00002A   add     byte ptr [2A00000A], cl
004010CD    8BEC            mov     ebp, esp
004010CF    83EC 44         sub     esp, 44
004010D2    56              push    esi
004010D3    E8 E3BE0A00     call    004ACFBB;这就是被加密的API调用,可以搜索到这里,直接Enter进入
004010D8  ^ 7D 8B           jge     short 00401065
004010DA    F0:8A00         lock mov al, byte ptr [eax]
004010DD    3C 22           cmp     al, 22
004010DF    75 1B           jnz     short 004010FC
004010E1    56              push    esi
004010E2    E8 D6AF0A00     call    004AC0BD

;call来自004010D3:
004ACFBB    90              nop;直接在这里下断点,运行断下
004ACFBC    68 A448416D     push    6D4148A4                        ;IAT索引?后面用来储存所调用的API需要的地址
004ACFC1    9C              pushfd
004ACFC2    814424 04 341DA>add     dword ptr [esp+4], 74AB1D34        ;修改IAT索引为E1EC65D8
004ACEBA    60              pushad
004AC71C    E8 00000000     call    004AC721
004AC721    58              pop     eax
004AC722    81E8 79C386D7   sub     eax, D786C379                ;貌似是GetModuleHandleA的定位
004AC644   ?  E8 0D000000   call    004AC656
004AC649   .  6B 65 72 6E 6>ascii   "kernel32.dll",0
004AC656    FF90 CD8286D7   call    dword ptr [eax+D78682CD]         ; kernel32.GetModuleHandleA
004AC362    85C0            test    eax, eax                         ; kernel32.7C800000
004AC364  ^ 0F84 0CFDFFFF   je      004AC076                        ;不成功?就得到自己的句柄……Nooby说是为了支持插件
004AC01A      E8 10000000   call    004AC02F
004AC01F   .  47 65 74 43 6>ascii   "GetCommandLineA",0                ;其实这里已经看到API的名字了……
004ABFF8    50              push    eax                                ;下面的一坨代码是用来模拟GetProcAddress的…
004AC055    E8 B089F6FF     call    00414A0A
00414A0A    E8 F7A90600     call    0047F406
0047F406    50              push    eax
0047F40C    9C              pushfd
0047D183    E8 00000000     call    0047D188
0047D188    E9 902A0000     jmp     0047FC1D
0047FC1D    58              pop     eax
0047FC8B    81E8 81A56389   sub     eax, 8963A581
0047FC91    81C0 5AC66389   add     eax, 8963C65A                ;定位SEH异常处理流程
0047FC97    874424 04       xchg    dword ptr [esp+4], eax        ;充当SEH handler
0047FC9B    9D              popfd
0047FC9C    64:FF35 0000000>push    dword ptr fs:[0]
0047FC25    64:8925 0000000>mov     dword ptr fs:[0], esp        ;建立异常处理
0047D161    CC              int3                                ;邪恶的CC 9D
0047D162    9D              popfd                                ;Nooby说这里本来是用于猥琐OD的一个Bug,后来因为StrongOD,OD都不吃这套了

;异常类型,STATUS_BREAKPOINT
;到异常处理流程里看看去
0047F261    60              pushad;这里下int3断点
0047F262    8B45 08         mov     eax, dword ptr [ebp+8]        ;pEXCEPTION_RECORD
0047F265    EB 5F           jmp     short 0047F2C6                ;= =SEH处理过程也被猥琐了……
0047F2C6    8B4D 10         mov     ecx, dword ptr [ebp+10]        ;ecx:pContext
0047F270    8B00            mov     eax, dword ptr [eax]        ;eax = dwExceptionCode
0047F2D2    8061 18 F0      and     byte ptr [ecx+18], 0F0        ;iDr7清零
0047F27B    80E8 03         sub     al, 3
0047F2FC  ^\70 FA           jo      short 0047F2F8                ;这样可以用来判断异常类型,不是不处理,交给上一层SEH
0047F33F    8B99 C1000000   mov     ebx, dword ptr [ecx+C1]        ;ebx=Eflag+1
0047F450    80E3 01         and     bl, 1                        ;TF标志判断
0047F34A    3AC3            cmp     al, bl                        ;猥琐单步用
0047F429  ^\0F85 C9FEFFFF   jnz     0047F2F8                        ;做个标记了……免得下次再走进去……
0047F3B8    8381 B8000000 0>add     dword ptr [ecx+B8], 0D        ;计算返回位置,加13个字节
0047F3BF    8B81 B8000000   mov     eax, dword ptr [ecx+B8]        ;返回点 = 0047D16E
0047F3C5    0FB600          movzx   eax, byte ptr [eax]                ;返回点的第一个字节
0047F3C8    81C0 9F109961   add     eax, 6199109F
0047F391    81F8 6B119961   cmp     eax, 6199116B                ;判断是否是CC……跳转Demo里没有……
0047F3F0    61              popad
0047F3F1    C7C0 00000000   mov     eax, 0                        ;EXCEPTION_CONTINUE_EXECTION
0047F337    C2 1000         retn    10                                ;安全返回……

;从0047F2FC跳出来的分支
;死亡谷……
0047F2F8    61              popad
0047F331    C7C0 FFFFFFFF   mov     eax, -1                        ;EXCEPTION_CONTINUE_SEARCH
0047F337    C2 1000         retn    10

;返回后:
0047D16E   /E9 5F220000     jmp     0047F3D2
0047F3D2    64:8F05 0000000>pop     dword ptr fs:[0]                 ; 解除异常处理,其实可以跑到这个地方下Int3 断点,这样不会被SEH里的检测猥琐
0047F3FC    8D6424 08       lea     esp, dword ptr [esp+8]        ;平衡堆栈
0047F45A    55              push    ebp
0047F4FE    8BEC            mov     ebp, esp
0047F500    81EC 0C010000   sub     esp, 10C
0047F506    53              push    ebx
0047F507    8B5D 08         mov     ebx, dword ptr [ebp+8]        ;dll image base
0047F50A    85DB            test    ebx, ebx
0047F50C    56              push    esi                                ;什么玩艺?
0047F4E1    57              push    edi
0047F515   /74 1D           je      short 0047F534                ;不太可能出问题吧……
0047F738    8BCB            mov     ecx, ebx                    ;这里的代码猥琐程度终于降低了
0047F73A    33FF            xor     edi, edi
0047F73C    E8 F2D2FCFF     call    0044CA33;这里算是比较远的Call,跟进……
0047F741    8B48 7C         mov     ecx, dword ptr [eax+7C]
0047F744    8B70 78         mov     esi, dword ptr [eax+78]
0047F747    03F3            add     esi, ebx
0047F749    85C9            test    ecx, ecx


;call 来自0047F73C:
0044CA33    50              push    eax                              ; kernel32.7C800000
0044CA36    9C              pushfd
00449DE3    E8 00000000     call    00449DE8
00449DE8    E9 BD2C0000     jmp     0044CAAA
0044CAAA    58              pop     eax                              ; 复件_未?00449DE8
0044CAAB    81E8 6C21BA96   sub     eax, 96BA216C
0044CAB1    81C0 C24CBA96   add     eax, 96BA4CC2
0044CAB7    874424 04       xchg    dword ptr [esp+4], eax
0044CABB    9D              popfd
0044CABC    64:FF35 0000000>push    dword ptr fs:[0]
0044CB07    64:8925 0000000>mov     dword ptr fs:[0], esp
00449C38    CC              int3                                ;这个壳考验的是人的耐心……
00449C39    9D              popfd


;SEH
0044C93E    60              pushad
0044C9B8    8B45 08         mov     eax, dword ptr [ebp+8]
0044C9BB    8B4D 10         mov     ecx, dword ptr [ebp+10]
0044C9BE    8B00            mov     eax, dword ptr [eax]
0044C9C0    8061 18 F0      and     byte ptr [ecx+18], 0F0
0044C9C4    80E8 03         sub     al, 3
0044C9C7  ^ 0F80 78FFFFFF   jo      0044C945

;下面代码同上一个SEH……代码核心完全一样……只是猥琐程度不同……懒得分析了……


;返回
00449C3D   /E9 BA2D0000     jmp     0044C9FC
0044CA56    64:8F05 0000000>pop     dword ptr fs:[0]
0044CA26    8D6424 04       lea     esp, dword ptr [esp+4]
00413BC4    E8 3A1A0600     call    00475603
00413BC9    1ACA            sbb     cl, dl
00413BCB    53              push    ebx
00413BCC    C3              retn

;call来自00413BC4
;……接下来省略一些猥琐代码……= =还是老一套……

;返回到
00475062   /E9 2E050000     jmp     00475595
00475549    66:8139 4D5A    cmp     word ptr [ecx], 5A4D;终于到了激动人心的时刻……
004755B8  ^\74 B0           je      short 0047556A        ;是PE文件?
0047556A    8B41 3C         mov     eax, dword ptr [ecx+3C];e_lfanew
004755CD    03C1            add     eax, ecx                ;定位Signature PE
0047F741    8B48 7C         mov     ecx, dword ptr [eax+7C];size of Export Directory
0047F744    8B70 78         mov     esi, dword ptr [eax+78];RVA of Export Directory
0047F747    03F3            add     esi, ebx;VA of Export Directory
0047F749    85C9            test    ecx, ecx;有导出表吗?
0047F6F2    894D F8         mov     dword ptr [ebp-8], ecx;输出表大小保存
0047F6F5  ^\0F84 39FEFFFF   je      0047F534;没有还扯什么……
0047F6FB    3BF3            cmp     esi, ebx
0047F6BD  ^\0F86 71FEFFFF   jbe     0047F534;导出表怎么会在PE头前面?
0047F713    8B55 0C         mov     edx, dword ptr [ebp+C];哪个API?EDX=API名称
0047F6CD    81FA 00000100   cmp     edx, 10000;?
0047F762  ^\73 B4           jnb     short 0047F718;堆栈怎么会用那么多?
0047F718    8B46 20         mov     eax, dword ptr [esi+20];定位export name table
0047F7E0    8A0A            mov     cl, byte ptr [edx]
0047F84D    03C3            add     eax, ebx;VA of export name table
0047F84F    80F9 40         cmp     cl, 40;大于等于'@'?
0047F852    8945 FC         mov     dword ptr [ebp-4], eax
0047F855  ^ 7E 8E           jle     short 0047F7E5
0047F857    80F9 53         cmp     cl, 53;大于等于'S'?
0047F85A  ^ 7E D1           jle     short 0047F82D
0047F82D    217D 08         and     dword ptr [ebp+8], edi;清零?
0047F880    397E 18         cmp     dword ptr [esi+18], edi;NumberOfNames
0047F883  ^ 0F86 E6FEFFFF   jbe     0047F76F;不能是是负数或者0
0047F860    8B4D 08         mov     ecx, dword ptr [ebp+8];ecx=计数器
0047F958    8B0488          mov     eax, dword ptr [eax+ecx*4]
0047F894    03C3            add     eax, ebx;第N个export name
0047F896    E8 80D3FCFF     call    0044CC1B;不是这个函数吗?
0047F89B    85C0            test    eax, eax;返回1继续,返回0找到
0047F8B8   /74 1E           je      short 0047F8D8;是
0047F8BA   |EB 6D           jmp     short 0047F929;下一个
0047F929    FF45 08         inc     dword ptr [ebp+8]
0047F8FF    8B45 08         mov     eax, dword ptr [ebp+8]
0047F938    3B46 18         cmp     eax, dword ptr [esi+18]
0047F906  ^\72 83           jb      short 0047F88B
0047F88B    8B55 0C         mov     edx, dword ptr [ebp+C]
0047F88E    8B45 FC         mov     eax, dword ptr [ebp-4]
0047F860    8B4D 08         mov     ecx, dword ptr [ebp+8]
0047F958    8B0488          mov     eax, dword ptr [eax+ecx*4]
0047F894    03C3            add     eax, ebx
0047F896    E8 80D3FCFF     call    0044CC1B
0047F89B    85C0            test    eax, eax

;找到所需API的时候
0047F8D8    8B46 24         mov     eax, dword ptr [esi+24];AddressOfNameOrdinals
0047F90B    8B4D 08         mov     ecx, dword ptr [ebp+8]
0047F8E1    8D0448          lea     eax, dword ptr [eax+ecx*2]
0047F9B7    0FB70418        movzx   eax, word ptr [eax+ebx]
0047FB1F    8B4E 1C         mov     ecx, dword ptr [esi+1C];AddressOfFunctions
0047FB22    8D0481          lea     eax, dword ptr [ecx+eax*4]
0047F7B6    8B3C18          mov     edi, dword ptr [eax+ebx];RAV of func
0047FAA0    03FB            add     edi, ebx;VA
0047F76F    3BFE            cmp     edi, esi;这里的EDI就是需要的API                         ; kernel32.7C80262C
0047FAC9  ^\72 AF           jb      short 0047FA7A
0047FACB    8B45 F8         mov     eax, dword ptr [ebp-8]
0047FACE    03F0            add     esi, eax
0047FAD0    3BFE            cmp     edi, esi
0047FAD2  ^ 73 A6           jnb     short 0047FA7A
0047FA7A    8BC7            mov     eax, edi                         ; kernel32.GetCommandLineA
0047FC47    E8 51D7FCFF     call    0044D39D;后面省略N多猥琐代码
0044D059   /E9 6C030000     jmp     0044D3CA
004149D0    E8 70A50600     call    0047EF45;继续猥琐
0047D104   /E9 6E1D0000     jmp     0047EE77
0047EF33    E8 57A0F9FF     call    00418F8F;VM Check?
0047EF3C    C3              retn;直接在这里下断点吧……

0047FC4C  ^\E9 46FFFFFF     jmp     0047FB97
0047FB97    5F              pop     edi
0047FB98  ^ E9 E4FEFFFF     jmp     0047FA81
0047FA81    5E              pop     esi
0047FA82    E9 5C010000     jmp     0047FBE3
0047FBE3    5B              pop     ebx
0047FBE4    C9              leave
0047FBE5    C2 0800         retn    8
;返回以后的最后一段代码……光明就在眼前了……
004AC05A  ^\EB A3           jmp     short 004ABFFF
004ABFFF    E8 00000000     call    004AC004
004AC004    EB 30           jmp     short 004AC036
004AC036    59              pop     ecx                              ; 复件_未?004AC004
004AC037    E9 56010000     jmp     004AC192
004AC192    81E9 04C04A00   sub     ecx, 004AC004
004AC198    8981 BDCF4A00   mov     dword ptr [ecx+4ACFBD], eax
004AC19E    C781 C2CF4A00 F>mov     dword ptr [ecx+4ACFC2], 82444FF
004AC1A8  ^ EB BF           jmp     short 004AC169
004AC169    66:C781 C6CF4A0>mov     word ptr [ecx+4ACFC6], 0C39D
004AC088    0FB618          movzx   ebx, byte ptr [eax]      ;检测API开头的1个字节
004AC13E    81C3 58363566   add     ebx, 66353658
004AC0E2    81FB 24373566   cmp     ebx, 66353724      ;是CC吗?
004AC0E8    74 5C           je      short 004AC146      ;是就猥琐你
004AC0AC    894424 24       mov     dword ptr [esp+24], eax    ;不是就可以转到真正的API了……
004AC0B0    61              popad
004AC0B1    FF4424 08       inc     dword ptr [esp+8];返回地址修正
004AC0B5    90              nop
004AC0B6    9D              popfd
004AC0B7    C3              retn;光明了……
;啊!终于到站了……晕死我了……把我猥琐坏了……
004010D9    8BF0            mov     esi, eax
004010DB    8A00            mov     al, byte ptr [eax]
004010DD    3C 22           cmp     al, 22

返回,IAT分析告一段落……有一些地方有些疑问…欢迎大家指正错误……
--------------------------------------------------------------------------------
【经验总结】
  总结下:追踪NP的IAT加密的时候能用Int3断点尽量用……因为整个程序对硬件断点的猥琐很严格……
  我一开始以为要用GetProcAddress的……后来发现其实GetProcAddress他是自己实现的……具体步骤就是找到需要Dll的导
  出表,然后再挨个找……
  写个脚本吧……自己太菜……写不出来……0047F76F每次停在这一行就可以得到地址了,至于调用地址可以读堆栈,修正下
  就可以了……
  
  跟以前版本相比的区别……
  1.整个流程显得非常猥琐,Demo版本的不足也很容易看到……比较完了不给你跳……囧
  2.自己实现了GetProcAddress,这期间没有调用系统API。
  3.ZP和VMP的优点融合的非常融洽……搞得那个貌似VM_Check的函数进去直接跟晕了……所以这个函数的功能只是猜测……
  具体作用等待Nooby作解析
  4.那个貌似IAT索引的东西到底是什么?是为了后面函数返回所Push的一个随即值?程序里好像没有对他进行读取……等待
  Nooby作解析
  
  
  
  VM+乱续+SEH除了猥琐……还能怎么评价?

  
--------------------------------------------------------------------------------
【版权声明】: 转载请注明作者并保持文章的完整, 谢谢!

                                                       2009年08月15日 11:39:57

npse.rar

409.46 KB, 下载次数: 66, 下载积分: 吾爱币 -1 CB

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

小马甲 发表于 2009-8-15 14:37
太强了,做我的师傅把
wuhanqi 发表于 2009-8-15 15:14
Hmily 发表于 2009-8-15 16:29
 楼主| yangjt 发表于 2009-8-15 17:03
毅力很足,搞完了问一句,累吗?
Hmily 发表于 2009-8-15 16:29

还行……有点累……
shsww 发表于 2009-8-16 16:00
你也太强悍了吧!厉害
wyg5858 发表于 2009-8-16 17:24
毅力很足,搞完了问一句,累吗
小生我怕怕 发表于 2009-8-16 17:42
楼主好问彩,膜拜加学习~
ZeNiX 发表于 2009-8-17 08:45
注解寫得很不錯.
學習了
20010501 发表于 2009-8-17 20:01
给你加分支持
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-5-7 09:06

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表