pe头变形+加节

 

 

 

;++
;
; int
;    AddSectionTable(
;     pByte pMemory
;     DWORD dwLen
;    )
;
; Routine Description:
;
;     变形PE头添加节函数
;
; Arguments:
;
;    (esp)    - return address
;
;    [esp+4*8+4*1] - pMemory
;
;    [esp+4*8+4*2] - dwLen
;
; Return Value:
;
;     eax = New Section PhysicalOffset, 0
;     edx = New Section VirtualOffset
;  
;--

AddSectionTable proc pMemory:DWORD, dwLen:DWORD
   pushad
   mov  ebx, pMemory   ;这个iyige参数实际上文件基地址
   mov  esi, ebx
   add  esi, [esi+3ch]    ;找到可选头里的那个偏移,,为了找到NT头
   
   ;++
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;这段是为了找到节表
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   ; edi = Section Table
   movzx  ecx, WORD ptr [esi+IMAGE_FILE_HEADER.SizeOfOptionalHeader+4]
   lea  edi, DWORD ptr [esi+ecx+4+sizeof.IMAGE_FILE_HEADER]
   ;--
   
   ;++
   ; Clear Bound Import Entry
   lea  edx, [esi+74h]   ;这个里面放着    DWORD    SizeOfHeapCommit;////一开始就被指定给进程堆(process heap)的内存数量。此值预设为0x1000个字节(位元组)。
   cmp  DWORD ptr [edx], 10h   ;小于的话就直接到节表处
   jl   .GoSectionTable
   mov  DWORD ptr [edx+4+11*8], 0 ;;;;;;大于的话就把后面的给清空了,就相当于在10个内存处划了个界限
   
   ;--
   
   .GoSectionTable:
   ;++
   ; edx = First Section Offset
   ; edi = Last   Section Table Offset
   mov  edx, [edi+IMAGE_SECTION_HEADER.PointerToRawData]     ;First Section Offset
   add  edx, ebx     ;跳转到节表开始处
   movzx  ecx, WORD ptr [esi+IMAGE_FILE_HEADER.NumberOfSections+4]
   imul  ecx, ecx, sizeof IMAGE_SECTION_HEADER
   add  edi, ecx       ;跳转到节表的末尾
   ;--
   
   ;++
   ; pe头变形
   ; BaseOfData equ .lfanew
   push  edx
   mov  eax, edi
   sub  edx, eax
   cmp  edx, sizeof IMAGE_SECTION_HEADER
   pop  edx   ;放着节表的大小
   jge   .AddSectionTable
   
   ; Test Expand Is Exist
   cmp  WORD ptr [ebx+0ch], 'PE'
   jnz   .Expand    ;就是说看看是不是已经扩展过了,如果已经扩展过了那就不要再执行什么了
    ;xor  eax, eax
  ; mov   [esp+pushad_eax], eax
   jmp   .Result
   
.Expand:
   sub  eax, esi
   xchg  eax, ecx
   pushad
   lea  edi, [ebx+0ch]
    ;mov  dword [esp+pushad_esi], edi
   push esi
   cld
   rep  movsb   ;这句的话就是把整个NT header和节表的内容都拷贝倒dos header的0ch处
    ;mov  DWORD ptr [esp+pushad_edi], edi
   push edi
   
   
   pop edi
   sub  edx, edi
   xchg  ecx, edx
   xor  eax, eax
   rep  stosb    ;这段的作用就是清空原来的那个节表处的东西,没用了
   popad
   
   mov  DWORD ptr [ebx+3ch], 0ch   ;更新下偏移
   ;--
   
.AddSectionTable:
   ; Inc     Num
   inc  WORD ptr [esi+06h]   ;这个地方的成员是表示节的个数,,我加一个节,,就加1就可以了
   
   ; Section Name
   mov  DWORD ptr [edi], '.chr'   ;节表的刚开始一个成员是存放节表的名称
   mov  WORD ptr [edi+4], 'me'
   
  ; Physical size
  mov eax,dwLen
  push eax
  pop  DWORD ptr [edi+10h]      ;   DWORD VirtualAddress;    // RVA某一节在内存中的偏移
  
  ; Physical offset
  lea  edx, [edi-28h]   ;这个就是把指针移到最后一个节表的开头28h=40字节,也就是一个节表的大小
   mov  eax, [edx+14h]  ;   DWORD SizeOfRawData;    // 物理长度,也就是文件中的对齐粒度   之前一般都定义为200
   mov  ecx, [edx+10h]   ;DWORD VirtualAddress;    // RVA某一节在内存中的偏移
   add  eax, ecx
   mov  DWORD ptr [edi+14h], eax
    ;mov  dword [esp+pushad_eax], eax
   push eax
   ; Virtual size
   mov ebx,dwLen
   push ebx
   
   pop  DWORD ptr [edi+8h]
  
  ; Virtual offset
  push  DWORD ptr [esi+50h]
  pop  eax
  mov  DWORD ptr [edi+0ch], eax
   ;mov   [esp+pushad_edx], eax
  push eax
  
   ; Flags
  mov  DWORD ptr [edi+24h], 0E0000020h   ;设置属性
   
   ; SizeOfImage
   mov  ecx, [edi+08h]
   add  ecx, [edi+0ch]
   mov  DWORD PTR [esi+50h], ecx
   
.Result:
   popad
   retn   4*2
   
AddSectionTable endp

posted on 2009-07-02 23:43 彭洲 阅读(219) 评论(0) 编辑 收藏

导航

统计

公告