站长工具关键词营业推广促销方式有哪些
1. PE头部总体组成
2. DOS MZ头
3. PE头
PE头由3部分组成:
下面分别:
OptionalHeader比较大:
然后是节表, 节表有多个:
PE文件头部就结束了, 最后就是节区了, 来看几段代码:
; main.asm
.586
.model flat, stdcall
option casemap:noneinclude windows.inc
include kernel32.inc
includelib kernel32.lib
include msvcrt.inc
includelib msvcrt.lib.data
strPause BYTE "pause", 0
strFilePath BYTE "winmine.exe", 0
.codeinclude PE.asm
include IO.asmRVA2FOA PROTO _pFileHdr:PTR BYTE, _dwRVA:DWORD
_vReadFile PROTO _pFileName:PTR BYTEmain PROCLOCAL @pDosHdr:PTR BYTEpush OFFSET strFilePath call _vReadFile test eax, eax jz Ending mov @pDosHdr, eax push 5000hpush @pDosHdr call FindSectionNamepush eax call crt_printfEnding:push OFFSET strPausecall crt_systeminvoke ExitProcess, 0
main ENDP
end main
; PE.asm
IFNDEF _PEOPA_ASM
_PEOPA_ASM MACRO
ENDM; 作用: 用于判定是否是PE文件
; 参数: _pFileHdr 指向读到内存中文件的基址指针
; 返回: eax == 1是PE文件, eax == 0则不是PE文件
CheckPE PROC PROC _pFileHdr:PTR BYTE xor eax, eax mov esi, _pFileHdr assume esi:PTR IMAGE_DOS_HEADERcmp WORD PTR [esi].e_magic, 5A4Dhjne Ending add esi, [esi].e_lfanewassume esi:PTR IMAGE_NT_HEADERS32cmp WORD PTR [esi].Signature, 4550hjnz Ending mov eax, 1
Ending:ret CheckPE ENDP ; 作用: 查找RVA地址所在节的名称地址
; 参数: _pFileHdr 指向读到内存中文件的基址指针
; _dwRVA 目标RVA地址
; 返回: 指向RVA所在节区的名称指针
FindSectionName PROC _pFileHdr:PTR BYTE, _dwRVA:DWORD mov esi, _pFileHdr assume esi:PTR IMAGE_DOS_HEADERadd esi, [esi].e_lfanewassume esi:PTR IMAGE_NT_HEADERS32; 获取节数movzx ecx, [esi].FileHeader.NumberOfSections; 获取节表指针add esi, SIZEOF IMAGE_NT_HEADERS32assume esi:PTR IMAGE_SECTION_HEADER
L0:; 对比是否在当节mov edx, _dwRVA mov edi, [esi].VirtualAddresscmp edx, edijb @F add edi, [esi].SizeOfRawDatacmp edx, edi jae @F ; 在当节则获取节名, RVA+ImageBaselea eax, [esi].Name1mov ecx, 1
@@:add esi, SIZEOF IMAGE_SECTION_HEADERloop L0 ret FindSectionName ENDP ; 作用: 将RVA地址转成FOA即文件偏移
; 参数: _pFileHdr 指向读到内存中文件的基址指针
; _dwRVA 目标RVA地址
; 返回: 目标RVA转成文件偏移的值
RVA2FOA PROC _pFileHdr:PTR BYTE, _dwRVA:DWORDpushadmov esi, _pFileHdr assume esi:ptr IMAGE_DOS_HEADER; 获取PE头mov edi, [esi].e_lfanewassume esi:nothingadd edi, esi assume edi:ptr IMAGE_NT_HEADERS32; 获取节数movzx ecx, [edi].FileHeader.NumberOfSectionsassume edi:nothing; 获取节表地址add edi, SIZEOF IMAGE_NT_HEADERS32assume edi:ptr IMAGE_SECTION_HEADER
L0:mov edx, _dwRVAcmp edx, [edi].VirtualAddressjb @Fmov eax, [edi].VirtualAddressadd eax, [edi].SizeOfRawDatacmp edx, eaxjae @Fsub edx, [edi].VirtualAddressadd edx, [edi].PointerToRawDatamov eax, edxjmp Ending
@@:add edi, SIZEOF IMAGE_SECTION_HEADERloop L0xor eax, eax
Ending:popadretRVA2FOA ENDPENDIF
; IO.asm
IFNDEF _IO_ASM
_IO_ASM MACRO
ENDM ; 作用: 读取文件到内存, 会分配堆空间存储
; 参数: _pFileName 要读取的文件名
; 返回: eax中存储着指向文件内容的指针, 失败则是NULL
_vReadFile PROC _pFileName:PTR BYTELOCAL @hFile:HANDLE, @liFileSize:LARGE_INTEGER,@pFileAddr:PTR BYTE,@dwReaded:DWORDpushad ; 打开文件invoke CreateFile, _pFileName, FILE_ALL_ACCESS, FILE_SHARE_READ,NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULLcmp eax, INVALID_HANDLE_VALUE je Ending mov @hFile, eax ; 获取文件大小invoke GetFileSizeEx, @hFile, ADDR @liFileSize ; 分配堆空间invoke VirtualAlloc, NULL, [@liFileSize].LowPart, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE test eax, eax jz Ending mov @pFileAddr, eax ; 清空缓存invoke RtlZeroMemory, @pFileAddr, @liFileSize.LowPart; 读取内容invoke ReadFile, @hFile, @pFileAddr, @liFileSize.LowPart, ADDR @dwReaded, NULL test eax, eax jz Ending jmp @F Ending:cmp @pFileAddr, 0jz @F invoke VirtualFree, @pFileAddr, 0, MEM_RELEASEmov @pFileAddr, 0
@@:cmp @hFile, INVALID_HANDLE_VALUEjz @F invoke CloseHandle, @hFile mov @hFile, INVALID_HANDLE_VALUE
@@:popad mov eax, @pFileAddrret
_vReadFile ENDPENDIF
(完)