macho/macho-go/internal/wrapper/info.go
2023-06-26 15:33:37 +07:00

106 lines
2.0 KiB
Go

package wrapper
import (
"bytes"
"encoding/binary"
"fmt"
"io"
"os"
. "ios-wrapper/pkg/ios"
. "ios-wrapper/pkg/ios/fat"
. "ios-wrapper/pkg/ios/macho"
)
type InfoPrinter struct {
contexts []*MachoContext
}
func (printer *InfoPrinter) Print() {
for _, mc := range printer.contexts {
fmt.Printf("Mach-O arch: %s\n", mc.ArchName())
for i, cmd := range mc.Commands() {
fmt.Printf("%d: %s\n", i, cmd.Cmdname())
}
fmt.Printf("Image Base: 0x%x\n", mc.ImageBase())
init_funcs := mc.InitFunctions()
if len(init_funcs) == 0 {
fmt.Println("No Init functions")
}
for _, fun := range init_funcs {
fmt.Printf("Init functions at offset %s\n", &fun)
}
symbols := mc.CollectBindSymbols()
for _, sym := range symbols {
fmt.Printf(
"%s (%s)\n\tStub=0x%x Address=0x%x\n\tDylib=%s\n",
sym.Name(),
sym.Type(),
sym.Stub(),
sym.Address(),
sym.Dylib(),
)
}
fmt.Println("======")
}
}
func machoPrinter(file *os.File) *InfoPrinter {
var mc MachoContext
err := mc.ParseFile(file, 0)
if err != nil {
return &InfoPrinter{
contexts: []*MachoContext{},
}
} else {
return &InfoPrinter{
contexts: []*MachoContext{&mc},
}
}
}
func fatPrinter(file *os.File) *InfoPrinter {
var fat FatContext
fat.ParseFile(file)
var contexts []*MachoContext
for _, m := range fat.Machos() {
buf := make([]byte, m.Size)
file.Seek(int64(m.Offset), io.SeekStart)
file.Read(buf)
var mc MachoContext
mc.ParseBuffer(buf)
contexts = append(contexts, &mc)
}
return &InfoPrinter{
contexts,
}
}
func InfoPrinterFromFile(file *os.File) *InfoPrinter {
var magic uint32
magic_buf := []byte{0, 0, 0, 0}
file.Read(magic_buf)
magic_r := bytes.NewReader(magic_buf)
binary.Read(magic_r, binary.LittleEndian, &magic)
file.Seek(0, io.SeekStart)
if magic == MagicFat || magic == CigamFat {
return fatPrinter(file)
}
if magic == Magic32 || magic == Magic64 || magic == Cigam32 ||
magic == Cigam64 {
return machoPrinter(file)
}
return &InfoPrinter{}
}