rework ios-wrapper cli parsing

This commit is contained in:
2023-06-15 10:41:18 +07:00
parent a257286d2e
commit e2c75bf718
12 changed files with 269 additions and 63 deletions

View File

@ -57,6 +57,10 @@ func (sym *ImportSymbol) Stub() uint64 {
return sym.stub
}
func (sym *ImportSymbol) Segment() uint32 {
return sym.segment
}
func (mc *MachoContext) CollectBindSymbols() []*ImportSymbol {
if mc.dyldinfo == nil {
return mc.CollectBindSymbolsModern()

View File

@ -5,6 +5,7 @@ import (
"io"
"math/rand"
"time"
"bytes"
log "github.com/sirupsen/logrus"
@ -190,10 +191,6 @@ func (mc *MachoContext) RemoveUnnecessaryInfo() bool {
return false
}
func (mc *MachoContext) RemoveClassicSymbol() bool {
return false
}
func (mc *MachoContext) AddLoadCmd(lcmd LoadCommand) {
var offset uint64
payload := lcmd.Serialize(mc)
@ -285,42 +282,15 @@ func (mc *MachoContext) RemoveBindSymbols() {
} else {
mc.removeBindSymbolsLegacy()
}
calculateHash := func(name string) uint32 {
var h uint32 = 0x811c9dc5
for _, s := range name {
h ^= uint32(s)
h *= 0x01000193
}
return h
}
mc.RenameObjcClasslist()
// 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; int segment_i; uint64_t offset;};")
fmt.Println("const char* lib_to_resolve = \"main\";")
fmt.Println("struct imported_symbol imported_table[] = {")
count := 0
for _, symbol := range mc.CollectBindSymbols() {
if symbol.Type() != "lazy" {
continue
}
count += 1
dylib_hash := calculateHash(symbol.Dylib())
seg := mc.segments[symbol.segment]
var offset uint64
if symbol.address >= seg.Vmaddr() {
// this is virtual address
offset = symbol.address - seg.Vmaddr()
} else {
// this is file address
offset = symbol.address - seg.Fileoff()
}
fmt.Printf("{\"%s\", \"%s\", 0x%x, 0x%x, 0x%x},\n",
symbol.Name(), symbol.Dylib(), dylib_hash, symbol.segment, offset);
if mc.dyldinfo != nil {
// for legacy resolve the opcodes can be rewritten as 0x00
mc.file.WriteAt(make([]byte, 8), int64(symbol.file_address))
@ -344,8 +314,6 @@ func (mc *MachoContext) RemoveBindSymbols() {
mc.file.WriteAt(v, int64(symbol.file_address))
}
}
fmt.Println("};")
fmt.Printf("uint32_t nimports = %d;\n", count);
}
func (mc *MachoContext) removeBindSymbolsModern() {
@ -385,6 +353,45 @@ func (mc *MachoContext) removeBindSymbolsLegacy() {
mc.file.WriteAt(make([]byte, size), int64(start))
}
func (mc *MachoContext) RenameObjcClasslist() {
ptr := int64(0)
if mc.Is64bit() {
ptr, _ = mc.file.Seek(int64(Header_size_64), io.SeekStart)
} else {
ptr, _ = mc.file.Seek(int64(Header_size), io.SeekStart)
}
for _, cmd := range mc.commands {
if cmd.Cmd() != LC_SEGMENT_64 {
ptr += int64(cmd.Cmdsize())
continue
}
var segment = cmd.(*Segment64)
if bytes.Compare(bytes.Trim(segment.SegName(), "\x00"), []byte("__DATA_CONST")) == 0 {
section_ptr := ptr + 0x40 + 8
for _, section := range segment.Sections() {
if bytes.Compare(bytes.Trim(section.SectName(), "\x00"), []byte("__objc_classlist")) == 0 {
mc.file.WriteAt([]byte("__objc_classbruh"), section_ptr)
}
if bytes.Compare(bytes.Trim(section.SectName(), "\x00"), []byte("__objc_nlclslist")) == 0 {
mc.file.WriteAt([]byte("__objc_nlclsbruh"), section_ptr)
}
section_ptr += 16 * 2 + 8 * 2 + 4 * 8
}
}
// if bytes.Compare(bytes.Trim(segment.SegName(), "\x00"), []byte("__DATA")) == 0 {
// section_ptr := ptr + 0x40 + 8
// for _, section := range segment.Sections() {
// section_ptr += 16 * 2 + 8 * 2 + 4 * 8
// }
// }
ptr += int64(cmd.Cmdsize())
}
mc.file.Seek(0, io.SeekStart)
}
func (mc *MachoContext) RemoveSymbolTable() {
// try to remove symtab and dysymtab
mc.removeSymtabCommand()

View File

@ -97,6 +97,7 @@ int ParseFixValue(int format, uint64_t value, int* bind, uint64_t* ret1, uint64_
uint64_t MakeRebaseFixupOpcode(int next, uint64_t target, uint64_t high8) {
uint64_t value;
struct dyld_chained_ptr_64_rebase* b = (struct dyld_chained_ptr_64_rebase*)&value;
b->bind = 0;
b->next = next;
b->target = target;
b->high8 = high8;

View File

@ -72,7 +72,6 @@ func (mc *MachoContext) CollectSymbols() []*Symbol {
var flags uint8
var sect uint8
var desc uint16
var value32 uint32
var value64 uint64
binary.Read(symtab_buffer, mc.byteorder, &strx)
@ -83,6 +82,7 @@ func (mc *MachoContext) CollectSymbols() []*Symbol {
binary.Read(symtab_buffer, mc.byteorder, &value64)
} else {
// always use value64
var value32 uint32
binary.Read(symtab_buffer, mc.byteorder, &value32)
value64 = uint64(value32)
}