Alex-protect外壳完全分析

yoda's Protector V1.03.3(默认保护)的脱壳方法和具体分析 描述对于破解爱好者对于程序壳的去发的工具。此工具就针对于yoda's Protector 壳的脱掉。 立即下载
Alex-protect外壳完全分析
【目     标】:Alex-Protect v1.0 beta2
【工     具】:
【任     务】: 
【操作平台】:
【作     者】: LOVEBOOM[DFCG][FCG][US]
【相关链接】: 看雪里,自己找找
【简要说明】: 快到圣诞节了,献上文章一篇.这个壳不算强,不过花指令到不少。
【详细过程】:
OD设置:打开全部异常。我先自己写了一个去花指令脚本,方便我分析。因为壳后面分检查代码,所以实际跟时可以不去掉垃圾代码的。
载入程序开始我们的旅程:
00438000 >  60                 PUSHAD                                   ; 保护现场
00438001    E8 00000000        CALL 00438006
00438006    5D                 POP EBP
00438007    81ED 06104000      SUB EBP,00401006                         ; 取BASE=37000
……                            ;这里有一堆垃圾,我清除了先。
00438103   /E9 B3000000        JMP 004381BB                             ; 清完垃圾就直接到这里了
……
004381BB    8B85 C4244000      MOV EAX,DWORD PTR SS:[EBP+4024C4]        ; 把GetProcAddress的地址放到EAX中,用于后面的比较有没有下CC断
……
00438266    E8 46FFFFFF        CALL 004381B1                            ; 这里进去就是比较有没有在相关的api上下断,第一次我们时去看看
进入后:
004381B1    8038 CC            CMP BYTE PTR DS:[EAX],0CC                ; 看到了吧,这里比较相关API的第一位是否为CC,也就是判断有没有下断
004381B4    74 01              JE SHORT 004381B7                        ; 如果下断了,就跳,也就over了
004381B6    C3                 RETN
004381B7    F0:0FC7C8        LOCK CMPXCHG8B EAX                      
好了,知道情况后,后面的CALL 4381B1就不用再跟进去.
00438310    8B85 C8244000      MOV EAX,DWORD PTR SS:[EBP+4024C8]        ; 比较GetModuleHandleA有没有下断
00438367    E8 45FEFFFF        CALL 004381B1
……
00438411    8B85 CC244000      MOV EAX,DWORD PTR SS:[EBP+4024CC]        ; 判断LoadLibraryA有没有下断
00438417    E8 95FDFFFF        CALL 004381B1                            ; 同上,进去检测
00438512    8B85 BC244000      MOV EAX,DWORD PTR SS:[EBP+4024BC]        ; 判断MessageBoxA
00438518    E8 94FCFFFF        CALL 004381B1                            ; 同上
……
004385C2    E8 35060000        CALL 00438BFC                            ; 这里跟进
……
00438CA1    8D85 25244000      LEA EAX,DWORD PTR SS:[EBP+402425]
00438CA7    50                 PUSH EAX
00438CA8    FF95 C8244000      CALL DWORD PTR SS:[EBP+4024C8]           ; 获取Kernel32的handle
00438CAE    8BF8               MOV EDI,EAX                              ; 获取到的handle入edi
00438CB0    8D9D 3D244000      LEA EBX,DWORD PTR SS:[EBP+40243D]        ; 把VirtualAlloc所在的地址传递到ebx中
00438CB6    53                 PUSH EBX
00438CB7    50                 PUSH EAX                                 ; push handle
00438CB8    E8 B4030000        CALL 00439071
再跟进:
00439071    60                 PUSHAD
00439072    8B5C24 24          MOV EBX,DWORD PTR SS:[ESP+24]            ; handle 入ebx
0043911B    8B43 3C            MOV EAX,DWORD PTR DS:[EBX+3C]            ; 定位pe头
004391C3    03C3               ADD EAX,EBX
004391C5    8B48 7C            MOV ECX,DWORD PTR DS:[EAX+7C]            ; Size Export Table入ecx(6c7b)
004391C8    E3 2F              JECXZ SHORT 004391F9
004391CA    8B68 78            MOV EBP,DWORD PTR DS:[EAX+78]            ; RVA Export table导出表相对虚拟地址(262C)
004391CD    03EB               ADD EBP,EBX
004391CF    8B4424 28          MOV EAX,DWORD PTR SS:[ESP+28]
004391D3    8B00               MOV EAX,DWORD PTR DS:[EAX]
004391D5    A9 0000FFFF        TEST EAX,FFFF0000
004391DA    51                 PUSH ECX
004391DB    74 21              JE SHORT 004391FE
004391DD    8B55 20            MOV EDX,DWORD PTR SS:[EBP+20]
004391E0    FC                 CLD
004391E1    03D3               ADD EDX,EBX
004391E3    33C0               XOR EAX,EAX
004391E5    8B4D 18            MOV ECX,DWORD PTR SS:[EBP+18]
004391E8    8BF3               MOV ESI,EBX
004391EA    8B7C24 2C          MOV EDI,DWORD PTR SS:[ESP+2C]
004391EE    033482             ADD ESI,DWORD PTR DS:[EDX+EAX*4]
004391F1    A6                 CMPS BYTE PTR DS:[ESI],BYTE PTR ES:[EDI]
004391F2    74 12              JE SHORT 00439206
004391F4    40                 INC EAX
004391F5    49                 DEC ECX
004391F6  ^ 75 F0              JNZ SHORT 004391E8                       ; 通过遍历的方法找到VirtualAlloc的地址
004391F8    59                 POP ECX
004391F9    E9 7F010000        JMP 0043937D
004391FE    2B45 10            SUB EAX,DWORD PTR SS:[EBP+10]
00439201    E9 B5000000        JMP 004392BB
……
004392B2    8B55 24            MOV EDX,DWORD PTR SS:[EBP+24]
004392B5    03D3               ADD EDX,EBX
004392B7    0FB70442           MOVZX EAX,WORD PTR DS:[EDX+EAX*2]
004392BB    3B45 14            CMP EAX,DWORD PTR SS:[EBP+14]
004392BE  ^ 0F83 35FFFFFF      JNB 004391F9
004392C4    8B55 1C            MOV EDX,DWORD PTR SS:[EBP+1C]
004392C7    03D3               ADD EDX,EBX
004392C9    031C82             ADD EBX,DWORD PTR DS:[EDX+EAX*4]
004392CC    8BC3               MOV EAX,EBX                              ; 获取到的地址入eax
004392CE    90                 NOP
00439373    2BDD               SUB EBX,EBP
00439375    3BD9               CMP EBX,ECX
00439377  ^ 0F82 7CFEFFFF      JB 004391F9
0043937D    894424 1C          MOV DWORD PTR SS:[ESP+1C],EAX            ; 取出的值入[esp+c](7c809a81)
00439381    61                 POPAD
00439382    C2 0800            RETN 8
出来后我们就可以知道:
CALL 00439071实际上就是 call GetProcAddress.
……
00438D62    E8 4AF4FFFF        CALL 004381B1                            ; 无聊,又进去检查有没有下断
00438D67    8985 11244000      MOV DWORD PTR SS:[EBP+402411],EAX        ; 取出VirtualAlloc的实际地址放到变量[EBP+402411]中
00438D6D    8D9D 4A244000      LEA EBX,DWORD PTR SS:[EBP+40244A]
00438D73    53                 PUSH EBX                                 ; /ProcNameOrOrdinal = "VirtualFree"
00438D74    57                 PUSH EDI                                 ; |hModule = 7C800000 (kernel32)
00438D75    E8 F7020000        CALL 00439071                            ; /GetProcAddress
……
00438E1F    E8 8DF3FFFF        CALL 004381B1                            ; 又是无聊的判断
00438E24    8985 15244000      MOV DWORD PTR SS:[EBP+402415],EAX        ; 取出VirtualFree地址放到变量[EBP+402415]处
00438E2A    8D9D 56244000      LEA EBX,DWORD PTR SS:[EBP+402456]
00438E30    53                 PUSH EBX                                 ; /ProcNameOrOrdinal = "GetstdHandle"
00438E31    57                 PUSH EDI                                 ; |hModule = 7C800000 (kernel32)
00438E32    E8 3A020000        CALL 00439071                            ; /GetProcAddress
……
00438EDC    E8 D0F2FFFF        CALL 004381B1                            ; 无聊判断
00438EE1    8985 19244000      MOV DWORD PTR SS:[EBP+402419],EAX        ; 取出GetStdHandle的地址放入变量[EBP+402419]处
00438EE7    8D9D 63244000      LEA EBX,DWORD PTR SS:[EBP+402463]
00438EED    53                 PUSH EBX                                 ; /ProcNameOrOrdinal = "CreateThread"
00438EEE    57                 PUSH EDI                                 ; |hModule = 7C800000 (kernel32)
00438EEF    E8 7D010000        CALL 00439071                            ; /GetProcAddress
……
00438F99    E8 13F2FFFF        CALL 004381B1                            ; 无聊的判断
00438F9E    8985 21244000      MOV DWORD PTR SS:[EBP+402421],EAX        ; 取出CreateThread的地址入变量[EBP+402421]处
00438FA4    8D85 32244000      LEA EAX,DWORD PTR SS:[EBP+402432]        ; 准备获取USER32.DLL中要用的API
00438FAA    50                 PUSH EAX                                 ; /FileName = "user32.dll"
00438FAB    FF95 CC244000      CALL DWORD PTR SS:[EBP+4024CC]           ; /LoadLibraryA
00438FB1    8BF8               MOV EDI,EAX                              ; 这个作者为了"节省"代码,不用GetModuleHandleA来判断有没有加载
00438FB3    8D9D 70244000      LEA EBX,DWORD PTR SS:[EBP+402470]
00438FB9    53                 PUSH EBX                                 ; /ProcNameOrOrdinal = "FindWindowA"
00438FBA    57                 PUSH EDI                                 ; |hModule = 77D10000 (USER32)
00438FBB    E8 B1000000        CALL 00439071                            ; /GetProcAddress
……
00439065    E8 47F1FFFF        CALL 004381B1                            ; 又一个无聊的判断
0043906A    8985 1D244000      MOV DWORD PTR SS:[EBP+40241D],EAX        ; 取出FindWindowA的地址入变量[EBP+40241D]处
00439070    C3                 RETN                                     ; 取完这么几个API后返回
……
004386BD    8D85 00104000      LEA EAX,DWORD PTR SS:[EBP+401000]        ; EP(438000)入EAX
004386C3    B9 85130000        MOV ECX,1385                             ; 这里开始CRC前面的代码了检查范围是438000-439385(438000+1385)
004386C8    E8 E7040000        CALL 00438BB4                            ; 这里进去就是CRC(35FAFA4B,每次的值不同)
004386CD    8DBD 31254000      LEA EDI,DWORD PTR SS:[EBP+402531]        ; [EBP+402531]=439531
004386D3    EB 01              JMP SHORT 004386D6
……
004386F7    8BC3               MOV EAX,EBX
004386F9    8B8D B5234000      MOV ECX,DWORD PTR SS:[EBP+4023B5]        ; 准备解压的大小(4B7)
004386FF    3007               XOR BYTE PTR DS:[EDI],AL                 ; 从439531处开始解压下一段代码
00438701    47                 INC EDI
00438702    49                 DEC ECX
00438703  ^ 75 FA              JNZ SHORT 004386FF                       ; 没解压完继续
……
00438756    6A 04              PUSH 4                                   ; 解压完准备分配空间
004388AE    FF95 11244000      CALL DWORD PTR SS:[EBP+402411]           ; VirtualAlloc
004388B4    8985 BD234000      MOV DWORD PTR SS:[EBP+4023BD],EAX        ; 申请到的空间入[EBP+4023BD](3d0000)
……
0012FF84   004388B4  /CALL to VirtualAlloc from alexprot.004388AE
0012FF88   00000000  |Address = NULL
0012FF8C   0000EF74  |Size = EF74 (61300.)
0012FF90   00001000  |AllocationType = MEM_COMMIT
……
0043895F    8BF8               MOV EDI,EAX                              ; 申请到的地址放入EDI中EDI=3D0000
00438961    57                 PUSH EDI                                 ; 地址入栈
……
00438A07    8D85 31254000      LEA EAX,DWORD PTR SS:[EBP+402531]        ; EAX=439531
00438A0D    50                 PUSH EAX                                 ; PUSH 439531
……
00438AB4    E8 4FF6FFFF        CALL 00438108                            ; apLib解压代码
00438AB9    83C4 08            ADD ESP,8
……
00438BB2  - FFE7               JMP EDI                                  ; 解压完毕跳去已经解压的代码处
……
003D0015    E8 88130000        CALL 003D13A2                            ; 这里进去看看
进来首先看到的就是清除断点:
003D138B    8948 04            MOV DWORD PTR DS:[EAX+4],ECX             ; 开始清除断点
003D138E    8948 08            MOV DWORD PTR DS:[EAX+8],ECX
003D1391    8948 0C            MOV DWORD PTR DS:[EAX+C],ECX
003D1394    8948 10            MOV DWORD PTR DS:[EAX+10],ECX
003D1397    C740 18 55010000   MOV DWORD PTR DS:[EAX+18],155
003D139E    59                 POP ECX
003D139F    33C0               XOR EAX,EAX
003D13A1    C3                 RETN
……
返回后,分析一下就会发现CALL 003D13A2就是清除断点CALL.
003D001A    6A 04              PUSH 4
003D00C1    68 00100000        PUSH 1000
003D00C6    8B85 A1234000      MOV EAX,DWORD PTR SS:[EBP+4023A1]        ; EAX=F0
003D0171    BB 4A000000        MOV EBX,4A
003D0176    F7E3               MUL EBX
003D0178    50                 PUSH EAX                   ‘计算要申请空间的size
003D021E    6A 00              PUSH 0
003D0220    FF95 11244000      CALL DWORD PTR SS:[EBP+402411]           ; VirtualAlloc
003D0226    8985 A5234000      MOV DWORD PTR SS:[EBP+4023A5],EAX        ; 第二次申请的空间地址3E0000入[EBP+4023A5]
……
0012FF78   003D0226  /CALL to VirtualAlloc from 003D0220
0012FF7C   00000000  |Address = NULL
0012FF80   00004560  |Size = 4560 (17760.)
0012FF84   00001000  |AllocationType = MEM_COMMIT
 
