Skip to content

Commit

Permalink
fix: DYLD_CHAINED_PTR_64_OFFSET edge case #29 #30
Browse files Browse the repository at this point in the history
  • Loading branch information
blacktop committed Dec 19, 2023
1 parent ad5d214 commit 9d4af2d
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 16 deletions.
1 change: 1 addition & 0 deletions file.go
Original file line number Diff line number Diff line change
Expand Up @@ -1487,6 +1487,7 @@ func (f *File) convertToVMAddr(value uint64) uint64 {
}
return uint64(int64(symAddr) + addend)
}
return value
}
}
// TODO: fix this dumb hack for SUPPORT_OLD_ARM64E_FORMAT
Expand Down
32 changes: 20 additions & 12 deletions file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -844,7 +844,9 @@ func TestNewFileWithObjC(t *testing.T) {
fmt.Printf("%#x: %#v\n", cfstr.Address, cfstr.Name)
}
} else {
t.Errorf(err.Error())
if !errors.Is(err, ErrObjcSectionNotFound) {
t.Fatalf(err.Error())
}
}

if meths, err := got.GetObjCMethodLists(); err == nil {
Expand All @@ -854,47 +856,53 @@ func TestNewFileWithObjC(t *testing.T) {
fmt.Printf("%#x: (%s) %s [%d]\n", m.ImpVMAddr, m.ReturnType(), m.Name, m.NumberOfArguments())
}
} else {
t.Errorf(err.Error())
if !errors.Is(err, ErrObjcSectionNotFound) {
t.Fatalf(err.Error())
}
}

if protos, err := got.GetObjCProtocols(); err == nil {
for _, proto := range protos {
fmt.Println(proto.String())
}
} else {
t.Errorf(err.Error())
if !errors.Is(err, ErrObjcSectionNotFound) {
t.Fatalf(err.Error())
}
}

if classes, err := got.GetObjCClasses(); err == nil {
for _, class := range classes {
fmt.Println(class.Verbose())
}
} else {
t.Errorf(err.Error())
if !errors.Is(err, ErrObjcSectionNotFound) {
t.Fatalf(err.Error())
}
}

if nlclasses, err := got.GetObjCNonLazyClasses(); err == nil {
for _, class := range nlclasses {
fmt.Println(class.String())
}
} else {
t.Errorf(err.Error())
t.Fatalf(err.Error())
}

if cats, err := got.GetObjCCategories(); err == nil {
for _, cat := range cats {
fmt.Println(cat.String())
}
} else {
t.Errorf(err.Error())
t.Fatalf(err.Error())
}

if nlcats, err := got.GetObjCNonLazyCategories(); err == nil {
for _, cat := range nlcats {
fmt.Println(cat.String())
}
} else {
t.Errorf(err.Error())
t.Fatalf(err.Error())
}

