Pespin v1.0外壳完全分析

类别:编程语言 点击:0 评论:0 推荐:
【目    标】: PeSpin 1.0主程序【工    具】:Olydbg1.1【任    务】:抓它的衣服个光光.哈哈【操作平台】:WINXP pro sp1 【作    者】:loveboom[DFCG][FCG][US]【相关链接】: http://pespin.w.interia.pl/(作者的官方站点)【简要说明】:不知不觉就过了这么久了,很久没写什么文章。看到别的朋友们在不断的进步,我都感觉自己是不是真的老了哦:-).写这篇文章也算是给大家中秋节的一个礼物吧,祝大家中秋快乐!身体健康!工作顺利!!【详细过程】:设置没什么特别,因为这次想稍微看细一点,所以是慢慢的来跟。打开全部的异常就行了。00410087 >  90              NOP                                      ; EP,壳入口,是垃圾代码,所以我直接nop掉它了00410088    90              NOP00410089    90              NOP0041008A    60              PUSHAD0041008B    E8 00000000     CALL 0041009000410090    8B1C24          MOV EBX,DWORD PTR SS:[ESP]               ; 这里就就是pop ebx00410093    83C3 12         ADD EBX,1200410096    812B E8B10600   SUB DWORD PTR DS:[EBX],6B1E8             ; 这里开始就动态改变代码0041009C    FE4B FD         DEC BYTE PTR DS:[EBX-3]0041009F    812C24 E02A4000 SUB DWORD PTR SS:[ESP],00402AE0004100A6    DC9E 83B17501   FCOMP QWORD PTR DS:[ESI+175B183]004100AC    90              NOP004100AD    8173 04 D77AF72>XOR DWORD PTR DS:[EBX+4],2FF77AD7        ; 又是动态生成代码004100B4    8173 19 770043B>XOR DWORD PTR DS:[EBX+19],B7430077004100BB    81C3 28000000   ADD EBX,28004100C1    F9              STC                                      ; 设置C标志004100C2    FFE3            JMP EBX004100C4    C9              LEAVE004100C5    C2 0800         RETN 8004100C8    90              NOP004100C9    90              NOP004100CA    72 01           JB SHORT 004100CD                        ; 其实就是jmp xxx,因为上面已经设置了C标志004100CC    90              NOP004100CD    5D              POP EBP004100CE    33C9            XOR ECX,ECX004100D0    41              INC ECX004100D1    E2 17           LOOPD SHORT 004100EA004100D3   /EB 07           JMP SHORT 004100DC004100D5   |90              NOP004100D6   |EB 01           JMP SHORT 004100D9004100D8   |90              NOP004100D9   |EB 0D           JMP SHORT 004100E8004100DB   |90              NOP004100DC   \E8 01000000     CALL 004100E2004100E1    90              NOP004100E2    5A              POP EDX004100E3    83EA 0B         SUB EDX,0B004100E6    FFE2            JMP EDX                                  ; 这个壳里好多这样的东西哦004100F1    8B95 D2424000   MOV EDX,DWORD PTR SS:[EBP+4042D2]        ; [EBP+4042D2]=4042d2+d5b0处存放的就是程序的IMGBASE004100F7    8B42 3C         MOV EAX,DWORD PTR DS:[EDX+3C]            ; 这里不就是取PE所以在的地方+3C004100FA    03C2            ADD EAX,EDX                              ; 相加后就是PE文件的开始处了004100FC    8985 DC424000   MOV DWORD PTR SS:[EBP+4042DC],EAX        ; PE文件开始处4000D0处入[EBP+4042DC]处00410102    EB 02           JMP SHORT 0041010600410104    90              NOP00410105    90              NOP00410106    F9              STC                                      ; 这里也是明显的变形jmp00410107    72 08           JB SHORT 0041011100410109    73 0E           JNB SHORT 004101190041010B    F9              STC0041010C    830424 17       ADD DWORD PTR SS:[ESP],1700410110    C3              RETN00410111    E8 04000000     CALL 0041011A00410116    90              NOP00410117    F5              CMC00410118    73 11           JNB SHORT 0041012B                       ; 又是一堆垃圾代码0041011A    EB 06           JMP SHORT 004101220041011C    90              NOP0041011D  ^ 72 ED           JB SHORT 0041010C0041011F    1F              POP DS                                   ; Modification of segment register00410120    EB 07           JMP SHORT 0041012900410122    F5              CMC                                      ; 这里也就是清除c标志,所以下面也不会跳(实际是取反)00410123    72 0E           JB SHORT 0041013300410125    F5              CMC                                      ; 再次取反,这次下面就会跳了00410126  ^ 72 F8           JB SHORT 0041012000410128    90              NOP00410129  ^ EB EC           JMP SHORT 004101170041012B    830424 07       ADD DWORD PTR SS:[ESP],70041012F    F5              CMC00410130    FF3424          PUSH DWORD PTR SS:[ESP]                  ; PESpin.0041011D00410133    C3              RETN 00410134    41              INC ECX00410135    C1E1 07         SHL ECX,700410138    8B0C01          MOV ECX,DWORD PTR DS:[ECX+EAX]           ; 取code段的start address0041013B    03CA            ADD ECX,EDX                              ; ecx就是保存CODE段的开始RVA……0041014E    8B59 10         MOV EBX,DWORD PTR DS:[ECX+10]00410151    03DA            ADD EBX,EDX00410153    8B1B            MOV EBX,DWORD PTR DS:[EBX]00410155    899D F0424000   MOV DWORD PTR SS:[EBP+4042F0],EBX        ; [EBP+4042F0]存放MessageBox的地址?0041015B    53              PUSH EBX0041015C    8F85 94414000   POP DWORD PTR SS:[EBP+404194]            ; [EBP+404194]存放MessageBox的地址?00410162    BB E1000000     MOV EBX,0E100410167    B9 8C0B0000     MOV ECX,0B8C                             ; 传入要解压的SIZE0041016C    8DBD 80434000   LEA EDI,DWORD PTR SS:[EBP+404380]00410172    4F              DEC EDI00410173    EB 01           JMP SHORT 0041017600410175    90              NOP00410176    301C39          XOR BYTE PTR DS:[ECX+EDI],BL             ; 从4124BB处开始解压大小为0b8c的代码,是向上解压00410179    FECB            DEC BL0041017B  ^ E2 F9           LOOPD SHORT 00410176……00410180    68 CB000000     PUSH 0CB00410185    59              POP ECX                                  ; mov ecx,0cb00410186    8DBD 404E4000   LEA EDI,DWORD PTR SS:[EBP+404E40]        ; 把刚才解压后的起始地址41192F传人EDI……0041019D    C00C39 02       ROR BYTE PTR DS:[ECX+EDI],2              ; 41192f+0CB=4124bb(上面的结束地址)处的值ror 2004101A1  ^ E2 FA           LOOPD SHORT 0041019D                     ; 这里再次从4124BB处解压大小为0CB的代码……004101A1  ^\E2 FA           LOOPD SHORT 0041019D                       ; 这里再次从4124BB处解压大小为0CB的代码004101A3    E8 02000000     CALL 004101AA                              ; 到这里还是只解压壳的部分代码004101A8    90              NOP004101A9    90              NOP004101AA    5A              POP EDX                                    ; mov edx,401A8004101AB    8D85 FD685600   LEA EAX,DWORD PTR SS:[EBP+5668FD]          ; [EBP+5668FD]=D5B0+5668FD=573EAD地址入eax中004101B1    BB 54130B00     MOV EBX,0B1354004101B6    D1E3            SHL EBX,1004101B8    2BC3            SUB EAX,EBX004101BA    FFE0            JMP EAX                                    ; PESpin.00411805……00411820    66:813F 4D5A    CMP WORD PTR DS:[EDI],5A4D                 ; 这里通过循环找kernel32.dll的KERNEL BASE(77e410000)00411825    75 11           JNZ SHORT 00411838                         ; 如果找到了就不跳00411827    0FB757 3C       MOVZX EDX,WORD PTR DS:[EDI+3C]0041182B    66:F7C2 00F8    TEST DX,0F800                              ; 比较KERBASE+3C处是不是0f80000411830    75 06           JNZ SHORT 00411838                         ; 如果不是就跳,这里没有跳00411832    3B7C3A 34       CMP EDI,DWORD PTR DS:[EDX+EDI+34]00411836    74 08           JE SHORT 00411840                          ; 这里再次判断KERNEL32.DLL的imgbase对不对00411838    81EF 00000100   SUB EDI,10000                              ; UNICODE "ALLUSERSPROFILE=D:\Documents and Settings\All Users"0041183E  ^ EB E0           JMP SHORT 0041182000411840    97              XCHG EAX,EDI                               ; 如果找到就把EAX和edi的值互换一下00411857    50              PUSH EAX                                   ; push KERNEL BASE00411858    8785 F4424000   XCHG DWORD PTR SS:[EBP+4042F4],EAX         ; 把KERNEL BASE保存到[EBP+4042F4]=4118A4处.0041185E    016C24 04       ADD DWORD PTR SS:[ESP+4],EBP00411862    8D85 FB9883EB   LEA EAX,DWORD PTR SS:[EBP+EB8398FB]00411868    8D80 BDAABC14   LEA EAX,DWORD PTR DS:[EAX+14BCAABD]        ; 4119680041186E    EB 01           JMP SHORT 0041187100411870    90              NOP00411871    FFD0            CALL EAX                                   ; 这里也就是CALL 411968,这里进去就是通过循环的方法来获取KERNEL32.DLL的输出表来找到所要用到的输出函数。我们进去看看:0041196E    8BF0            MOV ESI,EAX00411970    0340 3C         ADD EAX,DWORD PTR DS:[EAX+3C]            ; e_lfanew00411973    8B40 78         MOV EAX,DWORD PTR DS:[EAX+78]            ; RVA Export Table00411976    03C6            ADD EAX,ESI                              ; 输出表的位置的RVA=6D04000411978    FF70 20         PUSH DWORD PTR DS:[EAX+20]               ; 定位AddressofName=6DF200041197B    5B              POP EBX0041197C    03DE            ADD EBX,ESI0041197E    FF70 18         PUSH DWORD PTR DS:[EAX+18]               ; NumberofNames ==03AE00411981    8F85 46444000   POP DWORD PTR SS:[EBP+404446]            ; MOV [ebp+404446],03AE(4119F6)00411987    FF70 24         PUSH DWORD PTR DS:[EAX+24]               ; AddressOfNameOrdianls=6EDD80041198A    5A              POP EDX                                  ; mov edx,addressofnameordinals0041198B    03D6            ADD EDX,ESI                              ; 转换成VA0041198D    FF70 1C         PUSH DWORD PTR DS:[EAX+1C]               ; AddressOfFunctions=6D06800411990    59              POP ECX                                  ; mov ecx,AddressOfFunctions00411991    03CE            ADD ECX,ESI00411993    898D 36444000   MOV DWORD PTR SS:[EBP+404436],ECX        ; 保存AddressOfFunctions到[EBP+404436]处00411999    83EF 05         SUB EDI,50041199C    83C7 05         ADD EDI,50041199F    833F 00         CMP DWORD PTR DS:[EDI],0                 ; 如果取完了就跳004119A2    74 71           JE SHORT 00411A15004119A4    8A07            MOV AL,BYTE PTR DS:[EDI]004119A6    8885 1D444000   MOV BYTE PTR SS:[EBP+40441D],AL004119AC    FF77 01         PUSH DWORD PTR DS:[EDI+1]……004119C6    8B3B            MOV EDI,DWORD PTR DS:[EBX]               ; AddressOfNames保存到EDI中004119C8    03FE            ADD EDI,ESI……00411A00    5B              POP EBX00411A01    0BC0            OR EAX,EAX                               ; 判断取出的结果是为为空,如果为空就跳00411A03    74 12           JE SHORT 00411A1700411A05    EB 01           JMP SHORT 00411A0800411A07    90              NOP00411A08    8038 CC         CMP BYTE PTR DS:[EAX],0CC                ; 判断我们有没有在相关api处下cc断点00411A0B    75 03           JNZ SHORT 00411A1000411A0D    8028 00         SUB BYTE PTR DS:[EAX],0                  ; 如果发现你在相关的API处下断了,就把应该放的API地址给清000411A10    8947 01         MOV DWORD PTR DS:[EDI+1],EAX             ; 如果没有就从4118b4处开始写入相关的API00411A13  ^ EB 87           JMP SHORT 0041199C00411A15    0BC0            OR EAX,EAX00411A17    EB 01           JMP SHORT 00411A1A                       ; 取完后返回去了00411A19    90              NOP00411A1A    C3              RETN这里取了这么几个API:kernel32.LoadLibraryAkernel32.ExitProcesskernel32.GetProcAddresskernel32.VirtualProtectkernel32.CloseHandlekernel32.VirtualAllockernel32.VirtualFreekernel32.CreateFileAkernel32.ReadFilekernel32.GetTickCountkernel32.GetModuleHandleAkernel32.CreateThreadkernel32.Sleepkernel32.GetCurrentProcessIdkernel32.OpenProcesskernel32.TerminateProcesskernel32.GetFileSizekernel32.GetModuleFileNameA……00411F25    301F            XOR BYTE PTR DS:[EDI],BL                   ; 从4102C4处开始向下解压大小为421的代码00411F27    47              INC EDI00411F28  ^ E2 F1           LOOPD SHORT 00411F1B00411F2A    830424 05       ADD DWORD PTR SS:[ESP],500411F2E    C3              RETN                                       ; 解压后跳去解压后的地址4102c4……004102F7    53              PUSH EBX                                   ; 这里准备异常,EBX就是完全地方004102F8    50              PUSH EAX……00410301    B9 13000000     MOV ECX,1300410306    E8 00000000     CALL 0041030B0041030B    5F              POP EDI0041030C    83EF 0A         SUB EDI,0A0041030F    BE 54194100     MOV ESI,0041195400410314    F3:A4           REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]      ; 把411954处的代码复制13个到410301开始的地方…….00410334    5B              POP EBX                                  ; mov ebx,41033400410335    81C3 1E000000   ADD EBX,1E                               ; ebx=410334+1e0041033B    8DB5 502A4000   LEA ESI,DWORD PTR SS:[EBP+402A50]        ; mov esi,41000000410341    68 FF000000     PUSH 0FF00410346    56              PUSH ESI00410347    6A 00           PUSH 000410349    53              PUSH EBX                                 ; push 4103510041034A    FFA5 59434000   JMP DWORD PTR SS:[EBP+404359]            ; GetModuleFileNameA这里也就是:0012FF94   00410351  /CALL to GetModuleFileNameA0012FF98   00000000  |hModule = NULL0012FF9C   00410000  |PathBuffer = PESpin.004100000012FFA0   000000FF  \BufSize = FF (255.)410000处存放path,取出程序的完整路径和程序名,结果存放在410000处。00410358    81C3 22000000   ADD EBX,22                               ; 比较有意思壳调用API的都用这种方式,这里运算后的值就是等下要返回的地址0041035E    6A 00           PUSH 000410360    68 80000000     PUSH 8000410365    6A 03           PUSH 300410367    6A 00           PUSH 000410369    6A 01           PUSH 10041036B    68 00000080     PUSH 8000000000410370    56              PUSH ESI00410371    53              PUSH EBX00410372  - FFA5 27434000   JMP DWORD PTR SS:[EBP+404327]            ; CreateFileA我这里是这样的:0012FF84   00410378  /CALL to CreateFileA0012FF88   00410000  |FileName = "G:\ctools\加壳\PesPin1.0\PESpin.exe"0012FF8C   80000000  |Access = GENERIC_READ0012FF90   00000001  |ShareMode = FILE_SHARE_READ0012FF94   00000000  |pSecurity = NULL0012FF98   00000003  |Mode = OPEN_EXISTING0012FF9C   00000080  |Attributes = NORMAL0012FFA0   00000000  \hTemplateFile = NULL00410378    E8 01000000     CALL 0041037E0041037D    90              NOP0041037E    5A              POP EDX0041037F    81C2 1A000000   ADD EDX,1A                               ; 这里又来了,又是用这种方法来调用API00410385    8985 2C4F4000   MOV DWORD PTR SS:[EBP+404F2C],EAX        ; 把CreateFileA后返回的值传入[EBP+4042C]处0041038B    93              XCHG EAX,EBX0041038C    6A 00           PUSH 00041038E    53              PUSH EBX                                 ; push 文件的句柄0041038F    52              PUSH EDX                                 ; 这里是要返回的地址00410390  - FFA5 54434000   JMP DWORD PTR SS:[EBP+404354]            ; GetFileSize 0012FF98   00410397  /CALL to GetFileSize0012FF9C   00000038  |hFile = 00000038 (window)0012FFA0   00000000  \pFileSizeHigh = NULL 00410397    E8 01000000     CALL 0041039D0041039C    90              NOP0041039D    5A              POP EDX0041039E    81C2 23000000   ADD EDX,23                               ; CALL API后要返回的地址,4103bf004103A4    8BD8            MOV EBX,EAX                              ; 文件大小入EBX中004103A6    53              PUSH EBX004103A7    8F85 384F4000   POP DWORD PTR SS:[EBP+404F38]            ; 也就把文件大小B600存入[EBP+404F38]中004103AD    6A 04           PUSH 4004103AF    68 00300000     PUSH 3000004103B4    50              PUSH EAX004103B5    6A 00           PUSH 0004103B7    52              PUSH EDX004103B8    FFA5 1D434000   JMP DWORD PTR SS:[EBP+40431D]            ; 这里开始分配一个文件大小的空间 0012FF90   004103BF  /CALL to VirtualAlloc0012FF94   00000000  |Address = NULL0012FF98   0000B600  |Size = B600 (46592.)0012FF9C   00003000  |AllocationType = MEM_COMMIT|MEM_RESERVE0012FFA0   00000004  \Protect = PAGE_READWRITE申请返回的地址是:003E0000.004103BF    50              PUSH EAX004103C0    8F85 D8424000   POP DWORD PTR SS:[EBP+4042D8]            ; [EBP+4042D8]处保存申请后的地址003E0000004103C6    8D8D 384F4000   LEA ECX,DWORD PTR SS:[EBP+404F38]        ; 把文件大小的地址传入ecx中004103CC    E8 01000000     CALL 004103D2004103D1    90              NOP004103D2    5A              POP EDX004103D3    81C2 1C000000   ADD EDX,1C                               ; CALL API后要返回的地址4103ED004103D9    6A 00           PUSH 0                                   ; 这里开始通过ReadFile把文件读入刚才申请的地址003e0000处004103DB    51              PUSH ECX004103DC    53              PUSH EBX004103DD    50              PUSH EAX004103DE    FFB5 2C4F4000   PUSH DWORD PTR SS:[EBP+404F2C]004103E4    52              PUSH EDX004103E5    FFA5 2C434000   JMP DWORD PTR SS:[EBP+40432C]            ; ReadFile 004103ED    E8 01000000     CALL 004103F3004103F2    90              NOP004103F3    5A              POP EDX004103F4    81C2 16000000   ADD EDX,16004103FA    FFB5 2C4F4000   PUSH DWORD PTR SS:[EBP+404F2C]           ; push文件号00410400    52              PUSH EDX                                 ; push要返回的地址41040800410401  - FFA5 18434000   JMP DWORD PTR SS:[EBP+404318]            ; 操作完成就CloseHandle了00410407    90              NOP00410408    FFB5 384F4000   PUSH DWORD PTR SS:[EBP+404F38]            ; 文件大小入ecx了0041040E    59              POP ECX0041040F    81E9 111B0000   SUB ECX,1B11                              ; 用文件大小b600-1b11=9AEF00410415    8DBD D8424000   LEA EDI,DWORD PTR SS:[EBP+4042D8]0041041B    8B3F            MOV EDI,DWORD PTR DS:[EDI]                ; 申请的地址3E0000入edi中0041041D    8D85 0B616038   LEA EAX,DWORD PTR SS:[EBP+3860610B]00410423    0BC0            OR EAX,EAX00410425    75 19           JNZ SHORT 00410440                        ; 这里实际也是一个jmp来的00410447    2985 404F4000   SUB DWORD PTR SS:[EBP+404F40],EAX         ; 保存hash值58873d42?? [EBP+404F40]= 58873d420041044D    E8 01000000     CALL 0041045300410452    90              NOP00410453    5A              POP EDX00410454    81C2 1C000000   ADD EDX,1C0041045A    68 00800000     PUSH 80000041045F    6A 00           PUSH 000410461    FFB5 D8424000   PUSH DWORD PTR SS:[EBP+4042D8]            ; push 003E000000410467    52              PUSH EDX                                  ; push返回地址41046E00410468    FFA5 22434000   JMP DWORD PTR SS:[EBP+404322]             ; 这里释放刚才申请的空间003E00000041046E    BB 380D581C     MOV EBX,1C580D38                          ; 前的取出文件操作的只是为了得到一个hash值??……00410492    64:8920         MOV DWORD PTR FS:[EAX],ESP               ; 有意思,这里的异常,是通过call的那个esp值+ebp的00410495    C1EB 02         SHR EBX,2                                ; 上面其实就是设置 SEH句柄为4104ba…….004104BA    8B4424 04       MOV EAX,DWORD PTR SS:[ESP+4]             ; 这里几个是什么作用我也不知道;-(004104BE    8B4C24 0C       MOV ECX,DWORD PTR SS:[ESP+C]004104C2    8B00            MOV EAX,DWORD PTR DS:[EAX]004104C4    35 5B011238     XOR EAX,3812015B004104C9    3D 5E0112F8     CMP EAX,F812015E004104CE    75 0F           JNZ SHORT 004104DF                       ; 这里不相等004104D0    8181 B8000000 B>ADD DWORD PTR DS:[ECX+B8],18BF004104DA    EB 27           JMP SHORT 00410503004104DC    EB 01           JMP SHORT 004104DF004104DE    90              NOP004104DF    3D 460112F8     CMP EAX,F8120146                         ; EAX==F81201CF004104E4    75 0C           JNZ SHORT 004104F2004104E6    8181 B8000000 7>ADD DWORD PTR DS:[ECX+B8],172004104F0    EB 11           JMP SHORT 00410503004104F2    3D CF0112F8     CMP EAX,F81201CF004104F7    75 0A           JNZ SHORT 00410503004104F9    8181 B8000000 9>ADD DWORD PTR DS:[ECX+B8],149000410503    33C0            XOR EAX,EAX00410505    C3              RETN这里再回到411931处……00411942    803B CC         CMP BYTE PTR DS:[EBX],0CC                ; 这里判断4104a4处有没有下断点00411945    75 0B           JNZ SHORT 00411952                       ; 如果没有就跳00411947    81E4 FFFF0000   AND ESP,0FFFF0041194D    E8 1A000000     CALL 0041196C00411952  ^ FFE3            JMP EBX                                  ; 跳回去继续执行……00410549    90              NOP0041054A    51              PUSH ECX                                 ; push要解压的section值,ECX==40041054B    0FA3C3          BT EBX,EAX                               ; 如果ebx内容为空就c标志为0,否则CF=1,我们这里EBX=70041054E    73 24           JNB SHORT 00410574                       ; 如果段不需要解压就跳00410550    52              PUSH EDX                                 ; 这里开始解压各个section的数据00410551    8B7A 0C         MOV EDI,DWORD PTR DS:[EDX+C]             ; 第一次的结果:00410554    03BD D2424000   ADD EDI,DWORD PTR SS:[EBP+4042D2]        ; 传入要写起始的地址4010000041055A    8B4A 10         MOV ECX,DWORD PTR DS:[EDX+10]            ; 传入要写的代码SIZE==5200也就是解压.text段的大小0041055D    8B95 404F4000   MOV EDX,DWORD PTR SS:[EBP+404F40]        ; 这里取出上面hash的值,传入edx中00410563    D1EA            SHR EDX,100410565    72 06           JB SHORT 0041056D00410567    81F2 32AF43ED   XOR EDX,ED43AF320041056D    3017            XOR BYTE PTR DS:[EDI],DL0041056F    47              INC EDI00410570    49              DEC ECX00410571  ^ E2 F0           LOOPD SHORT 00410563                     ; 这里循环进行解压代码00410573    5A              POP EDX                                  ; 如果解压到前一个section,的话,就指向下一个section00410574    40              INC EAX00410575    83C2 28         ADD EDX,2800410578    59              POP ECX00410579    EB 01           JMP SHORT 0041057C0041057B    40              INC EAX0041057C  ^ E2 CC           LOOPD SHORT 0041054A                     ; 这时循环回去0041057E    838D 3A4E4000 0>OR DWORD PTR SS:[EBP+404E3A],000410585    74 0D           JE SHORT 0041059400410587    8D85 DA4B4000   LEA EAX,DWORD PTR SS:[EBP+404BDA]0041058D    2D D1030000     SUB EAX,3D100410592    FFD0            CALL EAX00410594    68 19010000     PUSH 11900410599    59              POP ECX0041059A    8DBD BC4A4000   LEA EDI,DWORD PTR SS:[EBP+404ABC]        ; 从41206c处解压大小为119的代码004105A0    BA E9909E01     MOV EDX,19E90E9004105A5    D1EA            SHR EDX,1004105A7    73 06           JNB SHORT 004105AF004105A9    81F2 32AF43ED   XOR EDX,ED43AF32004105AF    3017            XOR BYTE PTR DS:[EDI],DL004105B1    47              INC EDI                                  ; PESpin.00412070004105B2  ^ E2 F1           LOOPD SHORT 004105A5                     ; 如果没有解压完成就跳回去解压004105B4    8D85 5C888D65   LEA EAX,DWORD PTR SS:[EBP+658D885C]……004105BF    D1E3            SHL EBX,1004105C1    2BC3            SUB EAX,EBX004105C3    50              PUSH EAX                                 ; 跳去已经解压的地方41206c004105C4    C3              RETN……0041206C   /EB 01           JMP SHORT 0041206F                       ; 解压一段运行一段0041206E   |90              NOP0041206F   \8DBD 15304000   LEA EDI,DWORD PTR SS:[EBP+403015]        ; 又要解压代码了,开始解压地址4105c500412075    B9 20010000     MOV ECX,120                              ; 要解压的代码大小为120……004120A4   /EB 01           JMP SHORT 004120A7004120A6   |90              NOP004120A7   \0AC0            OR AL,AL004120A9    AA              STOS BYTE PTR ES:[EDI]004120AA  ^ E2 D7           LOOPD SHORT 00412083                     ; 感觉这里自己像是yoda's cryptor解压完后进入第三个异常.…….00412132    64:8923         MOV DWORD PTR FS:[EBX],ESP00412135    FB              STI                                      ; 到了第三个异常……004120AA  ^\E2 D7           LOOPD SHORT 00412083                     ; 感觉这里自己像是yoda's cryptor004120AC    55              PUSH EBP004120AD    9C              PUSHFD004120AE    E8 77000000     CALL 0041212A004120B3    90              NOP004120B4    8B5424 08       MOV EDX,DWORD PTR SS:[ESP+8]             ; 直接在这里下断就行了004120B4    8B5424 08       MOV EDX,DWORD PTR SS:[ESP+8]             ; 直接在这里下断就行了004120B8    8B4424 0C       MOV EAX,DWORD PTR SS:[ESP+C]004120BC    8142 04 3500000>ADD DWORD PTR DS:[EDX+4],35              ; 注意这里,作者的异常都用这一招的,在目标地址里的那个值处下断004120C3    81CA 29242123   OR EDX,23212429004120C9    2BC9            SUB ECX,ECX004120CB    2148 04         AND DWORD PTR DS:[EAX+4],ECX             ; 清除断点004120CE    2148 08         AND DWORD PTR DS:[EAX+8],ECX004120D1    2148 0C         AND DWORD PTR DS:[EAX+C],ECX004120D4    2148 10         AND DWORD PTR DS:[EAX+10],ECX004120D7    8160 14 F00FFFF>AND DWORD PTR DS:[EAX+14],FFFF0FF0004120DE    C740 18 5501000>MOV DWORD PTR DS:[EAX+18],155004120E5    33C0            XOR EAX,EAX004120E7    C3              RETN……004120E9    8B5424 08       MOV EDX,DWORD PTR SS:[ESP+8]004120ED    8142 04 1B00000>ADD DWORD PTR DS:[EDX+4],1B              ; 这里又异常了,看来作者也等不及了,哈哈004120F4    EB 01           JMP SHORT 004120F7……00412142    8DBD 35314000   LEA EDI,DWORD PTR SS:[EBP+403135]        ; EDI=4106E500412148    B9 240C0000     MOV ECX,0C24                             ; 又准备从4106E5处解压代码,大小为0C24……0041217C    AA              STOS BYTE PTR ES:[EDI]0041217D  ^ E2 D7           LOOPD SHORT 00412156                     ; 如果没有解压完就跳回去……004105E1    68 07000000     PUSH 7004105E6    5B              POP EBX                                  ; mov ebx,7……004105E7    25 25382C37     AND EAX,372C3825又回来解密一层00411D55    64:8923         MOV DWORD PTR FS:[EBX],ESP00411D58    83E0 00         AND EAX,000411D5B    64:3343 30      XOR EAX,DWORD PTR FS:[EBX+30]            ; 晕哦,作者这里连来几个异常一堆垃圾过后到第七个异常处……004104CE   /75 0F           JNZ SHORT 004104DF                       ; 这里不相等004104D0   |8181 B8000000 B>ADD DWORD PTR DS:[ECX+B8],18BF           ; 这里再次改东西记住改后的地址,然后在那个地址处下断:00411F81    2BC0            SUB EAX,EAX00411F83    90              NOP00411F84    90              NOP00411F85    90              NOP00411F86    90              NOP00411F87    90              NOP00411F88    90              NOP00411F89    90              NOP00411F8A    90              NOP00411F8B    90              NOP00411F8C    64:8F00         POP DWORD PTR FS:[EAX]00411F8F    58              POP EAX00411F90    5D              POP EBP00411F91    8D85 35314000   LEA EAX,DWORD PTR SS:[EBP+403135]        ; mov EAX,4106E500411F97    68 240C0000     PUSH 0C2400411F9C    59              POP ECX                                  ; mov ECX,0C2400411F9D    68 9952B30E     PUSH 0EB3529900411FA2    5A              POP EDX00411FA3    D1EA            SHR EDX,100411FA5    73 06           JNB SHORT 00411FAD00411FA7    81F2 32AF43ED   XOR EDX,ED43AF32                         ; 从4106E5 处解压代码大小为0c2400411FAD    3010            XOR BYTE PTR DS:[EAX],DL                 ; 这里又解压一层代码,tnnd压的还真多00411FAF    40              INC EAX00411FB0  ^ E2 F1           LOOPD SHORT 00411FA300411FB2    2D 240C0000     SUB EAX,0C2400411FB7    FFE0            JMP EAX                                  ; 解压完后跳回去执行解压后的代码现在我会可以总结一下,在第七次异常后按CTRL+S找SUB EAX,0C24JMP EAX处下断就是了.……下慢慢跟,注意,过那jmp eax后就不要去除垃圾代码了,要不会异常的.004122D6    B9 522D0000     MOV ECX,2D52                             ; 传入将要VirutalAlloc的size 2D52004122DB    8BD1            MOV EDX,ECX004122DD    EB 07           JMP SHORT 004122E6004122FA    96              XCHG EAX,ESI                             ; 分配出来的空间就是3E0000,把分配好的地址入esi中004122FB    5A              POP EDX                                  ; 把要分配的大小2d52入edx中004122FC    BF F0D30000     MOV EDI,0D3F000412301    81C7 00004000   ADD EDI,0040000000412307    56              PUSH ESI                                 ; push 3E000000412308    57              PUSH EDI                                 ; push 40D3F000412309    E8 83E7FFFF     CALL 00410A91                            ; 解压代码到刚才分配的空间里,这就是真正的Depack了,aplib v0.36的解压代码.0041230E    91              XCHG EAX,ECX                             ; 把解压的大小传入ecx,用于下面的复制代码0041230F    F3:A4           REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[>00412311    5F              POP EDI                                  ; 操作完毕还原edi和esi的值00412312    5E              POP ESI00412313    EB 01           JMP SHORT 0041231600412315    90              NOP00412316    68 00400000     PUSH 40000041231B    52              PUSH EDX0041231C    56              PUSH ESI0041231D    FF95 22434000   CALL DWORD PTR SS:[EBP+404322]           ; 解压代码完毕后,再次释放刚申请的空间00412323    EB 01           JMP SHORT 0041232600412325    90              NOP  00412335    8338 00         CMP DWORD PTR DS:[EAX],0                 ; 判断412370里面有没有东西,没有就跳00412338    0F84 95000000   JE 004123D30041233E    B9 C09D0000     MOV ECX,9DC0                             ; push size 9dc000412343    6A 04           PUSH 400412345    68 00300000     PUSH 30000041234A    51              PUSH ECX0041234B    6A 00           PUSH 0                                   ; 准备再次申请空间0041234D    FF95 1D434000   CALL DWORD PTR SS:[EBP+40431D]           ; VirtualAlloc 0012FF8C   00412353  /CALL to VirtualAlloc from PESpin.0041234D0012FF90   00000000  |Address = NULL0012FF94   00009DC0  |Size = 9DC0 (40384.)0012FF98   00003000  |AllocationType = MEM_COMMIT|MEM_RESERVE0012FF9C   00000004  \Protect = PAGE_READWRITE……0041238A    03BD D2424000   ADD EDI,DWORD PTR SS:[EBP+4042D2]        ; 晕哦,又脱一层马甲:-)00412390    BE 00009000     MOV ESI,90000000412395    56              PUSH ESI00412396    57              PUSH EDI00412397    E8 F5E6FFFF     CALL 00410A91                            ; 这里又进行apLib解压代码.004123B6    8B8D 8F4D4000   MOV ECX,DWORD PTR SS:[EBP+404D8F]        ; 解压完毕,再次释放刚才的空间900000004123BC    8B85 E14D4000   MOV EAX,DWORD PTR SS:[EBP+404DE1]004123C2    0BC0            OR EAX,EAX004123C4    74 0D           JE SHORT 004123D3004123C6    68 00400000     PUSH 4000004123CB    51              PUSH ECX                                 ; push size004123CC    56              PUSH ESI                                 ; push address004123CD    FF95 22434000   CALL DWORD PTR SS:[EBP+404322]           ; kernel32.VirtualFree……0012FF90   004123D3  /CALL to VirtualFree from PESpin.004123CD0012FF94   00900000  |Address = 009000000012FF98   00009DC0  |Size = 9DC0 (40384.)0012FF9C   00004000  \FreeType = MEM_DECOMMIT……0012FF88   00411C71  /CALL to VirtualProtect from PESpin.00411C6E0012FF8C   004001C8  |Address = PESpin.004001C80012FF90   0000025C  |Size = 25C (604.)0012FF94   00000040  |NewProtect = PAGE_EXECUTE_READWRITE0012FF98   004124D8  \pOldProtect = PESpin.004124D8通过VirtualProtect来把段改为可以读写执行的属性.00411C9D    C643 02 C3      MOV BYTE PTR DS:[EBX+2],0C300411CA1    53              PUSH EBX再小心一点到最后一个异常:0012FF94   0012FFE0  Pointer to next SEH record0012FF98   00411CD6  SE handler在411cd6处下断:00411CD6    2BDB            SUB EBX,EBX00411CD8    8B6424 08       MOV ESP,DWORD PTR SS:[ESP+8]00411CDC    64:8F03         POP DWORD PTR FS:[EBX]……00411D0F    B9 2E000000     MOV ECX,2E00411D14    FF1401          CALL DWORD PTR DS:[ECX+EAX]              ; 这里用GetTickCount不知道起什么作用来的00411D23    59              POP ECX                                  ; mov ECX,8700411D24    66:35 4C50      XOR AX,504C00411D28    66:05 8911      ADD AX,118900411D2C    AA              STOS BYTE PTR ES:[EDI]                   ; 到了这里还要解压代码……00410D3A    8000 81         ADD BYTE PTR DS:[EAX],8100410D3D    E9 0F000000     JMP 00410D51                             ; 如果加壳时选择了检测测试器的话,这里会跳去一个int3处00410D42    C9              LEAVE00410D43    E8 76000000     CALL 00410DBE00410D48    0BC0            OR EAX,EAX                               ; PesPin到现在还不检测OD的存在,不知道为什么00410D4A  ^ 74 ED           JE SHORT 00410D39                        ; 只是用了两个int3来检测SICE而已00410D4C  - E9 7217FF35     JMP 364024C300410D51    EB 01           JMP SHORT 00410D54                       ; 加了或没加检测调试器都一定会来这里的.00410D53    90              NOP……00410D54    68 B95734E1     PUSH E13457B9                            ; 这里作者还要来骗一下我们00410D59    EB 01           JMP SHORT 00410D5C00410D5B    90              NOP00410D5C    59              POP ECX                                  ; 这里mov ECX,E134578900410D5D    90              NOP……00410D6E    81E9 B95734E1   SUB ECX,E13457B9                         ; 这里又减回去,不就是白做了嘛.00410D74    0BC9            OR ECX,ECX00410D76    EB 01           JMP SHORT 00410D79……00410D79    9C              PUSHFD00410D7A    C12C24 06       SHR DWORD PTR SS:[ESP],600410D7E    832424 01       AND DWORD PTR SS:[ESP],100410D82    50              PUSH EAX00410D83    52              PUSH EDX00410D84    B8 066F7579     MOV EAX,79756F0600410D89    05 51918A86     ADD EAX,868A915100410D8E    F76424 08       MUL DWORD PTR SS:[ESP+8]                 ; 又是垃圾代码来的00410D92    8D8428 F9374000 LEA EAX,DWORD PTR DS:[EAX+EBP+4037F9]00410D99    894424 08       MOV DWORD PTR SS:[ESP+8],EAX00410D9D    5A              POP EDX00410D9E    58              POP EAX00410D9F    8D6424 04       LEA ESP,DWORD PTR SS:[ESP+4]             ; 这里我就有点搞不懂了,直接用jmp [esp]不行吗?最多后面加一个add esp,400410DA3    FF6424 FC       JMP DWORD PTR SS:[ESP-4]                 ; 这不是浪费代码吗?……00410E09   .  F685 3E4E4000 0>TEST BYTE PTR SS:[EBP+404E3E],100410E10   .  74 40           JE SHORT 00410E5200410E12   .  BB 3C080000     MOV EBX,83C00410E17   .  0BDB            OR EBX,EBX                                                  ;如果是VB的程序的话,壳就是mov ebx,0了00410E19   .  74 37           JE SHORT 00410E52                        ;  这里就是jmp来的,因为上面赋值了,所以这里不可能跳的00410E1B   .  2BC0            SUB EAX,EAX                              ;  eax清000410E1D   .  2185 E0424000   AND DWORD PTR SS:[EBP+4042E0],EAX00410E23   .  E8 01000000     CALL 00410E2900410E28   .  90              NOP00410E29   $  59              POP ECX                                  ;  MOV ECX,410E2800410E2A   .  6A 40           PUSH 4000410E2C   .  68 00300000     PUSH 300000410E31   .  53              PUSH EBX                                 ;  PUSH SIZE 83C00410E32   .  50              PUSH EAX00410E33   .  8D6424 FC       LEA ESP,DWORD PTR SS:[ESP-4]00410E37   .  81C1 23000000   ADD ECX,2300410E3D   .  890C24          MOV DWORD PTR SS:[ESP],ECX               ;  PUSH ECX,也就是push 要返回的地址00410E40   .- FFA5 1D434000   JMP DWORD PTR SS:[EBP+40431D]            ;  VirtualAlloc申请一个内存空间 0012FF90   00410E4B  /CALL to VirtualAlloc0012FF94   00000000  |Address = NULL0012FF98   0000083C  |Size = 83C (2108.)0012FF9C   00003000  |AllocationType = MEM_COMMIT|MEM_RESERVE0012FFA0   00000040  \Protect = PAGE_EXECUTE_READWRITE……00410E4B      50              PUSH EAX                                 ;  申请到的空间900000入栈00410E4C      8F85 D8424000   POP DWORD PTR SS:[EBP+4042D8]            ;  MOV [EBP+4042D8],90000000410E52      90              NOP                                      ;  MOV 410E19,900000……00410E66   .  E8 01000000     CALL 00410E6C00410E6B   .  90              NOP00410E6C   $  83C4 04         ADD ESP,400410E6F   .  8BB5 393B4000   MOV ESI,DWORD PTR SS:[EBP+403B39]        ;  输入表RVA起始地址00410E75   .  03B5 D2424000   ADD ESI,DWORD PTR SS:[EBP+4042D2]        ;  转换为VA==40A16000410E7B   .  90              NOP……00410E8C   .  3BB5 D2424000   CMP ESI,DWORD PTR SS:[EBP+4042D2]        ;  判断输入表的起始地址和ImageBase是否相等00410E92   .  90              NOP00410E93   .  90              NOP00410E94   .  90              NOP00410E9E   .  75 0F           JNZ SHORT 00410EAF                       ;  如果不相等则跳00410EA0   .  90              NOP00410EAF   >  817E 10 C8FB000>CMP DWORD PTR DS:[ESI+10],0FBC8          ;  比较ThunkRVA(A028)是否为0FBC800410EB6   . |9C              PUSHFD00410EB7   . |EB 01           JMP SHORT 00410EBA00410EB9     |90              NOP00410EBA   > |C12C24 06       SHR DWORD PTR SS:[ESP],600410EBE   . |832424 01       AND DWORD PTR SS:[ESP],100410EC2   . |50              PUSH EAX                                 ;  保护好EAX00410EC3   . |52              PUSH EDX00410EC4   . |B8 9C7791BE     MOV EAX,BE91779C00410EC9   . |05 798A6E41     ADD EAX,416E8A7900410ECE   . |F76424 08       MUL DWORD PTR SS:[ESP+8]00410ED2   . |8D8428 38394000 LEA EAX,DWORD PTR DS:[EAX+EBP+403938]00410ED9   . |894424 08       MOV DWORD PTR SS:[ESP+8],EAX             ;  将要跳去的地方410EE800410EDD   . |5A              POP EDX00410EDE   . |58              POP EAX                                  ;  还原现场00410EDF      8D6424 04       LEA ESP,DWORD PTR SS:[ESP+4]             ;  又来让我们的CPU加负担了:-)00410EE3   .  FF6424 FC       JMP DWORD PTR SS:[ESP-4]                 ;  jmp 410EE800410EE7      90              NOP00410EE8   .  8B5E 0C         MOV EBX,DWORD PTR DS:[ESI+C]             ;  定位输入表的NAME==A4C400410EEB   .  039D D2424000   ADD EBX,DWORD PTR SS:[EBP+4042D2]        ;  转换成VA==40A4C400410EF1   .  8BFB            MOV EDI,EBX                              ;  把Name入EDI中00410EF3   .  E8 6B0F0000     CALL 00411E63                            ;  取出NAME来,我们可以进去看看00411E63  /$  57              PUSH EDI                                 ;  保护 EDI(Name的值)00411E64  |>  800F 00         /OR BYTE PTR DS:[EDI],0                  ;  如果取完了Name就返回00411E67  |.  74 16           |JE SHORT 00411E7F00411E69  |.  90              |NOP00411E6A  |.  90              |NOP00411E6B  |.  90              |NOP00411E6C  |.  90              |NOP00411E6D  |.  90              |NOP00411E6E  |.  90              |NOP00411E6F  |.  90              |NOP00411E70  |.  90              |NOP00411E71  |.  90              |NOP00411E72  |.  90              |NOP00411E73  |.  90              |NOP00411E74  |.  90              |NOP00411E75  |.  90              |NOP00411E76  |.  90              |NOP00411E77  |.  90              |NOP00411E78  |.  90              |NOP00411E79  |.  90              |NOP00411E7A  |.  F617            |NOT BYTE PTR DS:[EDI]                   ;  NAMAE就是通过取反来还原NAME00411E7C  |.  47              |INC EDI00411E7D  |.^ EB E5           \JMP SHORT 00411E6400411E7F  |>  5F              POP EDI                                  ;  恢复现场00411E80  \.  C3              RETN 00410EF8    E8 01000000       CALL 00410EFE00410EFD    90                NOP00410EFE    58                POP EAX                                  ; MOV EAX,410EFD00410EFF    53                PUSH EBX                                 ; push NAME00410F00    50                PUSH EAX00410F01    FFB5 04434000     PUSH DWORD PTR SS:[EBP+404304]           ; push LoadLibraryA00410F07    814424 04 1400000>ADD DWORD PTR SS:[ESP+4],14              ; push返回地址410EFD+14=410F1100410F0F    C3                RETN00410F10    90                NOP00410F11    85C0              TEST EAX,EAX                             ; 这是个人觉得应该是BUG来的吧,怎么不先GetModuleHandleA先呢00410F13    0F84 31080000     JE 0041174A                              ; 如果载入失败就去出错的地方00410F19    E8 01000000       CALL 00410F1F00410F1E    90                NOP00410F1F    59                POP ECX                                  ; MOV ECX,EIP-100410F20    50                PUSH EAX                                 ; PUSH hmodule00410F21    51                PUSH ECX00410F22    55                PUSH EBP00410F23    810424 AE324000   ADD DWORD PTR SS:[ESP],004032AE          ; push 41085E00410F2A    814424 04 2200000>ADD DWORD PTR SS:[ESP+4],22              ; 先进41085E然后返回到410F40处00410F32    C3                RETN                                     ; 返回41085E处,进去后获取相关DLL的输出表信息……00410862    5A                POP EDX                                  ; 把hmodule入edx中00410863    41                INC ECX00410864    51                PUSH ECX                                 ; push 410F41这里改变后就是返回到410F41了00410865    57                PUSH EDI                                 ; push Name00410866    53                PUSH EBX00410867    8995 31334000     MOV DWORD PTR SS:[EBP+403331],EDX        ; 把hmodule保存到[EBP+403331]==4108E1处0041086D    8BDA              MOV EBX,EDX0041086F    0352 3C           ADD EDX,DWORD PTR DS:[EDX+3C]            ; 定位e_lfnew(定位pe头)00410872    FF72 7C           PUSH DWORD PTR DS:[EDX+7C]00410875    8F85 29334000     POP DWORD PTR SS:[EBP+403329]            ; 输出表的size入[EBP+403329](4108d9)处0041087B    8B52 78           MOV EDX,DWORD PTR DS:[EDX+78]            ; 定位输出表0041087E    03D3              ADD EDX,EBX                              ; 把输出表转换成VA00410880    52                PUSH EDX00410881    8F85 25334000     POP DWORD PTR SS:[EBP+403325]            ; 输出表起始地址入[EBP+403325](4108d5]处00410887    90                NOP00410887    90                NOP00410888    90                NOP00410889    90                NOP0041088A    90                NOP0041088B    90                NOP0041088C    90                NOP0041088D    90                NOP0041088E    90                NOP0041088F    90                NOP00410890    FF72 20           PUSH DWORD PTR DS:[EDX+20]               ; AddressOfNames00410893    5F                POP EDI00410894    03FB              ADD EDI,EBX                              ; AddresOfNames转换成VA00410896    57                PUSH EDI00410897    8F85 35334000     POP DWORD PTR SS:[EBP+403335]0041089D    FF72 18           PUSH DWORD PTR DS:[EDX+18]               ; NumberOfNames004108A0    8F85 E8334000     POP DWORD PTR SS:[EBP+4033E8]004108A6    EB 01             JMP SHORT 004108A9004108A8    90                NOP004108A9    FF72 1C           PUSH DWORD PTR DS:[EDX+1C]               ; AddressofFunctions004108AC    5F                POP EDI004108AD    03FB              ADD EDI,EBX                              ; AddressOfFunctions转为VA004108AF    57                PUSH EDI004108B0    8F85 39334000     POP DWORD PTR SS:[EBP+403339]            ; 输出表的AddressOfFunctions 入[EBP+403339]004108B6    FF72 24           PUSH DWORD PTR DS:[EDX+24]               ; AddressOfNamesOrdinals004108B9    5F                POP EDI004108BA    03FB              ADD EDI,EBX004108BC    57                PUSH EDI004108BD    8F85 2D334000     POP DWORD PTR SS:[EBP+40332D]            ; 输出表的AddressOfNamesOrdinals 入[EBP+40332D](004108DD)004108C3    FF72 10           PUSH DWORD PTR DS:[EDX+10]               ; nBase004108C6    8F85 53334000     POP DWORD PTR SS:[EBP+403353]            ; 输出表的Base  入[EBP+403353](00410903)004108CC    EB 01             JMP SHORT 004108CF                       ; 获取完毕回去操作第一次是KERNEL32.DLL函数输出表的SIZE 00006B39入[EBP+403329](4108d9)输出表起始地址77EAD040入[EBP+403325](4108d5]输出表的AddressOfNames 77EAD2F0入[EBP+403335](4108E5)输出表的NumberOfNames 03AE入[EBP+4033E8](00410998)输出表的AddressOfFunctions 77EAD068入[EBP+403339](004108E9)输出表的AddressOfNamesOrdinals 77EAEDD8入[EBP+40332D](004108DD)输出表的Base 1 入[EBP+403353](00410903) 00410F41    2BD2              SUB EDX,EDX                              ; 清除EDX,这样的方式不会改变标志的……00410F70    800B 00           OR BYTE PTR DS:[EBX],0                   ; 取完那个DLL后就把函数再给清除掉00410F73    74 0D             JE SHORT 00410F82                        ; 如果清完了就跳00410F75    8813              MOV BYTE PTR DS:[EBX],DL00410F77    C1C2 04           ROL EDX,400410F7A    90                NOP00410F7B    90                NOP00410F7C    90                NOP00410F7D    43                INC EBX00410F7E  ^ FF6424 FC         JMP DWORD PTR SS:[ESP-4]                 ; 这里跳回去直到函数名已经清除完了……00410F83    8B56 10           MOV EDX,DWORD PTR DS:[ESI+10]            ; 把ThunkRVA入EDX中,并转成VA00410F86    0395 D2424000     ADD EDX,DWORD PTR SS:[EBP+4042D2]00410F8C    830A 00           OR DWORD PTR DS:[EDX],0                  ; 判断有没有操作完相关的API,操作完了就跳00410F8F    0F84 32010000     JE 004110C700410F95    90                NOP00410F96    90                NOP……00410FB6    0385 D2424000     ADD EAX,DWORD PTR SS:[EBP+4042D2]        ; TunkValue转换成VA00410FBC    97                XCHG EAX,EDI                             ; ThunkVlue入edi,00410FBD    68 7AF3D0F9       PUSH F9D0F37A00410FC2    012C24            ADD DWORD PTR SS:[ESP],EBP00410FC5    810424 B4466F06   ADD DWORD PTR SS:[ESP],66F46B400410FCC    68 D476630F       PUSH 0F6376D400410FD1    812C24 9643230F   SUB DWORD PTR SS:[ESP],0F23439600410FD8    012C24            ADD DWORD PTR SS:[ESP],EBP00410FDB    C3                RETN                                     ; 跳去填充API函数里,相当于我们的GetProcAddress进入后发现和以前的版本没什么很大的变化.……004108F8    0BFF              OR EDI,EDI                               ; 判断ThunkValue是不是为空,不是则跳004108FA    75 19             JNZ SHORT 00410915……00410921    8B9D 35334000     MOV EBX,DWORD PTR SS:[EBP+403335]        ; 输出表的AddresOfNames入EBX00410927    8A47 FF           MOV AL,BYTE PTR DS:[EDI-1]……00410959    8B3B              MOV EDI,DWORD PTR DS:[EBX]               ; 循环搜索相关DLL的输出表0041095B    03BD 31334000     ADD EDI,DWORD PTR SS:[EBP+403331]        ; 取出的输出表转换成VA…….00410964   /75 2C           JNZ SHORT 0041099200410966   |E8 B0100000     CALL 00411A1B0041096B   |3D F7DEBCA1     CMP EAX,A1BCDEF700410970   |75 20           JNZ SHORT 0041099200410972   |8B85 2D334000   MOV EAX,DWORD PTR SS:[EBP+40332D]        ; 循环得到程序所要的API,找到后到这里00410978   |D1E1            SHL ECX,10041097A   |03C1            ADD EAX,ECX0041097C   |0FB700          MOVZX EAX,WORD PTR DS:[EAX]0041097F   |C1E0 02         SHL EAX,200410982   |0385 39334000   ADD EAX,DWORD PTR SS:[EBP+403339]00410988   |8B00            MOV EAX,DWORD PTR DS:[EAX]0041098A   |0385 31334000   ADD EAX,DWORD PTR SS:[EBP+403331]        ; 把API地址转换成VA00410990   |EB 10           JMP SHORT 004109A2004109A2    8BBD 25334000   MOV EDI,DWORD PTR SS:[EBP+403325]004109A8    3BC7            CMP EAX,EDI                              ; EAX就是取出的API了004109AA    76 35           JBE SHORT 004109E1                       ; 这里要跳了,要不然,壳还要"照顾"的这里改成:004109AA   /EB 35           JMP SHORT 004109E1        ……..004109E3    90              NOP004109E4    894424 1C       MOV DWORD PTR SS:[ESP+1C],EAX            ; 这里又我们通过跟踪知道改成mov ss:[edx],eax就是传入正确的API所以这里改成:004109E4    36:8902         MOV DWORD PTR SS:[EDX],EAX            004109E7    90              NOP 004109E8    61              POPAD004109E9    FF0424          INC DWORD PTR SS:[ESP]                   ; 把上面要返回的地址+1(410FDF)004109EC    0BC0            OR EAX,EAX……00411085    90              NOP00411086    E8 ECF6FFFF     CALL 004107770041108B    0BE4            OR ESP,ESP0041108D    90              NOP0041108E    90              NOP0041108F    90              NOP0041109C    E8 51F9FFFF     CALL 004109F2                            ; 这里进去将再改填充API004110A1    90              NOP跟进看看:……00410A0B    90              NOP00410A0C    BF 96844000     MOV EDI,00408496                         ; 传入Address00410A11    EB 01           JMP SHORT 00410A1400410A13    90              NOP00410A14    B9 86010000     MOV ECX,186                              ; 传入size…….00410A29    90              NOP00410A2A    3917            CMP DWORD PTR DS:[EDI],EDX00410A2C    74 0D           JE SHORT 00410A3B00410A2E    47              INC EDI00410A2F    EB 01           JMP SHORT 00410A3200410A31    90              NOP00410A32  ^ E2 F6           LOOPD SHORT 00410A2A00410A34    EB 01           JMP SHORT 00410A3700410A36    90              NOP00410A37    8902            MOV DWORD PTR DS:[EDX],EAX               ; 这里又想破坏输入表,也nop掉00410A39    EB 4E           JMP SHORT 00410A8900410A3B    90              NOP……00410A5A    90              NOP00410A5B    807F FF EA      CMP BYTE PTR DS:[EDI-1],0EA00410A5F  ^ 75 D6           JNZ SHORT 00410A3700410A61    90              NOP                                      ; 这里要改成这样子,传入FF2500410A62    90              NOP00410A63    90              NOP00410A64    90              NOP00410A65    90              NOP                                      ; 因为加壳的时候壳把FF25改成了FFEA00410A66    90              NOP00410A67    90              NOP00410A68    90              NOP00410A69    90              NOP00410A6A    FE4F FF         DEC BYTE PTR DS:[EDI-1]                  ; 这里开始nop掉00410A6D    83C7 04         ADD EDI,400410A70    2BC7            SUB EAX,EDI00410A72    8947 FC         MOV DWORD PTR DS:[EDI-4],EAX00410A75    EB 12           JMP SHORT 00410A89改好后:00410A5A    90              NOP00410A5B    807F FF EA      CMP BYTE PTR DS:[EDI-1],0EA00410A5F  ^ 75 D6           JNZ SHORT 00410A3700410A61    66:C747 FE FF25 MOV WORD PTR DS:[EDI-2],25FF             ; 这里要改成这样子,传入FF2500410A67    90              NOP00410A68    90              NOP00410A69    90              NOP00410A6A    90              NOP                                      ; 这里开始nop掉00410A6B    90              NOP00410A6C    90              NOP00410A6D    90              NOP00410A6E    90              NOP00410A6F    90              NOP00410A70    90              NOP00410A71    90              NOP00410A72    90              NOP00410A73    90              NOP00410A74    90              NOP00410A75    EB 12           JMP SHORT 00410A89……00410A83    90              NOP00410A84    8907            MOV DWORD PTR DS:[EDI],EAX               ; 这里也是破坏输入表的,清除之00410A86    EB 01           JMP SHORT 00410A89好了,输入表处理完毕,进入下一个环节,还原壳所抽的代码.……0041114B    90               NOP0041114C    90               NOP0041114D    F3:              PREFIX REP:                              ; 通过RDTSC检测反跟踪,这是最后一个反跟踪了0041114E    0F31             RDTSC00411150    50               PUSH EAX00411151    F3:              PREFIX REP:                              ; Superfluous prefix00411152    0F31             RDTSC00411154    EB 01            JMP SHORT 0041115700411156    90               NOP……00411191    8D6424 04        LEA ESP,DWORD PTR SS:[ESP+4]00411195    FF6424 FC        JMP DWORD PTR SS:[ESP-4]                 ; 如果没发现就去正常执行程序处00411199    90               NOP0041119A    2200             AND AL,BYTE PTR DS:[EAX]0041119C    0000             ADD BYTE PTR DS:[EAX],AL0041119E    85C0             TEST EAX,EAX004111A0    75 1F            JNZ SHORT 004111C1004111A2    74 34            JE SHORT 004111D8004111A4    F8               CLC004111A5    83C9 FF          OR ECX,FFFFFFFF                          ; 发现的话到这里就挂004111A8    F3:AB            REP STOS DWORD PTR ES:[EDI]004111AA    E8 1C000000      CALL 004111CB……004111CE    90               NOP004111CF    90               NOP004111D0    B8 7B4D5F0E      MOV EAX,0E5F4D7B                         ; 如果没有发现跟踪的话就跳到这里004111D5    90               NOP……004111FB   /74 45            JE SHORT 00411242004111FD   |BE F4244100      MOV ESI,004124F400411202   |B9 5C020000      MOV ECX,25C                              ; 传入SIZE也就是壳所抽的代码的大小00411207   |51               PUSH ECX00411208   |B0 3C            MOV AL,3C0041120A   |304431 FF        XOR BYTE PTR DS:[ECX+ESI-1],AL           ; 还原壳所抽的代码,这个不是程序的入口那一点哦0041120E   |90               NOP0041120F   |90               NOP00411210   |90               NOP00411211   |90               NOP00411212   |90               NOP00411213   |90               NOP00411214   |90               NOP00411215   |90               NOP00411216   |90               NOP00411217   |90               NOP00411218   |90               NOP00411219   |90               NOP0041121A   |004C31 FF        ADD BYTE PTR DS:[ECX+ESI-1],CL0041121E  ^|E2 EA            LOOPD SHORT 0041120A……00411231    90               NOP00411232    BF C8014000      MOV EDI,004001C8                         ; 这里处理壳所抽的代码,俺是在这里动的手脚,具体怎么改我就不讲,以免卖弄之嫌(看看我已经脱好的就怎么怎么改的).00411237    90               NOP00411238    90               NOP00411239    90               NOP0041123A    90               NOP0041123B    90               NOP0041123C    90               NOP0041123D    90               NOP0041123E    90               NOP0041123F    90               NOP00411240    F3:A4            REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[>; 把代码放到PE HEADER部分,够狠……00411279    61               POPAD                                    ; 解压完毕,执行程序代码0041127A    BA 0F5C8CCE      MOV EDX,CE8C5C0F                         ; 终于着陆了;-)0041127F    EB 01            JMP SHORT 0041128200411281    90               NOP00411282    81F2 753DE58A    XOR EDX,8AE53D75 看看程序里面的东西,哈哈,抽的不错嘛,于是乎,动手乱写一下修复脚本.……var addrvar addrlvar addrtvar addrt1var addr40var addrt2 start:  mov addr,4101c6              //写的比较乱,但愿你能看懂:-)  lbl1:                      //修复代码一  cmp addr,410430  jae lbl2  find addr,#E9#  mov addr,$RESULT  mov addrt,addr  mov addrt1,addr  mov addr40,addr  sub addr40,10000  add addr40,5  dec addrt             inc addrt1  mov addrt1,[addrt1]  add addr40,addrt1  mov addrl,addr40  add addrt,5  sub addrt,addrl  mov addrt2,FFFFFFFF  sub addrt2,addrt  inc addr  mov [addr],addrt2 jmp lbl1 lbl2:                      //修复代码二  repl 401000,#E8??81FFFF#,#E8??810000#,8b24  repl 401000,#E9??81FFFF#,#E9??810000#,8b24   repl 401000,#E8??82FFFF#,#E8??820000#,8b24  repl 401000,#E9??82FFFF#,#E9??820000#,8b24   repl 401000,#E8??83FFFF#,#E8??830000#,8b24  repl 401000,#E9??83FFFF#,#E9??830000#,8b24  ret ret好了,现在到了最后一步了,把jmp表全部下一个地址,也就是这样子.00408495      90            NOP00408496   $- FF25 88A04000 JMP DWORD PTR DS:[<&kernel32.CloseHandle>;  kernel32.CloseHandle0040849C   $- FF25 78A04000 JMP DWORD PTR DS:[<&kernel32.CopyFileA>] ;  kernel32.CopyFileA好了,现在dump再用import REC修复一下输入表就行了。至于stolencode可以找也可以不用,这么简单的几行,我自己就不再补上去(要补也简单,看一眼就知道怎么改).OK,壳到此脱完了,谢谢你能够坚持把文章看完!BTW:自己脱了后,看了一下FLY的已脱程序,感触很深的,他真是头大牛来的!努力向他学习才行.因时间比较紧,发了几天的时间才写完了这篇文章.文章不足之处还请指正.  Greetz: Fly,Jingulong,yock,tDasm,David,ahao,vcasm,UFO(brother),alan(sister),heXpe,hexer, all of my friends and you!                            Welcome to:----====China Decrytpion Fans Cracking Group====----http://www.chinadfcg.com----====Free Cracking Group====----http://www.fcgchina.com----====Unpacking Sage(China Unpacking Group)====----                             By loveboom[DFCG][FCG]                            Email:bmd2chen#tom.com 

本文地址:http://com.8s8s.com/it/it22396.htm