……
003D02D1    8DB5 C1234000      LEA ESI,DWORD PTR SS:[EBP+4023C1]        ; ESI=4393C1
003D02D7    8B46 04            MOV EAX,DWORD PTR DS:[ESI+4]             ; EAX=9BE8(text段的大小)
003D02DA    6A 04              PUSH 4
003D02DC    68 00100000        PUSH 1000
003D02E1    50                 PUSH EAX
003D0387    6A 00              PUSH 0
003D0389    FF95 11244000      CALL DWORD PTR SS:[EBP+402411]           ; VirtualAlloc
003D038F    8985 9D234000      MOV DWORD PTR SS:[EBP+40239D],EAX        ; 第三次申请到的空间地址3F0000存放在[EBP+40239D]处
……
0012FF78   003D038F  /CALL to VirtualAlloc from 003D0389
0012FF7C   00000000  |Address = NULL
0012FF80   00009BE8  |Size = 9BE8 (39912.)
0012FF84   00001000  |AllocationType = MEM_COMMIT
……
003D0395    56                 PUSH ESI
003D0396    8B1E               MOV EBX,DWORD PTR DS:[ESI]               ; Voffset 1000
003D0398    039D 99234000      ADD EBX,DWORD PTR SS:[EBP+402399]        ; 转为VA(401000)
003D039E    50                 PUSH EAX                                 ; 刚才申请的空间入栈003D0444    53                 PUSH EBX                                 ; push Text section地址
003D0445    8D8D 08114000      LEA ECX,DWORD PTR SS:[EBP+401108]        ; ECX=438108
003D044B    FFD1               CALL ECX                                 ; 这里进去就是ApLib解压text段
003D044D    83C4 08            ADD ESP,8
003D0450    8BC8               MOV ECX,EAX                              ; text段的大小9BE8入ECX
003D0452    8B3E               MOV EDI,DWORD PTR DS:[ESI]               ; text段的RVA入edi
……
003D04F9    03BD 99234000      ADD EDI,DWORD PTR SS:[EBP+402399]        ; 转换成VA(401000)
003D04FF    8BB5 9D234000      MOV ESI,DWORD PTR SS:[EBP+40239D]        ; 这里实际就是先申请一个空间把Text段解压数据临时到到申请空间里,完毕后,写回实际地址
003D0505    F3:A4              REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[>
003D0507    5E                 POP ESI
003D0508    8B85 9D234000      MOV EAX,DWORD PTR SS:[EBP+40239D]
003D050E    68 00800000        PUSH 8000
003D0513    6A 00              PUSH 0
003D0515    50                 PUSH EAX
003D0516    FF95 15244000      CALL DWORD PTR SS:[EBP+402415]           ; 还原出text段的数据后,释放临时空间(3F0000)
……
003D05C1    83C6 08            ADD ESI,8
003D05C4    833E 00            CMP DWORD PTR DS:[ESI],0
003D05C7  ^ 0F85 0AFDFFFF      JNZ 003D02D7                             ; 判断有没有解压完全部段,没有则回去继续解压
003D05CD    E8 D00D0000        CALL 003D13A2                            ; 这里前面说是是清除断点的,所以不用跟进去
003D05D2    6A 04              PUSH 4
003D05D4    68 00100000        PUSH 1000
003D05D9    8B85 91234000      MOV EAX,DWORD PTR SS:[EBP+402391]        ; EAX=C5E
003D05DF    6BC0 02            IMUL EAX,EAX,2
003D0687    50                 PUSH EAX            ;push申请空间大小
003D0688    6A 00              PUSH 0
003D068A    FF95 11244000      CALL DWORD PTR SS:[EBP+402411]           ; VirtualAlloc
……
0012FF74   003D0690  /CALL to VirtualAlloc from 003D068A
0012FF78   00000000  |Address = NULL
0012FF7C   000018BC  |Size = 18BC (6332.)
0012FF80   00001000  |AllocationType = MEM_COMMIT
……
003D0690    8985 AD234000      MOV DWORD PTR SS:[EBP+4023AD],EAX        ; 申请的空间3F0000入[EBP+4023AD]处
003D0696    6A 04              PUSH 4
003D0698    68 00100000        PUSH 1000
003D069D    8B85 8D234000      MOV EAX,DWORD PTR SS:[EBP+40238D]        ; EAX=830(申请空间大小)
……
003D0748    50                 PUSH EAX
003D0749    6A 00              PUSH 0
003D074B    FF95 11244000      CALL DWORD PTR SS:[EBP+402411]           ; VirtualAlloc
……
0012FF74   003D0751  /CALL to VirtualAlloc from 003D074B
0012FF78   00000000  |Address = NULL
0012FF7C   00000830  |Size = 830 (2096.)
0012FF80   00001000  |AllocationType = MEM_COMMIT
……
003D0757    8D85 00104000      LEA EAX,DWORD PTR SS:[EBP+401000]        ; EP入EAX
003D075D    B9 85130000        MOV ECX,1385                                          ;要解压的大小
003D0762    8D95 B41B4000      LEA EDX,DWORD PTR SS:[EBP+401BB4]        ; 下一段要解压的起始地址438bb4
003D0768    FFD2               CALL EDX                                 ; 这个CALL就是计算CRC的值
……
003D080F    8DBD 31254000      LEA EDI,DWORD PTR SS:[EBP+402531]        ; 这里又开始解压下一面的代码
003D0815    03BD B5234000      ADD EDI,DWORD PTR SS:[EBP+4023B5]
003D081B    33D2               XOR EDX,EDX
003D081D    B9 00010000        MOV ECX,100
003D0822    F7F1               DIV ECX
003D0824    8BDA               MOV EBX,EDX
003D0826    F7F1               DIV ECX
003D0828    03DA               ADD EBX,EDX
003D082A    F7F1               DIV ECX
003D082C    03DA               ADD EBX,EDX
003D082E    F7F1               DIV ECX
003D0830    03DA               ADD EBX,EDX
003D0832    59                 POP ECX
003D0833    8BC3               MOV EAX,EBX
003D0835    8B8D B9234000      MOV ECX,DWORD PTR SS:[EBP+4023B9]
003D083B    3007               XOR BYTE PTR DS:[EDI],AL                 ; 这次从4399e8处开始解码
003D083D    47                 INC EDI
003D083E    49                 DEC ECX
003D083F  ^ 75 FA              JNZ SHORT 003D083B                       ; 没解压完跳回去继续
……
003D08E6    E8 B70A0000        CALL 003D13A2                            ; 又清除断点
003D08EB    8B85 A9234000      MOV EAX,DWORD PTR SS:[EBP+4023A9]        ; 把上面申请的地址空间920000入EAX
003D08F1    8BF0               MOV ESI,EAX
003D08F3    50                 PUSH EAX
003D08F4    8D9D 31254000      LEA EBX,DWORD PTR SS:[EBP+402531]
003D08FA    039D B5234000      ADD EBX,DWORD PTR SS:[EBP+4023B5]        ; 004399E8
……
003D09A5    53                 PUSH EBX
003D09A6    8D95 08114000      LEA EDX,DWORD PTR SS:[EBP+401108]
003D09AC    FFD2               CALL EDX                                 ; ApLib解码
003D09AE    83C4 08            ADD ESP,8
003D09B1    8BBD A9234000      MOV EDI,DWORD PTR SS:[EBP+4023A9]        ; 申请的空间920000入EDI
003D09B7    803F C3            CMP BYTE PTR DS:[EDI],0C3                ; 判断是否开始处理相关的DLL(也就是就是否第一次处理相应的DLL中的API)
003D09BA    0F85 CC000000      JNZ 003D0A8C                             ; 如果不是则跳
003D09C0    83C7 02            ADD EDI,2
003D09C3    57                 PUSH EDI                                 ; /Push "User32.dll"
003D09C4    FF95 C8244000      CALL DWORD PTR SS:[EBP+4024C8]           ; /GetModuleHandleA判断DLL有没有载入
003D09CA    85C0               TEST EAX,EAX
003D09CC    0F85 AC000000      JNZ 003D0A7E                             ; 如果已经加载则跳
……
003D0A77    57                 PUSH EDI                                 ; 如果没有载入则加载user32.dll
003D0A78    FF95 CC244000      CALL DWORD PTR SS:[EBP+4024CC]           ; LoadLibraryA
003D0A7E    8985 7C244000      MOV DWORD PTR SS:[EBP+40247C],EAX        ; hModule(77D1000.USER32.DLL)入[EBP+40247C]处
003D0A84    33DB               XOR EBX,EBX
003D0A86    8A5F FF            MOV BL,BYTE PTR DS:[EDI-1]
003D0A89    03FB               ADD EDI,EBX
003D0A8B    47                 INC EDI
003D0A8C    803F C4            CMP BYTE PTR DS:[EDI],0C4                ; 对输入表的几种不同情况进行处理??
003D0A8F    0F84 98010000      JE 003D0C2D                              ; 第一次这里没有跳,主程序没有跳。
003D0A95    47                 INC EDI
003D0A96    57                 PUSH EDI                                 ; /PUSH "TranslateMessage"
003D0A97    FFB5 7C244000      PUSH DWORD PTR SS:[EBP+40247C]           ; |hModule = 77D10000 (USER32)
003D0A9D    FF95 C4244000      CALL DWORD PTR SS:[EBP+4024C4]           ; /GetProcAddress
……
 
003D0B4A    8A5F FF            MOV BL,BYTE PTR DS:[EDI-1]               ; 加地址
003D0B4D    03FB               ADD EDI,EBX
003D0B4F    47                 INC EDI
003D0B50    8A1F               MOV BL,BYTE PTR DS:[EDI]
003D0B52    47                 INC EDI
003D0B53    E9 B5000000        JMP 003D0C0D
……
003D0C0D    80FB 00            CMP BL,0                                 ; 如果BL大于0就跳
003D0C10  ^ 0F87 42FFFFFF      JA 003D0B58
……
003D0B58    50                 PUSH EAX                                 ; PUSH API(77D18bce)
003D0B59    8B0F               MOV ECX,DWORD PTR DS:[EDI]               ; 把要写入iat的地址入ECX
003D0B5B    E8 62090000        CALL 003D14C2                            ; 这看到这里我就猜它里面应该填充API,进去看看
003D14C2    60                 PUSHAD                                   ; 进入后到这里
003D14C3    8BF0               MOV ESI,EAX                              ; API地址入esi
003D14C5    8B85 A5234000      MOV EAX,DWORD PTR SS:[EBP+4023A5]        ; EAX=003E0000
……
003D1570    0385 B1234000      ADD EAX,DWORD PTR SS:[EBP+4023B1]        ; [EBP+4023B1](4393b1)处保存放后的值,比如第一没写就是0,第二的话就是4了
003D1576    894424 1C          MOV DWORD PTR SS:[ESP+1C],EAX            ; 这里的用意就是把API的部分放到申请的空间里,真正的IAT调用申请的地址
003D157A    E8 00000000        CALL 003D157F
003D157F    5B                 POP EBX
003D1580    81C3 61020000      ADD EBX,261                              ; 3d157F+261=3D17E0 处临时保存API的地址
003D1586    8933               MOV DWORD PTR DS:[EBX],ESI               ; API临时保存到3D17E0处
003D1588    8BF8               MOV EDI,EAX                              ; EDI=3E0000
……
003D162F    8BF3               MOV ESI,EBX                                      ; 再把API存放的地址放到ESI中
003D1631    81EE 38000000      SUB ESI,38
003D1637    B9 4A000000        MOV ECX,4A
003D163C    FC                 CLD
003D163D    F3:A4              REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]     ; 这里把作者自己搞的花指令先填在我们去API的代码前
003D163F    8B85 A5234000      MOV EAX,DWORD PTR SS:[EBP+4023A5]
003D1645    0385 B1234000      ADD EAX,DWORD PTR SS:[EBP+4023B1]                ; EAX=3E0000
……
003D16F0    8BD8               MOV EBX,EAX                                      ; 再把003E0000的地址放到ebx上去
003D16F2    83C3 04            ADD EBX,4
003D179A    8918               MOV DWORD PTR DS:[EAX],EBX
003D179C    8185 B1234000 4A00>ADD DWORD PTR SS:[EBP+4023B1],4A                 ; 这也就是说代码指定大小为4A
003D17A6    61                 POPAD
003D17A7    C3                 RETN                                        ;返回上去
……
003D0C05    8901               MOV DWORD PTR DS:[ECX],EAX                       ; 把加密后的地址放到IAT中,这个值是壳计算生成的.
003D0C07    83C7 04            ADD EDI,4                                        ; 继续指向下一个要处理的API
003D0C0A    FECB               DEC BL
003D0C0C    58                 POP EAX
003D0C0D    80FB 00            CMP BL,0                                         ; 如果BL大于0就跳
003D0C10  ^ 0F87 42FFFFFF      JA 003D0B58
003D0C16    803F C3            CMP BYTE PTR DS:[EDI],0C3                        ; 到这里跟过就会发现壳是通过两个C3来判断有没有处理完当前的DLL
003D0C19  ^ 0F84 A1FDFFFF      JE 003D09C0                                      ; 判断当前DLL是否已经处理完,处理则跳去下一个DLL的api处理
003D0C1F    833F 00            CMP DWORD PTR DS:[EDI],0
003D0C22    0F84 DE000000      JE 003D0D06                                      ; 判断有没有处理完全部的API,如果处理完就跳
003D0C28  ^ E9 8AFDFFFF        JMP 003D09B7                                     ; 没处理完则回去继续
好了,处理完输入表,到这里:
003D0D06    E8 97060000        CALL 003D13A2                                    ; 处理完IAT就到这里,清除断点,不用跟进
003D0D0B    8D9D 31254000      LEA EBX,DWORD PTR SS:[EBP+402531]                ; EBX=439531
……
003D0DB6    039D B5234000      ADD EBX,DWORD PTR SS:[EBP+4023B5]
003D0DBC    039D B9234000      ADD EBX,DWORD PTR SS:[EBP+4023B9]                ; 00439C6D
……
003D0E67    8B8D 95234000      MOV ECX,DWORD PTR SS:[EBP+402395]                ; ECX=A1E
……
003D0F12    8B85 AD234000      MOV EAX,DWORD PTR SS:[EBP+4023AD]                ; EAX=3F0000
003D0F18    50                 PUSH EAX
003D0F19    53                 PUSH EBX                                         ; 解开439c6d开始,大小为A1E的代码段
003D0F1A    8D95 08114000      LEA EDX,DWORD PTR SS:[EBP+401108]
003D0F20    FFD2               CALL EDX                                         ; ApLib解压
003D0F22    90                 NOP
……
003D0FC7    83C4 08            ADD ESP,8
003D0FCA    8B85 AD234000      MOV EAX,DWORD PTR SS:[EBP+4023AD]                ; EAX=3F0000
003D0FD0    8B9D 91234000      MOV EBX,DWORD PTR SS:[EBP+402391]                ; EBX=C5E
……
003D107B    8BB5 85234000      MOV ESI,DWORD PTR SS:[EBP+402385]                ; ESI=406B07(这个就是OEP后的第二条指令来的,第一行代码被壳抽掉了)
003D1081    03C3               ADD EAX,EBX                                      ; EAX=eax+ebx=3F0000+C5E
003D1083    C600 E9            MOV BYTE PTR DS:[EAX],0E9                        ; 003F0C5E处写入E9远程跳
003D1086    40                 INC EAX
003D1087    8BCE               MOV ECX,ESI                                      ; alexprot.00406B07
……
003D112E    2BC8               SUB ECX,EAX                                      ; 计算跳去OEP后第二条指令的代码的值
003D1130    83E9 04            SUB ECX,4
003D1133    8908               MOV DWORD PTR DS:[EAX],ECX                       ; 计算出来值当然要填到上面的地址了
……
003D11DA    8B85 AD234000      MOV EAX,DWORD PTR SS:[EBP+4023AD]                ; 好了快到站了
003D11E0    894424 1C          MOV DWORD PTR SS:[ESP+1C],EAX                    ; 这里还要再玩一下,先跳去申请的3F0000的那里再跳去OEP后的第二条指令
003D11E4    61                 POPAD
003D11E5  - FFE0               JMP EAX                                          ; 跳去壳里,然后壳再跳去OEP后的第二条指令
进入壳抽代码处一下就可以找到第一行代码。好了,分析到此结束。
 
