ASP壳2.12浅层分析

查看 20|回复 1
作者:huchen   
引言
没想到拖了这么久哈哈哈哈,最近忙着工作和论文还有答辩(绝对不是我懒,绝对不是),最近因为一些原因马上要失业了,难道这就是不更新的代价吗!!不要啊!!!。废话不多说开始
ASP2.12分析
环境准备
xdbg、asp2.12壳文件、ida
首先进入xdbg调试asp文件分析
00405001       |跳转到40500E
0040500A            | 5D                 | pop ebp                             |
0040500B            | 45                 | inc ebp                             |
0040500C


image-20250502232205704.png (36.37 KB, 下载次数: 0)
下载附件
2025-5-24 17:35 上传

当第一次进来的时候可能是这样的,在进入call时的机器码发现不是在首位上,为了便于观察,我们只需要如图操作


image-20250502232437471.png (192.63 KB, 下载次数: 0)
下载附件
2025-5-24 17:36 上传

选中该包含该地址的代码,如图点击,然后在选择要跳转的地址,按相同的步骤,选择code(1字节上面的)就可以了
0040500E
这里的操作是载入kernel32.dll中的VirtuslAlloc和VirtualFree这两个函数。
0040508A            | 8B9D 31050000      | mov ebx,dword ptr ss:[ebp+531]      | 设置为0,暂时没发现作用
00405090            | 0BDB               | or ebx,ebx                          |
00405092            | 74 0A              | je capturescreen.40509E             |
00405094            | 8B03               | mov eax,dword ptr ds:[ebx]          |
00405096            | 8785 35050000      | xchg dword ptr ss:[ebp+535],eax     | ebp+535:sub_40553E+A
0040509C            | 8903               | mov dword ptr ds:[ebx],eax          |
0040509E            | 8DB5 69050000      | lea esi,dword ptr ss:[ebp+569]      | 各区段的RVA和Size信息
004050A4            | 833E 00            | cmp dword ptr ds:[esi],0            | esi:sub_40553E+5E
004050A7            | 0F84 21010000      | je capturescreen.4051CE             |
004050AD            | 6A 04              | push 4                              |
004050AF            | 68 00100000        | push 1000                           | 内存分配的类型MEM_COMMIT
004050B4            | 68 00180000        | push 1800                           | 内存分配的大小
004050B9            | 6A 00              | push 0                              |
004050BB            | FF95 4D050000      | call dword ptr ss:[ebp+54D]         | 调用VirtualAlloc
004050C1            | 8985 56010000      | mov dword ptr ss:[ebp+156],eax      | 分配内存的起始地址为5B0000
004050C7            | 8B46 04            | mov eax,dword ptr ds:[esi+4]        | 读取区段的大小
004050CA            | 05 0E010000        | add eax,10E                         |
004050CF            | 6A 04              | push 4                              |
004050D1            | 68 00100000        | push 1000                           |
004050D6            | 50                 | push eax                            | 内存分配的大小
004050D7            | 6A 00              | push 0                              |
004050D9            | FF95 4D050000      | call dword ptr ss:[ebp+54D]         | 调用VirtualAlloc
004050DF            | 8985 52010000      | mov dword ptr ss:[ebp+152],eax      | 内存分配的起始地址
004050E5            | 56                 | push esi                            | esi:sub_40553E+5E
004050E6            | 8B1E               | mov ebx,dword ptr ds:[esi]          | esi:sub_40553E+5E
004050E8            | 039D 22040000      | add ebx,dword ptr ss:[ebp+422]      |
004050EE            | FFB5 56010000      | push dword ptr ss:[ebp+156]         | 分配的内存地址
004050F4            | FF76 04            | push dword ptr ds:[esi+4]           | esi+4:sub_40553E+62
004050F7            | 50                 | push eax                            | 缓存的地址
004050F8            | 53                 | push ebx                            | 区段地址
004050F9            | E8 6E050000        | call capturescreen.40566C           | 解密函数,返回的是大小
004050FE            | B3 01              | mov bl,1                            |
00405100            | 80FB 00            | cmp bl,0                            | 判断是否是代码段
00405103            | 75 5E              | jne capturescreen.405163            |
00405105            | FE85 EC000000      | inc byte ptr ss:[ebp+EC]            | 代码段标识+1
0040510B            | 8B3E               | mov edi,dword ptr ds:[esi]          | esi:sub_40553E+5E
0040510D            | 03BD 22040000      | add edi,dword ptr ss:[ebp+422]      |
00405113            | FF37               | push dword ptr ds:[edi]             | 无意义代码开始
00405115            | C607 C3            | mov byte ptr ds:[edi],C3            |
00405118            | FFD7               | call edi                            |
0040511A            | 8F07               | pop dword ptr ds:[edi]              | 无意义代码结束
0040511C            | 50                 | push eax                            |
0040511D            | 51                 | push ecx                            |
0040511E            | 56                 | push esi                            | esi:sub_40553E+5E
0040511F            | 53                 | push ebx                            |
00405120            | 8BC8               | mov ecx,eax                         |
00405122            | 83E9 06            | sub ecx,6                           |
00405125            | 8BB5 52010000      | mov esi,dword ptr ss:[ebp+152]      | esi:sub_40553E+5E, ebp+152:sub_405071+F4
0040512B            | 33DB               | xor ebx,ebx                         |
0040512D            | 0BC9               | or ecx,ecx                          |
0040512F            | 74 2E              | je capturescreen.40515F             |
00405131            | 78 2C              | js capturescreen.40515F             |
00405133            | AC                 | lodsb                               | 从si寄存器按对应字节累计读入eax寄存器,读入后si就增加或者减少,即对缓存地址里的数据进行还原
00405134            | 3C E8              | cmp al,E8                           | 寻找E8,找call
00405136            | 74 0A              | je capturescreen.405142             |
00405138            | EB 00              | jmp capturescreen.40513A            |
0040513A            | 3C E9              | cmp al,E9                           | 寻找E9,找jmp
0040513C            | 74 04              | je capturescreen.405142             |
0040513E            | 43                 | inc ebx                             |
0040513F            | 49                 | dec ecx                             |
00405140            | EB EB              | jmp capturescreen.40512D            |
00405142            | 8B06               | mov eax,dword ptr ds:[esi]          | 读取跳转后的4字节
00405144            | EB 00              | jmp capturescreen.405146            |
00405146            | 803E 01            | cmp byte ptr ds:[esi],1             | 判断是否为1,不是则跳过修复
00405149            | 75 F3              | jne capturescreen.40513E            |
0040514B            | 24 00              | and al,0                            | 后面就是开始修复的操作,之后就是重新开始遍历寻找E8和E9
0040514D            | C1C0 18            | rol eax,18                          | 循环左移
00405150            | 2BC3               | sub eax,ebx                         |
00405152            | 8906               | mov dword ptr ds:[esi],eax          | esi:sub_40553E+5E
00405154            | 83C3 05            | add ebx,5                           |
00405157            | 83C6 04            | add esi,4                           | esi:sub_40553E+5E
0040515A            | 83E9 05            | sub ecx,5                           |
0040515D            | EB CE              | jmp capturescreen.40512D            |
0040515F            | 5B                 | pop ebx                             |
00405160            | 5E                 | pop esi                             | esi:sub_40553E+5E
00405161            | 59                 | pop ecx                             |
00405162            | 58                 | pop eax                             |
00405163            | EB 08              | jmp capturescreen.40516D            |
00405165            | 0000               | add byte ptr ds:[eax],al            |
00405167            | 58                 | pop eax                             |
00405168            | 0000               | add byte ptr ds:[eax],al            |
0040516A            | 0049 00            | add byte ptr ds:[ecx],cl            |
0040516D            | 8BC8               | mov ecx,eax                         |
0040516F            | 8B3E               | mov edi,dword ptr ds:[esi]          | esi:sub_40553E+5E
00405171            | 03BD 22040000      | add edi,dword ptr ss:[ebp+422]      | 区段地址
00405177            | 8BB5 52010000      | mov esi,dword ptr ss:[ebp+152]      | 缓存地址
0040517D            | C1F9 02            | sar ecx,2                           | 算术右移
00405180            | F3:A5              | rep movsd                           |
00405182            | 8BC8               | mov ecx,eax                         |
00405184            | 83E1 03            | and ecx,3                           |
00405187            | F3:A4              | rep movsb                           |
00405189            | 5E                 | pop esi                             | esi:sub_40553E+5E
0040518A            | 68 00800000        | push 8000                           | MEM_RELEASE属性
0040518F            | 6A 00              | push 0                              |
00405191            | FFB5 52010000      | push dword ptr ss:[ebp+152]         | 传入缓存地址
00405197            | FF95 51050000      | call dword ptr ss:[ebp+551]         | 调用VirtualFree函数
0040519D            | 83C6 08            | add esi,8                           | esi:sub_40553E+5E
004051A0            | 833E 00            | cmp dword ptr ds:[esi],0            | esi:sub_40553E+5E
004051A3            | 0F85 1EFFFFFF      | jne capturescreen.4050C7            | 判断区段是否还有区段的RVA和Size
004051A9            | 68 00800000        | push 8000                           |
004051AE            | 6A 00              | push 0                              |
004051B0            | FFB5 56010000      | push dword ptr ss:[ebp+156]         | ebp+156:sub_405071+F8
004051B6            | FF95 51050000      | call dword ptr ss:[ebp+551]         |
004051BC            | 8B9D 31050000      | mov ebx,dword ptr ss:[ebp+531]      | ebp+531:sub_40553E+6
004051C2            | 0BDB               | or ebx,ebx                          |
004051C4            | 74 08              | je capturescreen.4051CE             |
004051C6            | 8B03               | mov eax,dword ptr ds:[ebx]          |
004051C8            | 8785 35050000      | xchg dword ptr ss:[ebp+535],eax     | ebp+535:sub_40553E+A
这里的操作是对节区的还原处理操作,对.text区段、.data区段和.rsrc区段进行处理,text区段有对call和jmp代码进行还原的操作,每当调用解密函数时,数据就会被写入缓存地址,然后通过rep movsb,来写入原本的区段地址。这里可以被分为两个部分来处理,一个是处理代码段,;另一个处理非代码段。
004051CE            | 8B95 22040000      | mov edx,dword ptr ss:[ebp+422]      |
004051D4            | 8B85 2D050000      | mov eax,dword ptr ss:[ebp+52D]      | 这个基地址我不知道是怎么得到的,读取文件16进制也是这么多
004051DA            | 2BD0               | sub edx,eax                         | 看文章说是判断下当前的ImageBase 决定是否要进行重定位
004051DC            | 74 79              | je capturescreen.405257             |
004051DE            | 8BC2               | mov eax,edx                         | 下面是重定位的处理,由于没遇见过,所以就没有分析了
004051E0            | C1E8 10            | shr eax,10                          | eax:"USER32.dll"
004051E3            | 33DB               | xor ebx,ebx                         |
004051E5            | 8BB5 39050000      | mov esi,dword ptr ss:[ebp+539]      | ebp+539:sub_40553E+E
004051EB            | 03B5 22040000      | add esi,dword ptr ss:[ebp+422]      |
004051F1            | 833E 00            | cmp dword ptr ds:[esi],0            | esi:"`("
004051F4            | 74 61              | je capturescreen.405257             |
004051F6            | 8B4E 04            | mov ecx,dword ptr ds:[esi+4]        |
004051F9            | 83E9 08            | sub ecx,8                           |
004051FC            | D1E9               | shr ecx,1                           |
004051FE            | 8B3E               | mov edi,dword ptr ds:[esi]          | esi:"`("
00405200            | 03BD 22040000      | add edi,dword ptr ss:[ebp+422]      |
00405206            | 83C6 08            | add esi,8                           | esi:"`("
00405209            | 66:8B1E            | mov bx,word ptr ds:[esi]            | esi:"`("
0040520C            | C1EB 0C            | shr ebx,C                           |
0040520F            | 83FB 01            | cmp ebx,1                           |
00405212            | 74 0C              | je capturescreen.405220             |
00405214            | 83FB 02            | cmp ebx,2                           |
00405217            | 74 16              | je capturescreen.40522F             |
00405219            | 83FB 03            | cmp ebx,3                           |
0040521C            | 74 20              | je capturescreen.40523E             |
0040521E            | EB 2C              | jmp capturescreen.40524C            |
00405220            | 66:8B1E            | mov bx,word ptr ds:[esi]            | esi:"`("
00405223            | 81E3 FF0F0000      | and ebx,FFF                         |
00405229            | 66:01041F          | add word ptr ds:[edi+ebx],ax        |
0040522D            | EB 1D              | jmp capturescreen.40524C            |
0040522F            | 66:8B1E            | mov bx,word ptr ds:[esi]            | esi:"`("
00405232            | 81E3 FF0F0000      | and ebx,FFF                         |
00405238            | 66:01141F          | add word ptr ds:[edi+ebx],dx        |
0040523C            | EB 0E              | jmp capturescreen.40524C            |
0040523E            | 66:8B1E            | mov bx,word ptr ds:[esi]            | esi:"`("
00405241            | 81E3 FF0F0000      | and ebx,FFF                         |
00405247            | 01141F             | add dword ptr ds:[edi+ebx],edx      |
0040524A            | EB 00              | jmp capturescreen.40524C            |
0040524C            | 66:830E FF         | or word ptr ds:[esi],FFFF           | esi:"`("
00405250            | 83C6 02            | add esi,2                           | esi:"`("
00405253            | E2 B4              | loop capturescreen.405209           |
00405255            | EB 9A              | jmp capturescreen.4051F1            |
。重定位的操作
00405257            | 8B95 22040000      | mov edx,dword ptr ss:[ebp+422]      |
0040525D            | 8BB5 41050000      | mov esi,dword ptr ss:[ebp+541]      | ebp+541:sub_40553E+16
00405263            | 0BF6               | or esi,esi                          | esi:"`("
00405265            | 74 11              | je capturescreen.405278             |
00405267            | 03F2               | add esi,edx                         | esi:"`("
00405269            | AD                 | lodsd                               |
0040526A            | 0BC0               | or eax,eax                          | eax:"USER32.dll"
0040526C            | 74 0A              | je capturescreen.405278             |
0040526E            | 03C2               | add eax,edx                         | eax:"USER32.dll"
00405270            | 8BF8               | mov edi,eax                         | eax:"USER32.dll"
00405272            | 66:AD              | lodsw                               |
00405274            | 66:AB              | stosw                               |
00405276            | EB F1              | jmp capturescreen.405269            |
00405278            | BE 08260000        | mov esi,2608                        | 获取原本导入表的RVA,这里猜测是通过解密函数来实现这种静态获取的
0040527D            | 8B95 22040000      | mov edx,dword ptr ss:[ebp+422]      |
00405283            | 03F2               | add esi,edx                         | esi:"`("
00405285            | 8B46 0C            | mov eax,dword ptr ds:[esi+C]        | 获取导入表中的dll名称的RVA
00405288            | 85C0               | test eax,eax                        | eax:"USER32.dll"
0040528A            | 0F84 0A010000      | je capturescreen.40539A             |
00405290            | 03C2               | add eax,edx                         | eax:"USER32.dll"
00405292            | 8BD8               | mov ebx,eax                         | eax:"USER32.dll"
00405294            | 50                 | push eax                            | eax:"USER32.dll"
00405295            | FF95 4D0F0000      | call dword ptr ss:[ebp+F4D]         | 调用GetModuleHandle函数
0040529B            | 85C0               | test eax,eax                        | eax:"USER32.dll"
0040529D            | 75 07              | jne capturescreen.4052A6            | 如果获取失败,则用loadlibiraryA来导入
0040529F            | 53                 | push ebx                            |
004052A0            | FF95 510F0000      | call dword ptr ss:[ebp+F51]         | ebp+F51:sub_405F3C+28
004052A6            | 8985 45050000      | mov dword ptr ss:[ebp+545],eax      | ebp+545:sub_40553E+1A
004052AC            | C785 49050000 0000 | mov dword ptr ss:[ebp+549],0        | ebp+549:sub_40553E+1E
004052B6            | 8B95 22040000      | mov edx,dword ptr ss:[ebp+422]      | 取出基地址Imagebase
004052BC            | 8B06               | mov eax,dword ptr ds:[esi]          | 取OriginalFirstThunk值
004052BE            | 85C0               | test eax,eax                        | 如果为0的话就取FirstThunk
004052C0            | 75 03              | jne capturescreen.4052C5            |
004052C2            | 8B46 10            | mov eax,dword ptr ds:[esi+10]       | eax:"USER32.dll"
004052C5            | 03C2               | add eax,edx                         | eax:"USER32.dll"
004052C7            | 0385 49050000      | add eax,dword ptr ss:[ebp+549]      | 加上偏移
004052CD            | 8B18               | mov ebx,dword ptr ds:[eax]          | eax:"USER32.dll"
004052CF            | 8B7E 10            | mov edi,dword ptr ds:[esi+10]       | 取FirstThunk
004052D2            | 03FA               | add edi,edx                         |
004052D4            | 03BD 49050000      | add edi,dword ptr ss:[ebp+549]      | 加上偏移
004052DA            | 85DB               | test ebx,ebx                        |
004052DC            | 0F84 A2000000      | je capturescreen.405384             |
004052E2            | F7C3 00000080      | test ebx,80000000                   | 判断是不是序号导入
004052E8            | 75 04              | jne capturescreen.4052EE            |
004052EA            | 03DA               | add ebx,edx                         |
004052EC            | 43                 | inc ebx                             |
004052ED            | 43                 | inc ebx                             | 获取到函数名
004052EE            | 53                 | push ebx                            | 保存ebx
004052EF            | 81E3 FFFFFF7F      | and ebx,7FFFFFFF                    | 去掉最高位
004052F5            | 53                 | push ebx                            |
004052F6            | FFB5 45050000      | push dword ptr ss:[ebp+545]         | 当前dll的句柄
004052FC            | FF95 490F0000      | call dword ptr ss:[ebp+F49]         | 调用GetProcAdrress函数
00405302            | 85C0               | test eax,eax                        | eax:"USER32.dll"
00405304            | 5B                 | pop ebx                             | 返回原来的ebx
00405305            | 75 6F              | jne capturescreen.405376            | 成功返回就跳走
00405307            | F7C3 00000080      | test ebx,80000000                   |
0040530D            | 75 19              | jne capturescreen.405328            |
0040530F            | 57                 | push edi                            |
00405310            | 8B46 0C            | mov eax,dword ptr ds:[esi+C]        | eax:"USER32.dll", esi+C:"n*"R32.dll"
00405313            | 0385 22040000      | add eax,dword ptr ss:[ebp+422]      |
00405319            | 50                 | push eax                            | eax:"USER32.dll"
0040531A            | 53                 | push ebx                            |
0040531B            | 8D85 75040000      | lea eax,dword ptr ss:[ebp+475]      |
00405321            | 50                 | push eax                            | eax:"USER32.dll"
00405322            | 57                 | push edi                            |
00405323            | E9 98000000        | jmp capturescreen.4053C0            |
00405328            | 81E3 FFFFFF7F      | and ebx,7FFFFFFF                    |
0040532E            | 8B85 26040000      | mov eax,dword ptr ss:[ebp+426]      |
00405334            | 3985 45050000      | cmp dword ptr ss:[ebp+545],eax      | ebp+545:sub_40553E+1A
0040533A            | 75 24              | jne capturescreen.405360            |
0040533C            | 57                 | push edi                            |
0040533D            | 8BD3               | mov edx,ebx                         |
0040533F            | 4A                 | dec edx                             |
00405340            | C1E2 02            | shl edx,2                           |
00405343            | 8B9D 45050000      | mov ebx,dword ptr ss:[ebp+545]      | ebp+545:sub_40553E+1A
00405349            | 8B7B 3C            | mov edi,dword ptr ds:[ebx+3C]       |
0040534C            | 8B7C3B 78          | mov edi,dword ptr ds:[ebx+edi+78]   |
00405350            | 035C3B 1C          | add ebx,dword ptr ds:[ebx+edi+1C]   |
00405354            | 8B0413             | mov eax,dword ptr ds:[ebx+edx]      | eax:"USER32.dll"
00405357            | 0385 45050000      | add eax,dword ptr ss:[ebp+545]      | ebp+545:sub_40553E+1A
0040535D            | 5F                 | pop edi                             |
0040535E            | EB 16              | jmp capturescreen.405376            |
00405360            | 57                 | push edi                            |
00405361            | 8B46 0C            | mov eax,dword ptr ds:[esi+C]        | eax:"USER32.dll", esi+C:"n*"R32.dll"
00405364            | 0385 22040000      | add eax,dword ptr ss:[ebp+422]      |
0040536A            | 50                 | push eax                            | eax:"USER32.dll"
0040536B            | 53                 | push ebx                            |
0040536C            | 8D85 C6040000      | lea eax,dword ptr ss:[ebp+4C6]      |
00405372            | 50                 | push eax                            | eax:"USER32.dll"
00405373            | 57                 | push edi                            |
00405374            | EB 4A              | jmp capturescreen.4053C0            |
00405376            | 8907               | mov dword ptr ds:[edi],eax          | 返回的函数地址写进IAT
00405378            | 8385 49050000 04   | add dword ptr ss:[ebp+549],4        | 循环填IAT
0040537F            | E9 32FFFFFF        | jmp capturescreen.4052B6            |
00405384            | 8906               | mov dword ptr ds:[esi],eax          | esi:"`(", eax:"USER32.dll"
00405386            | 8946 0C            | mov dword ptr ds:[esi+C],eax        | esi+C:"n*", eax:"USER32.dll"
00405389            | 8946 10            | mov dword ptr ds:[esi+10],eax       | eax:"USER32.dll"
0040538C            | 83C6 14            | add esi,14                          | 下一个dll
0040538F            | 8B95 22040000      | mov edx,dword ptr ss:[ebp+422]      |
00405395            | E9 EBFEFFFF        | jmp capturescreen.405285            |
这里是为原来的PE导入IAT
0040539A            | B8 10190000        | mov eax,1910                        | 原PE文件的入口点
0040539F            | 50                 | push eax                            |
004053A0            | 0385 22040000      | add eax,dword ptr ss:[ebp+422]      | 换成VA
004053A6            | 59                 | pop ecx                             | ecx:EntryPoint
004053A7            | 0BC9               | or ecx,ecx                          | ecx:EntryPoint
004053A9            | 8985 A8030000      | mov dword ptr ss:[ebp+3A8],eax      |把入口点存入[ebp+3A8]里,在查找以下这个地址就是下面push 0中0的地址
004053AF            | 61                 | popad                               | 返回壳之前的状态
004053B0            | 75 08              | jne capturescreen.4053BA            |
004053B2            | B8 01000000        | mov eax,1                           |
004053B7            | C2 0C00            | ret C                               |
004053BA            | 68 10194000        | push capturescreen.401910           |这里本来是push 0,然后通过地址0x4053A9动态修改,从而实现跳转到真正的入口点
004053BF            | C3                 | ret                                 | 跳转到真正的入口点
通过动态修改地址内容,跳转到真正的入口点
至此asp2.12壳浅层分析完毕,这里还没有去分析解密函数内部的内容。
在参考文章中,都是把解密函数用IDA把解密函数给抠出来,编译为obj使用的
接下来就是代码的分析,我把我认为的困难的部分给拎出来单独说一下
首先就是
if(pTemp.VirtualAddress AddressOfEntryPoint
    && (pTemp.VirtualAddress + pTemp.Misc.VirtualSize) > newOptHead->AddressOfEntryPoint)
{
    packaddr = (LPBYTE)(pImageBase + pTemp.PointerToRawData + 0x57c);//0x57c是加密数据的偏移
    //修正解压函数地址
    g_esi = (DWORD)(pNewPe + pTemp.VirtualAddress + 0x70E - 0x44403E);
    //修正OEP
    DWORD dwOEP = *(DWORD*)(pNewPe + pTemp.VirtualAddress + 0x39b);
    newOptHead->AddressOfEntryPoint = dwOEP;
    //修正导入表数据目录
    DWORD dwIAT = *(DWORD*)(pNewPe + pTemp.VirtualAddress + 0x279);
    newOptHead->DataDirectory[1].VirtualAddress = dwIAT;
    //取出地址表异或值
    bXorVal = *(BYTE*)(pNewPe + pTemp.VirtualAddress + 0x148);
    //地址表是否参与异或运算
    isXor = *(BYTE*)(pNewPe + pTemp.VirtualAddress + 0x145) > 0 ? 0 : 1;
}
首先看packaddr,这个指针是加密区段的内存偏移,这里是通过文件偏移来读取区段的偏移地址。去下图,0x1A00 + 0x57C = 0x1F7C,0x1A00是.aspack区段的文件偏移地址。