if selRefs, err := got.GetObjCProtoReferences(); err == nil {
Expand All @@ -903,39 +911,39 @@ func TestNewFileWithObjC(t *testing.T) {
fmt.Printf("%#x -> %#x: %s\n", off, prot.Ptr, prot.Name)
}
} else {
t.Errorf(err.Error())
t.Fatalf(err.Error())
}
if selRefs, err := got.GetObjCClassReferences(); err == nil {
fmt.Println("@class refs")
for off, sel := range selRefs {
fmt.Printf("%#x -> %#x: %s\n", off, sel.ClassPtr, sel.Name)
}
} else {
t.Errorf(err.Error())
t.Fatalf(err.Error())
}
if selRefs, err := got.GetObjCSuperReferences(); err == nil {
fmt.Println("@super refs")
for off, sel := range selRefs {
fmt.Printf("%#x -> %#x: %s\n", off, sel.ClassPtr, sel.SuperClass)
}
} else {
t.Errorf(err.Error())
t.Fatalf(err.Error())
}
if selRefs, err := got.GetObjCSelectorReferences(); err == nil {
fmt.Println("@selectors refs")
for off, sel := range selRefs {
fmt.Printf("%#x -> %#x: %s\n", off, sel.VMAddr, sel.Name)
}
} else {
t.Errorf(err.Error())
t.Fatalf(err.Error())
}
if methods, err := got.GetObjCMethodNames(); err == nil {
fmt.Printf("\n@methods\n")
for vmaddr, method := range methods {
fmt.Printf("%#x: %s\n", vmaddr, method)
}
} else {
t.Errorf(err.Error())
t.Fatalf(err.Error())
}
}
}
15 changes: 11 additions & 4 deletions pkg/fixupchains/fixupchains.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,17 @@ func (dcf *DyldChainedFixups) walkDcFixupChain(segIdx int, pageIndex uint16, off
if err := binary.Read(dcf.sr, dcf.bo, &dcPtr64); err != nil {
return err
}
dcf.Starts[segIdx].Fixups = append(dcf.Starts[segIdx].Fixups, DyldChainedPtr64RebaseOffset{
Pointer: dcPtr64,
Fixup: fixupLocation,
})
// NOTE: the fixup-chains.h seems to indicate that DYLD_CHAINED_PTR_64_OFFSET is a rebase, but can also be a bind
if Generic64IsBind(dcPtr64) {
bind := DyldChainedPtr64Bind{Pointer: dcPtr64, Fixup: fixupLocation}
bind.Import = dcf.Imports[bind.Ordinal()].Name
dcf.Starts[segIdx].Fixups = append(dcf.Starts[segIdx].Fixups, bind)
} else {
dcf.Starts[segIdx].Fixups = append(dcf.Starts[segIdx].Fixups, DyldChainedPtr64RebaseOffset{
Pointer: dcPtr64,
Fixup: fixupLocation,
})
}
if Generic64Next(dcPtr64) == 0 {
chainEnd = true
}
Expand Down
102 changes: 102 additions & 0 deletions pkg/fixupchains/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ type DyldChainedFixups struct {

type Fixup interface {
Offset() uint64
IsRebase() bool
IsBind() bool
Raw() uint64
String(baseAddr ...uint64) string
}

Expand Down Expand Up @@ -210,6 +213,12 @@ type DyldChainedPtrArm64eRebase struct {
Pointer uint64
}

func (d DyldChainedPtrArm64eRebase) IsRebase() bool {
return d.Bind() == 0
}
func (d DyldChainedPtrArm64eRebase) IsBind() bool {
return d.Bind() != 0
}
func (d DyldChainedPtrArm64eRebase) Offset() uint64 {
return d.Fixup
}
Expand Down Expand Up @@ -258,6 +267,12 @@ type DyldChainedPtrArm64eBind struct {
Import string
}

func (d DyldChainedPtrArm64eBind) IsRebase() bool {
return d.Bind() == 0
}
func (d DyldChainedPtrArm64eBind) IsBind() bool {
return d.Bind() != 0
}
func (d DyldChainedPtrArm64eBind) Offset() uint64 {
return d.Fixup
}
Expand Down Expand Up @@ -315,6 +330,12 @@ type DyldChainedPtrArm64eAuthRebase struct {
Pointer uint64
}

func (d DyldChainedPtrArm64eAuthRebase) IsRebase() bool {
return d.Bind() == 0
}
func (d DyldChainedPtrArm64eAuthRebase) IsBind() bool {
return d.Bind() != 0
}
func (d DyldChainedPtrArm64eAuthRebase) Offset() uint64 {
return d.Fixup
}
Expand Down Expand Up @@ -368,6 +389,12 @@ type DyldChainedPtrArm64eAuthBind struct {
Import string
}

func (d DyldChainedPtrArm64eAuthBind) IsRebase() bool {
return d.Bind() == 0
}
func (d DyldChainedPtrArm64eAuthBind) IsBind() bool {
return d.Bind() != 0
}
func (d DyldChainedPtrArm64eAuthBind) Offset() uint64 {
return d.Fixup
}
Expand Down Expand Up @@ -429,6 +456,12 @@ type DyldChainedPtr64Rebase struct {
Pointer uint64
}

func (d DyldChainedPtr64Rebase) IsRebase() bool {
return d.Bind() == 0
}
func (d DyldChainedPtr64Rebase) IsBind() bool {
return d.Bind() != 0
}
func (d DyldChainedPtr64Rebase) Offset() uint64 {
return d.Fixup
}
Expand Down Expand Up @@ -476,6 +509,12 @@ type DyldChainedPtr64RebaseOffset struct {
Pointer uint64
}

func (d DyldChainedPtr64RebaseOffset) IsRebase() bool {
return d.Bind() == 0
}
func (d DyldChainedPtr64RebaseOffset) IsBind() bool {
return d.Bind() != 0
}
func (d DyldChainedPtr64RebaseOffset) Offset() uint64 {
return d.Fixup
}
Expand Down Expand Up @@ -523,6 +562,12 @@ type DyldChainedPtrArm64eRebase24 struct {
Pointer uint64
}

func (d DyldChainedPtrArm64eRebase24) IsRebase() bool {
return d.Bind() == 0
}
func (d DyldChainedPtrArm64eRebase24) IsBind() bool {
return d.Bind() != 0
}
func (d DyldChainedPtrArm64eRebase24) Offset() uint64 {
return d.Fixup
}
Expand Down Expand Up @@ -571,6 +616,12 @@ type DyldChainedPtrArm64eAuthRebase24 struct {
Pointer uint64
}

func (d DyldChainedPtrArm64eAuthRebase24) IsRebase() bool {
return d.Bind() == 0
}
func (d DyldChainedPtrArm64eAuthRebase24) IsBind() bool {
return d.Bind() != 0
}
func (d DyldChainedPtrArm64eAuthRebase24) Offset() uint64 {
return d.Fixup
}
Expand Down Expand Up @@ -625,6 +676,12 @@ type DyldChainedPtrArm64eBind24 struct {
Import string
}

func (d DyldChainedPtrArm64eBind24) IsRebase() bool {
return d.Bind() == 0
}
func (d DyldChainedPtrArm64eBind24) IsBind() bool {
return d.Bind() != 0
}
func (d DyldChainedPtrArm64eBind24) Offset() uint64 {
return d.Fixup
}
Expand Down Expand Up @@ -676,6 +733,12 @@ type DyldChainedPtrArm64eAuthBind24 struct {
Import string
}

func (d DyldChainedPtrArm64eAuthBind24) IsRebase() bool {
return d.Bind() == 0
}
func (d DyldChainedPtrArm64eAuthBind24) IsBind() bool {
return d.Bind() != 0
}
func (d DyldChainedPtrArm64eAuthBind24) Offset() uint64 {
return d.Fixup
}
Expand Down Expand Up @@ -738,6 +801,12 @@ type DyldChainedPtr64Bind struct {
Import string
}

func (d DyldChainedPtr64Bind) IsRebase() bool {
return d.Bind() == 0
}
func (d DyldChainedPtr64Bind) IsBind() bool {
return d.Bind() != 0
}
func (d DyldChainedPtr64Bind) Offset() uint64 {
return d.Fixup
}
Expand Down Expand Up @@ -785,6 +854,12 @@ type DyldChainedPtr64KernelCacheRebase struct {
Pointer uint64
}

func (d DyldChainedPtr64KernelCacheRebase) IsRebase() bool {
return true
}
func (d DyldChainedPtr64KernelCacheRebase) IsBind() bool {
return false
}
func (d DyldChainedPtr64KernelCacheRebase) Offset() uint64 {
return d.Fixup
}
Expand Down Expand Up @@ -852,6 +927,12 @@ type DyldChainedPtr32Rebase struct {
Pointer uint32
}

func (d DyldChainedPtr32Rebase) IsRebase() bool {
return d.Bind() == 0
}
func (d DyldChainedPtr32Rebase) IsBind() bool {
return d.Bind() != 0
}
func (d DyldChainedPtr32Rebase) Offset() uint64 {
return d.Fixup
}
Expand All @@ -867,6 +948,9 @@ func (d DyldChainedPtr32Rebase) Bind() uint32 {
func (d DyldChainedPtr32Rebase) Kind() string {
return "ptr32-rebase"
}
func (d DyldChainedPtr32Rebase) Raw() uint64 {
return uint64(d.Pointer)
}
func (d DyldChainedPtr32Rebase) String(baseAddr ...uint64) string {
if len(baseAddr) > 0 {
d.Fixup += baseAddr[0]
Expand All @@ -881,6 +965,12 @@ type DyldChainedPtr32Bind struct {
Import string
}

func (d DyldChainedPtr32Bind) IsRebase() bool {
return d.Bind() == 0
}
func (d DyldChainedPtr32Bind) IsBind() bool {
return d.Bind() != 0
}
func (d DyldChainedPtr32Bind) Offset() uint64 {
return d.Fixup
}
Expand Down Expand Up @@ -918,6 +1008,12 @@ type DyldChainedPtr32CacheRebase struct {
Pointer uint32
}

func (d DyldChainedPtr32CacheRebase) IsRebase() bool {
return true
}
func (d DyldChainedPtr32CacheRebase) IsBind() bool {
return false
}
func (d DyldChainedPtr32CacheRebase) Offset() uint64 {
return d.Fixup
}
Expand Down Expand Up @@ -946,6 +1042,12 @@ type DyldChainedPtr32FirmwareRebase struct {
Pointer uint32
}

func (d DyldChainedPtr32FirmwareRebase) IsRebase() bool {
return true
}
func (d DyldChainedPtr32FirmwareRebase) IsBind() bool {
return false
}
func (d DyldChainedPtr32FirmwareRebase) Offset() uint64 {
return d.Fixup
}
Expand Down

0 comments on commit 9d4af2d

Please sign in to comment.