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