image-20250522215641433.png (14.52 KB, 下载次数: 0)
下载附件
2025-5-24 17:37 上传

那0x57C又是怎么来的呢?这里先回到调试器中,看到0x40509E地址,这里就把各区段的RVA和Size存在esi寄存器中,把[ebp + 569]地址转到内存中,如下图的内存1这里的偏移的地址就是0x57C


image-20250522220115611.png (125.05 KB, 下载次数: 0)
下载附件
2025-5-24 17:37 上传

接下来就是g_esi,这个是解密函数里需要用到的,在调试器中如下图


image-20250524001504251.png (10.97 KB, 下载次数: 0)
下载附件
2025-5-24 17:37 上传



image-20250522223554308.png (97.02 KB, 下载次数: 0)
下载附件
2025-5-24 17:38 上传

在解密函数中都会有调用0x405C96,而0x405C96这个函数每次都会返回给esi这个寄存器固定的值,这里的常量与代码中的不一样,但经过调试,得出的结果是一样的,我这里是0x405C9B - 0x4445CB = 0xFFFC16D0,得到exi后进行下一个代码,从0x40570E开始以eax为偏移获取后续的数据,由于基址为0x40000,所以偏移量为0x570E,因此代码中是求esi,通过恒等式移项就可以,即  esi + 0x44403E = 基址 + 0x570E ==> esi  = 基址 + 0x570E - 0x44403E


