Added Mach-O file format
This commit is contained in:
parent
cc215a27c7
commit
58f010b81a
10 changed files with 266 additions and 4 deletions
107
src/macho/MachO.go
Normal file
107
src/macho/MachO.go
Normal file
|
@ -0,0 +1,107 @@
|
|||
package macho
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"io"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/config"
|
||||
)
|
||||
|
||||
// MachO is the executable format used on MacOS.
|
||||
type MachO struct {
|
||||
Header
|
||||
Code []byte
|
||||
Data []byte
|
||||
}
|
||||
|
||||
// New creates a new Mach-O binary.
|
||||
func New(code []byte, data []byte) *MachO {
|
||||
return &MachO{
|
||||
Header: Header{
|
||||
Magic: 0xFEEDFACF,
|
||||
Architecture: CPU_X86_64,
|
||||
MicroArchitecture: 0x80000003,
|
||||
Type: TypeExecute,
|
||||
NumCommands: 3,
|
||||
SizeCommands: 0x48*2 + 184,
|
||||
Flags: FlagNoUndefs,
|
||||
Reserved: 0,
|
||||
},
|
||||
Code: code,
|
||||
Data: data,
|
||||
}
|
||||
}
|
||||
|
||||
// Write writes the Mach-O format to the given writer.
|
||||
func (m *MachO) Write(writer io.Writer) {
|
||||
binary.Write(writer, binary.LittleEndian, &m.Header)
|
||||
|
||||
binary.Write(writer, binary.LittleEndian, &Segment64{
|
||||
LoadCommand: LcSegment64,
|
||||
Length: 0x48,
|
||||
Name: [16]byte{'_', '_', 'P', 'A', 'G', 'E', 'Z', 'E', 'R', 'O'},
|
||||
Address: 0,
|
||||
SizeInMemory: config.BaseAddress,
|
||||
Offset: 0,
|
||||
SizeInFile: 0,
|
||||
NumSections: 0,
|
||||
Flag: 0,
|
||||
MaxProt: 0,
|
||||
InitProt: 0,
|
||||
})
|
||||
|
||||
codeStart := 32 + m.Header.SizeCommands
|
||||
totalSize := uint64(codeStart) + uint64(len(m.Code))
|
||||
|
||||
binary.Write(writer, binary.LittleEndian, &Segment64{
|
||||
LoadCommand: LcSegment64,
|
||||
Length: 0x48,
|
||||
Name: [16]byte{'_', '_', 'T', 'E', 'X', 'T'},
|
||||
Address: config.BaseAddress,
|
||||
SizeInMemory: totalSize,
|
||||
Offset: 0,
|
||||
SizeInFile: totalSize,
|
||||
NumSections: 0,
|
||||
Flag: 0,
|
||||
MaxProt: ProtReadable | ProtWritable | ProtExecutable,
|
||||
InitProt: ProtReadable | ProtExecutable,
|
||||
})
|
||||
|
||||
binary.Write(writer, binary.LittleEndian, &Thread{
|
||||
LoadCommand: LcUnixthread,
|
||||
Len: 184,
|
||||
Type: 0x4,
|
||||
})
|
||||
|
||||
binary.Write(writer, binary.LittleEndian, []uint32{
|
||||
42,
|
||||
0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
config.BaseAddress + uint32(codeStart), 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
})
|
||||
|
||||
writer.Write(m.Code)
|
||||
|
||||
if totalSize < 4096 {
|
||||
writer.Write(bytes.Repeat([]byte{0}, 4096-int(totalSize)))
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue