From 3a30f12019a9e0aacc3946d436a2fce1887d89a5 Mon Sep 17 00:00:00 2001 From: nganhkhoa Date: Fri, 2 Jun 2023 15:24:43 +0700 Subject: [PATCH] support for LC_DYLD_INFO_ONLY strip --- macho-go/pkg/ios/macho/dyld_info.go | 19 +++++---------- macho-go/pkg/ios/macho/edit.go | 36 +++++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/macho-go/pkg/ios/macho/dyld_info.go b/macho-go/pkg/ios/macho/dyld_info.go index 5053f36..c5e7bb4 100644 --- a/macho-go/pkg/ios/macho/dyld_info.go +++ b/macho-go/pkg/ios/macho/dyld_info.go @@ -98,19 +98,6 @@ func (mc *MachoContext) CollectBindSymbolsModern() []*ImportSymbol { // Old convention using LC_DYLD_INFO_ONLY section and bytecode runner func (mc *MachoContext) CollectBindSymbolsLegacy() []*ImportSymbol { - // // clear this whole section to 0x00 BIND_OPCODE_DONE - // dummy := []byte{ - // 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, - // 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, - // } - // // make LINK EDIT section writable - // // mc.file.WriteAt([]byte{0x03}, int64(0x3f8)) - // // set number of symbols to 0 - // mc.file.WriteAt([]byte{0, 0, 0, 0}, int64(0x444)) - // mc.file.WriteAt([]byte{0, 0, 0, 0}, int64(0x44c)) - // mc.file.WriteAt([]byte{0, 0, 0, 0}, int64(0x48c)) - // mc.file.WriteAt(dummy, int64(start)) - noLazy := (func() []*ImportSymbol { start := mc.dyldinfo.bind_off size := mc.dyldinfo.bind_size @@ -187,6 +174,7 @@ func (mc *MachoContext) readBindStream(buf *bytes.Buffer, typ string) []*ImportS "symbol": sym.name, }).Trace("Bind") sym.name = "" + sym.address += 8 } offset += 1 break @@ -241,7 +229,12 @@ func (mc *MachoContext) readBindStream(buf *bytes.Buffer, typ string) []*ImportS offset += br break + case BIND_OPCODE_SET_TYPE_IMM: + fmt.Println("// symbol type", imm) + break + default: + fmt.Println("BIND OPCODE NOT SUPPORTED", op, imm) break } } diff --git a/macho-go/pkg/ios/macho/edit.go b/macho-go/pkg/ios/macho/edit.go index 1938c9a..9f4d48e 100644 --- a/macho-go/pkg/ios/macho/edit.go +++ b/macho-go/pkg/ios/macho/edit.go @@ -280,7 +280,31 @@ func (mc *MachoContext) RemoveBindSymbols() { } } -func (mc *MachoContext) removeBindSymbolsModern() {} +func (mc *MachoContext) removeBindSymbolsModern() { + calculateHash := func(name string) uint32 { + var h uint32 = 0x811c9dc5 + for _, s := range name { + h ^= uint32(s) + h *= 0x01000193 + } + return h + } + + // due to some limitations when design this tool + // we write the c code to stdout lol + fmt.Println("struct imported_symbol {const char* name; const char* lib; uint32_t hash; uint64_t address;};") + fmt.Println("struct imported_symbol imported_table[] = {") + count := 0 + for _, symbol := range mc.CollectBindSymbols() { + count += 1 + dylib_hash := calculateHash(symbol.Dylib()) + fmt.Printf("{\"%s\", \"%s\", 0x%x, 0x%x},\n", + symbol.Name(), symbol.Dylib(), dylib_hash, symbol.Address()); + mc.file.WriteAt(make([]byte, 8), int64(symbol.file_address)) + } + fmt.Println("};") + fmt.Printf("uint32_t nimports = %d;\n", count); +} func (mc *MachoContext) removeBindSymbolsLegacy() { start := mc.dyldinfo.lazy_bind_off @@ -300,7 +324,7 @@ func (mc *MachoContext) removeBindSymbolsLegacy() { // due to some limitations when design this tool // we write the c code to stdout lol - fmt.Println("struct imported_symbol {const char* name; const char* lib; uint32_t hash; uint64_t address;};") + fmt.Println("struct imported_symbol {const char* name; const char* lib; uint32_t hash; int segment_i; uint64_t offset;};") fmt.Println("struct imported_symbol imported_table[] = {") count := 0 for _, symbol := range mc.CollectBindSymbols() { @@ -309,8 +333,12 @@ func (mc *MachoContext) removeBindSymbolsLegacy() { } count += 1 dylib_hash := calculateHash(symbol.Dylib()) - fmt.Printf("{\"%s\", \"%s\", 0x%x, 0x%x},\n", - symbol.Name(), symbol.Dylib(), dylib_hash, symbol.Address()); + seg := mc.segments[symbol.segment] + offset := symbol.address - seg.Vmaddr() + + fmt.Printf("{\"%s\", \"%s\", 0x%x, 0x%x, 0x%x},\n", + symbol.Name(), symbol.Dylib(), dylib_hash, symbol.segment, offset); + mc.file.WriteAt(make([]byte, 8), int64(seg.Fileoff() + offset)) } fmt.Println("};") fmt.Printf("uint32_t nimports = %d;\n", count);