image-20250524002346214.png (36.8 KB, 下载次数: 0)
下载附件
2025-5-24 17:38 上传

接下来是OEP,只需要注意代码中的数据,如图


image-20250524004139212.png (107.45 KB, 下载次数: 0)
下载附件
2025-5-24 17:38 上传

标灰的地方就是OEP的RVA了,所以直接读取该数据所在的RVA的地址了
下面的导入表的修正也是同样的道理,直接贴图就不细说了


image-20250524004427530.png (142.13 KB, 下载次数: 0)
下载附件
2025-5-24 17:39 上传

下面是jmp/call指令还原的条件判断,但是文章说
jmp/CALL后面的第一个字节为还原条件,针对不同的程序,判断条件不同
因此可能有dll之类不同的分类,总之在当前情况下就是还原条件,后面会详说
接下来就是还原跳转指令了,如图中的0x405133地址的代码,解密函数中的参数就有缓存地址,因此执行解密函数后,缓存地址就是需要还原的数据,代码中fixCode函数中的 char *addrbuff 参数好像没有用处。下面的代码就是修复的操作,根据汇编语言来写成高级语言


image-20250524111909689.png (89.11 KB, 下载次数: 0)
下载附件
2025-5-24 17:39 上传

然后我认为代码中比较难理解的部分我就分析完了,接下来是提取ida中代码编译成obj文件的操作说明