输入表的处理:
 
我取的以下两个地址
411000  开始写入数据地址
410FD0  记录地址
 
003D0A61   /EB 11              JMP SHORT 003D0A74
003D0A63   |90                 NOP
003D0A64   |8305 D00F4100 04   ADD DWORD PTR DS:[410FD0],4                      ; 当处理不同DLL时加8(第一次自己写个地址)
003D0A6B   |8985 7C244000      MOV DWORD PTR SS:[EBP+40247C],EAX                ; 执行原壳的代码
003D0A71   |C3                 RETN
003D0A72   |90                 NOP
003D0A73   |90                 NOP
003D0A74   /90                 NOP
003D0A75    90                 NOP
003D0A76    90                 NOP                                              ; ---------------------------
003D0A77    57                 PUSH EDI                                         ; 原壳代码
003D0A78    FF95 CC244000      CALL DWORD PTR SS:[EBP+4024CC]                   ; ---------------------------
003D0A7E    E8 E1FFFFFF        CALL 003D0A64                                    ; 这里修改Call上面的代码
003D0A83    90                 NOP
……
 
第二处就是写入输入表:
003D0BEC    58                 POP EAX                                          ; 出栈
003D0BED    53                 PUSH EBX
003D0BEE    8B1D D00F4100      MOV EBX,DWORD PTR DS:[410FD0]                    ; 把要写入IAT的地址放到EBX中
003D0BF4    8903               MOV DWORD PTR DS:[EBX],EAX                       ; API写到IAT中
003D0BF6    8919               MOV DWORD PTR DS:[ECX],EBX                       ; IAT地址写到程序调用中
003D0BF8    8305 D00F4100 04   ADD DWORD PTR DS:[410FD0],4                      ; 调用完毕递增
003D0BFF    5B                 POP EBX                                          ; EBX出栈
003D0C00    90                 NOP
003D0C01    90                 NOP
003D0C02    90                 NOP
003D0C03    90                 NOP
003D0C04    90                 NOP
003D0C05    90                 NOP                                              ; 去除原来的代码
003D0C06    90                 NOP
003D0C07    83C7 04            ADD EDI,4
003D0C0A    FECB               DEC BL
003D0C0C    90                 NOP                                              ; 前面已经出栈了,所以不用再出栈
 
