首页
社区
课程
招聘
[原创]ASProtect 2.11外壳分析
发表于: 2011-11-6 01:27 6446

[原创]ASProtect 2.11外壳分析

2011-11-6 01:27
6446
这是一个SMC补丁的里面的实例,他的方法有一步我完成不了,就自己分析了。大家感兴趣的可以看下。
以下完全自己的看法,如果和大家的看法不同,帮忙指出来一下,谢谢。
SMC补丁:在外壳中就是动态修改代码,由我们把我们的SMC代码写进磁盘文件,然后我们动态引导外壳处理。
先说下第一步:ASProtect外壳有4个解密代码的地址.我们要引导这4个地址,这几个地址都是JMP的形式存在。
jnz Decode
jmp xxxxxx2 修改为我们的地址。因为是动态解码,我们修改下面的地址,就会解码错误
jnz Decode1
jmp xxxxxx3这样依次修改到最后一个解码的地址,就是静态代码了
00468037    50              PUSH EAX
00468038    53              PUSH EBX
00468039    FFB5 ED090000   PUSH DWORD PTR SS:[EBP+9ED]
0046803F    8D45 35         LEA EAX,DWORD PTR SS:[EBP+35]
00468042    50              PUSH EAX
00468043    E9 82000000     JMP InlineMe.004680CA                    ; 跳到解码地址一

解码地址一,0x0046817B处硬件断点,开始解码地址二
0046816F    81E8 01000000   SUB EAX,1
00468175    0F85 19000000   JNZ InlineMe.00468194                    ; 判断解码代码的大小,是否继续解码
0046817B    E9 2E000000     JMP InlineMe.004681AE                    ; 跳到解码地址二

解码地址二,0x468225处硬件断点,跳向解码地址三
00468246    4B              DEC EBX
00468247    81FB 34F9FFFF   CMP EBX,-6CC                             ; 以负数形式比较大小
0046824D    0F85 0C000000   JNZ InlineMe.0046825F                    ; 判断是否继续解码
00468253    8BD1            MOV EDX,ECX
00468255    E9 27000000     JMP InlineMe.00468281                    ; 跳向解码地址三

解码地址三,依然断点:
00468354    81EE 01000000   SUB ESI,1                                ; 解码大小
0046835A    0F85 0B000000   JNZ InlineMe.0046836B                    ; 判断解码大小
00468360    E9 23000000     JMP InlineMe.00468388                    ; 跳向解码地址4

解码地址4,依然断点
00468419    83EE 01         SUB ESI,1                                ; 解码大小
0046841C  ^ 0F85 9DFFFFFF   JNZ InlineMe.004683BF                    ; 判断解码大小
00468422    B4 02           MOV AH,2                                                 ; 断点

接下来就是把储存的压缩后的代码解密到分配的内存空间,然后重定向等等,处理,返回到指定虚拟内存空间执行代码:
004684CB    6A 40           PUSH 40
004684CD    68 00100000     PUSH 1000
004684D2    FFB5 08040000   PUSH DWORD PTR SS:[EBP+408]              ; 大小
004684D8    6A 00           PUSH 0
004684DA    FF95 F0030000   CALL DWORD PTR SS:[EBP+3F0]              ; VirtualAlloc分配内存
004684E0    8985 CC010000   MOV DWORD PTR SS:[EBP+1CC],EAX           ; EAX=00970000
004684E6    8B9D 00040000   MOV EBX,DWORD PTR SS:[EBP+400]
004684EC    039D 0D040000   ADD EBX,DWORD PTR SS:[EBP+40D]
004684F2    50              PUSH EAX
004684F3    53              PUSH EBX
004684F4    E8 04010000     CALL InlineMe.004685FD                   ; 解码函数
004684F9    6A 40           PUSH 40
004684FB    68 00100000     PUSH 1000
00468500    FFB5 08040000   PUSH DWORD PTR SS:[EBP+408]              ; 大小
00468506    6A 00           PUSH 0
00468508    FF95 F0030000   CALL DWORD PTR SS:[EBP+3F0]              ; VirtualAlloc分配内存
0046850E    8985 31040000   MOV DWORD PTR SS:[EBP+431],EAX           ; EAX=009C0000

