601 lines
16 KiB
Go
601 lines
16 KiB
Go
package macho
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"encoding/binary"
|
|
"fmt"
|
|
|
|
. "ios-wrapper/pkg/ios"
|
|
)
|
|
|
|
// A Serializable interface
|
|
// Serialize to bytes and Deserialize to struct
|
|
// with MachoContext to know the byteorder
|
|
type Serializable interface {
|
|
Serialize(mc *MachoContext) []byte
|
|
Deserialize(mc *MachoContext, buf []byte)
|
|
}
|
|
|
|
// macho_header and macho_header64
|
|
type Header struct {
|
|
magic uint32
|
|
cputype uint32
|
|
cpusubtype uint32
|
|
filetype uint32
|
|
ncmds uint32
|
|
sizeofcmds uint32
|
|
flags uint32
|
|
reserved uint32
|
|
}
|
|
|
|
func (h *Header) Cputype() uint32 {
|
|
return h.cputype
|
|
}
|
|
|
|
func (h *Header) Cpusubtype() uint32 {
|
|
return h.cpusubtype
|
|
}
|
|
|
|
func (h *Header) Serialize(mc *MachoContext) []byte {
|
|
buf := new(bytes.Buffer)
|
|
binary.Write(buf, mc.byteorder, h.magic)
|
|
binary.Write(buf, mc.byteorder, h.cputype)
|
|
binary.Write(buf, mc.byteorder, h.cpusubtype)
|
|
binary.Write(buf, mc.byteorder, h.filetype)
|
|
binary.Write(buf, mc.byteorder, h.ncmds)
|
|
binary.Write(buf, mc.byteorder, h.sizeofcmds)
|
|
binary.Write(buf, mc.byteorder, h.flags)
|
|
if mc.Is64bit() {
|
|
binary.Write(buf, mc.byteorder, h.reserved)
|
|
}
|
|
return buf.Bytes()
|
|
}
|
|
|
|
func (h *Header) Deserialize(mc *MachoContext, r *bufio.Reader) {
|
|
binary.Read(r, mc.byteorder, &h.magic)
|
|
binary.Read(r, mc.byteorder, &h.cputype)
|
|
binary.Read(r, mc.byteorder, &h.cpusubtype)
|
|
binary.Read(r, mc.byteorder, &h.filetype)
|
|
binary.Read(r, mc.byteorder, &h.ncmds)
|
|
binary.Read(r, mc.byteorder, &h.sizeofcmds)
|
|
binary.Read(r, mc.byteorder, &h.flags)
|
|
if mc.Is64bit() {
|
|
binary.Read(r, mc.byteorder, &h.reserved)
|
|
}
|
|
}
|
|
|
|
type LoadCommand interface {
|
|
Serializable
|
|
Cmd() uint32
|
|
Cmdsize() uint32
|
|
Cmdname() string
|
|
}
|
|
|
|
// Stores the common value of load command
|
|
// Raw stores the rest of the command
|
|
// where no struct defined for cmd
|
|
type LoadCmd struct {
|
|
cmd uint32
|
|
cmdsize uint32
|
|
Raw []byte
|
|
}
|
|
|
|
func (lcmd *LoadCmd) Cmd() uint32 {
|
|
return lcmd.cmd
|
|
}
|
|
|
|
func (lcmd *LoadCmd) Cmdsize() uint32 {
|
|
return lcmd.cmdsize
|
|
}
|
|
|
|
func (lcmd *LoadCmd) Cmdname() string {
|
|
switch lcmd.cmd {
|
|
case LC_RPATH:
|
|
return "LC_RPATH"
|
|
case LC_DYLD_INFO:
|
|
return "LC_DYLD_INFO"
|
|
case LC_DYLD_INFO_ONLY:
|
|
return "LC_DYLD_INFO_ONLY"
|
|
case LC_CODE_SIGNATURE:
|
|
return "LC_CODE_SIGNATURE"
|
|
case LC_LAZY_LOAD_DYLIB:
|
|
return "LC_LAZY_LOAD_DYLIB"
|
|
case LC_LOAD_DYLIB:
|
|
return "LC_LOAD_DYLIB"
|
|
case LC_ID_DYLIB:
|
|
return "LC_ID_DYLIB"
|
|
case LC_REEXPORT_DYLIB:
|
|
return "LC_REEXPORT_DYLIB"
|
|
case LC_ENCRYPTION_INFO:
|
|
return "LC_ENCRYPTION_INFO"
|
|
case LC_ENCRYPTION_INFO_64:
|
|
return "LC_ENCRYPTION_INFO_64"
|
|
case LC_DYSYMTAB:
|
|
return "LC_DYSYMTAB"
|
|
case LC_LOAD_WEAK_DYLIB:
|
|
return "LC_LOAD_WEAK_DYLIB"
|
|
case LC_SEGMENT:
|
|
return "LC_SEGMENT"
|
|
case LC_SEGMENT_64:
|
|
return "LC_SEGMENT_64"
|
|
case LC_MAIN:
|
|
return "LC_MAIN"
|
|
case LC_FUNCTION_STARTS:
|
|
return "LC_FUNCTION_STARTS"
|
|
case LC_DATA_IN_CODE:
|
|
return "LC_DATA_IN_CODE"
|
|
case LC_SYMTAB:
|
|
return "LC_SYMTAB"
|
|
default:
|
|
// TODO: Update
|
|
return fmt.Sprintf("LC_DONT_KNOW_0x%x", lcmd.Cmd())
|
|
}
|
|
}
|
|
|
|
func (lcmd *LoadCmd) Serialize(mc *MachoContext) []byte {
|
|
buf := new(bytes.Buffer)
|
|
binary.Write(buf, mc.byteorder, lcmd.Cmd())
|
|
binary.Write(buf, mc.byteorder, lcmd.Cmdsize())
|
|
binary.Write(buf, mc.byteorder, lcmd.Raw)
|
|
return buf.Bytes()
|
|
}
|
|
|
|
func (lcmd *LoadCmd) Deserialize(mc *MachoContext, buf []byte) {
|
|
r := bytes.NewBuffer(buf)
|
|
binary.Read(r, mc.byteorder, &lcmd.cmd)
|
|
binary.Read(r, mc.byteorder, &lcmd.cmdsize)
|
|
lcmd.Raw = make([]byte, lcmd.cmdsize-8)
|
|
r.Read(lcmd.Raw)
|
|
}
|
|
|
|
type RPath struct {
|
|
c LoadCmd
|
|
offset uint32
|
|
path []byte
|
|
}
|
|
|
|
func (lcmd *RPath) Cmd() uint32 {
|
|
return LC_RPATH
|
|
}
|
|
|
|
func (lcmd *RPath) Cmdsize() uint32 {
|
|
raw_cmd_size := 8 + 4 + len(lcmd.path) + 1
|
|
if raw_cmd_size%8 == 0 {
|
|
return uint32(raw_cmd_size)
|
|
}
|
|
padded_cmd_size := raw_cmd_size + (8 - (raw_cmd_size % 8))
|
|
return uint32(padded_cmd_size)
|
|
}
|
|
|
|
func (lcmd *RPath) Cmdname() string {
|
|
return fmt.Sprintf("%s %s", lcmd.c.Cmdname(), string(lcmd.path))
|
|
}
|
|
|
|
func (lcmd *RPath) Serialize(mc *MachoContext) []byte {
|
|
buf := new(bytes.Buffer)
|
|
binary.Write(buf, mc.byteorder, lcmd.Cmd())
|
|
binary.Write(buf, mc.byteorder, lcmd.Cmdsize())
|
|
binary.Write(buf, mc.byteorder, lcmd.offset)
|
|
binary.Write(buf, mc.byteorder, []byte(lcmd.path))
|
|
buf.WriteByte(0)
|
|
if buf.Len()%8 != 0 {
|
|
bytes_padded := 8 - (buf.Len() % 8)
|
|
binary.Write(buf, mc.byteorder, make([]byte, bytes_padded))
|
|
}
|
|
return buf.Bytes()
|
|
}
|
|
|
|
func (lcmd *RPath) Deserialize(mc *MachoContext, buf []byte) {
|
|
r := bytes.NewBuffer(buf)
|
|
binary.Read(r, mc.byteorder, &lcmd.c.cmd)
|
|
binary.Read(r, mc.byteorder, &lcmd.c.cmdsize)
|
|
binary.Read(r, mc.byteorder, &lcmd.offset)
|
|
lcmd.path, _ = r.ReadBytes(0)
|
|
lcmd.path = bytes.Trim(lcmd.path, "\x00")
|
|
}
|
|
|
|
type Dylib struct {
|
|
c LoadCmd
|
|
nameoff uint32
|
|
name []byte
|
|
timestamp uint32
|
|
current_version uint32
|
|
compatibility_version uint32
|
|
}
|
|
|
|
func (lcmd *Dylib) Cmd() uint32 {
|
|
return lcmd.c.Cmd()
|
|
}
|
|
|
|
func (lcmd *Dylib) Cmdsize() uint32 {
|
|
raw_cmd_size := 8 + 16 + len(lcmd.name) + 1
|
|
if raw_cmd_size%8 == 0 {
|
|
return uint32(raw_cmd_size)
|
|
}
|
|
padded_cmd_size := raw_cmd_size + (8 - (raw_cmd_size % 8))
|
|
return uint32(padded_cmd_size)
|
|
}
|
|
|
|
func (lcmd *Dylib) Cmdname() string {
|
|
return fmt.Sprintf("%s %s", lcmd.c.Cmdname(), string(lcmd.name))
|
|
}
|
|
|
|
func (lcmd *Dylib) Serialize(mc *MachoContext) []byte {
|
|
buf := new(bytes.Buffer)
|
|
binary.Write(buf, mc.byteorder, lcmd.Cmd())
|
|
binary.Write(buf, mc.byteorder, lcmd.Cmdsize())
|
|
binary.Write(buf, mc.byteorder, lcmd.nameoff)
|
|
binary.Write(buf, mc.byteorder, lcmd.timestamp)
|
|
binary.Write(buf, mc.byteorder, lcmd.current_version)
|
|
binary.Write(buf, mc.byteorder, lcmd.compatibility_version)
|
|
binary.Write(buf, mc.byteorder, lcmd.name)
|
|
buf.WriteByte(0)
|
|
|
|
// size must align with 8
|
|
if buf.Len()%8 != 0 {
|
|
bytes_padded := 8 - (buf.Len() % 8)
|
|
binary.Write(buf, mc.byteorder, make([]byte, bytes_padded))
|
|
}
|
|
return buf.Bytes()
|
|
}
|
|
|
|
func (lcmd *Dylib) Deserialize(mc *MachoContext, buf []byte) {
|
|
r := bytes.NewBuffer(buf)
|
|
binary.Read(r, mc.byteorder, &lcmd.c.cmd)
|
|
binary.Read(r, mc.byteorder, &lcmd.c.cmdsize)
|
|
binary.Read(r, mc.byteorder, &lcmd.nameoff)
|
|
binary.Read(r, mc.byteorder, &lcmd.timestamp)
|
|
binary.Read(r, mc.byteorder, &lcmd.current_version)
|
|
binary.Read(r, mc.byteorder, &lcmd.compatibility_version)
|
|
lcmd.name, _ = r.ReadBytes(0)
|
|
lcmd.name = bytes.Trim(lcmd.name, "\x00")
|
|
}
|
|
|
|
type EncryptionInfo struct {
|
|
c LoadCmd
|
|
cryptoff uint32
|
|
cryptsize uint32
|
|
cryptid uint32
|
|
pad uint32
|
|
}
|
|
|
|
func (lcmd *EncryptionInfo) Cmd() uint32 {
|
|
return lcmd.c.Cmd()
|
|
}
|
|
|
|
func (lcmd *EncryptionInfo) Cmdsize() uint32 {
|
|
if lcmd.Cmd() == LC_ENCRYPTION_INFO {
|
|
return uint32(8 + 4*3)
|
|
} else {
|
|
return uint32(8 + 4*4)
|
|
}
|
|
}
|
|
|
|
func (lcmd *EncryptionInfo) Cmdname() string {
|
|
return fmt.Sprintf("%s start:0x%x size:0x%x encrypted:%d",
|
|
lcmd.c.Cmdname(), lcmd.cryptoff, lcmd.cryptsize, lcmd.cryptid)
|
|
}
|
|
|
|
func (lcmd *EncryptionInfo) Serialize(mc *MachoContext) []byte {
|
|
buf := new(bytes.Buffer)
|
|
binary.Write(buf, mc.byteorder, lcmd.Cmd())
|
|
binary.Write(buf, mc.byteorder, lcmd.Cmdsize())
|
|
binary.Write(buf, mc.byteorder, lcmd.cryptoff)
|
|
binary.Write(buf, mc.byteorder, lcmd.cryptsize)
|
|
binary.Write(buf, mc.byteorder, lcmd.cryptid)
|
|
if mc.Is64bit() {
|
|
binary.Write(buf, mc.byteorder, lcmd.pad)
|
|
}
|
|
return buf.Bytes()
|
|
}
|
|
|
|
func (lcmd *EncryptionInfo) Deserialize(mc *MachoContext, buf []byte) {
|
|
r := bytes.NewBuffer(buf)
|
|
binary.Read(r, mc.byteorder, &lcmd.c.cmd)
|
|
binary.Read(r, mc.byteorder, &lcmd.c.cmdsize)
|
|
binary.Read(r, mc.byteorder, &lcmd.cryptoff)
|
|
binary.Read(r, mc.byteorder, &lcmd.cryptsize)
|
|
binary.Read(r, mc.byteorder, &lcmd.cryptid)
|
|
if mc.Is64bit() {
|
|
binary.Read(r, mc.byteorder, &lcmd.pad)
|
|
}
|
|
}
|
|
|
|
type EntryPoint struct {
|
|
c LoadCmd
|
|
entryoff uint64
|
|
stacksize uint64
|
|
}
|
|
|
|
func (lcmd *EntryPoint) Cmd() uint32 {
|
|
return lcmd.c.Cmd()
|
|
}
|
|
|
|
func (lcmd *EntryPoint) Cmdsize() uint32 {
|
|
return uint32(8 + 8*2)
|
|
}
|
|
|
|
func (lcmd *EntryPoint) Cmdname() string {
|
|
return lcmd.c.Cmdname()
|
|
}
|
|
|
|
func (lcmd *EntryPoint) Serialize(mc *MachoContext) []byte {
|
|
buf := new(bytes.Buffer)
|
|
binary.Write(buf, mc.byteorder, lcmd.Cmd())
|
|
binary.Write(buf, mc.byteorder, lcmd.Cmdsize())
|
|
binary.Write(buf, mc.byteorder, lcmd.entryoff)
|
|
binary.Write(buf, mc.byteorder, lcmd.stacksize)
|
|
return buf.Bytes()
|
|
}
|
|
|
|
func (lcmd *EntryPoint) Deserialize(mc *MachoContext, buf []byte) {
|
|
r := bytes.NewBuffer(buf)
|
|
binary.Read(r, mc.byteorder, &lcmd.c.cmd)
|
|
binary.Read(r, mc.byteorder, &lcmd.c.cmdsize)
|
|
binary.Read(r, mc.byteorder, &lcmd.entryoff)
|
|
binary.Read(r, mc.byteorder, &lcmd.stacksize)
|
|
}
|
|
|
|
type DyldInfo struct {
|
|
c LoadCmd
|
|
rebase_off uint32
|
|
rebase_size uint32
|
|
bind_off uint32
|
|
bind_size uint32
|
|
weak_bind_off uint32
|
|
weak_bind_size uint32
|
|
lazy_bind_off uint32
|
|
lazy_bind_size uint32
|
|
export_off uint32
|
|
export_size uint32
|
|
}
|
|
|
|
func (lcmd *DyldInfo) Cmd() uint32 {
|
|
return lcmd.c.Cmd()
|
|
}
|
|
|
|
func (lcmd *DyldInfo) Cmdsize() uint32 {
|
|
return uint32(8 + 4*10)
|
|
}
|
|
|
|
func (lcmd *DyldInfo) Cmdname() string {
|
|
return lcmd.c.Cmdname()
|
|
}
|
|
|
|
func (lcmd *DyldInfo) Serialize(mc *MachoContext) []byte {
|
|
buf := new(bytes.Buffer)
|
|
binary.Write(buf, mc.byteorder, lcmd.Cmd())
|
|
binary.Write(buf, mc.byteorder, lcmd.Cmdsize())
|
|
binary.Write(buf, mc.byteorder, lcmd.rebase_off)
|
|
binary.Write(buf, mc.byteorder, lcmd.rebase_size)
|
|
binary.Write(buf, mc.byteorder, lcmd.bind_off)
|
|
binary.Write(buf, mc.byteorder, lcmd.bind_size)
|
|
binary.Write(buf, mc.byteorder, lcmd.weak_bind_off)
|
|
binary.Write(buf, mc.byteorder, lcmd.weak_bind_size)
|
|
binary.Write(buf, mc.byteorder, lcmd.lazy_bind_off)
|
|
binary.Write(buf, mc.byteorder, lcmd.lazy_bind_size)
|
|
binary.Write(buf, mc.byteorder, lcmd.export_off)
|
|
binary.Write(buf, mc.byteorder, lcmd.export_size)
|
|
return buf.Bytes()
|
|
}
|
|
|
|
func (lcmd *DyldInfo) Deserialize(mc *MachoContext, buf []byte) {
|
|
r := bytes.NewBuffer(buf)
|
|
binary.Read(r, mc.byteorder, &lcmd.c.cmd)
|
|
binary.Read(r, mc.byteorder, &lcmd.c.cmdsize)
|
|
binary.Read(r, mc.byteorder, &lcmd.rebase_off)
|
|
binary.Read(r, mc.byteorder, &lcmd.rebase_size)
|
|
binary.Read(r, mc.byteorder, &lcmd.bind_off)
|
|
binary.Read(r, mc.byteorder, &lcmd.bind_size)
|
|
binary.Read(r, mc.byteorder, &lcmd.weak_bind_off)
|
|
binary.Read(r, mc.byteorder, &lcmd.weak_bind_size)
|
|
binary.Read(r, mc.byteorder, &lcmd.lazy_bind_off)
|
|
binary.Read(r, mc.byteorder, &lcmd.lazy_bind_size)
|
|
binary.Read(r, mc.byteorder, &lcmd.export_off)
|
|
binary.Read(r, mc.byteorder, &lcmd.export_size)
|
|
}
|
|
|
|
type Fixups struct {
|
|
fixups_version uint32
|
|
starts_offset uint32
|
|
imports_offset uint32
|
|
symbols_offset uint32
|
|
imports_count uint32
|
|
imports_format uint32
|
|
symbols_format uint32
|
|
}
|
|
|
|
func (lcmd *Fixups) Serialize(mc *MachoContext) []byte {
|
|
buf := new(bytes.Buffer)
|
|
binary.Write(buf, mc.byteorder, lcmd.fixups_version)
|
|
binary.Write(buf, mc.byteorder, lcmd.starts_offset)
|
|
binary.Write(buf, mc.byteorder, lcmd.imports_offset)
|
|
binary.Write(buf, mc.byteorder, lcmd.symbols_offset)
|
|
binary.Write(buf, mc.byteorder, lcmd.imports_count)
|
|
binary.Write(buf, mc.byteorder, lcmd.imports_format)
|
|
binary.Write(buf, mc.byteorder, lcmd.symbols_format)
|
|
return buf.Bytes()
|
|
}
|
|
|
|
func (lcmd *Fixups) Deserialize(mc *MachoContext, buf []byte) {
|
|
r := bytes.NewBuffer(buf)
|
|
binary.Read(r, mc.byteorder, &lcmd.fixups_version)
|
|
binary.Read(r, mc.byteorder, &lcmd.starts_offset)
|
|
binary.Read(r, mc.byteorder, &lcmd.imports_offset)
|
|
binary.Read(r, mc.byteorder, &lcmd.symbols_offset)
|
|
binary.Read(r, mc.byteorder, &lcmd.imports_count)
|
|
binary.Read(r, mc.byteorder, &lcmd.imports_format)
|
|
binary.Read(r, mc.byteorder, &lcmd.symbols_format)
|
|
}
|
|
|
|
type LinkEdit struct {
|
|
c LoadCmd
|
|
dataoff uint32
|
|
datasize uint32
|
|
}
|
|
|
|
func (lcmd *LinkEdit) Dataoff() uint32 {
|
|
return lcmd.dataoff
|
|
}
|
|
|
|
func (lcmd *LinkEdit) Datasize() uint32 {
|
|
return lcmd.datasize
|
|
}
|
|
|
|
func (lcmd *LinkEdit) Cmd() uint32 {
|
|
return lcmd.c.Cmd()
|
|
}
|
|
|
|
func (lcmd *LinkEdit) Cmdsize() uint32 {
|
|
return uint32(8 + 4*2)
|
|
}
|
|
|
|
func (lcmd *LinkEdit) Cmdname() string {
|
|
return lcmd.c.Cmdname()
|
|
}
|
|
|
|
func (lcmd *LinkEdit) Serialize(mc *MachoContext) []byte {
|
|
buf := new(bytes.Buffer)
|
|
binary.Write(buf, mc.byteorder, lcmd.Cmd())
|
|
binary.Write(buf, mc.byteorder, lcmd.Cmdsize())
|
|
binary.Write(buf, mc.byteorder, lcmd.dataoff)
|
|
binary.Write(buf, mc.byteorder, lcmd.datasize)
|
|
return buf.Bytes()
|
|
}
|
|
|
|
func (lcmd *LinkEdit) Deserialize(mc *MachoContext, buf []byte) {
|
|
r := bytes.NewBuffer(buf)
|
|
binary.Read(r, mc.byteorder, &lcmd.c.cmd)
|
|
binary.Read(r, mc.byteorder, &lcmd.c.cmdsize)
|
|
binary.Read(r, mc.byteorder, &lcmd.dataoff)
|
|
binary.Read(r, mc.byteorder, &lcmd.datasize)
|
|
}
|
|
|
|
type Symtab struct {
|
|
c LoadCmd
|
|
symoff uint32
|
|
nsyms uint32
|
|
stroff uint32
|
|
strsize uint32
|
|
}
|
|
|
|
func (lcmd *Symtab) Cmd() uint32 {
|
|
return lcmd.c.Cmd()
|
|
}
|
|
|
|
func (lcmd *Symtab) Cmdsize() uint32 {
|
|
return uint32(8 + 4*4)
|
|
}
|
|
|
|
func (lcmd *Symtab) Cmdname() string {
|
|
return fmt.Sprintf("%s symoff:0x%x nsyms:%d stroff:0x%x strsize:0x%x",
|
|
lcmd.c.Cmdname(), lcmd.symoff, lcmd.nsyms, lcmd.stroff, lcmd.strsize)
|
|
}
|
|
|
|
func (lcmd *Symtab) Serialize(mc *MachoContext) []byte {
|
|
buf := new(bytes.Buffer)
|
|
binary.Write(buf, mc.byteorder, lcmd.Cmd())
|
|
binary.Write(buf, mc.byteorder, lcmd.Cmdsize())
|
|
binary.Write(buf, mc.byteorder, lcmd.symoff)
|
|
binary.Write(buf, mc.byteorder, lcmd.nsyms)
|
|
binary.Write(buf, mc.byteorder, lcmd.stroff)
|
|
binary.Write(buf, mc.byteorder, lcmd.strsize)
|
|
return buf.Bytes()
|
|
}
|
|
|
|
func (lcmd *Symtab) Deserialize(mc *MachoContext, buf []byte) {
|
|
r := bytes.NewBuffer(buf)
|
|
binary.Read(r, mc.byteorder, &lcmd.c.cmd)
|
|
binary.Read(r, mc.byteorder, &lcmd.c.cmdsize)
|
|
|
|
binary.Read(r, mc.byteorder, &lcmd.symoff)
|
|
binary.Read(r, mc.byteorder, &lcmd.nsyms)
|
|
binary.Read(r, mc.byteorder, &lcmd.stroff)
|
|
binary.Read(r, mc.byteorder, &lcmd.strsize)
|
|
}
|
|
|
|
type DySymtab struct {
|
|
c LoadCmd
|
|
ilocalsym uint32
|
|
nlocalsym uint32
|
|
iextdefsym uint32
|
|
nextdefsym uint32
|
|
iundefsym uint32
|
|
nundefsym uint32
|
|
tocoff uint32
|
|
ntoc uint32
|
|
modtaboff uint32
|
|
nmodtab uint32
|
|
extrefsymoff uint32
|
|
nextrefsyms uint32
|
|
indirectsymoff uint32
|
|
nindirectsyms uint32
|
|
extreloff uint32
|
|
nextrel uint32
|
|
localrefoff uint32
|
|
nlocref uint32
|
|
}
|
|
|
|
func (lcmd *DySymtab) Cmd() uint32 {
|
|
return lcmd.c.Cmd()
|
|
}
|
|
|
|
func (lcmd *DySymtab) Cmdsize() uint32 {
|
|
return uint32(8 + 4*18)
|
|
}
|
|
|
|
func (lcmd *DySymtab) Cmdname() string {
|
|
return fmt.Sprintf("%s indirectsymoff:0x%x nindirectsyms:%d",
|
|
lcmd.c.Cmdname(), lcmd.indirectsymoff, lcmd.nindirectsyms)
|
|
}
|
|
|
|
func (lcmd *DySymtab) Serialize(mc *MachoContext) []byte {
|
|
buf := new(bytes.Buffer)
|
|
binary.Write(buf, mc.byteorder, lcmd.Cmd())
|
|
binary.Write(buf, mc.byteorder, lcmd.Cmdsize())
|
|
binary.Write(buf, mc.byteorder, lcmd.ilocalsym)
|
|
binary.Write(buf, mc.byteorder, lcmd.nlocalsym)
|
|
binary.Write(buf, mc.byteorder, lcmd.iextdefsym)
|
|
binary.Write(buf, mc.byteorder, lcmd.nextdefsym)
|
|
binary.Write(buf, mc.byteorder, lcmd.iundefsym)
|
|
binary.Write(buf, mc.byteorder, lcmd.nundefsym)
|
|
binary.Write(buf, mc.byteorder, lcmd.tocoff)
|
|
binary.Write(buf, mc.byteorder, lcmd.ntoc)
|
|
binary.Write(buf, mc.byteorder, lcmd.modtaboff)
|
|
binary.Write(buf, mc.byteorder, lcmd.nmodtab)
|
|
binary.Write(buf, mc.byteorder, lcmd.extrefsymoff)
|
|
binary.Write(buf, mc.byteorder, lcmd.nextrefsyms)
|
|
binary.Write(buf, mc.byteorder, lcmd.indirectsymoff)
|
|
binary.Write(buf, mc.byteorder, lcmd.nindirectsyms)
|
|
binary.Write(buf, mc.byteorder, lcmd.extreloff)
|
|
binary.Write(buf, mc.byteorder, lcmd.nextrel)
|
|
binary.Write(buf, mc.byteorder, lcmd.localrefoff)
|
|
binary.Write(buf, mc.byteorder, lcmd.nlocref)
|
|
return buf.Bytes()
|
|
}
|
|
|
|
func (lcmd *DySymtab) Deserialize(mc *MachoContext, buf []byte) {
|
|
r := bytes.NewBuffer(buf)
|
|
binary.Read(r, mc.byteorder, &lcmd.c.cmd)
|
|
binary.Read(r, mc.byteorder, &lcmd.c.cmdsize)
|
|
binary.Read(r, mc.byteorder, &lcmd.ilocalsym)
|
|
binary.Read(r, mc.byteorder, &lcmd.nlocalsym)
|
|
binary.Read(r, mc.byteorder, &lcmd.iextdefsym)
|
|
binary.Read(r, mc.byteorder, &lcmd.nextdefsym)
|
|
binary.Read(r, mc.byteorder, &lcmd.iundefsym)
|
|
binary.Read(r, mc.byteorder, &lcmd.nundefsym)
|
|
binary.Read(r, mc.byteorder, &lcmd.tocoff)
|
|
binary.Read(r, mc.byteorder, &lcmd.ntoc)
|
|
binary.Read(r, mc.byteorder, &lcmd.modtaboff)
|
|
binary.Read(r, mc.byteorder, &lcmd.nmodtab)
|
|
binary.Read(r, mc.byteorder, &lcmd.extrefsymoff)
|
|
binary.Read(r, mc.byteorder, &lcmd.nextrefsyms)
|
|
binary.Read(r, mc.byteorder, &lcmd.indirectsymoff)
|
|
binary.Read(r, mc.byteorder, &lcmd.nindirectsyms)
|
|
binary.Read(r, mc.byteorder, &lcmd.extreloff)
|
|
binary.Read(r, mc.byteorder, &lcmd.nextrel)
|
|
binary.Read(r, mc.byteorder, &lcmd.localrefoff)
|
|
binary.Read(r, mc.byteorder, &lcmd.nlocref)
|
|
}
|