跳至主要内容

ASPACK 壳代码全解析

http://ift.tt/2B0IJS5
01237001 >  60              PUSHAD
01237002    E8 03000000     CALL 00_aspac.0123700A
01237007  - E9 EB045D45     JMP 468074F7                                        ; 花指令
0123700C    55              PUSH EBP
0123700D    C3              RETN
0123700E    E8 01000000     CALL 00_aspac.01237014
01237013    EB 5D           JMP SHORT 00_aspac.01237072                         ; 花指令
01237015    BB EDFFFFFF     MOV EBX,-0x13
0123701A    03DD            ADD EBX,EBP                                         ; ebx -0x13,就是把零头给减去了,因为本来的指令就是末尾带着13
0123701C    81EB 00700100   SUB EBX,0x17000                                     ; 然后减去这个数,怀疑是基址,看了一下果然是程序的加载基址
01237022    83BD 88040000 0>CMP DWORD PTR SS:[EBP+0x488],0x0
01237029    899D 88040000   MOV DWORD PTR SS:[EBP+0x488],EBX
0123702F    0F85 CB030000   JNZ 00_aspac.01237400                               ; 这个发现,跟这个地址里面的内容比较,如果不是0,直接跳转到popad附近了,感觉因该是判断有没有加壳的标志
01237035    8D85 94040000   LEA EAX,DWORD PTR SS:[EBP+0x494]                    ; 这个地方取了kernel32.dll,看下面的函数到时是干什么的把
0123703B    50              PUSH EAX                                            ; 这字符串入栈,2中可能,GetModuleHandleA或者LoadLibrayA
0123703C    FF95 A90F0000   CALL DWORD PTR SS:[EBP+0xFA9]                       ; 发现是kernel32.GetModuleHandleA,程序加载之后最少要加载ntdll和kernel32这个2个dll
01237042    8985 8C040000   MOV DWORD PTR SS:[EBP+0x48C],EAX                    ; 这个地址保存的是GetModuleHandle的返回值,也就是hModule
01237048    8BF0            MOV ESI,EAX                                         ; 现在esi =eax ,就是Kernel32的hModule
0123704A    8D7D 51         LEA EDI,DWORD PTR SS:[EBP+0x51]                     ; edi = VirtualAlloc字符串的地址,因为asp是压缩壳,这个行为很可能就是要解压缩
0123704D    57              PUSH EDI
0123704E    56              PUSH ESI                                            ; esi保存的是Kernel32.dll的句柄,然后Edi是字符串,下面的call基本上就是GetProcAddress了
0123704F    FF95 A50F0000   CALL DWORD PTR SS:[EBP+0xFA5]                       ;  kernel32.GetProcAddress
01237055    AB              STOS DWORD PTR ES:[EDI]                             ; 把eax中保存的值,也就是函数的地址,放入到Edi中保存的地址中
01237056    B0 00           MOV AL,0x0
01237058    AE              SCAS BYTE PTR ES:[EDI]                              ; 用al跟edi中的值进行比较,然后edi+1,应该是取下一字符串的
01237059  ^ 75 FD           JNZ SHORT 00_aspac.01237058
0123705B    3807            CMP BYTE PTR DS:[EDI],AL
0123705D  ^ 75 EE           JNZ SHORT 00_aspac.0123704D                         ; 啊这个循环就是循环的取函数的地址
0123705F    8D45 7A         LEA EAX,DWORD PTR SS:[EBP+0x7A]                     ; 这下面两句暂时没有看懂
01237062    FFE0            JMP EAX                                             ; 通过看内存发现,真是代码
01237064    F4              HLT
01237065    05 F1757561     ADD EAX,0x617575F1
0123706A    6C              INS BYTE PTR ES:[EDI],DX
0123706B    41              INC ECX
0123706C    6C              INS BYTE PTR ES:[EDI],DX
0123706D    6C              INS BYTE PTR ES:[EDI],DX
0123706E    6F              OUTS DX,DWORD PTR DS:[ESI]
0123706F    6300            ARPL WORD PTR DS:[EAX],AX
01237071    35 0DF17575     XOR EAX,0x7575F10D
01237076    61              POPAD
01237077    6C              INS BYTE PTR ES:[EDI],DX
01237078    46              INC ESI
01237079    72 65           JB SHORT 00_aspac.012370E0
0123707B    65:00AB 50F0757>ADD BYTE PTR GS:[EBX+0x7575F050],CH
01237082    61              POPAD
01237083    6C              INS BYTE PTR ES:[EDI],DX
01237084    50              PUSH EAX
01237085    72 6F           JB SHORT 00_aspac.012370F6
01237087    74 65           JE SHORT 00_aspac.012370EE
01237089    637400 00       ARPL WORD PTR DS:[EAX+EAX],SI
0123708D    8B9D 95050000   MOV EBX,DWORD PTR SS:[EBP+0x595]                    ; 这个地方没有看懂,不过都是0的话会不会是缓冲区地址?
01237093    0BDB            OR EBX,EBX
01237095    74 0A           JE SHORT 00_aspac.012370A1
01237097    8B03            MOV EAX,DWORD PTR DS:[EBX]
01237099    8785 99050000   XCHG DWORD PTR SS:[EBP+0x599],EAX
0123709F    8903            MOV DWORD PTR DS:[EBX],EAX
012370A1    8DB5 C5050000   LEA ESI,DWORD PTR SS:[EBP+0x5C5]                    ; 唉这个地方有点意思了,发现发现是取区段的RVA
012370A7    833E 00         CMP DWORD PTR DS:[ESI],0x0                          ; 如果的rva= 0,就进行跳转
012370AA    0F84 0A010000   JE 00_aspac.012371BA                                ; 跳哪去了暂时知道, 等会回来分析
012370B0    6A 04           PUSH 0x4                                            ; 内存保护属性:0x4 = PAGE_READWRITE
012370B2    68 00100000     PUSH 0x1000                                         ; 申请的内存类型:0x1000= MEM_COMMIT,直接提交了
012370B7    68 00180000     PUSH 0x1800                                         ; 0x1800 就是申请的内存大小
012370BC    6A 00           PUSH 0x0                                            ; 直接从0开始申请的,怀疑有重定位啊,要不这么猖狂?
012370BE    FF55 51         CALL DWORD PTR SS:[EBP+0x51]                        ;  kernel32.VirtualAlloc,返回值是申请的这个空间的地址
012370C1    8985 48010000   MOV DWORD PTR SS:[EBP+0x148],EAX                    ; 把内存地址保存起来
012370C7    8B46 04         MOV EAX,DWORD PTR DS:[ESI+0x4]                      ; esi 我们知道是取RVA,+0x4 应该就是取区段的大小了吧
012370CA    05 0E010000     ADD EAX,0x10E                                       ; 额,这个大小+0x10E,不明白,可能是编译器做的,也可能是这个壳自己做的
012370CF    0F84 B7000000   JE 00_aspac.0123718C
012370D5    6A 04           PUSH 0x4
012370D7    68 00100000     PUSH 0x1000
012370DC    50              PUSH EAX                                            ; 又根据区段的大小又申请了一块大小
012370DD    6A 00           PUSH 0x0
012370DF    FF55 51         CALL DWORD PTR SS:[EBP+0x51]                        ; kernel32.VirtualAlloc
012370E2    8985 44010000   MOV DWORD PTR SS:[EBP+0x144],EAX                    ; 还是把申请的空间的地址保存起来
012370E8    56              PUSH ESI                                            ; 这个没明白,后面慢慢看
012370E9    8B1E            MOV EBX,DWORD PTR DS:[ESI]
012370EB    039D 88040000   ADD EBX,DWORD PTR SS:[EBP+0x488]                    ; 基址+区段rva,是取这区段了
012370F1    FFB5 48010000   PUSH DWORD PTR SS:[EBP+0x148]                       ; 把申请的0x1800的地址的空间入栈了
012370F7    FF76 04         PUSH DWORD PTR DS:[ESI+0x4]                         ; 然后把区段的大小入栈了
012370FA    50              PUSH EAX                                            ; 按照区段大小申请的虚拟空间的地址,入栈,到这怀疑是进行拷贝了
012370FB    53              PUSH EBX                                            ; 区段的va
012370FC    E8 C7050000     CALL 00_aspac.012376C8                              ; 这个地方是对区段的数据进行拷贝,并返回这区段的大小
01237101    B3 01           MOV BL,0x1
01237103    80FB 00         CMP BL,0x0
01237106    75 4D           JNZ SHORT 00_aspac.01237155
01237108    FE85 EF000000   INC BYTE PTR SS:[EBP+0xEF]                          ; 这里增加了,上面的竟然mov bl,xx这条指令加了1
0123710E    50              PUSH EAX                                            ; 区段大小入栈
0123710F    51              PUSH ECX                                            ; 这个ecx的值忘记从哪里来的了QAQ
01237110    56              PUSH ESI                                            ; 区段rva
01237111    53              PUSH EBX                                            ; 区段的va
01237112    8BC8            MOV ECX,EAX                                         ; ecx = 区段的大小
01237114    83E9 05         SUB ECX,0x5                                         ; 区段大小减0x5
01237117    8BB5 44010000   MOV ESI,DWORD PTR SS:[EBP+0x144]                    ; 以这个区段大小申请的空间的地址
0123711D    33DB            XOR EBX,EBX                                         ; ebx =0
0123711F    0BC9            OR ECX,ECX                                          ; ecx 不变,还是区段大大小减0x5
01237121    74 2E           JE SHORT 00_aspac.01237151
01237123    78 2C           JS SHORT 00_aspac.01237151
01237125    AC              LODS BYTE PTR DS:[ESI]                              ; 将esi地址中保存的内容取一个字节放到eax中
01237126    3C E8           CMP AL,0xE8                                         ; 这里判断是不是call 和jmp ,解压?
01237128    74 0A           JE SHORT 00_aspac.01237134
0123712A    EB 00           JMP SHORT 00_aspac.0123712C
0123712C    3C E9           CMP AL,0xE9
0123712E    74 04           JE SHORT 00_aspac.01237134
01237130    43              INC EBX
01237131    49              DEC ECX                                             ; 反正上面都是循环从这个区段中找e8 和e9
01237132  ^ EB EB           JMP SHORT 00_aspac.0123711F
01237134    8B06            MOV EAX,DWORD PTR DS:[ESI]                          ; 把这个空间中有jmp或call的地址的下一条取出来个给了eax
01237136    EB 00           JMP SHORT 00_aspac.01237138
01237138    803E 05         CMP BYTE PTR DS:[ESI],0x5                           ; 跟0x5进行比较,暂时没看明白
0123713B  ^ 75 F3           JNZ SHORT 00_aspac.01237130
0123713D    24 00           AND AL,0x0
0123713F    C1C0 18         ROL EAX,0x18                                        ; 把eax循环左移0x18个
01237142    2BC3            SUB EAX,EBX
01237144    8906            MOV DWORD PTR DS:[ESI],EAX                          ; 怎么看着像rva,怀疑给是jmp和call加了密
01237146    83C3 05         ADD EBX,0x5
01237149    83C6 04         ADD ESI,0x4                                         ; call 或者jmp跳过去了,到下一条指令
0123714C    83E9 05         SUB ECX,0x5                                         ; 因该是循环往下找下面的字节
0123714F  ^ EB CE           JMP SHORT 00_aspac.0123711F                         ; 循环去找这个区段的jmp和call了
01237151    5B              POP EBX
01237152    5E              POP ESI
01237153    59              POP ECX
01237154    58              POP EAX                                             ; 还原寄存器的环境
01237155    EB 08           JMP SHORT 00_aspac.0123715F
01237157 >  0000            ADD BYTE PTR DS:[EAX],AL
01237159    1000            ADC BYTE PTR DS:[EAX],AL
0123715B >  0000            ADD BYTE PTR DS:[EAX],AL
0123715D    0F008B C88B3E03 STR WORD PTR DS:[EBX+0x33E8BC8]
01237164    BD 88040000     MOV EBP,0x488
01237169    8BB5 44010000   MOV ESI,DWORD PTR SS:[EBP+0x144]                    ; 这个区段大小开辟的空间的的地址
0123716F    C1F9 02         SAR ECX,0x2                                         ; ecx  =ecx/4
01237172    F3:A5           REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
01237174    8BC8            MOV ECX,EAX
01237176    83E1 03         AND ECX,0x3                                         ; 为什么要与上0x3?
01237179    F3:A4           REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
0123717B    5E              POP ESI
0123717C    68 00800000     PUSH 0x8000
01237181    6A 00           PUSH 0x0
01237183    FFB5 44010000   PUSH DWORD PTR SS:[EBP+0x144]
01237189    FF55 5E         CALL DWORD PTR SS:[EBP+0x5E]                        ;  kernel32.VirtualFree ,应该是拷贝完成了
0123718C    83C6 0C         ADD ESI,0xC                                         ; 下一个区段的rva
0123718F    833E 00         CMP DWORD PTR DS:[ESI],0x0                          ; 判断是不是最后一个区段
01237192  ^ 0F85 2FFFFFFF   JNZ 00_aspac.012370C7                               ; 上面应该是循环往区段中拷贝数据(解压),然后解密call 和jmp的指令
01237198    68 00800000     PUSH 0x8000
0123719D    6A 00           PUSH 0x0
0123719F    FFB5 48010000   PUSH DWORD PTR SS:[EBP+0x148]
012371A5    FF55 5E         CALL DWORD PTR SS:[EBP+0x5E]                        ;  kernel32.VirtualFree ,整个区段应该是拷贝完成了
012371A8    8B9D 95050000   MOV EBX,DWORD PTR SS:[EBP+0x595]                    ; 暂时还没有看懂
012371AE    0BDB            OR EBX,EBX
012371B0    74 08           JE SHORT 00_aspac.012371BA
012371B2    8B03            MOV EAX,DWORD PTR DS:[EBX]
012371B4    8785 99050000   XCHG DWORD PTR SS:[EBP+0x599],EAX
012371BA    8B95 88040000   MOV EDX,DWORD PTR SS:[EBP+0x488]                    ; edx = 基址
012371C0    8B85 91050000   MOV EAX,DWORD PTR SS:[EBP+0x591]                    ; 保存的是400000,应该是默认加载基址,猜测要判断进行是不是重定位了
012371C6    2BD0            SUB EDX,EAX                                         ; edx =现在的加载基址- 默认加载基址
012371C8    74 79           JE SHORT 00_aspac.01237243                          ; 如果=0,就跳转了,应该是判断没有进行重定位,下面的代码都是进行重定位的修复了
012371CA    8BC2            MOV EAX,EDX                                         ; eax == 两个基址减的差
012371CC    C1E8 10         SHR EAX,0x10                                        ; eax  右移16位,去掉地位,只保留高位
012371CF    33DB            XOR EBX,EBX                                         ; ebx =0
012371D1    8BB5 9D050000   MOV ESI,DWORD PTR SS:[EBP+0x59D]                    ; esi 取的是重定位表的rva
012371D7    03B5 88040000   ADD ESI,DWORD PTR SS:[EBP+0x488]                    ; esi += 基址 ,也就是重定位表的va
012371DD    833E 00         CMP DWORD PTR DS:[ESI],0x0                          ; 再判断一下是不是有重定位表
012371E0    74 61           JE SHORT 00_aspac.01237243
012371E2    8B4E 04         MOV ECX,DWORD PTR DS:[ESI+0x4]                      ; 重定位区段的大小
012371E5    83E9 08         SUB ECX,0x8
012371E8    D1E9            SHR ECX,1                                           ; ecx整个重定位区段内重定位项的个数
012371EA    8B3E            MOV EDI,DWORD PTR DS:[ESI]                          ; edi = 重定位表的rva
012371EC    03BD 88040000   ADD EDI,DWORD PTR SS:[EBP+0x488]                    ; edi = 重定位表的rva
012371F2    83C6 08         ADD ESI,0x8
012371F5    66:8B1E         MOV BX,WORD PTR DS:[ESI]                            ; 小循环
012371F8    C1EB 0C         SHR EBX,0xC                                         ; 判断重定位项的type
012371FB    83FB 01         CMP EBX,0x1
012371FE    74 0C           JE SHORT 00_aspac.0123720C
01237200    83FB 02         CMP EBX,0x2
01237203    74 16           JE SHORT 00_aspac.0123721B
01237205    83FB 03         CMP EBX,0x3
01237208    74 20           JE SHORT 00_aspac.0123722A
0123720A    EB 2C           JMP SHORT 00_aspac.01237238
0123720C    66:8B1E         MOV BX,WORD PTR DS:[ESI]
0123720F    81E3 FF0F0000   AND EBX,0xFFF
01237215    66:01041F       ADD WORD PTR DS:[EDI+EBX],AX
01237219    EB 1D           JMP SHORT 00_aspac.01237238
0123721B    66:8B1E         MOV BX,WORD PTR DS:[ESI]
0123721E    81E3 FF0F0000   AND EBX,0xFFF
01237224    66:01141F       ADD WORD PTR DS:[EDI+EBX],DX
01237228    EB 0E           JMP SHORT 00_aspac.01237238
0123722A    66:8B1E         MOV BX,WORD PTR DS:[ESI]                            ; bx = 重定位项
0123722D    81E3 FF0F0000   AND EBX,0xFFF                                       ; 取重定位项的偏移
01237233    01141F          ADD DWORD PTR DS:[EDI+EBX],EDX                      ; 基地址+偏移+基地址差,就是重定位的数据
01237236    EB 00           JMP SHORT 00_aspac.01237238
01237238    66:830E FF      OR WORD PTR DS:[ESI],0xFFFF                         ; 直接把重定位表给FFFF了,数据手工修复了之后就把重定位表给干掉了
0123723C    83C6 02         ADD ESI,0x2
0123723F  ^ E2 B4           LOOPD SHORT 00_aspac.012371F5                       ; 循环移动
01237241  ^ EB 9A           JMP SHORT 00_aspac.012371DD                         ; 大循环
01237243    8B95 88040000   MOV EDX,DWORD PTR SS:[EBP+0x488]                    ; edx = 程序基址
01237249    8BB5 A5050000   MOV ESI,DWORD PTR SS:[EBP+0x5A5]
0123724F    0BF6            OR ESI,ESI
01237251    74 11           JE SHORT 00_aspac.01237264
01237253    03F2            ADD ESI,EDX
01237255    AD              LODS DWORD PTR DS:[ESI]
01237256    0BC0            OR EAX,EAX
01237258    74 0A           JE SHORT 00_aspac.01237264
0123725A    03C2            ADD EAX,EDX
0123725C    8BF8            MOV EDI,EAX
0123725E    66:AD           LODS WORD PTR DS:[ESI]
01237260    66:AB           STOS WORD PTR ES:[EDI]
01237262  ^ EB F1           JMP SHORT 00_aspac.01237255
01237264    BE B4F00000     MOV ESI,0xF0B4                                      ; 感觉像是个rva,怀疑是IAT的地址
01237269    8B95 88040000   MOV EDX,DWORD PTR SS:[EBP+0x488]                    ; edx = 程序基址
0123726F    03F2            ADD ESI,EDX                                         ; esi = 程序基址 + esi(rva),得到的是一个va
01237271    8B46 0C         MOV EAX,DWORD PTR DS:[ESI+0xC]                      ; eax 应该也是一个偏移,现在这里就清晰了,+c导入表中的就是dll的的名字
01237274    85C0            TEST EAX,EAX                                        ; 判断eax是不是0,至少以全0结尾的表并没有很多
01237276    0F84 0D010000   JE 00_aspac.01237389
0123727C    03C2            ADD EAX,EDX                                         ; eax = 这个偏移的va,我看到是一个dll的名称,就是iat表
0123727E    8BD8            MOV EBX,EAX
01237280    50              PUSH EAX                                            ; eax = dll的名字,肯定是去获取模块句柄了
01237281    FF95 A90F0000   CALL DWORD PTR SS:[EBP+0xFA9]                       ; kernel32.GetModuleHandleA
01237287    85C0            TEST EAX,EAX                                        ; eax = 模块句柄,判断是不是为空
01237289    75 07           JNZ SHORT 00_aspac.01237292
0123728B    53              PUSH EBX
0123728C    FF95 AD0F0000   CALL DWORD PTR SS:[EBP+0xFAD]
01237292    8985 A9050000   MOV DWORD PTR SS:[EBP+0x5A9],EAX                    ; 保存hModule
01237298    C785 AD050000 0>MOV DWORD PTR SS:[EBP+0x5AD],0x0                    ; 这个没看懂
012372A2    8B95 88040000   MOV EDX,DWORD PTR SS:[EBP+0x488]                    ; edx = 程序基地址
012372A8    8B06            MOV EAX,DWORD PTR DS:[ESI]                          ; eax = 重定位表的rva
012372AA    85C0            TEST EAX,EAX
012372AC    75 03           JNZ SHORT 00_aspac.012372B1
012372AE    8B46 10         MOV EAX,DWORD PTR DS:[ESI+0x10]
012372B1    03C2            ADD EAX,EDX                                         ; eax = 导入表的va
012372B3    0385 AD050000   ADD EAX,DWORD PTR SS:[EBP+0x5AD]                    ; 这个地址是记录了已经修复了几个字节
012372B9    8B18            MOV EBX,DWORD PTR DS:[EAX]
012372BB    8B7E 10         MOV EDI,DWORD PTR DS:[ESI+0x10]                     ; 现在去的是IAT的Rva
012372BE    03FA            ADD EDI,EDX                                         ; edi = IAT表的VA
012372C0    03BD AD050000   ADD EDI,DWORD PTR SS:[EBP+0x5AD]                    ; edi中保存的是ebx的值,说明ebx就是名字的rva
012372C6    85DB            TEST EBX,EBX
012372C8    0F84 A5000000   JE 00_aspac.01237373
012372CE    F7C3 00000080   TEST EBX,0x80000000                                 ; 可能判断是不是名称导入的
012372D4    75 04           JNZ SHORT 00_aspac.012372DA
012372D6    03DA            ADD EBX,EDX                                         ; ebx = iat的名字的va
012372D8    43              INC EBX
012372D9    43              INC EBX
012372DA    53              PUSH EBX
012372DB    81E3 FFFFFF7F   AND EBX,0x7FFFFFFF                                  ; 判断后7为是不是有值
012372E1    53              PUSH EBX                                            ; 把函数名称入栈
012372E2    FFB5 A9050000   PUSH DWORD PTR SS:[EBP+0x5A9]                       ; 把这个dll的hModule入栈
012372E8    FF95 A50F0000   CALL DWORD PTR SS:[EBP+0xFA5]                       ; kernel32.GetProcAddress
012372EE    85C0            TEST EAX,EAX                                        ; 判断是否查找地址成功,eax = 函数地址
012372F0    5B              POP EBX
012372F1    75 72           JNZ SHORT 00_aspac.01237365
012372F3    F7C3 00000080   TEST EBX,0x80000000
012372F9    75 19           JNZ SHORT 00_aspac.01237314
012372FB    57              PUSH EDI
012372FC    8B46 0C         MOV EAX,DWORD PTR DS:[ESI+0xC]
012372FF    0385 88040000   ADD EAX,DWORD PTR SS:[EBP+0x488]
01237305    50              PUSH EAX
01237306    53              PUSH EBX
01237307    8D85 DB040000   LEA EAX,DWORD PTR SS:[EBP+0x4DB]
0123730D    50              PUSH EAX
0123730E    57              PUSH EDI
0123730F    E9 12010000     JMP 00_aspac.01237426
01237314    81E3 FFFFFF7F   AND EBX,0x7FFFFFFF
0123731A    8B85 8C040000   MOV EAX,DWORD PTR SS:[EBP+0x48C]
01237320    3985 A9050000   CMP DWORD PTR SS:[EBP+0x5A9],EAX
01237326    75 24           JNZ SHORT 00_aspac.0123734C
01237328    57              PUSH EDI
01237329    8BD3            MOV EDX,EBX
0123732B    4A              DEC EDX
0123732C    C1E2 02         SHL EDX,0x2
0123732F    8B9D A9050000   MOV EBX,DWORD PTR SS:[EBP+0x5A9]
01237335    8B7B 3C         MOV EDI,DWORD PTR DS:[EBX+0x3C]
01237338    8B7C3B 78       MOV EDI,DWORD PTR DS:[EBX+EDI+0x78]
0123733C    035C3B 1C       ADD EBX,DWORD PTR DS:[EBX+EDI+0x1C]
01237340    8B0413          MOV EAX,DWORD PTR DS:[EBX+EDX]
01237343    0385 A9050000   ADD EAX,DWORD PTR SS:[EBP+0x5A9]
01237349    5F              POP EDI
0123734A    EB 19           JMP SHORT 00_aspac.01237365
0123734C    57              PUSH EDI
0123734D    8B46 0C         MOV EAX,DWORD PTR DS:[ESI+0xC]
01237350    0385 88040000   ADD EAX,DWORD PTR SS:[EBP+0x488]
01237356    50              PUSH EAX
01237357    53              PUSH EBX
01237358    8D85 2C050000   LEA EAX,DWORD PTR SS:[EBP+0x52C]
0123735E    50              PUSH EAX
0123735F    57              PUSH EDI
01237360    E9 C1000000     JMP 00_aspac.01237426
01237365    8907            MOV DWORD PTR DS:[EDI],EAX                          ; 直接把iat的名称填充为地址
01237367    8385 AD050000 0>ADD DWORD PTR SS:[EBP+0x5AD],0x4
0123736E  ^ E9 2FFFFFFF     JMP 00_aspac.012372A2                               ; 因该是一个dll的小循环循环
01237373    8906            MOV DWORD PTR DS:[ESI],EAX                          ; esi保存的是iat表
01237375    8946 0C         MOV DWORD PTR DS:[ESI+0xC],EAX
01237378    8946 10         MOV DWORD PTR DS:[ESI+0x10],EAX
0123737B    83C6 14         ADD ESI,0x14                                        ; esi = 下一个dll的va
0123737E    8B95 88040000   MOV EDX,DWORD PTR SS:[EBP+0x488]                    ; edx = 程序加载基址
01237384  ^ E9 E8FEFFFF     JMP 00_aspac.01237271                               ; 大循环
01237389    8BB5 88040000   MOV ESI,DWORD PTR SS:[EBP+0x488]                    ; esi  =程序加基址
0123738F    8B7E 3C         MOV EDI,DWORD PTR DS:[ESI+0x3C]                     ; 这个没看懂,反正是pe头的东西
01237392    03FE            ADD EDI,ESI                                         ; edi = nt头va
01237394    51              PUSH ECX
01237395    54              PUSH ESP
01237396    51              PUSH ECX
01237397    54              PUSH ESP
01237398    6A 04           PUSH 0x4
0123739A    FF77 54         PUSH DWORD PTR DS:[EDI+0x54]
0123739D    56              PUSH ESI                                            ; 程序加载基址,更改内存属性
0123739E    FF55 6A         CALL DWORD PTR SS:[EBP+0x6A]                        ;  kernel32.VirtualProtect
012373A1    FF77 54         PUSH DWORD PTR DS:[EDI+0x54]
012373A4    56              PUSH ESI
012373A5    0FB74F 06       MOVZX ECX,WORD PTR DS:[EDI+0x6]
012373A9    0FB747 14       MOVZX EAX,WORD PTR DS:[EDI+0x14]
012373AD    8D7C07 F0       LEA EDI,DWORD PTR DS:[EDI+EAX-0x10]
012373B1    8DB5 C5050000   LEA ESI,DWORD PTR SS:[EBP+0x5C5]
012373B7    AD              LODS DWORD PTR DS:[ESI]                             ; 可以看出下面主要是更改区段的属性的
012373B8    85C0            TEST EAX,EAX
012373BA    74 40           JE SHORT 00_aspac.012373FC
012373BC    83C7 28         ADD EDI,0x28
012373BF    3B47 0C         CMP EAX,DWORD PTR DS:[EDI+0xC]
012373C2  ^ E0 F8           LOOPDNE SHORT 00_aspac.012373BC
012373C4    75 36           JNZ SHORT 00_aspac.012373FC
012373C6    41              INC ECX
012373C7    51              PUSH ECX
012373C8    56              PUSH ESI
012373C9    6A 01           PUSH 0x1
012373CB    F646 07 E0      TEST BYTE PTR DS:[ESI+0x7],0xE0
012373CF    74 03           JE SHORT 00_aspac.012373D4
012373D1    D12424          SHL DWORD PTR SS:[ESP],1
012373D4    F646 07 80      TEST BYTE PTR DS:[ESI+0x7],0x80
012373D8    74 03           JE SHORT 00_aspac.012373DD
012373DA    D12424          SHL DWORD PTR SS:[ESP],1
012373DD    F646 07 20      TEST BYTE PTR DS:[ESI+0x7],0x20
012373E1    74 04           JE SHORT 00_aspac.012373E7
012373E3    C12424 04       SHL DWORD PTR SS:[ESP],0x4
012373E7    FF77 08         PUSH DWORD PTR DS:[EDI+0x8]
012373EA    0385 88040000   ADD EAX,DWORD PTR SS:[EBP+0x488]
012373F0    50              PUSH EAX
012373F1    FF55 6A         CALL DWORD PTR SS:[EBP+0x6A]
012373F4    59              POP ECX
012373F5    AD              LODS DWORD PTR DS:[ESI]
012373F6    AD              LODS DWORD PTR DS:[ESI]
012373F7    8947 24         MOV DWORD PTR DS:[EDI+0x24],EAX
012373FA  ^ E2 BB           LOOPD SHORT 00_aspac.012373B7
012373FC    FF55 6A         CALL DWORD PTR SS:[EBP+0x6A]
012373FF    59              POP ECX
01237400    B8 D2110000     MOV EAX,0x11D2
01237405    50              PUSH EAX
01237406    0385 88040000   ADD EAX,DWORD PTR SS:[EBP+0x488]
0123740C    59              POP ECX
0123740D    0BC9            OR ECX,ECX
0123740F    8985 0E040000   MOV DWORD PTR SS:[EBP+0x40E],EAX
01237415    61              POPAD
01237416    75 08           JNZ SHORT 00_aspac.01237420
01237418    B8 01000000     MOV EAX,0x1
0123741D    C2 0C00         RETN 0xC
01237420    68 00000000     PUSH 0x0
01237425    C3              RETN