复制过程就是把解码到虚拟内存空间的代码,依次复制到VirtualAlloc第2次的地址,然后定位返回地址。
00468562    8B7C1A 0C       MOV EDI,DWORD PTR DS:[EDX+EBX+C]
00468566    0BFF            OR EDI,EDI
00468568    74 1E           JE SHORT InlineMe.00468588
0046856A    8B4C1A 10       MOV ECX,DWORD PTR DS:[EDX+EBX+10]
0046856E    0BC9            OR ECX,ECX
00468570    74 11           JE SHORT InlineMe.00468583
00468572    03BD D0010000   ADD EDI,DWORD PTR SS:[EBP+1D0]
00468578    8B741A 14       MOV ESI,DWORD PTR DS:[EDX+EBX+14]
0046857C    03F2            ADD ESI,EDX
0046857E    C1F9 02         SAR ECX,2
00468581    F3:A5           REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS>
00468583    83C3 28         ADD EBX,28
00468586  ^ EB DA           JMP SHORT InlineMe.00468562

接下来这个地址很重要:
004685E0    53              PUSH EBX
004685E1    68 00800000     PUSH 8000
004685E6    6A 00           PUSH 0
004685E8    56              PUSH ESI                                 ; 第一次的VirtualAlloc的地址
004685E9    FF95 F4030000   CALL DWORD PTR SS:[EBP+3F4]              ; VirtualFree
004685EF    68 0010A000     PUSH 0A01000     ;返回到这个虚拟空间地址
004685F4    C3              RETN

注意下面
00A010B6    6A 04           PUSH 4
00A010B8    68 00100000     PUSH 1000
00A010BD    68 46050000     PUSH 546                                     ; 大小
00A010C2    6A 00           PUSH 0
00A010C4    FF95 79294400   CALL DWORD PTR SS:[EBP+442979]               ; VirtualAlloc
00A010CA    8985 75294400   MOV DWORD PTR SS:[EBP+442975],EAX            ; EAX=00970000
00A010D0    8D9D 452A4400   LEA EBX,DWORD PTR SS:[EBP+442A45]
00A010D6    50              PUSH EAX
00A010D7    53              PUSH EBX
00A010D8    E8 74050000     CALL 00A01651                                ; 再次解码,第2次中的压缩代码到第3次的VirtualAlloc
00A010DD    8BC8            MOV ECX,EAX
00A010DF    8DBD 452A4400   LEA EDI,DWORD PTR SS:[EBP+442A45]
00A010E5    8BB5 75294400   MOV ESI,DWORD PTR SS:[EBP+442975]
00A010EB    F3:A4           REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] ; 解压出来的代码重新复制到第2次VirtualAlloc的空间
00A010ED    8B85 75294400   MOV EAX,DWORD PTR SS:[EBP+442975]
00A010F3    68 00800000     PUSH 8000
00A010F8    6A 00           PUSH 0
00A010FA    50              PUSH EAX                                     ; 第3次的地址
00A010FB    FF95 7D294400   CALL DWORD PTR SS:[EBP+44297D]               ; VirtualFree
00A01101    8D85 512C4400   LEA EAX,DWORD PTR SS:[EBP+442C51]
00A01107    50              PUSH EAX                                     ; jmp 0xA0130D
00A01108    C3              RETN

下面这里之后,就是处理E8E9,一系列处理完毕后依然会把解码出来的代码放回VirtualAlloc的第2次:
00A01339    6A 04           PUSH 4
00A0133B    68 00100000     PUSH 1000
00A01340    50              PUSH EAX
00A01341    6A 00           PUSH 0
00A01343    FF95 79294400   CALL DWORD PTR SS:[EBP+442979]               ; VirtualAlloc
00A01349    8985 75294400   MOV DWORD PTR SS:[EBP+442975],EAX            ; EAX=00970000
00A0134F    56              PUSH ESI
00A01350    8B1E            MOV EBX,DWORD PTR DS:[ESI]
00A01352    039D D8304400   ADD EBX,DWORD PTR SS:[EBP+4430D8]
00A01358    50              PUSH EAX
00A01359    53              PUSH EBX
00A0135A    E8 F2020000     CALL 00A01651                                ; 再次解码

