怎么做一个壳 Part

恩..首先我假设浏览这篇文章的你已经对PE结构非常熟悉,并且具备一定的编程功力.这样我才能说下去]

一. 做个压缩壳

0. 壳加载被保护/保护文件的流程

加:

读取文件->分析并XXOO操作->组装壳代码->建立文件头并添加一个节->把数据写入缓冲->生成文件

保护壳比压缩壳多的部分便是各种保护了,以最经常使用的SDK,窃取代码说明一下

通常在使用某个壳的SDK时,壳都会提供一个个成对出现的INC文件,他们通常都是

db 0xxh,0xxh,0xxh,0xxh 之类的,这就是壳在加上保护时确定你需要的功能以及定位

需要保护的代码所使用。简单的例子便是保护某个API或者某段函数。

其实他们只是在上面的流程中第二步里定位到那段DB xxx

保护API则是把CALL地址替换到壳代码在运行后的PE文件中的位置,API功能由壳实现

窃取代码相对复杂些,在搜索到后,把这段代码CUT下来,在壳中另外加密。

然后在这对标志的开头处添加一个JMP或者一个CALL。最常见的形式就是CALL

push 代码段标志,告诉壳应解密并执行那个参数
push 操作数,比如是不是执行后立即清除等等
call 壳处理这些SDK的代码位置

在完这样的代码后把数据移进缓冲[记得别把DB xxxx也复制过去了]

重复这样的操作后得到的便是保护后的代码了,记得重新计算下节大小

而类似 CopyMem 这样的保护则更复杂些,这样的保护利用的是自调试实现的

在收到一个读取或执行异常后分析异常,如果是特定的异常代码则把一段代码

解密并复制到内存,清理掉其他位置的代码然后让进程继续执行

但是这样的保护办法将会让进程的效率变的非常非常的差

话说我好象没见那个著名的壳主动的采用这样的保护

而检测Debuger则通常都是由壳的线程实现,当然在被保护进程代码段里插入检查Debug代码

也是经常被使用的方式,but 实际上要是在壳的 loader 部分不能搞定,线程检测和代码段里

进行检测也就没什么意义了。


解:

解压缩数据->把数据放回PE文件在内存中对应的节中->为PE文件加载DLL->填充IAT->跳回原入口

实际上你可以把自己的代码段在跳回原入口前清理掉,而对IAT加密则可以在填充IAT这一步进行。

最简单的办法就是:

在填充IAT的时候判断一下API的名称,如果是要保护的,则填入实现这个API功能函数在壳的地址

但是这样做并不能保护软件在脱壳后无法使用。仅仅是让ImportREC等重建导入表工具失效而已

1. 选择一个好的编译器

理论上,只要是能把你的代码编译成一堆16进制的编译器都能完成工作。

但是我还是推荐你使用以下三者之一

他们是, delphi 5的dcc32.exe, VC 8.0 的 cl.exe, masm 9.0 的 ml.exe

这系列的文章我将用 delphi 来完成所有的代码,原因和很多人讨厌 beign ... end 一样,我讨厌 {...}

2. 选择一种算法来使用

实际上,你可以采用任何的压缩算法,只要你乐意。

这一步的选择关键在于压缩算法的解压缩代码大小,

最符合这一条件的便是 APlib 了,他的解压代码仅仅 126 bytes。

当然可以不必要这样做,我们有更好的办法。

去掉下面这两句可以让APlib解压代码更小
sub edi,[esp+40]
mov [esp+28],edi

3. 壳代码需要些什么?

一个壳代码至少需要一个参数 原入口点,另至少需要五个API

GetProcAddress,LoadLibraryA 这两个API是用来加载被保护文件的导入表所使用

VirtualAlloc,VirtualFree 是用来解压缩时使用

pVirtualProtect 是用来修改PE头时使用

另外自己做GetProcAddress也是个相当好的办法,但是这会让壳体积变大

为了简单,我这里采用的方法是压缩整个文件的方式

知道了这些,我们就可以先开始制作自己的 Loader 了,完整的代码如下

这段代码在我的dcc32.exe编译后