The post ASPACK 壳代码全解析 appeared first on cole.

http://ift.tt/eA8V8J reverse engineering, pack, reverse, shell, unpack December 07, 2017 at 06:20PM

评论

此博客中的热门博文

反Hook 之自己实现GetProcAddress和LoadLibraryA(c++ version)

http://ift.tt/2AocAD0 // 课上练习.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <windows.h> //要实现的功能: /* 自己实现GerProcAddress LoadLibraryA */ //思路: /* GerProcAddress和LoadLibraryA都是在Kernel32.dll中的 首要的任务就是找到Kernel32.dll,然后遍历IAT就能找到这两个函数 现在首要的难点就是如何找到kernel32.dll() 通过dll的加载顺序可以找到,而且虽然需要使用未文档化的API,但是好在windgb可以直接看,而且用到的也并不是很多 懒得去晚上搜了,直接自己实现一个得了,作为演示,能用就行(最好还是搜一个正规的结构体) */ /* 0: kd> dt _TEB /a nt!_TEB +0x000 NtTib : _NT_TIB +0x01c EnvironmentPointer : Ptr32 Void +0x020 ClientId : _CLIENT_ID +0x028 ActiveRpcHandle : Ptr32 Void +0x02c ThreadLocalStoragePointer : Ptr32 Void +0x030 ProcessEnvironmentBlock : Ptr32 _PEB //首先实现部分TEB结构体,因为只需要用的PEB的部分,所以实现到这就ok了 */ //构建 TEB typedef struct _TEB { //保证0x30是peb的结构体就ok了 struct _tem { DWORD a1; DWORD a2; DWORD a3; DWORD a4; DWORD a5; DWORD a6; DWORD a7; DWORD a8; DWORD a9; DWORD a10; ...