上面是个循环处理,没必要详细了解
看着
00A015C1    61              POPAD
00A015C2    75 08           JNZ SHORT 00A015CC
00A015C4    B8 01000000     MOV EAX,1
00A015C9    C2 0C00         RETN 0C
00A015CC    68 501E9F00     PUSH 9F1E50                                  ; 新的地址
00A015D1    C3              RETN

009F1E50    55              PUSH EBP
009F1E51    8BEC            MOV EBP,ESP
009F1E53    83C4 B4         ADD ESP,-4C
009F1E56    B8 B81B9F00     MOV EAX,9F1BB8
009F1E5B    E8 383EFDFF     CALL 009C5C98
009F1E60    E8 5B17FDFF     CALL 009C35C0                                ; 跟进

接下来一直F8,直到下面的地址后才F7跟进,009C3690是一个变形JMP
009C3676    52              PUSH EDX
009C3677    E8 74DAFFFF     CALL 009C10F0                                ; JMP 到 kernel32.FreeLibrary
009C367C    E8 F3FCFFFF     CALL 009C3374
009C3681    807B 24 01      CMP BYTE PTR DS:[EBX+24],1
009C3685    75 03           JNZ SHORT 009C368A
009C3687    FF53 28         CALL DWORD PTR DS:[EBX+28]
009C368A    807B 24 00      CMP BYTE PTR DS:[EBX+24],0
009C368E    74 05           JE SHORT 009C3695
009C3690    E8 F7FEFFFF     CALL 009C358C                                ; 跟进

这里:
009F0938    56              PUSH ESI
009F0939    E8 7D000000     CALL 009F09BB                                ; SEH处理,处理的地址指向下面地址
009F093E    53              PUSH EBX                                     ; SEH处理的地址,断点

上面之后,接下来就是一系列的花指令,jmp等等,注意这条语句
009F0990    1BD1            SBB EDX,ECX
009F0992    5A              POP EDX
009F0993    8343 61 0D      ADD DWORD PTR DS:[EBX+61],0D                 ; 记下这里相加后的地址,数据窗口查看,跳过去下个断点
009F0997    81E3 580B2C39   AND EBX,392C0B58
009F099D    5B              POP EBX
009F099E    034424 38       ADD EAX,DWORD PTR SS:[ESP+38]
009F09A2    034424 18       ADD EAX,DWORD PTR SS:[ESP+18]

上面过后就是跳到系统代码,恢复SEH,上面下了断点之后运行,就到这里了,这个是重点,依次恢复到下面PUSH的地址,从009F0A0B    68 B0FE9E00     PUSH 9EFEB0开始一次向上恢复SEH,所谓的恢复,就相当于JMP吧:
009F09E1    67:64:8F06 0000 POP DWORD PTR FS:[0]
009F09E7    83C4 04         ADD ESP,4
009F09EA    2BF5            SUB ESI,EBP
009F09EC    5E              POP ESI
009F09ED    68 E4DD9C00     PUSH 9CDDE4
009F09F2    68 540A9F00     PUSH 9F0A54
009F09F7    68 94EB9E00     PUSH 9EEB94
009F09FC    68 74F69E00     PUSH 9EF674
009F0A01    68 E0E39E00     PUSH 9EE3E0
009F0A06    68 94D39E00     PUSH 9ED394
009F0A0B    68 B0FE9E00     PUSH 9EFEB0
009F0A10    C3              RETN   完全解码完毕

大家依次F8跟踪,处理SEH的时候就过去断点,每当发现这个特征的时候就去上面的地址下断点。
特征:
009ED7D1    C3              RETN    ; 返回到 7C9232A8 (ntdll.7C9232A8)