全长度是 720 Bytes 减去解压缩代码的126 Bytes,我们的代码长度 594 Bytes
复制内容到剪贴板
代码:
type
TRegs = record
Edi: Cardinal;
Esi: Cardinal;
Ebp: Cardinal;
Esp: Cardinal;
Ebx: Cardinal;
Edx: Cardinal;
Ecx: Cardinal;
Eax: Cardinal;
end;

function StartHere: PDWORD; assembler;//定位代码开始
asm
call @GetPointer
dd $FFFFFFFF   //压缩后数据的位置
dd $FFFFFFFF   //压缩后数据的大小
dd $FFFFFFFF   //FUNC1 GetProcAddress
dd $FFFFFFFF   //FUNC3 LoadLibraryA
dd $FFFFFFFF   //FUNC4 VirtualAlloc
dd $FFFFFFFF   //FUNC5 VirtualFree
dd $FFFFFFFF   //FUNC5 VirtualProtect
dd 0
@GetPointer:
pop result
end;

procedure ApDepack(var Source, Destination); assembler;
asm
  pushad
  mov  esi, Source
  mov  edi, Destination
  cld
  mov  dl, 80h
  xor  ebx, ebx
@@literal:
  movsb
  mov  bl, 2
@@nexttag:
  call  @@getbit
  jnc  @@literal
  xor  ecx, ecx
  call  @@getbit
  jnc  @@codepair
  xor  eax, eax
  call  @@getbit
  jnc  @@shortmatch
  mov  bl, 2
  inc  ecx
  mov  al, 10h
@@getmorebits:
  call  @@getbit
  adc  al, al
  jnc  @@getmorebits
  jnz  @@domatch
  stosb
  jmp  @@nexttag
@@codepair:
  call  @@getgamma_no_ecx
  sub  ecx, ebx
  jnz  @@normalcodepair
  call  @@getgamma
  jmp  @@domatch_lastpos
@@shortmatch:
  lodsb
  shr  eax, 1
  jz   @@donedepacking
  adc  ecx, ecx
  jmp  @@domatch_with_2inc
@@normalcodepair:
  xchg  eax, ecx
  dec  eax
  shl  eax, 8
  lodsb
  call  @@getgamma
  cmp  eax, 32000
  jae  @@domatch_with_2inc
  cmp  ah, 5
  jae  @@domatch_with_inc
  cmp  eax, 7fh
  ja   @@domatch_new_lastpos
@@domatch_with_2inc:
  inc  ecx
@@domatch_with_inc:
  inc  ecx
@@domatch_new_lastpos:
  xchg  eax, ebp
@@domatch_lastpos:
  mov  eax, ebp
  mov  bl, 1
@@domatch:
  push  esi
  mov  esi, edi
  sub  esi, eax
  rep  movsb
  pop  esi
  jmp  @@nexttag
@@getbit:
  add   dl, dl
  jnz   @@stillbitsleft
  mov   dl, [esi]
  inc   esi
  adc   dl, dl
@@stillbitsleft:
  ret
@@getgamma:
  xor  ecx, ecx
@@getgamma_no_ecx:
  inc  ecx
@@getgammaloop:
  call  @@getbit
  adc  ecx, ecx
  call  @@getbit
  jc   @@getgammaloop
  ret
@@donedepacking:
  popad
end;

function NextPChar(s:PChar):PChar;
begin
result:=s;
while PByte(result)^<>0 do inc(result);
inc(result);
end;

function NextDWORD(d:Pointer):PDWORD;
begin
result:=d;
inc(result);
end;

procedure Loader(Regs:TRegs); stdcall;
var
pGetProcAddress:function(hModule:HMODULE;lpProcName:LPCSTR):FARPROC;stdcall;
pLoadLibraryA:function(lpLibFileName:PChar):HMODULE;stdcall;
pVirtualAlloc:function(lpvAddress:Pointer;dwSize,flAllocationType,flProtect:DWORD):Pointer;stdcall;
pVirtualFree:function(lpAddress:Pointer;dwSize,dwFreeType:DWORD):BOOL;stdcall;
pVirtualProtect:function(lpAddress:Pointer;dwSize,flNewProtect:DWORD;lpflOldProtect:Pointer):BOOL;stdcall;

