Skip to content

Commit 8dceebf

Browse files
authored
Merge pull request #11 from p-x9/feature/improve-read-class-protocol
Return protocols and classes paired with their defining Mach-O files
2 parents a2df544 + b961b6b commit 8dceebf

File tree

8 files changed

+322
-111
lines changed

8 files changed

+322
-111
lines changed

Sources/MachOObjCSection/Extension/DyldCache+.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,14 @@ extension DyldCache {
115115
return nil
116116
}
117117
}
118+
119+
extension DyldCache {
120+
func machO(containing unslidAddress: UInt64) -> MachOFile? {
121+
for machO in self.machOFiles() {
122+
if machO.contains(unslidAddress: unslidAddress) {
123+
return machO
124+
}
125+
}
126+
return nil
127+
}
128+
}

Sources/MachOObjCSection/Extension/DyldCacheLoaded+.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,23 @@ extension DyldCacheLoaded {
9999
return nil
100100
}
101101
}
102+
103+
extension DyldCacheLoaded {
104+
func machO(containing ptr: UnsafeRawPointer) -> MachOImage? {
105+
for machO in machOImages() {
106+
if machO.contains(ptr: ptr) {
107+
return machO
108+
}
109+
}
110+
return nil
111+
}
112+
113+
func machO(containing unslidAddress: UInt64) -> MachOImage? {
114+
for machO in self.machOImages() {
115+
if machO.contains(unslidAddress: unslidAddress) {
116+
return machO
117+
}
118+
}
119+
return nil
120+
}
121+
}

Sources/MachOObjCSection/Model/Protocol/ObjCProtocolList32.swift

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ public struct ObjCProtocolList32: ObjCProtocolListProtocol {
2626
extension ObjCProtocolList32 {
2727
public func protocols(
2828
in machO: MachOImage
29-
) -> [ObjCProtocol]? {
29+
) -> [(MachOImage, ObjCProtocol)]? {
3030
_readProtocols(in: machO, pointerType: UInt32.self)
3131
}
3232

3333
public func protocols(
3434
in machO: MachOFile
35-
) -> [ObjCProtocol]? {
35+
) -> [(MachOFile, ObjCProtocol)]? {
3636
guard !isListOfLists else {
3737
assertionFailure()
3838
return nil
@@ -63,23 +63,32 @@ extension ObjCProtocolList32 {
6363
let offset = $0 + numericCast(headerStartOffset)
6464
var resolvedOffset = offset
6565

66+
var targetMachO = machO
67+
6668
var fileHandle = machO.fileHandle
6769

6870
if let (_cache, _offset) = machO.cacheAndFileOffset(
6971
fromStart: offset
7072
) {
7173
resolvedOffset = _offset
7274
fileHandle = _cache.fileHandle
75+
76+
let unslidAddress = offset + _cache.mainCacheHeader.sharedRegionStart
77+
if !targetMachO.contains(unslidAddress: unslidAddress),
78+
let machO = _cache.machO(containing: unslidAddress) {
79+
targetMachO = machO
80+
}
7381
}
7482

7583
let layout: ObjCProtocol32.Layout = fileHandle.read(
7684
offset: numericCast(resolvedOffset),
7785
swapHandler: { _ in }
7886
)
79-
return .init(
87+
let `protocol`: ObjCProtocol = .init(
8088
layout: layout,
8189
offset: numericCast(offset) - machO.headerStartOffset
8290
)
91+
return (targetMachO, `protocol`)
8392
}
8493
}
8594
}

Sources/MachOObjCSection/Model/Protocol/ObjCProtocolList64.swift

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ public struct ObjCProtocolList64: ObjCProtocolListProtocol {
2626
extension ObjCProtocolList64 {
2727
public func protocols(
2828
in machO: MachOImage
29-
) -> [ObjCProtocol]? {
29+
) -> [(MachOImage, ObjCProtocol)]? {
3030
_readProtocols(in: machO, pointerType: UInt64.self)
3131
}
3232

3333
public func protocols(
3434
in machO: MachOFile
35-
) -> [ObjCProtocol]? {
35+
) -> [(MachOFile, ObjCProtocol)]? {
3636
guard !isListOfLists else {
3737
assertionFailure()
3838
return nil
@@ -63,23 +63,32 @@ extension ObjCProtocolList64 {
6363
let offset = machO.fileOffset(of: $0) + numericCast(headerStartOffset)
6464
var resolvedOffset = offset
6565

66+
var targetMachO = machO
67+
6668
var fileHandle = machO.fileHandle
6769

6870
if let (_cache, _offset) = machO.cacheAndFileOffset(
6971
fromStart: offset
7072
) {
7173
resolvedOffset = _offset
7274
fileHandle = _cache.fileHandle
75+
76+
let unslidAddress = offset + _cache.mainCacheHeader.sharedRegionStart
77+
if !targetMachO.contains(unslidAddress: unslidAddress),
78+
let machO = _cache.machO(containing: unslidAddress) {
79+
targetMachO = machO
80+
}
7381
}
7482

7583
let layout: ObjCProtocol64.Layout = fileHandle.read(
7684
offset: numericCast(resolvedOffset),
7785
swapHandler: { _ in }
7886
)
79-
return .init(
87+
let `protocol`: ObjCProtocol = .init(
8088
layout: layout,
8189
offset: numericCast(offset) - machO.headerStartOffset
8290
)
91+
return (targetMachO, `protocol`)
8392
}
8493
}
8594
}

0 commit comments

Comments
 (0)