附两个去花指令脚本:
PatList_Alex=_alex_push01,_alex_call01
 
[CODE_alex_push01]
S =60EB03EB03??EBFBE801000000??83C4040F318BD8EB03EB03??EBFBE801000000??83C4048BCAEB03EB03??EBFBE801000000??83C4040F312BC3EB03EB03??EBFBE801000000??83C4041BD10F3103C3EB03EB03??EBFBE801000000??83C40413D10F312BC3EB03EB03??EBFBE801000000??83C404EB05??????????EB03EB03??EBFBE801000000??83C4041BD1EB03EB03??EBFBE801000000??83C40485D275D661
R =909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090
 
[CODE_alex_call01]
S =E824000000EB01E98B44240CEB03EB03C7EBFBE801000000A883C4048380B80000000233C0EB01E9C35883C404EB03EB03C7EBFBE801000000A883C4045064FF350000000064892500000000EB01??FFFF
R =909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090
 
全文完,跟完后才发现这个壳原来……:-)
 
圣诞节快到了,先祝大家圣诞节愉快!身体健康!
Greetz:
 Fly.Jingulong,yock,tDasm.David.hexer,hmimys,ahao.UFO(brother).alan(sister).all of my friends and you!
 
By loveboom[DFCG][FCG][US]
Email:bmd2chen#tom.com
 