PFileHeader:PImageFileHeader;
POptHeader,POptHeader2:PImageOptionalHeader;
PSectionHead:PImageSectionHeader;
PDatDir,PDatDir2:PImageDataDirectory;
EPDATA,Buffer,pSrc,PDst,PImpTable:Pointer;
ImageBase,I,hDll,EPDATASIZE,hSize:Cardinal;
pName:PChar;
pFixThunkRva,pThunkRva,PFunc:PDWORD;
begin
//初始化参数
asm
mov eax,fs: [$30]
mov eax,[eax+$0c] //PEB
mov eax,[eax+$0c] //LDR
mov eax,[eax+$18] //ImageBase
mov ImageBase,eax //ImageBase
end;
PFunc:=StartHere;
EPDATA:=Pointer(ImageBase+PFunc^);
Inc(PFunc);
EPDATASIZE:=PFunc^;
Inc(PFunc);
pGetProcAddress:=Pointer(PFunc^);
Inc(PFunc);
pLoadLibraryA:=Pointer(PFunc^);
Inc(PFunc);
pVirtualAlloc:=Pointer(PFunc^);
Inc(PFunc);
pVirtualFree:=Pointer(PFunc^);
Inc(PFunc);
pVirtualProtect:=Pointer(PFunc^);

//分配缓冲并解压缩
Buffer:=pVirtualAlloc(nil,EPDATASIZE,MEM_COMMIT,PAGE_READWRITE);
ApDepack(EPDATA^,Buffer^);

//复制节数据到原来的位置
{$WARNINGS OFF}
PFileHeader:=PImageFileHeader(ImageBase+PImageDosHeader(ImageBase)^._lfanew+4);
{$WARNINGS ON}
POptHeader:=PImageOptionalHeader(DWORD(PFileHeader)+IMAGE_SIZEOF_FILE_HEADER);
PSectionHead:=PImageSectionHeader(DWORD(POptHeader)+IMAGE_SIZEOF_NT_OPTIONAL_HEADER);
for I:=0 to PFileHeader^.NumberOfSections-1 do
begin
hSize:=PDWORD(DWORD(PSectionHead)+IMAGE_SIZEOF_SHORT_NAME)^;
if hSize>0 then
begin
pSrc:=Pointer(DWORD(ImageBase)+PSectionHead^.VirtualAddress);
pDst:=Pointer(DWORD(Buffer)+PSectionHead^.VirtualAddress);
asm
mov edi,pSrc
mov esi,pDst
mov ecx,hSize
rep movsb
end; //简单的CopyMemory到原来的地址
end;
Inc(PSectionHead);
end;

//重要的一步 IAT
{$WARNINGS OFF}
PFileHeader:=PImageFileHeader(DWORD(Buffer)+PImageDosHeader(Buffer)^._lfanew+4);
{$WARNINGS ON}
POptHeader2:=PImageOptionalHeader(DWORD(PFileHeader)+IMAGE_SIZEOF_FILE_HEADER);
PDatDir:=PImageDataDirectory(@POptHeader2^.DataDirectory[1]);
PImpTable:=Pointer(PDatDir^.VirtualAddress+DWORD(Buffer));

while DWORD(PImpTable^)<>0 do
begin
pThunkRva:=Pointer(DWORD(PImpTable)+$10); //得到原导入表的FirstThunk
pName:=Pointer(DWORD(EPDATA)+DWORD(pThunkRva)-4); //取得DLL名称
hDll:=pLoadLibraryA(pName); //加载DLL
pName:=NextPChar(pName); //移动到指向函数名

pFixThunkRva:=Pointer(ImageBase+DWORD(pThunkRva)); //被保护进程的IAT地址
while pThunkRva^<>0 do
begin
if PDWORD(pName)^ and $FFFF0000 = 0 then
begin
pFixThunkRva^:=DWORD(pGetProcAddress(hDll,Pointer(PWORD(pName)^)));
pName:=PChar(NextDWORD(pName));
end else begin
pFixThunkRva^:=DWORD(pGetProcAddress(hDll,pName));
pName:=NextPChar(pName);
end;
inc(pFixThunkRva); //下一个IA
inc(pThunkRva); //下一个IA
end;

