1 ;处理外壳程序
2 DisposeShell PROC
3
4 ;局部变量
5 LOCAL ShellBufferMap :DWORD ;VirtualAlloc 返回值
6 LOCAL ShellBufferMapUsed :DWORD ;shell代码的长度
7 LOCAL MEM :DWORD ;为压缩花指令+shell代码申请的内存
8 LOCAL MEMSize :DWORD ;大小
9 LOCAL ShellSize :DWORD ;shell的大小
10 LOCAL ShellSize_NoPack :DWORD ;未压缩时,ShellEnd到ShellStart的大小
11 LOCAL FunkCodeSize :DWORD ;垃圾代码的大小
12
13 ;因为这是子程序,保存寄存器值
14 pushad
15 ;*******申请内存*******
16 invoke VirtualAlloc, NULL, 20000h, MEM_COMMIT, PAGE_READWRITE
17 mov ShellBufferMap,eax ;ShellBufferMap====VirtualAlloc 返回值
18 ;*******在申请的内存产生花指令*******
19 invoke MakeFunkCode,ShellBufferMap
20 ;FunkCodeSize==MakeFunkCode返回值,垃圾代码的大小
21 mov FunkCodeSize,eax
22 ;*******读入外壳*******
23 ;ShellEnd,ShellStart,shell.asm中的标号
24 mov ecx,ShellEnd-ShellStart
25 ;未压缩时,ShellEnd到ShellStart的大小
26 mov ShellSize_NoPack,ecx
27 ;复制ShellStart到ShellEnd的代码到缓冲区
28 lea esi,ShellStart
29 mov edi,ShellBufferMap
30 add edi,FunkCodeSize
31 rep movsb ;复制ShellEnd,ShellStart之间的代码,到ShellBufferMap
32 ;*******保存OEP
33 mov ebx,ShellBufferMap
34 add ebx,FunkCodeSize ;ebx=花指令结束的地址
35 add ebx,OEP-ShellStart ;ebx==oep变量地址-ShellStart标号地址
36 mov edx,PeHeadBase ;edx==NT头
37 assume edx : ptr IMAGE_NT_HEADERS
38 mov eax,dword ptr [edx].OptionalHeader.AddressOfEntryPoint ;OEP给eax
39 mov dword ptr [ebx],eax ;oep给[ebx]指向的地方,即shell里OEP变量的值
40 ;*******保存是否处理输入表的标记
41 mov ebx,ShellBufferMap ;S_IsProtImpTable,IsProtImpTable标记
42 add ebx,FunkCodeSize
43 add ebx,S_IsProtImpTable-ShellStart
44 mov eax,IsProtImpTable
45 mov dword ptr [ebx],eax
46 ;*******保存输入表地址
47 ;输入表未加密,保存输入表地址到ImpTableAddr
48 .if IsProtImpTable == 0
49 mov eax,dword ptr [edx].OptionalHeader.DataDirectory[SIZEOF IMAGE_DATA_DIRECTORY].VirtualAddress
50 mov ebx,ShellBufferMap
51 add ebx,FunkCodeSize
52 add ebx,ImpTableAddr-ShellStart
53 mov dword ptr [ebx],eax
54 ;在加壳时,输入表已加密
55 ;shellstart到end的大小给ImpTableAddr,复制加密过的输入表信息到shell代码的后面
56 .else
57 mov eax,ShellSize_NoPack
58 mov ebx,ShellBufferMap
59 add ebx,FunkCodeSize
60 add ebx,ImpTableAddr-ShellStart
61 mov dword ptr [ebx],eax
62 mov edi,ShellBufferMap ;edi==
63 add edi,FunkCodeSize
64 add edi,ShellSize_NoPack;把MapOfImpProt复制到ShellBufferMap
65 mov esi,MapOfImpProt ;edi=map+funkcodesize+shellsize
66 mov ecx,MapOfImpProtUsed
67 add ShellSize_NoPack,ecx
68 rep movsb
69 .endif
70 ;*******保存特殊代码加密信息
71 .if IsCodeProt == 1
72 mov ebx,ShellBufferMap
73 add ebx,FunkCodeSize
74 add ebx,S_IsCodeProt-ShellStart
75 mov dword ptr [ebx],1
76 mov eax,ShellSize_NoPack
77 mov ebx,ShellBufferMap
78 add ebx,FunkCodeSize
79 add ebx,CodeProtAddr-ShellStart
80 mov dword ptr [ebx],eax
81 mov edi,ShellBufferMap
82 add edi,FunkCodeSize
83 add edi,ShellSize_NoPack
84 mov esi,MapOfCodeProt
85 mov ecx,MapOfCodeProtUsed
86 add ShellSize_NoPack,ecx
87 rep movsb
88 .endif
89 ;*******保存压缩块表信息
90 mov ecx,0a0h
91 lea esi,PackSection ;全局变量,保存还原区块的信息
92 mov edi,ShellBufferMap
93 add edi,FunkCodeSize
94 add edi,S_PackSection-ShellStart
95 rep movsb ;PackSection还原信息追加写入ShellBufferMap
96 ;*******
97 mov eax,FunkCodeSize
98 add ShellSize_NoPack,eax;ShellSize_NoPack==花指令长度+shell代码长度
99 ;*******压缩花指令+shell代码
100 mov eax,ShellSize_NoPack
101 mov edx, 9
102 mul edx
103 shr eax,3
104 add eax,16
105 mov MEMSize,eax ;计算需要占用的内存空间
106 invoke VirtualAlloc, NULL, eax, MEM_COMMIT, PAGE_READWRITE
107 mov MEM, eax
108 invoke aP_pack,ShellBufferMap,MEM,ShellSize_NoPack,lpPackBuffer,0
109 mov ShellBufferMapUsed,eax
110 ;*******读取外壳引导段**********
111 ;复制shell0到MapOfShell(上层函数申请的buffer)
112 mov ecx,ShellEnd0-ShellStart0
113 mov ShellSize,ecx
114 mov edi,MapOfShell
115 lea esi,ShellStart0
116 rep movsb
117 .if IsPackRes == 1 ;如果压缩资源被选中,把压缩的资源放到shell0后面
118 mov ecx,MapOfPackResUsed
119 add ShellSize,ecx
120 mov esi,MapOfPackRes
121 rep movsb
122 .endif
123 ;*******写入压缩后的外壳 ;MapOfShell在加上压缩后的shell
124 ;追加加密后的shell到MapOfShell
125 mov ecx,ShellBufferMapUsed
126 add ShellSize,ecx
127 mov esi,MEM
128 rep movsb
129 ;*******修正外壳输入表
130 ;eax=PeImageSize+ImportTable-ShellStart0,然后和相对于ImportTable的偏移相加
131 ;加壳后shell0代码至少应放在PeImageSize后面,因为PeImageSize即PE文件占用内存的大小,在这个后面写不会影响到原程序的运行
132 ;此作者直接把shell0放在PeImageSize后面,那么,PeImageSize也是shell0的在内存中的RVA,好机智!!
133 mov eax,PeImageSize
134 add eax,ImportTable-ShellStart0 ;得到外壳输入表偏移,不懂!!现在懂了吧,哈哈
135 mov ebx,MapOfShell ;修改外壳输入表头 ;MapOfShell地址
136 add ebx,ImportTable-ShellStart0 ;ebx定位到originalFirstThunk,
137 add dword ptr [ebx],eax ;[ebx]即shell里的shell0里的ImportTable
138 mov ebx,MapOfShell
139 add ebx,AppImpRVA1-ShellStart0
140 add dword ptr [ebx],eax
141 mov ebx,MapOfShell
142 add ebx,AppImpRVA2-ShellStart0
143 add dword ptr [ebx],eax
144 mov ebx,MapOfShell ;修改外壳输入地址表
145 add ebx,AddressFirst-ShellStart0
146 add dword ptr [ebx],eax
147 mov ebx,MapOfShell
148 add ebx,AddressSecond-ShellStart0
149 add dword ptr [ebx],eax
150 mov ebx,MapOfShell
151 add ebx,AddressThird-ShellStart0
152 add dword ptr [ebx],eax
153 ;*******保存外壳压缩资料,以备解压******
154 mov ebx,MapOfShell
155 add ebx,ShellBase-ShellStart0
156 mov eax,ShellEnd0-ShellStart0
157 .if IsPackRes == 1
158 add eax,MapOfPackResUsed
159 .endif
160 mov dword ptr [ebx],eax
161 mov ebx,MapOfShell
162 add ebx,ShellPackSize-ShellStart0
163 mov eax,ShellSize_NoPack
164 mov dword ptr [ebx],eax
165 ;*******在文件头增加一个区段资料
166 mov edi,PeHeadBase
167 assume edi : ptr IMAGE_NT_HEADERS ;edi=NT头
168 mov eax,SecTableBase ;eax=节表头
169 movzx ecx,word ptr [edi].FileHeader.NumberOfSections ;ecx=区块数
170 ModifySectionCharact: ;从第一个区块开始修改区块属性
171 or dword ptr [eax+24h],0c0000000h ;为0c0000000h
172 add eax,28h
173 loop ModifySectionCharact
174 mov esi,eax ;新加区块起点
175 push edi
176 mov edi,esi
177 xor eax,eax
178 mov ecx,28h
179 rep stosb ;28h清零
180 pop edi
181 mov dword ptr [esi],'gcc.' ;新区块名称
182 invoke GetIntegral,ShellSize,SectionAlignment ;壳区块的大小
183 mov dword ptr [esi+08h],eax ;映象大小
184 mov eax,PeImageSize
185 mov dword ptr [esi+0ch],eax ;映象偏移
186 invoke GetIntegral,ShellSize,FileAlignment ;文件大小
187 mov dword ptr [esi+10h],eax ;文件大小
188 mov eax,dword ptr [esi-14h]
189 add eax,dword ptr [esi-18h]
190 invoke GetIntegral,eax,FileAlignment
191 mov dword ptr [esi+14h],eax ;文件偏移
192 mov dword ptr [esi+24h],0c0000040h
193 inc word ptr [edi].FileHeader.NumberOfSections ;区块数加一
194 ;*******修改文件头的一些资料
195 ;修改EntryPoint程序入口点
196 mov eax,PeImageSize
197 mov dword ptr [edi].OptionalHeader.AddressOfEntryPoint,eax
198 invoke GetIntegral,ShellSize,SectionAlignment
199 add eax,PeImageSize
200 mov dword ptr [edi].OptionalHeader.SizeOfImage,eax ;修改映象大小
201 mov eax,PeImageSize
202 add eax,ImportTable-ShellStart0 ;修改输入表为自建输入表
203 mov dword ptr [edi].OptionalHeader.DataDirectory[SIZEOF IMAGE_DATA_DIRECTORY].VirtualAddress,eax
204 mov dword ptr [edi].OptionalHeader.DataDirectory[5*SIZEOF IMAGE_DATA_DIRECTORY].VirtualAddress,0h
205 mov dword ptr [edi].OptionalHeader.DataDirectory[5*SIZEOF IMAGE_DATA_DIRECTORY].isize,0h
206 mov dword ptr [edi].OptionalHeader.DataDirectory[11*SIZEOF IMAGE_DATA_DIRECTORY].VirtualAddress,0h
207 mov dword ptr [edi].OptionalHeader.DataDirectory[11*SIZEOF IMAGE_DATA_DIRECTORY].isize,0h
208 mov dword ptr [edi].OptionalHeader.DataDirectory[12*SIZEOF IMAGE_DATA_DIRECTORY].VirtualAddress,0h
209 mov dword ptr [edi].OptionalHeader.DataDirectory[12*SIZEOF IMAGE_DATA_DIRECTORY].isize,0h
210 mov esi,dword ptr [edi].OptionalHeader.DataDirectory[9*SIZEOF IMAGE_DATA_DIRECTORY].VirtualAddress
211 .if esi != 0
212 add esi,MapOfFile
213 mov eax,PeImageSize
214 add eax,TlsTable-ShellStart0
215 mov dword ptr [edi].OptionalHeader.DataDirectory[9*SIZEOF IMAGE_DATA_DIRECTORY].VirtualAddress,eax
216 mov edi,MapOfShell
217 add edi,TlsTable-ShellStart0
218 mov ecx,18h
219 rep movsb
220 .endif
221 invoke VirtualFree, ShellBufferMap, 0, MEM_RELEASE
222 popad
223 invoke GetIntegral,ShellSize,FileAlignment
224 ret
225 DisposeShell endp