Skip to content

Commit

Permalink
more swifty goodness
Browse files Browse the repository at this point in the history
  • Loading branch information
blacktop committed Oct 5, 2020
1 parent d4ed7f2 commit 2e4c7f4
Show file tree
Hide file tree
Showing 8 changed files with 379 additions and 145 deletions.
61 changes: 18 additions & 43 deletions file.go
Original file line number Diff line number Diff line change
Expand Up @@ -991,10 +991,10 @@ func NewFile(r io.ReaderAt, loads ...types.LoadCmd) (*File, error) {
l.LoadBytes = LoadBytes(cmddat)
l.Offset = led.Offset
l.Size = led.Size
// l.Data = make([]byte, led.Size)
// if _, err := r.ReadAt(l.Data, int64(led.Offset)); err != nil {
// return nil, err
// }
l.Data = make([]byte, led.Size)
if _, err := r.ReadAt(l.Data, int64(led.Offset)); err != nil {
return nil, err
}
f.Loads[i] = l
case types.LC_DYLD_CHAINED_FIXUPS:
var led types.DyldChainedFixupsCmd
Expand Down Expand Up @@ -1187,13 +1187,13 @@ func (f *File) readLeUint64(offset int64) (uint64, error) {
return binary.LittleEndian.Uint64(u64), nil
}

func (f *File) GetOffset(address uint64) (uint64, error) {
func (f *File) GetOffset(address uint64) (int64, error) {
for _, seg := range f.Segments() {
if seg.Addr <= address && address < seg.Addr+seg.Memsz {
return (address - seg.Addr) + seg.Offset, nil
return int64((address - seg.Addr) + seg.Offset), nil
}
}
return 0, fmt.Errorf("address not within any segments adress range")
return 0, fmt.Errorf("address 0x%x not within any segments adress range", address)
}

func (f *File) GetVMAddress(offset uint64) (uint64, error) {
Expand All @@ -1202,7 +1202,7 @@ func (f *File) GetVMAddress(offset uint64) (uint64, error) {
return (offset - seg.Offset) + seg.Addr, nil
}
}
return 0, fmt.Errorf("offset not within any segments file offset range")
return 0, fmt.Errorf("offset 0x%x not within any segments file offset range", offset)
}

func (f *File) GetBaseAddress() uint64 {
Expand Down Expand Up @@ -1234,45 +1234,19 @@ func (f *File) convertToVMAddr(value uint64) uint64 {

func (f *File) GetCString(strVMAdr uint64) (string, error) {

// for _, sec := range f.Sections {
// if sec.Flags.IsCstringLiterals() {
// data, err := sec.Data()
// if err != nil {
// return "", err
// }

// if strVMAdr > sec.Addr {
// strOffset := strVMAdr - sec.Addr
// if strOffset > sec.Size {
// return "", fmt.Errorf("offset out of bounds of the cstring section")
// }
strOffset, err := f.GetOffset(strVMAdr)
if err != nil {
return "", err
}
// csr := bytes.NewBuffer(data[strOffset:])
f.sr.Seek(int64(strOffset), io.SeekStart)
s, err := bufio.NewReader(f.sr).ReadString('\x00')
// s, err := csr.ReadString('\x00')
if err != nil {
log.Fatal(err.Error())
}

if len(s) > 0 {
return strings.Trim(s, "\x00"), nil
}
// }
// }
// }

return "", fmt.Errorf("string not found")
return f.GetCStringAtOffset(strOffset)
}

// GetCStringAtOffset returns a c-string at a given offset into the MachO
func (f *File) GetCStringAtOffset(strOffset int64) (string, error) {

if _, err := f.sr.Seek(strOffset, io.SeekStart); err != nil {
return "", fmt.Errorf("failed to Seek: %v", err)
return "", fmt.Errorf("failed to Seek to offset 0x%x: %v", strOffset, err)
}

s, err := bufio.NewReader(f.sr).ReadString('\x00')
Expand All @@ -1284,7 +1258,7 @@ func (f *File) GetCStringAtOffset(strOffset int64) (string, error) {
return strings.Trim(s, "\x00"), nil
}

return "", fmt.Errorf("string not found")
return "", fmt.Errorf("string not found at offset 0x%x", strOffset)
}

// Segment returns the first Segment with the given name, or nil if no such segment exists.
Expand Down Expand Up @@ -1552,16 +1526,17 @@ func (f *File) ImportedSymbols() ([]Symbol, error) {
// referred to by the binary f that are expected to be
// satisfied by other libraries at dynamic load time.
func (f *File) ImportedSymbolNames() ([]string, error) {
if f.Dysymtab == nil || f.Symtab == nil {
return nil, &FormatError{0, "missing symbol table", nil}
var all []string

syms, err := f.ImportedSymbols()
if err != nil {
return nil, err
}

st := f.Symtab
dt := f.Dysymtab
var all []string
for _, s := range st.Syms[dt.Iundefsym : dt.Iundefsym+dt.Nundefsym] {
for _, s := range syms {
all = append(all, s.Name)
}

return all, nil
}

Expand Down
58 changes: 29 additions & 29 deletions objc.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func (f *File) GetObjCClassInfo(vmAddr uint64) (*objc.ClassRO64, error) {

off, err := f.GetOffset(vmAddr)
if err != nil {
return nil, fmt.Errorf("failed to convert vmaddr 0x%x to offset: %v", vmAddr, err)
return nil, fmt.Errorf("failed to convert vmaddr: %v", err)
}

f.sr.Seek(int64(off), io.SeekStart)
Expand All @@ -125,7 +125,7 @@ func (f *File) GetObjCMethodNames() (map[string]uint64, error) {
if sec := f.Section("__TEXT", "__objc_methname"); sec != nil {
off, err := f.GetOffset(sec.Addr)
if err != nil {
return nil, fmt.Errorf("failed to convert vmaddr 0x%x to offset: %v", sec.Addr, err)
return nil, fmt.Errorf("failed to convert vmaddr: %v", err)
}

stringPool := make([]byte, sec.Size)
Expand Down Expand Up @@ -218,7 +218,7 @@ func (f *File) GetObjCClass(vmaddr uint64) (*objc.Class, error) {

off, err := f.GetOffset(vmaddr)
if err != nil {
return nil, fmt.Errorf("failed to convert vmaddr 0x%x to offset: %v", vmaddr, err)
return nil, fmt.Errorf("failed to convert vmaddr: %v", err)
}

f.sr.Seek(int64(off), io.SeekStart)
Expand All @@ -233,7 +233,7 @@ func (f *File) GetObjCClass(vmaddr uint64) (*objc.Class, error) {

name, err := f.GetCString(f.convertToVMAddr(info.NameVMAddr))
if err != nil {
return nil, fmt.Errorf("failed to read cstring at 0x%x; %v", info.NameVMAddr, err)
return nil, fmt.Errorf("failed to read cstring: %v", err)
}

var methods []objc.Method
Expand Down Expand Up @@ -300,7 +300,7 @@ func (f *File) GetObjCCategories() ([]objc.Category, error) {
for _, ptr := range ptrs {
off, err := f.GetOffset(f.convertToVMAddr(ptr))
if err != nil {
return nil, fmt.Errorf("failed to convert vmaddr 0x%x to offset: %v", f.convertToVMAddr(ptr), err)
return nil, fmt.Errorf("failed to convert vmaddr: %v", err)
}

f.sr.Seek(int64(off), io.SeekStart)
Expand All @@ -312,7 +312,7 @@ func (f *File) GetObjCCategories() ([]objc.Category, error) {

category.Name, err = f.GetCString(f.convertToVMAddr(categoryPtr.NameVMAddr))
if err != nil {
return nil, fmt.Errorf("failed to read cstring at 0x%x; %v", f.convertToVMAddr(categoryPtr.NameVMAddr), err)
return nil, fmt.Errorf("failed to read cstring: %v", err)
}

categories = append(categories, category)
Expand Down Expand Up @@ -346,7 +346,7 @@ func (f *File) GetObjCProtocols() ([]objc.Protocol, error) {
for _, ptr := range ptrs {
off, err := f.GetOffset(f.convertToVMAddr(ptr))
if err != nil {
return nil, fmt.Errorf("failed to convert vmaddr 0x%x to offset: %v", f.convertToVMAddr(ptr), err)
return nil, fmt.Errorf("failed to convert vmaddr: %v", err)
}

f.sr.Seek(int64(off), io.SeekStart)
Expand All @@ -358,7 +358,7 @@ func (f *File) GetObjCProtocols() ([]objc.Protocol, error) {

proto.Name, err = f.GetCString(f.convertToVMAddr(protoPtr.NameVMAddr))
if err != nil {
return nil, fmt.Errorf("failed to read cstring at 0x%x; %v", f.convertToVMAddr(protoPtr.NameVMAddr), err)
return nil, fmt.Errorf("failed to read cstring: %v", err)
}

if protoPtr.InstanceMethodsVMAddr > 0 {
Expand Down Expand Up @@ -394,7 +394,7 @@ func (f *File) GetObjCProtocols() ([]objc.Protocol, error) {
if protoPtr.ExtendedMethodTypesVMAddr > 0 {
extOff, err := f.GetOffset(f.convertToVMAddr(protoPtr.ExtendedMethodTypesVMAddr))
if err != nil {
return nil, fmt.Errorf("failed to convert vmaddr 0x%x to offset: %v", f.convertToVMAddr(protoPtr.ExtendedMethodTypesVMAddr), err)
return nil, fmt.Errorf("failed to convert vmaddr: %v", err)
}

f.sr.Seek(int64(extOff), io.SeekStart)
Expand All @@ -405,13 +405,13 @@ func (f *File) GetObjCProtocols() ([]objc.Protocol, error) {

proto.ExtendedMethodTypes, err = f.GetCString(f.convertToVMAddr(extMPtr))
if err != nil {
return nil, fmt.Errorf("failed to read cstring at 0x%x; %v", f.convertToVMAddr(extMPtr), err)
return nil, fmt.Errorf("failed to read cstring: %v", err)
}
}
if protoPtr.DemangledNameVMAddr > 0 {
dnOff, err := f.GetOffset(f.convertToVMAddr(protoPtr.DemangledNameVMAddr))
if err != nil {
return nil, fmt.Errorf("failed to convert vmaddr 0x%x to offset: %v", f.convertToVMAddr(protoPtr.DemangledNameVMAddr), err)
return nil, fmt.Errorf("failed to convert vmaddr: %v", err)
}

f.sr.Seek(int64(dnOff), io.SeekStart)
Expand All @@ -422,7 +422,7 @@ func (f *File) GetObjCProtocols() ([]objc.Protocol, error) {

proto.DemangledName, err = f.GetCString(f.convertToVMAddr(dnPtr))
if err != nil {
return nil, fmt.Errorf("failed to read cstring at 0x%x; %v", f.convertToVMAddr(dnPtr), err)
return nil, fmt.Errorf("failed to read cstring: %v", err)
}
}

Expand Down Expand Up @@ -470,7 +470,7 @@ func (f *File) GetObjCMethodList() ([]objc.Method, error) {
}
n, err := f.GetCString(uint64(nameAddr))
if err != nil {
return nil, fmt.Errorf("failed to read cstring at 0x%x; %v", nameAddr, err)
return nil, fmt.Errorf("failed to read cstring: %v", err)
}

typesVMAddr, err := f.GetVMAddress(uint64(method.TypesOffset) + uint64(currOffset+4))
Expand All @@ -479,7 +479,7 @@ func (f *File) GetObjCMethodList() ([]objc.Method, error) {
}
t, err := f.GetCString(typesVMAddr)
if err != nil {
return nil, fmt.Errorf("failed to read cstring at 0x%x; %v", typesVMAddr, err)
return nil, fmt.Errorf("failed to read cstring: %v", err)
}

impVMAddr, err := f.GetVMAddress(uint64(method.ImpOffset) + uint64(currOffset+8))
Expand All @@ -497,7 +497,7 @@ func (f *File) GetObjCMethodList() ([]objc.Method, error) {
Types: t,
Pointer: types.FilePointer{
VMAdder: impVMAddr,
Offset: uint64(method.ImpOffset),
Offset: int64(method.ImpOffset),
},
})
}
Expand All @@ -518,7 +518,7 @@ func (f *File) GetObjCMethods(vmAddr uint64) ([]objc.Method, error) {

off, err := f.GetOffset(vmAddr)
if err != nil {
return nil, fmt.Errorf("failed to convert vmaddr 0x%x to offset: %v", vmAddr, err)
return nil, fmt.Errorf("failed to convert vmaddr: %v", err)
}

f.sr.Seek(int64(off), io.SeekStart)
Expand Down Expand Up @@ -551,7 +551,7 @@ func (f *File) readSmallMethods(methodList objc.MethodList) ([]objc.Method, erro
}
n, err := f.GetCString(uint64(nameAddr))
if err != nil {
return nil, fmt.Errorf("failed to read cstring at 0x%x; %v", nameAddr, err)
return nil, fmt.Errorf("failed to read cstring: %v", err)
}

typesVMAddr, err := f.GetVMAddress(uint64(method.TypesOffset) + uint64(currOffset+4))
Expand All @@ -560,7 +560,7 @@ func (f *File) readSmallMethods(methodList objc.MethodList) ([]objc.Method, erro
}
t, err := f.GetCString(typesVMAddr)
if err != nil {
return nil, fmt.Errorf("failed to read cstring at 0x%x; %v", typesVMAddr, err)
return nil, fmt.Errorf("failed to read cstring: %v", err)
}

impVMAddr, err := f.GetVMAddress(uint64(method.ImpOffset) + uint64(currOffset+8))
Expand All @@ -578,7 +578,7 @@ func (f *File) readSmallMethods(methodList objc.MethodList) ([]objc.Method, erro
Types: t,
Pointer: types.FilePointer{
VMAdder: impVMAddr,
Offset: uint64(method.ImpOffset),
Offset: int64(method.ImpOffset),
},
})
}
Expand All @@ -597,15 +597,15 @@ func (f *File) readBigMethods(methodList objc.MethodList) ([]objc.Method, error)
for _, method := range methods {
n, err := f.GetCString(f.convertToVMAddr(uint64(method.NameVMAddr)))
if err != nil {
return nil, fmt.Errorf("failed to read cstring at 0x%x; %v", f.convertToVMAddr(uint64(method.NameVMAddr)), err)
return nil, fmt.Errorf("failed to read cstring: %v", err)
}
t, err := f.GetCString(f.convertToVMAddr(uint64(method.TypesVMAddr)))
if err != nil {
return nil, fmt.Errorf("failed to read cstring at 0x%x; %v", f.convertToVMAddr(uint64(method.TypesVMAddr)), err)
return nil, fmt.Errorf("failed to read cstring: %v", err)
}
impOff, err := f.GetOffset(f.convertToVMAddr(method.ImpVMAddr))
if err != nil {
return nil, fmt.Errorf("failed to convert vmaddr 0x%x to offset: %v", f.convertToVMAddr(method.ImpVMAddr), err)
return nil, fmt.Errorf("failed to convert vmaddr: %v", err)
}
objcMethods = append(objcMethods, objc.Method{
NameVMAddr: method.NameVMAddr,
Expand All @@ -630,7 +630,7 @@ func (f *File) GetObjCIvars(vmAddr uint64) ([]objc.Ivar, error) {

off, err := f.GetOffset(vmAddr)
if err != nil {
return nil, fmt.Errorf("failed to convert vmaddr 0x%x to offset: %v", vmAddr, err)
return nil, fmt.Errorf("failed to convert vmaddr: %v", err)
}

f.sr.Seek(int64(off), io.SeekStart)
Expand All @@ -646,11 +646,11 @@ func (f *File) GetObjCIvars(vmAddr uint64) ([]objc.Ivar, error) {
for _, ivar := range ivs {
n, err := f.GetCString(f.convertToVMAddr(uint64(ivar.NameVMAddr)))
if err != nil {
return nil, fmt.Errorf("failed to read cstring at 0x%x; %v", ivar.NameVMAddr, err)
return nil, fmt.Errorf("failed to read cstring: %v", err)
}
t, err := f.GetCString(f.convertToVMAddr(uint64(ivar.TypesVMAddr)))
if err != nil {
return nil, fmt.Errorf("failed to read cstring at 0x%x; %v", ivar.TypesVMAddr, err)
return nil, fmt.Errorf("failed to read cstring: %v", err)
}
ivars = append(ivars, objc.Ivar{
Name: n,
Expand All @@ -669,7 +669,7 @@ func (f *File) GetObjCProperties(vmAddr uint64) ([]objc.Property, error) {

off, err := f.GetOffset(vmAddr)
if err != nil {
return nil, fmt.Errorf("failed to convert vmaddr 0x%x to offset: %v", vmAddr, err)
return nil, fmt.Errorf("failed to convert vmaddr: %v", err)
}

f.sr.Seek(int64(off), io.SeekStart)
Expand All @@ -685,11 +685,11 @@ func (f *File) GetObjCProperties(vmAddr uint64) ([]objc.Property, error) {
for _, prop := range properties {
name, err := f.GetCString(f.convertToVMAddr(prop.NameVMAddr))
if err != nil {
return nil, fmt.Errorf("failed to read cstring at 0x%x; %v", f.convertToVMAddr(prop.NameVMAddr), err)
return nil, fmt.Errorf("failed to read cstring: %v", err)
}
attrib, err := f.GetCString(f.convertToVMAddr(prop.AttributesVMAddr))
if err != nil {
return nil, fmt.Errorf("failed to read cstring at 0x%x; %v", f.convertToVMAddr(prop.AttributesVMAddr), err)
return nil, fmt.Errorf("failed to read cstring: %v", err)
}
objcProperties = append(objcProperties, objc.Property{
PropertyT: prop,
Expand Down Expand Up @@ -721,7 +721,7 @@ func (f *File) GetObjCSelectorReferences() (map[uint64]string, error) {
for _, sel := range selPtrs {
selName, err := f.GetCString(f.convertToVMAddr(sel))
if err != nil {
return nil, fmt.Errorf("failed to read cstring at 0x%x; %v", sel, err)
return nil, fmt.Errorf("failed to read cstring: %v", err)
}
selRefs[f.convertToVMAddr(sel)] = selName
}
Expand Down
Loading

0 comments on commit 2e4c7f4

Please sign in to comment.