VMProtect V2.13保护壳加密工具 VMProtect V2.13保护壳加密工具完美版 立即下载

相关推荐

SProtect SK E2.3破解版

ASProtect 是功能非常完善的加壳、加密保护工具。能够在对软件加壳的同时进行各种护。如:反调试跟踪、自校验及用密钥加密保护等;还有多种限制使用措施,如:使用天数限制、次数限制及对应的注册提醒信息等。另外,该软件还具有密钥生成功能

ahri8.php,webshell/other.php at master · HaiChecker/webshell · GitHub

Echo (gzuncompress(base64_decode('eF5MmseutFyWpud9FaW/S8pWUd0QEDi1eoD33qOUUtjAe3/1zVdZgxwgDuxNxDZrvet5D/Hvyb5V/5iSdf23//dvfyEQgefQNyNyHEW/RZJ+igT7EklaJBD2Xv71f//Hv2djNy5/Ov/PvET/3MiLMtm77R9JttXj8Lb8j...

weixin_36118025的博客 3万+

SProtect详细脱壳教程

SProtect详细脱壳教程,原理剖析

Xikug’s Protecter v0.3外壳完全分析

Xikug’s Protecter v0.3【目     标】:XiKug’s Protecter v0.3主程序【工     具】:Olydbg1.1(diy版)、LORDPE、ImportREC1.6F 【任     务】:分析外壳  【操作平台】:WinXP sp2 【作     者】: LOVEBOOM[DFCG][FCG][US]【相关链接】: 自己去上网搜搜 【简要说明】: 这个壳看是

loveboom's Reverse Enginering 3255

航空机载总线网络概述

1.机载总线网络概述 现代战斗机的航空电子系统是航空电子技术经历了半个多世纪的漫长演变和不断进步的结果。航空电子系统结构的每次变化,其核心的机载总线网络技术也不断跨上新台阶,而且每次变革都能使飞机性能得到大幅提升。现代飞机的飞行与作战任务包括起飞、巡航、飞行控制、目标搜索、识别跟踪、火控计算、武器投射、制导、电子战、通信等,都需要航空电子系统承担,航空电子系统是现代战斗机的“大脑”和“神经中枢”,机载总线网络则是其关键的“神经网络”。在机载通讯领域发展过程中,具有代表性的典型总线有ARINC429、1553

qq_41854911的博客 1万+

Cadence17.4 Allegro PCB制板(gerber / 光绘)文件输出的顺序及注意点

Cadence Allegro PCB制板文件输出 (gerber 光绘文件输出)

weixin_45331044的博客 1万+

几种常用加壳软件图文详解

为了保护自己的软件不轻易被他人“借鉴”,有必要对软件进行一些加密保护,而这方面目前己有成熟的专业加密软件可选择。但不要太依赖壳的保护,大多数壳是可以被攻破的,还是在自身保护上下些功夫。加密软件比较多,但在强度与兼容性上做的好的并不多,这里向大家介绍几款常见的。    现在壳的发展一个趋势就是虚拟机保护,利用虚拟机保护后,能大大提高强度,因此建议尽可能使用此类技术保护软件。如Themida ,W

鸟儿飞的专栏 3万+

告别Modern Standby噩梦:Win11睡眠断网冻结的根源剖析与S3睡眠回归实战

本文深入剖析了Windows 11中Modern Standby(现代待机)模式导致睡眠后断网、系统冻结等问题的根源,指出其与硬件驱动、后台活动的兼容性矛盾。文章提供了通过修改注册表键值强制系统回归稳定S3睡眠状态的详细实战步骤,帮助用户彻底解决睡眠故障,实现可靠的远程访问与挂机任务。

weixin_29210727的博客 609

五款加壳软件特色对比

现在壳的发展一个趋势就是虚拟机保护,利用虚拟机保护后,能大大提高强度,因此建议尽可能使用此类技术保护软件。如Themida ,WinLicense,VMProtectr等壳带有虚拟机保护功能,因此得用好其SDK。 VMProtect VMProtect是一款纯虚拟机保护软件,官方链接:www.VMProtect.ru。它是当前最强的虚拟机保护软件,经VMProtect处理过的代码,至今

小航爱分享 1万+

Gemini 2.5 Pro国内免魔法直连教程:5分钟搞定专业级PPT图表(附折线图/柱状图案例)

本文详细介绍了如何利用Gemini 2.5 Pro快速生成专业级PPT图表,包括折线图和柱状图等常见商业图表。通过自然语言交互和智能图表生成功能,用户可以在5分钟内完成数据可视化,大幅提升工作效率。文章还提供了实战案例和高级技巧,帮助用户轻松应对各种商业场景需求。

weixin_30733003的博客 460

反爬虫:对抗最新反爬技术 Cloudflare详解

本文针对Cloudflare最新反爬机制提供完整解决方案,覆盖TLS指纹、行为轨迹、设备指纹等检测场景。文章首先分析Cloudflare的三重检测体系(TLS指纹、行为指纹、设备指纹)及其拦截表现,随后提出四种绕过方案:1)使用curl_cffi模拟浏览器TLS指纹;2)通过undetected-chromedriver移除自动化特征;3)Playwright结合stealth插件模拟人类行为;4)动态请求调度策略。重点推荐轻量级Python方案curl_cffi和浏览器自动化方案Playwright-st

