diff --git a/build/Build.go b/build/Build.go index 0d0b156..ac3198e 100644 --- a/build/Build.go +++ b/build/Build.go @@ -38,9 +38,17 @@ func New(directory string) (*Build, error) { func (build *Build) Run() error { if build.WriteExecutable { sampleCode := []byte{ - 0xb8, 0x3c, 0x00, 0x00, 0x00, // mov rax, 60 - 0xbf, 0x00, 0x00, 0x00, 0x00, // mov rdi, 0 + 0xb8, 0x01, 0x00, 0x00, 0x00, // mov eax, 1 + 0xbf, 0x01, 0x00, 0x00, 0x00, // mov edi, 1 + 0xbe, 0x80 + 0x22, 0x00, 0x40, 0x00, // mov esi, 0x4000A2 + 0xba, 0x06, 0x00, 0x00, 0x00, // mov edx, 6 0x0f, 0x05, // syscall + + 0xb8, 0x3c, 0x00, 0x00, 0x00, // mov eax, 60 + 0xbf, 0x00, 0x00, 0x00, 0x00, // mov edi, 0 + 0x0f, 0x05, // syscall + + 'H', 'e', 'l', 'l', 'o', '\n', } return writeToDisk(build.ExecutablePath, sampleCode, nil) diff --git a/build/elf/Header.go b/build/elf/Header.go index bdb7e24..49b231c 100644 --- a/build/elf/Header.go +++ b/build/elf/Header.go @@ -4,8 +4,9 @@ const ( LittleEndian = 1 TypeExecutable = 2 ArchitectureAMD64 = 0x3E - Align = 16 HeaderSize = 64 + CacheLineSize = 64 + Align = CacheLineSize ) // Header contains general information. diff --git a/build/elf/elf.go b/build/elf/elf.go index 740ab77..1da251e 100644 --- a/build/elf/elf.go +++ b/build/elf/elf.go @@ -6,15 +6,14 @@ import ( ) const ( - baseAddress = 0x10000 + baseAddress = 0x400000 ) // ELF64 represents an ELF 64-bit file. type ELF64 struct { Header ProgramHeader - Padding []byte - Code []byte + Code []byte } // New creates a new 64-bit ELF binary. @@ -43,7 +42,7 @@ func New(code []byte) *ELF64 { }, ProgramHeader: ProgramHeader{ Type: ProgramTypeLOAD, - Flags: ProgramFlagsExecutable, + Flags: ProgramFlagsExecutable | ProgramFlagsReadable, Offset: 0x80, VirtualAddress: baseAddress + 0x80, PhysicalAddress: baseAddress + 0x80, @@ -51,8 +50,7 @@ func New(code []byte) *ELF64 { SizeInMemory: int64(len(code)), Align: Align, }, - Padding: []byte{0, 0, 0, 0, 0, 0, 0, 0}, - Code: code, + Code: code, } return elf @@ -62,6 +60,6 @@ func New(code []byte) *ELF64 { func (elf *ELF64) Write(writer io.Writer) { binary.Write(writer, binary.LittleEndian, &elf.Header) binary.Write(writer, binary.LittleEndian, &elf.ProgramHeader) - writer.Write(elf.Padding) + writer.Write([]byte{0, 0, 0, 0, 0, 0, 0, 0}) writer.Write(elf.Code) } diff --git a/build/elf/elf.md b/build/elf/elf.md index dd0de12..83df35c 100644 --- a/build/elf/elf.md +++ b/build/elf/elf.md @@ -1,12 +1,26 @@ # ELF -## File contents +## Basic structure -- ELF header -- Program headers -- Sections -- Section headers +1. ELF header (0x00 - 0x40) +2. Program header (0x40 - 0x78) +3. Padding (0x78 - 0x80) +4. Machine code (0x80) ## Entry point The entry point is defined in the first 64 bytes (ELF header). + +## Base address + +The minimum base address is controlled by the `mmap` settings: + +```shell +sysctl vm.mmap_min_addr +``` + +Usually, this value is 65536 (0x1000). + +## Initialization in Linux + +See `/lib/modules/$(uname -r)/build/arch/x86/include/asm/elf.h`.