Improved alignment function

This commit is contained in:
Eduard Urbach 2024-08-15 13:53:00 +02:00
parent 999e60e294
commit c7881ab0ef
Signed by: eduard
GPG key ID: 49226B848C78F6C8
8 changed files with 56 additions and 43 deletions

View file

@ -9,31 +9,36 @@ import (
"git.akyoto.dev/cli/q/src/exe"
)
const NumSections = 2
// EXE is the portable executable format used on Windows.
type EXE struct {
DOSHeader
NTHeader
OptionalHeader64
Sections [NumSections]SectionHeader
Sections []SectionHeader
}
// Write writes the EXE file to the given writer.
func Write(writer io.Writer, code []byte, data []byte) {
const (
HeaderEnd = DOSHeaderSize + NTHeaderSize + OptionalHeader64Size + SectionHeaderSize*NumSections
)
NumSections := 1
if len(data) != 0 {
NumSections += 1
}
HeaderEnd := DOSHeaderSize + NTHeaderSize + OptionalHeader64Size + SectionHeaderSize*NumSections
var (
codePadding = exe.Padding(HeaderEnd, config.Align)
codeEnd = config.CodeOffset + len(code)
dataPadding = exe.Padding(codeEnd, config.Align)
dataStart = codeEnd + dataPadding
codeStart, codePadding = exe.Align(HeaderEnd, config.Align)
dataStart, dataPadding = exe.Align(codeStart+len(code), config.Align)
)
imageSize := dataStart + len(data)
imageSize += exe.Padding(imageSize, config.Align)
imageSize := codeStart + len(code)
if len(data) != 0 {
imageSize = dataStart + len(data)
}
imageSize, _ = exe.Align(imageSize, config.Align)
pe := &EXE{
DOSHeader: DOSHeader{
@ -43,7 +48,7 @@ func Write(writer io.Writer, code []byte, data []byte) {
NTHeader: NTHeader{
Signature: [4]byte{'P', 'E', 0, 0},
Machine: IMAGE_FILE_MACHINE_AMD64,
NumberOfSections: NumSections,
NumberOfSections: uint16(NumSections),
SizeOfOptionalHeader: OptionalHeader64Size,
Characteristics: IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_LARGE_ADDRESS_AWARE,
},
@ -61,7 +66,7 @@ func Write(writer io.Writer, code []byte, data []byte) {
MajorSubsystemVersion: 0x06,
SizeOfImage: uint32(imageSize),
SizeOfHeaders: config.CodeOffset, // section bodies begin here
Subsystem: IMAGE_SUBSYSTEM_WINDOWS_GUI,
Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI,
DllCharacteristics: IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA | IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE | IMAGE_DLLCHARACTERISTICS_NX_COMPAT | IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE,
SizeOfStackReserve: 0x100000,
SizeOfStackCommit: 0x1000,
@ -87,7 +92,7 @@ func Write(writer io.Writer, code []byte, data []byte) {
{VirtualAddress: 0, Size: 0},
},
},
Sections: [NumSections]SectionHeader{
Sections: []SectionHeader{
{
Name: [8]byte{'.', 't', 'e', 'x', 't'},
VirtualSize: uint32(len(code)),
@ -110,10 +115,13 @@ func Write(writer io.Writer, code []byte, data []byte) {
binary.Write(writer, binary.LittleEndian, &pe.DOSHeader)
binary.Write(writer, binary.LittleEndian, &pe.NTHeader)
binary.Write(writer, binary.LittleEndian, &pe.OptionalHeader64)
binary.Write(writer, binary.LittleEndian, &pe.Sections)
binary.Write(writer, binary.LittleEndian, pe.Sections[:NumSections])
writer.Write(bytes.Repeat([]byte{0}, int(codePadding)))
writer.Write(bytes.Repeat([]byte{0x00}, int(codePadding)))
writer.Write(code)
writer.Write(bytes.Repeat([]byte{0}, int(dataPadding)))
writer.Write(data)
if len(data) != 0 {
writer.Write(bytes.Repeat([]byte{0x00}, int(dataPadding)))
writer.Write(data)
}
}