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.CollectLazyBindSymbols() if len(symbols) > 0 { fmt.Println("Lazy Symbols") for _, sym := range symbols { fmt.Printf( "%s\n\tStub=0x%x Address=0x%x\n\tDylib=%s\n", sym.Name(), sym.Stub(), sym.Address(), sym.Dylib(), ) } } else { fmt.Println("No lazy symbols") } 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{} }