激动部分一:
009EFEB0    55              PUSH EBP                                     ; 向上拉,就能看见MessageBoxA了,然后一直F8+F7到就是跳到OEP了
009EFEB1    8BEC            MOV EBP,ESP
009EFEB3    81C4 F8FEFFFF   ADD ESP,-108
009EFEB9    53              PUSH EBX
009EFEBA    56              PUSH ESI
009EFEBB    33C0            XOR EAX,EAX
009EFEBD    8985 F8FEFFFF   MOV DWORD PTR SS:[EBP-108],EAX

激动部分二:
009EFDFB    68 30200000     PUSH 2030
009EFE00    A1 38369F00     MOV EAX,DWORD PTR DS:[9F3638]
009EFE05    50              PUSH EAX
009EFE06    A1 34369F00     MOV EAX,DWORD PTR DS:[9F3634]
009EFE0B    50              PUSH EAX
009EFE0C    6A 00           PUSH 0
009EFE0E    E8 5561FDFF     CALL 009C5F68                                ; JMP 到 user32.MessageBoxA

激动部分三:
009EFE79    A1 C4379F00     MOV EAX,DWORD PTR DS:[9F37C4]
009EFE7E    C600 E3         MOV BYTE PTR DS:[EAX],0E3
009EFE81    8D55 C8         LEA EDX,DWORD PTR SS:[EBP-38]
009EFE84    A1 2CB69F00     MOV EAX,DWORD PTR DS:[9FB62C]
009EFE89    E8 D692FFFF     CALL 009E9164
009EFE8E    E8 915DFFFF     CALL 009E5C24
009EFE93    8B45 FC         MOV EAX,DWORD PTR SS:[EBP-4]
009EFE96    E8 792DFDFF     CALL 009C2C14
009EFE9B    E8 60CEFFFF     CALL 009ECD00                                ; 跳向程序的OEP

JUMP To上面的地址的过程由于粗心大意,又要重新跟踪,我懒得跟踪了。,感兴趣的自己跟踪吧
00453B54    55              PUSH EBP
00453B55    8BEC            MOV EBP,ESP
00453B57    83C4 F0         ADD ESP,-10
00453B5A    B8 74394500     MOV EAX,InlineMe.00453974
00453B5F    E8 FC20FBFF     CALL InlineMe.00405C60
00453B64    A1 58504500     MOV EAX,DWORD PTR DS:[455058]
00453B69    8B00            MOV EAX,DWORD PTR DS:[EAX]
00453B6B    E8 9CE5FFFF     CALL InlineMe.0045210C
00453B70    A1 58504500     MOV EAX,DWORD PTR DS:[455058]
00453B75    8B00            MOV EAX,DWORD PTR DS:[EAX]
00453B77    BA B43B4500     MOV EDX,InlineMe.00453BB4                ; ASCII "Annoying NAG"
00453B7C    E8 9BE1FFFF     CALL InlineMe.00451D1C
00453B81    8B0D 38514500   MOV ECX,DWORD PTR DS:[455138]            ; InlineMe.00456BFC
00453B87    A1 58504500     MOV EAX,DWORD PTR DS:[455058]
00453B8C    8B00            MOV EAX,DWORD PTR DS:[EAX]
00453B8E    8B15 AC364500   MOV EDX,DWORD PTR DS:[4536AC]            ; InlineMe.004536F8
00453B94    E8 8BE5FFFF     CALL InlineMe.00452124
00453B99    A1 58504500     MOV EAX,DWORD PTR DS:[455058]
00453B9E    8B00            MOV EAX,DWORD PTR DS:[EAX]
00453BA0    E8 FFE5FFFF     CALL InlineMe.004521A4
00453BA5    E8 B201FBFF     CALL InlineMe.00403D5C

[课程]Linux pwn 探索篇!

上传的附件:
收藏
免费 6
支持
分享
最新回复 (3)
雪    币: 65
活跃值: (118)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
2
前来膜拜 韬哥
2011-11-6 08:45
0
雪    币: 102
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
只能看看高手的讲解,这是我学不来的
2011-11-6 16:06
0
雪    币: 1534
活跃值: (738)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
4
膜拜韬哥。。
2011-11-6 20:21
0
游客
登录 | 注册 方可回帖
返回
//