数据知道的博客 4629

Greedy Fly's Crackme

前些天在Crakmes.de拿到一个keygenme,作者说这是for newbies的,好吧,我比初学者还弱搞了一整天什么都没弄出来 今天思路有点点清晰了,先写点东西总结一下再说! 这是个Name/Serial型的KM(keygenme) 怎么定位确定按钮我就不讲了,直接贴确定按钮的事件代码吧 这是个Name/Serial型的KM(keygenme) 怎么定位确定按钮我就不讲了,直接贴

潜心学习 891

TC3XX - MCAL知识点(二十四):UART MCAL配置及代码实战

UART驱动程序负责按照UART协议提供通信服务。ASCLIN模块为异步通信提供硬件支持,实现UART协议。UART驱动程序提供了配置、初始化、数据传输、接收等功能,还提供了中止传输和中止接收 abort等可选特性。软硬件匹配关系如下:UART驱动程序使用ASCLIN进行数据的传输和接收。驱动程序使用的关键硬件功能特性是:1、全双工异步工作模式2、支持半双工工作模式3、16字节的TXFIFO4、16字节的RXFIFO5、2 ~ 16位数据帧6、校验位生成/检查7、一个或两个停止位。

梦想技术家 1834

kerberos_API_fix

前言学脱壳时, 看到人家用kerberos.exe进行目标程序的API Trace. 可以先不上调试器, 看看cm调用的是哪些API(API名称,参数,API的调用地址). 这样就能先确定一些流程点. 还没等资料看完, 就发现这个工具有些问题. kerberos.exe在x86下好使, 在win7x64下不好使(运行后不打印TraceAPI的日志). 调了一天, 将k

