Improved section offset calculation

This commit is contained in:
2025-01-20 13:51:47 +01:00
parent e2a6a31d8e
commit 4b7c9f387d
7 changed files with 56 additions and 38 deletions

@ -10,6 +10,11 @@ import (
"git.akyoto.dev/cli/q/src/fs"
)
const (
NumSections = 3
HeaderEnd = DOSHeaderSize + NTHeaderSize + OptionalHeader64Size + SectionHeaderSize*NumSections
)
// EXE is the portable executable format used on Windows.
type EXE struct {
DOSHeader
@ -20,12 +25,6 @@ type EXE struct {
// Write writes the EXE file to the given writer.
func Write(writer io.Writer, code []byte, data []byte, dlls dll.List) {
if len(data) == 0 {
data = []byte{0}
}
NumSections := 3
HeaderEnd := DOSHeaderSize + NTHeaderSize + OptionalHeader64Size + SectionHeaderSize*NumSections
codeStart, codePadding := fs.Align(HeaderEnd, config.Align)
dataStart, dataPadding := fs.Align(codeStart+len(code), config.Align)
importsStart, importsPadding := fs.Align(dataStart+len(data), config.Align)
@ -115,8 +114,8 @@ func Write(writer io.Writer, code []byte, data []byte, dlls dll.List) {
SizeOfCode: uint32(len(code)),
SizeOfInitializedData: 0,
SizeOfUninitializedData: 0,
AddressOfEntryPoint: config.CodeOffset,
BaseOfCode: config.CodeOffset,
AddressOfEntryPoint: uint32(codeStart),
BaseOfCode: uint32(codeStart),
ImageBase: config.BaseAddress,
SectionAlignment: config.Align, // power of 2, must be greater than or equal to FileAlignment
FileAlignment: config.Align, // power of 2
@ -128,7 +127,7 @@ func Write(writer io.Writer, code []byte, data []byte, dlls dll.List) {
MinorSubsystemVersion: 0,
Win32VersionValue: 0,
SizeOfImage: uint32(imageSize),
SizeOfHeaders: config.CodeOffset, // section bodies begin here
SizeOfHeaders: uint32(codeStart), // section bodies begin here
CheckSum: 0,
Subsystem: uint16(subSystem),
DllCharacteristics: IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA | IMAGE_DLLCHARACTERISTICS_NX_COMPAT | IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE, // IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
@ -161,9 +160,9 @@ func Write(writer io.Writer, code []byte, data []byte, dlls dll.List) {
{
Name: [8]byte{'.', 't', 'e', 'x', 't'},
VirtualSize: uint32(len(code)),
VirtualAddress: config.CodeOffset,
VirtualAddress: uint32(codeStart),
RawSize: uint32(len(code)), // must be a multiple of FileAlignment
RawAddress: config.CodeOffset, // must be a multiple of FileAlignment
RawAddress: uint32(codeStart), // must be a multiple of FileAlignment
Characteristics: IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ,
},
{