PImpTable:=Pointer(DWORD(PImpTable)+20); //下一个导入表
end;

//把资源表重定向
pVirtualProtect(Pointer(ImageBase),$1000,PAGE_EXECUTE_READWRITE,@I); //使壳可写
PDatDir:=PImageDataDirectory(@POptHeader^.DataDirectory[2]);
PDatDir2:=PImageDataDirectory(@POptHeader2^.DataDirectory[2]);
PDatDir^.VirtualAddress:=PDatDir2^.VirtualAddress;
PDatDir^.Size:=PDatDir2^.Size;
//pVirtualProtect(Pointer(ImageBase),$1000,I,@I); //改回去,不用的话可以减少几BYTE

//使得下一个RET能返回到原入口
PDWORD(Regs.esp+SizeOf(TRegs))^:=ImageBase+POptHeader2^.AddressOfEntryPoint;

pVirtualFree(Buffer,0,MEM_RELEASE); //不释放也成,but...
end;

procedure EP;
asm
pushad
call Loader
popad
end;

procedure EndHere; assembler; asm end;//定位代码结束
这段代码的ASM则是这样,熟悉ASM的话可以看出还有很多的优化余地,有兴趣做个优化吗?
复制内容到剪贴板
代码:
004085D4  $ 55      push  ebp
004085D5  . 8BEC     mov   ebp, esp
004085D7  . 51      push  ecx
004085D8  . E8 20000000  call  004085FD
004085DD   FF      db   FF
004085DE   FF      db   FF
004085DF   FF      db   FF
004085E0   FF      db   FF
004085E1   FF      db   FF
004085E2   FF      db   FF
004085E3   FF      db   FF
004085E4   FF      db   FF
004085E5   FF      db   FF
004085E6   FF      db   FF
004085E7   FF      db   FF
004085E8   FF      db   FF
004085E9   FF      db   FF
004085EA   FF      db   FF
004085EB   FF      db   FF
004085EC   FF      db   FF
004085ED   FF      db   FF
004085EE   FF      db   FF
004085EF   FF      db   FF
004085F0   FF      db   FF
004085F1   FF      db   FF
004085F2   FF      db   FF
004085F3   FF      db   FF
004085F4   FF      db   FF
004085F5   FF      db   FF
004085F6   FF      db   FF
004085F7   FF      db   FF
004085F8   FF      db   FF
004085F9   00      db   00
004085FA   00      db   00
004085FB   00      db   00
004085FC   00      db   00
004085FD /$ 8F45 FC    pop   dword ptr [ebp-4]
00408600 |. 8B45 FC    mov   eax, dword ptr [ebp-4]
00408603 |. 59      pop   ecx
00408604 |. 5D      pop   ebp
00408605 /. C3      retn
00408606   8BC0     mov   eax, eax
00408608  $ 60      pushad
00408609  . 89C6     mov   esi, eax
0040860B  . 89D7     mov   edi, edx
0040860D  . FC      cld
0040860E  . B2 80     mov   dl, 80
00408610  . 31DB     xor   ebx, ebx
00408612  > A4      movs  byte ptr es:[edi], byte ptr [esi>
00408613  . B3 02     mov   bl, 2
00408615  > E8 6D000000  call  00408687
0040861A  .^ 73 F6     jnb   short 00408612
0040861C  . 31C9     xor   ecx, ecx
0040861E  . E8 64000000  call  00408687
00408623  . 73 1C     jnb   short 00408641
00408625  . 31C0     xor   eax, eax
00408627  . E8 5B000000  call  00408687
0040862C  . 73 23     jnb   short 00408651
0040862E  . B3 02     mov   bl, 2
00408630  . 41      inc   ecx
00408631  . B0 10     mov   al, 10
00408633  > E8 4F000000  call  00408687
00408638  . 10C0     adc   al, al
0040863A  .^ 73 F7     jnb   short 00408633
0040863C  . 75 3F     jnz   short 0040867D
0040863E  . AA      stos  byte ptr es:[edi]
0040863F  .^ EB D4     jmp   short 00408615
00408641  > E8 4D000000  call  00408693
00408646  . 29D9     sub   ecx, ebx
00408648  . 75 10     jnz   short 0040865A
0040864A  . E8 42000000  call  00408691
0040864F  . EB 28     jmp   short 00408679
00408651  > AC      lods  byte ptr [esi]
00408652  . D1E8     shr   eax, 1
00408654  . 74 4D     je   short 004086A3
00408656  . 11C9     adc   ecx, ecx
00408658  . EB 1C     jmp   short 00408676
0040865A  > 91      xchg  eax, ecx
0040865B  . 48      dec   eax
0040865C  . C1E0 08    shl   eax, 8
0040865F  . AC      lods  byte ptr [esi]
00408660  . E8 2C000000  call  00408691
00408665  . 3D 007D0000  cmp   eax, 7D00
0040866A  . 73 0A     jnb   short 00408676
0040866C  . 80FC 05    cmp   ah, 5
0040866F  . 73 06     jnb   short 00408677
00408671  . 83F8 7F    cmp   eax, 7F
00408674  . 77 02     ja   short 00408678
00408676  > 41      inc   ecx
00408677  > 41      inc   ecx
00408678  > 95      xchg  eax, ebp
00408679  > 89E8     mov   eax, ebp
0040867B  . B3 01     mov   bl, 1
0040867D  > 56      push  esi
0040867E  . 89FE     mov   esi, edi
00408680  . 29C6     sub   esi, eax
00408682  . F3:A4     rep   movs byte ptr es:[edi], byte ptr>
00408684  . 5E      pop   esi
00408685  .^ EB 8E     jmp   short 00408615
00408687 /$ 00D2     add   dl, dl
00408689 |. 75 05     jnz   short 00408690
0040868B |. 8A16     mov   dl, byte ptr [esi]
0040868D |. 46      inc   esi
0040868E |. 10D2     adc   dl, dl
00408690 /> C3      retn
00408691 /$ 31C9     xor   ecx, ecx
00408693 |$ 41      inc   ecx
00408694 |> E8 EEFFFFFF  /call  00408687
00408699 |. 11C9     |adc   ecx, ecx
0040869B |. E8 E7FFFFFF  |call  00408687
004086A0 |.^ 72 F2     /jb   short 00408694
004086A2 /. C3      retn
004086A3  > 61      popad
004086A4  . C3      retn
004086A5   8D40 00    lea   eax, dword ptr [eax]
004086A8 /$ EB 01     jmp   short 004086AB
004086AA |> 40      /inc   eax
004086AB |> 8038 00    cmp   byte ptr [eax], 0
004086AE |.^ 75 FA     /jnz   short 004086AA
004086B0 |. 40      inc   eax
004086B1 /. C3      retn
004086B2   8BC0     mov   eax, eax
004086B4 /$ 83C0 04    add   eax, 4
004086B7 /. C3      retn
004086B8 /$ 55      push  ebp
004086B9 |. 8BEC     mov   ebp, esp
004086BB |. 83C4 C4    add   esp, -3C
004086BE |. 53      push  ebx
004086BF |. 56      push  esi
004086C0 |. 57      push  edi
004086C1 |. 64:8B05 30000>mov   eax, dword ptr fs:[30]
004086C8 |. 8B40 0C    mov   eax, dword ptr [eax+C]
004086CB |. 8B40 0C    mov   eax, dword ptr [eax+C]
004086CE |. 8B40 18    mov   eax, dword ptr [eax+18]
004086D1 |. 8945 FC    mov   dword ptr [ebp-4], eax
004086D4 |. E8 FBFEFFFF  call  004085D4
004086D9 |. 8B10     mov   edx, dword ptr [eax]
004086DB |. 0355 FC    add   edx, dword ptr [ebp-4]
004086DE |. 8955 D4    mov   dword ptr [ebp-2C], edx
004086E1 |. 83C0 04    add   eax, 4
004086E4 |. 8B08     mov   ecx, dword ptr [eax]
004086E6 |. 83C0 04    add   eax, 4
004086E9 |. 8B10     mov   edx, dword ptr [eax]
004086EB |. 8955 EC    mov   dword ptr [ebp-14], edx
004086EE |. 83C0 04    add   eax, 4
004086F1 |. 8B10     mov   edx, dword ptr [eax]
004086F3 |. 8955 E8    mov   dword ptr [ebp-18], edx
004086F6 |. 83C0 04    add   eax, 4
004086F9 |. 8B10     mov   edx, dword ptr [eax]
004086FB |. 83C0 04    add   eax, 4
004086FE |. 8B18     mov   ebx, dword ptr [eax]
00408700 |. 895D E4    mov   dword ptr [ebp-1C], ebx
00408703 |. 83C0 04    add   eax, 4
00408706 |. 8B00     mov   eax, dword ptr [eax]
00408708 |. 8945 E0    mov   dword ptr [ebp-20], eax
0040870B |. 6A 04     push  4
0040870D |. 68 00100000  push  1000
00408712 |. 51      push  ecx
00408713 |. 6A 00     push  0
00408715 |. FFD2     call  edx
00408717 |. 8945 D0    mov   dword ptr [ebp-30], eax
0040871A |. 8B55 D0    mov   edx, dword ptr [ebp-30]
0040871D |. 8B45 D4    mov   eax, dword ptr [ebp-2C]
00408720 |. E8 E3FEFFFF  call  00408608
00408725 |. 8B45 FC    mov   eax, dword ptr [ebp-4]
00408728 |. 33D2     xor   edx, edx
0040872A |. 52      push  edx
0040872B |. 50      push  eax
0040872C |. 8B45 FC    mov   eax, dword ptr [ebp-4]
0040872F |. 8B40 3C    mov   eax, dword ptr [eax+3C]
00408732 |. 99      cdq
00408733 |. 030424    add   eax, dword ptr [esp]
00408736 |. 135424 04   adc   edx, dword ptr [esp+4]
0040873A |. 83C4 08    add   esp, 8
0040873D |. 83C0 04    add   eax, 4
00408740 |. 83D2 00    adc   edx, 0
00408743 |. 8BD0     mov   edx, eax
00408745 |. 8BC2     mov   eax, edx
00408747 |. 83C0 14    add   eax, 14
0040874A |. 8945 DC    mov   dword ptr [ebp-24], eax
0040874D |. 8B45 DC    mov   eax, dword ptr [ebp-24]
00408750 |. 05 E0000000  add   eax, 0E0
00408755 |. 0FB752 02   movzx  edx, word ptr [edx+2]
00408759 |. 4A      dec   edx
0040875A |. 85D2     test  edx, edx
0040875C |. 72 3E     jb   short 0040879C
0040875E |. 42      inc   edx
0040875F |. C745 C8 00000>mov   dword ptr [ebp-38], 0
00408766 |> 8BC8     /mov   ecx, eax
00408768 |. 83C1 08    |add   ecx, 8
0040876B |. 8B09     |mov   ecx, dword ptr [ecx]
0040876D |. 894D F0    |mov   dword ptr [ebp-10], ecx
00408770 |. 837D F0 00  |cmp   dword ptr [ebp-10], 0
00408774 |. 76 1D     |jbe   short 00408793
00408776 |. 8B48 0C    |mov   ecx, dword ptr [eax+C]
00408779 |. 034D FC    |add   ecx, dword ptr [ebp-4]
0040877C |. 894D F8    |mov   dword ptr [ebp-8], ecx
0040877F |. 8B48 0C    |mov   ecx, dword ptr [eax+C]
00408782 |. 034D D0    |add   ecx, dword ptr [ebp-30]
00408785 |. 894D F4    |mov   dword ptr [ebp-C], ecx
00408788 |. 8B7D F8    |mov   edi, dword ptr [ebp-8]
0040878B |. 8B75 F4    |mov   esi, dword ptr [ebp-C]
0040878E |. 8B4D F0    |mov   ecx, dword ptr [ebp-10]
00408791 |. F3:A4     |rep   movs byte ptr es:[edi], byte pt>
00408793 |> 83C0 28    |add   eax, 28
00408796 |. FF45 C8    |inc   dword ptr [ebp-38]
00408799 |. 4A      |dec   edx
0040879A |.^ 75 CA     /jnz   short 00408766
0040879C |> 8B4D D0    mov   ecx, dword ptr [ebp-30]
0040879F |. 8BC1     mov   eax, ecx
004087A1 |. 33D2     xor   edx, edx
004087A3 |. 52      push  edx
004087A4 |. 50      push  eax
004087A5 |. 8B45 D0    mov   eax, dword ptr [ebp-30]
004087A8 |. 8B40 3C    mov   eax, dword ptr [eax+3C]
004087AB |. 99      cdq
004087AC |. 030424    add   eax, dword ptr [esp]
004087AF |. 135424 04   adc   edx, dword ptr [esp+4]
004087B3 |. 83C4 08    add   esp, 8
004087B6 |. 83C0 04    add   eax, 4
004087B9 |. 83D2 00    adc   edx, 0
004087BC |. 8BD0     mov   edx, eax
004087BE |. 83C2 14    add   edx, 14
004087C1 |. 8955 D8    mov   dword ptr [ebp-28], edx
004087C4 |. 8B45 D8    mov   eax, dword ptr [ebp-28]
004087C7 |. 83C0 68    add   eax, 68
004087CA |. 8B00     mov   eax, dword ptr [eax]
004087CC |. 03C1     add   eax, ecx
004087CE |. 8945 CC    mov   dword ptr [ebp-34], eax
004087D1 |. EB 70     jmp   short 00408843
004087D3 |> 8B75 CC    /mov   esi, dword ptr [ebp-34]
004087D6 |. 83C6 10    |add   esi, 10
004087D9 |. 8B5D D4    |mov   ebx, dword ptr [ebp-2C]
004087DC |. 8BFE     |mov   edi, esi
004087DE |. 03DF     |add   ebx, edi
004087E0 |. 83EB 04    |sub   ebx, 4
004087E3 |. 53      |push  ebx
004087E4 |. FF55 E8    |call  dword ptr [ebp-18]
004087E7 |. 8945 C4    |mov   dword ptr [ebp-3C], eax
004087EA |. 8BC3     |mov   eax, ebx
004087EC |. E8 B7FEFFFF  |call  004086A8
004087F1 |. 8BD8     |mov   ebx, eax
004087F3 |. 8B45 FC    |mov   eax, dword ptr [ebp-4]
004087F6 |. 03C7     |add   eax, edi
004087F8 |. 8BF8     |mov   edi, eax
004087FA |. EB 39     |jmp   short 00408835
004087FC |> F703 0000FFFF |/test  dword ptr [ebx], FFFF0000
00408802 |. 75 18     ||jnz   short 0040881C
00408804 |. 0FB703    ||movzx  eax, word ptr [ebx]
00408807 |. 50      ||push  eax
00408808 |. 8B45 C4    ||mov   eax, dword ptr [ebp-3C]
0040880B |. 50      ||push  eax
0040880C |. FF55 EC    ||call  dword ptr [ebp-14]
0040880F |. 8907     ||mov   dword ptr [edi], eax
00408811 |. 8BC3     ||mov   eax, ebx
00408813 |. E8 9CFEFFFF  ||call  004086B4
00408818 |. 8BD8     ||mov   ebx, eax
0040881A |. EB 13     ||jmp   short 0040882F
0040881C |> 53      ||push  ebx
0040881D |. 8B45 C4    ||mov   eax, dword ptr [ebp-3C]
00408820 |. 50      ||push  eax
00408821 |. FF55 EC    ||call  dword ptr [ebp-14]
00408824 |. 8907     ||mov   dword ptr [edi], eax
00408826 |. 8BC3     ||mov   eax, ebx
00408828 |. E8 7BFEFFFF  ||call  004086A8
0040882D |. 8BD8     ||mov   ebx, eax
0040882F |> 83C7 04    ||add   edi, 4
00408832 |. 83C6 04    ||add   esi, 4
00408835 |> 833E 00    | cmp   dword ptr [esi], 0
00408838 |.^ 75 C2     |/jnz   short 004087FC
0040883A |. 8B45 CC    |mov   eax, dword ptr [ebp-34]
0040883D |. 83C0 14    |add   eax, 14
00408840 |. 8945 CC    |mov   dword ptr [ebp-34], eax
00408843 |> 8B45 CC    mov   eax, dword ptr [ebp-34]
00408846 |. 8338 00    |cmp   dword ptr [eax], 0
00408849 |.^ 75 88     /jnz   short 004087D3
0040884B |. 8D45 C8    lea   eax, dword ptr [ebp-38]
0040884E |. 50      push  eax
0040884F |. 6A 40     push  40
00408851 |. 68 00100000  push  1000
00408856 |. 8B45 FC    mov   eax, dword ptr [ebp-4]
00408859 |. 50      push  eax
0040885A |. FF55 E0    call  dword ptr [ebp-20]
0040885D |. 8B45 DC    mov   eax, dword ptr [ebp-24]
00408860 |. 83C0 70    add   eax, 70
00408863 |. 8B55 D8    mov   edx, dword ptr [ebp-28]
00408866 |. 83C2 70    add   edx, 70
00408869 |. 8B0A     mov   ecx, dword ptr [edx]
0040886B |. 8908     mov   dword ptr [eax], ecx
0040886D |. 8B52 04    mov   edx, dword ptr [edx+4]
00408870 |. 8950 04    mov   dword ptr [eax+4], edx
00408873 |. 8B45 D8    mov   eax, dword ptr [ebp-28]
00408876 |. 8B40 10    mov   eax, dword ptr [eax+10]
00408879 |. 0345 FC    add   eax, dword ptr [ebp-4]
0040887C |. 8B55 14    mov   edx, dword ptr [ebp+14]
0040887F |. 83C2 20    add   edx, 20
00408882 |. 8902     mov   dword ptr [edx], eax
00408884 |. 68 00800000  push  8000
00408889 |. 6A 00     push  0
0040888B |. 8B45 D0    mov   eax, dword ptr [ebp-30]
0040888E |. 50      push  eax
0040888F |. FF55 E4    call  dword ptr [ebp-1C]
00408892 |. 5F      pop   edi
00408893 |. 5E      pop   esi
00408894 |. 5B      pop   ebx
00408895 |. 8BE5     mov   esp, ebp
00408897 |. 5D      pop   ebp
00408898 /. C2 2000    retn  20
0040889B   90      nop                   ; |
0040889C  . 60      pushad                  ; |
0040889D  . E8 16FEFFFF  call  004086B8             ; /test.004086B8
004088A2  . 61      popad
004088A3  . C3      retn
压缩壳的Packe部分,其实要做的已经不多了。仅仅是如下:

读取要压缩的文件头,增加一个节,并且把原来所有节的 SizeOfRawData,PointerToRawData改为0

自己建立一个导入表,复制导入表到Nt头结尾,并修改NT头导入表大小把RVA修改为新节的 VirtualAddress

提取原文件图标,把原文件整个压缩,然后复制图标数据到导入表结尾

修改Nt头的资源表位置RVA修改为新节的 VirtualAddress+导入表大小,把资源表大小修改为图标大小

把压缩后的数据复制到图标数据结尾,计算出压缩数据在新文件中的RVA。

把RVA写入到 壳的StartHere+0,大小写到 StartHere+4,然后修改自建导入表的 FirstTunkRva 到 StartHere+8

把修改好的壳代码复制到压缩数据的后面,根据所有数据的大小修改新节的 VirtualSize[注意对齐],SizeOfRawData

把新节的PointerToRawData修改为导入表在新文件中的Offset,最后把 AddressOfEntryPoint 写为壳 EP 的 RVA

[就是新节VirtualAddress+图标大小+导入表大小+DWORD(@EP)-DWORD(@StartHere)]

---------------------------------------------------------------------------------------------------------

OK,这样就完成了。试试能不能在 Part II 出来前自己完成他吧

恩,Part I 到这里就完结了,Part II 将是继续完成这个压缩壳的Packe部分,

Part III 则是如果在这个压缩壳的基础上加比较简单的 窃取代码 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值