博客标题不能为空 1274

量化交易零基础入门教程

特点 从零开始教编程。靠谱的量化交易学习资源稀少,且具有不讲编程、代码较难、过多等不适合新手等问题,本教程中则会从零开始教编程,解决量化入门过难过编程门槛这一问题。 量化与编程相结合。本教程不仅会教编程,而且会尽量结合量化情景,减少“我要做量化交易为什么要看这些用来培训程序员的东西”的愤懑。 简易精炼,快速入门。尽量只讲最核心最常用的知识,助你快速摆脱想学习量化却处处陌生不知所措的茫然的新手阶段。 读前说明 文后会有自测与自学,包括一些额外的延伸自学内容以及稍有难度的自测题目。 最最最基础的股票.

JanLEE 2888

从零实现深度学习框架——理解正则化(一)

本文介绍解决过拟合与欠拟合的方法——正则化,主要介绍L1和L2正则化。

日积月累,天道酬勤 3394

AcProtect 1.41 外壳分析

【目 标】: 应作者要求,这里不贴上软件名【工 具】:Olydbg1.1(diy版)、LORDPE、ImportREC1.6F 【任 务】:分析外壳 【操作平台】:Windows 2003 server 【作 者】: LOVEBOOM[DFCG][FCG][US]【相关链接】: ......【简要说明】: 脱ACPROTECT的壳并不多,以前最多只

