Windows PE 文件加壳学习笔记(续1)

本文详细介绍了加壳程序的汇编代码实现过程,包括初始化、解码、IAT拷贝及重定位等关键步骤,并说明了所采用的类似PCX的游程码压缩算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 上回我给出了加壳程序的核心的代码,这回我给出 相关的汇编代码。  使用汇编我很无奈,我还不能能用纯C/C++来实现这些嵌入的代码。 代码注释得很清楚,是加壳这个壳的原始代码。  其中的加压缩的部分其实就是脱壳的部分。 其中注释中注明需重定位的,则需要在组装EXE文件的时候修改的。  也就是地址的重定位。。。
  1. cpu P3
  2. bits 32
  3. global _start
  4. section .text
  5. ;---------------------------------------------------------------
  6. ;初始化
  7. _start:
  8.         push ebp
  9.         mov ebp,esp
  10.         sub esp,0x20
  11.         pushad
  12.         
  13.         mov esi,0xFFFFFFFF  ;需重定位 解压源地址
  14.         mov [ebp-0x04*0x00],esi
  15.         mov edi,0xFFFFFFFF  ;需重定位   解压目的地址
  16.         mov [ebp-0x04*0x01],edi
  17.         mov ecx,0xFFFFFFFF  ;需重定位   压缩数据长度
  18.         mov [ebp-0x04*0x02],ecx 
  19.         mov eax,0xFFFFFFFF  ;需重定位   源代码入口
  20.         mov [ebp-0x04*0x03],eax 
  21.         
  22.         mov eax,0xFFFFFFFF  ;需重定位   IAT源地址
  23.         mov [ebp-0x04*0x04],eax     
  24.         mov eax,0xFFFFFFFF  ;需重定位   IAT目的地址
  25.         mov [ebp-0x04*0x05],eax     
  26.         mov eax,0xFFFFFFFF  ;需重定位   IAT长度
  27.         mov [ebp-0x04*0x06],eax             
  28.         
  29. ;---------------------------------------------------------------
  30. ;解码,恢复原映像数据
  31. ;   @decode_next_byte:
  32. ;       mov al,[esi]
  33. ;       not al
  34. ;       mov [edi],al
  35. ;       inc esi
  36. ;       inc edi
  37. ;       loop @decode_next_byte
  38. ;pcx 的RLE解码
  39.     @rle_decode_next_byte:
  40.         mov al,[esi]
  41.         cmp al,0xc0
  42.         je @rle_decode_exit ;0xC0结束符
  43.         jc @output_1
  44.         jnc @output_x
  45.         
  46.     @output_1:
  47.         mov al,[esi]
  48.         mov [edi],al
  49.         inc edi
  50.         inc esi
  51.         jmp @rle_decode_next_byte
  52.         
  53.     @output_x:
  54.         mov al,[esi]
  55.         sub al,0xC0
  56.         xor ecx,ecx
  57.         mov cl,al
  58.         inc esi
  59.         
  60.         mov al,[esi]
  61.     @next_repeat_byte:
  62.         mov al,[esi]
  63.         mov [edi],al
  64.         inc edi 
  65.         loop @next_repeat_byte
  66.         inc esi
  67.         jmp @rle_decode_next_byte
  68.         
  69.     @rle_decode_exit:
  70.         
  71. ;---------------------------------------------------------------
  72. ;拷贝IAT
  73.         mov ecx,[ebp-0x04*0x06]
  74.         mov esi,[ebp-0x04*0x04]
  75.         mov edi,[ebp-0x04*0x05]     
  76.         dec ecx
  77.     @copy_iat_next_byte:
  78.         mov al,[esi]
  79.         mov [edi],al
  80.         inc esi
  81.         inc edi     
  82.         loop @copy_iat_next_byte
  83. ;---------------------------------------------------------------
  84. ;准备进入原镜像代码
  85.         popad
  86.         mov eax,[ebp-0x04*0x03]     
  87.         mov esp,ebp
  88.         pop ebp     
  89.         jmp eax
  90. ;---------------------------------------------------------------

以上就是了那个啥,汇编代码了。。。 使用nasm编译通过
我是使用命令 nasm -f bin loader.asm -l loader.lst -o loader.dat。 对了,上述的汇编代码保存成 loader.asm文件哦

关于如何重定位,相关的C++代码是这样的
  1.     //重定位壳代码的地址
  2.     *((DWORD*)(tmpSectionBuf_text.begin()+nPackerCodeEntryOffset+PackerCodeRelocateOffset[0])) = pPEHeaders->OptionalHeader.ImageBase+pPEHeaders->OptionalHeader.SizeOfImage;
  3.     *((DWORD*)(tmpSectionBuf_text.begin()+nPackerCodeEntryOffset+PackerCodeRelocateOffset[1])) = pPEHeaders->OptionalHeader.ImageBase+pPEHeaders->OptionalHeader.SizeOfHeaders;
  4.     *((DWORD*)(tmpSectionBuf_text.begin()+nPackerCodeEntryOffset+PackerCodeRelocateOffset[2])) = nPackerCodeEntryOffset;
  5.     *((DWORD*)(tmpSectionBuf_text.begin()+nPackerCodeEntryOffset+PackerCodeRelocateOffset[3])) = pPEHeaders->OptionalHeader.ImageBase+pPEHeaders->OptionalHeader.AddressOfEntryPoint;
  6.     *((DWORD*)(tmpSectionBuf_text.begin()+nPackerCodeEntryOffset+PackerCodeRelocateOffset[4])) = pPEHeaders->OptionalHeader.ImageBase+pPEHeaders->OptionalHeader.SizeOfImage+nPackerIATOffset;
  7.     *((DWORD*)(tmpSectionBuf_text.begin()+nPackerCodeEntryOffset+PackerCodeRelocateOffset[5])) = pPEHeaders->OptionalHeader.ImageBase+pPEHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress;
  8.     *((DWORD*)(tmpSectionBuf_text.begin()+nPackerCodeEntryOffset+PackerCodeRelocateOffset[6])) = pPEHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size;
  9.     
具体的看上回发的代码~~  结合上下文就能看明白了

另外我提一下,就是我采用的压缩解压算法是类似于 PCX 的游程码压缩,压缩比不是很高。。。 我就顺便提一下,嘿嘿。

由于时间问题,我没时间研究PE的资源等结构。。。所以现在这个加壳器不支持带资源的EXE文件,目前测试过的就是使用VC++编译的控制台程序运行正常~
找个机会我把我的工程代码发到 csdn 资源


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值