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
;
; 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