IDA动态调试ELF中遇到的问题(1)

https://ift.tt/2Gxnf2F 遇到 got SIGCHLD singal(child status has changed)...这种提示 singal fork了子进程 直接点yes,然后继续单步执行,出来提示 pass to application就行了 内存查看 用od习惯了之后,凡事都想右键看一下内存,但是IDA中好像没有那么如意, 目前只是在栈中右键发现有查看hex的选项 动态调试的时候的nop ida保存动态调试的时候修改的数据 方法一:在程序运行的时候保存 The post IDA动态调试ELF中遇到的问题(1) appeared first on cole . https://ift.tt/2q9Qf5g WHATEVER April 05, 2018 at 09:44AM

数据库(MySQL)编程之数据库和表的基本操作

http://ift.tt/2gOXg6X     数据库和表的基本操作 操作前的基本知识 基本 sql语句不区分大小写(关键字建议用大小写),但字符串常量区分大小写 sql语句可单行或多行书写,以; 结尾 关键字不能跨行或简写 可以用空格或者缩进来提高可读性 注释 sql标准 /**/ : 多行注释 "--":单行注释 mysql 标准: "#":单行注释 "COMMENT":为字段或列添加注释 创建和查看数据库 创建数据库 模板 CREATE DATABASE [IF NOT EXISTS ] db_name create_specification: IF NOT EXITSTS : 检查数据库是否存在,如果存在就不创建 creat_specification :创建条件 CHARACTER SET: 制定数据聚采用的字符集 COLLATE :制定数据库字符集的比较方式 DEFAULT :表示默认内容,即使没有制定该项,也有默认的值 # 创建数据库使用字符集为 UTF-8 ,使用规则为 uftf_bin CREATE DATABASE db_name DEFAULT CHARACTER SET utf8 COLLATE uft8_bin; 一般默认的数据库就是utf8 和utf8_bin的比较方式,因此一般创建数据库的时候都用 CREATE DATABASE db_name mysql> create database testdb; Query OK, 1 row affected (0.02 sec) 查看数据库 命令 SHOW DATABASES     mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sakila | | sys | | testdb | |...