image-20250524164532888.png (81.82 KB, 下载次数: 0)
下载附件
2025-5-24 17:39 上传

首先载入IDA找到解密函数的地址,这里我把这个进行了函数处理,就是把这个当成函数来看待,从而生成函数相关的栈帧、参数、局部变量之类的。
然后把这函数全都复制出来,粘贴到asm文件,再用masm执行编译为obj文件的命令,由于我这边没有masm环境,想尝试的可以自行尝试和搜索资料。这里不仅仅只复制解密函数,还需要复制以前的代码,也就是call里面的代码。
至此asp分析完毕。
附件:

asp代码和测试文件.rar
(16.28 KB, 下载次数: 2)
2025-5-24 17:49 上传
点击文件名下载附件
下载积分: 吾爱币 -1 CB

参考资料:
[AsPack 2.12 分析及静态脱壳机编写,附源码]([原创]AsPack 2.12 分析及静态脱壳机编写,附源码-加壳脱壳-看雪-安全社区|安全招聘|kanxue.com)
AsPack2.12分析及静态脱壳机的编写

函数, 地址

jsyzjj   

建议标题使用 ASPack 而非简写 ASP。
因为他家还有个壳叫 ASProtect,使用 ASP 简写容易混淆。
您需要登录后才可以回帖 登录 | 立即注册

返回顶部