loveboom's Reverse Enginering 1万+

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

ReverseMe 不完美分析过程

ReverseMe 不完美分析过程lnn1123/2006.3为了响应老大的号召http://bbs.pediy.com//showthread.php?s=&threadid=22990去下了个ReverseMe玩玩下玩东西,先看说明You must insert a MenuItem called "Detour" into the menu of theReverseMe. When cli

lnn1123的专栏 1521

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

加Zprotect壳解析

Zprotect是新一代的软件加密保护壳,拥有多项独创的新颖技术,保护后的文件极度复杂,让破解变成一种高成本的体力劳动。

黑KING的博客 4603

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

加密壳之ACProtect之OEP的处理

加密 解密 ACProtect OEP

小驹的专栏 6332

打造对抗 OpenProcess 检测的 OD

有些壳, 如 ExeCrypter 2.2.x 用 OpenProcess("CSRSS.EXE") 的方法来检测 OD.其原理如下:普通进程是没有 SeDebugPrivilege 的,  这时 OpenProcess(系统进程) 不能成功.但用 OD 调试时, OpenProcess(系统进程) 成功, 壳利用这一点来检测 OD.我们先来看两个例子.第一个例子test.exe=========

土星·北海若 2439

【转】脱壳工具

脱壳工具http://www.pediy.com/tools/unpacker.htm 文件类型侦测工具 peid 0.94

学习........ 4393

易语言软件加VMProtect壳的正确方法

https://www.cnblogs.com/fox2013/p/4553977.html VMP是一款很强大的加密壳,代码虚拟化技术可以很好的保护程序不被恶意修改破J但是很多人不知道怎么给自己的程序加壳,今天给大家晋级下加壳的正确方法 相信很多新手都以为只要把软件直接拖到VMP里重新编译一下就是加壳了其实这样是没有达到任何的防破J效果。易语言加VPM壳少不了这两行重要代码 置入...

ljw5888的博客 9862

ACProtect壳2.0版本的分析

随着壳的更新,保护技术也在不断的更新,那么我们在这里分析下2.0版本的ACP壳。 我们在将程序载入OD之后。选择SOD的OD隐藏,然后选择取消内存访问忽略,开始shift+F9,还是上次的程序,来到了int1,然后找到E句柄,数据窗口跟随,下断,shift+F9,下断,然后再次shift+F9 下断,然后再次shift+F9,然后取消所有的断点,点击M,00401000,F2下断,shift +

m0_37120576的博客 759

ASPROTECT 2.x 脱壳系列(一)

ASPROTECT 2.x 脱壳系列(一)【目    标】:DVD Fab Gold 2.9.4.2【工    具】:Olydbg1.1(diy版)、LORDPE、ImportREC1.6F【任    务】:简单的脱壳【操作平台】:Windows XP sp2【作    者】: LOVEBOOM[DFCG][FCG][US]【相关链接】: 自己搜索下【简要说明】: 时间在不断的减少,人越靠近死亡的

loveboom's Reverse Enginering 1万+

ASPROTECT 2.x 脱壳系列(三)

ASPROTECT 2.x 脱壳系列(三)【目    标】:BeeIcons 4.02.1【工    具】:Olydbg1.1(diy版)、LORDPE、ImportREC1.6F【任    务】:简单的脱壳【操作平台】:Windows XP sp2【作    者】:LOVEBOOM[DFCG][FCG][US]【相关链接】:自己搜索下【简要说明】:继上一篇,这次的目标前两篇的又有所不同了.难度稍

loveboom's Reverse Enginering 6277
上一篇: Encyrptpe 2003.5.18主程序Unpacking tut
下一篇: 简略分析某外挂外壳
bmd2chen
博客等级 码龄23年 34粉丝 45原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值