File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -10,7 +10,7 @@ import Foundation
1010extension InjectorV3 {
1111 // MARK: - Constants
1212
13- private static let alternateSuffix = " troll-fools.bak "
13+ static let alternateSuffix = " troll-fools.bak "
1414
1515 static func alternateURL( for target: URL ) -> URL {
1616 target. appendingPathExtension ( Self . alternateSuffix)
Original file line number Diff line number Diff line change @@ -63,6 +63,10 @@ extension InjectorV3 {
6363 enumerator. skipDescendants ( )
6464 continue
6565 }
66+ // Skip backup files created before injection
67+ if itemURL. path. hasSuffix ( " . \( Self . alternateSuffix) " ) {
68+ continue
69+ }
6670 if enumerator. level == 2 {
6771 enumeratedURLs. append ( itemURL)
6872 if isMachO ( itemURL) {
@@ -113,6 +117,30 @@ extension InjectorV3 {
113117 }
114118 }
115119
120+ // Filter out previously-injected Mach-Os by diffing current vs. backup load commands.
121+ // Any load command present in the current binary but absent from its backup was added by injection.
122+ var injectedAssetNames = Set < String > ( )
123+ for machO in ( allMachOsInFrameworks. elements + [ executableURL] ) where hasAlternate ( machO) {
124+ if let current = try ? loadedDylibsOfMachO ( machO) ,
125+ let original = try ? loadedDylibsOfMachO ( Self . alternateURL ( for: machO) )
126+ {
127+ for name in current where !original. contains ( name) {
128+ injectedAssetNames. insert ( URL ( fileURLWithPath: name) . lastPathComponent)
129+ }
130+ }
131+ }
132+ if !injectedAssetNames. isEmpty {
133+ let preFilterCount = machOs. count
134+ machOs = machOs. filter { !injectedAssetNames. contains ( $0. lastPathComponent) }
135+ let excludedCount = preFilterCount - machOs. count
136+ if excludedCount > 0 {
137+ DDLogInfo (
138+ " Excluded \( excludedCount) previously-injected Mach-Os by backup diff: \( injectedAssetNames. sorted ( ) ) " ,
139+ ddlog: logger
140+ )
141+ }
142+ }
143+
116144 var sortedMachOs : [ URL ] =
117145 switch injectStrategy {
118146 case . lexicographic:
Original file line number Diff line number Diff line change @@ -66,7 +66,10 @@ extension InjectorV3 {
6666 var newCollected = collected
6767 newCollected. append ( target)
6868
69- let loadedDylibs = try loadedDylibsOfMachO ( target) . compactMap ( { resolveLoadCommand ( $0) } )
69+ // If the Mach-O has a backup (made before injection), read load commands
70+ // from the original to avoid picking up previously-injected dylibs.
71+ let readTarget = hasAlternate ( target) ? Self . alternateURL ( for: target) : target
72+ let loadedDylibs = try loadedDylibsOfMachO ( readTarget) . compactMap ( { resolveLoadCommand ( $0) } )
7073 for dylib in loadedDylibs {
7174 newCollected = try linkedDylibsRecursivelyOfMachO ( dylib, collected: newCollected)
7275 }
You can’t perform that action at this time.
0 commit comments