Skip to content

Commit

Permalink
Fix injecting Swift classes (#120)
Browse files Browse the repository at this point in the history
* Update expression in loadAndInject

This is done to match the new format when grep-ing classes.

* Refactor inject(tmpfile: String)

Add new condition to match swift classes.

Co-Authored-By: John Holdsworth <johnno1962@users.noreply.github.com>

* Bump version number to 1.5.1

* Fix log statement

Co-Authored-By: John Holdsworth <johnno1962@users.noreply.github.com>

* Add code comment about Swift metadata

Co-Authored-By: John Holdsworth <johnno1962@users.noreply.github.com>

* Include instructions for when to turn off code coverage.

* Update README.md

* Bump CFBundleVersion to 1616
  • Loading branch information
zenangst authored Mar 27, 2019
1 parent abb476a commit f05e96c
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 8 deletions.
8 changes: 6 additions & 2 deletions InjectionBundle/SwiftEval.swift
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,11 @@ public class SwiftEval: NSObject {
print("💉 Loading .dylib ...")
// load patched .dylib into process with new version of class
guard let dl = dlopen("\(tmpfile).dylib", RTLD_NOW) else {
throw evalError("dlopen() error: \(String(cString: dlerror()))")
let error = String(cString: dlerror())
if error.contains("___llvm_profile_runtime") {
print("💉 Loading .dylib has failed, try turning off collection of test coverage in your scheme")
}
throw evalError("dlopen() error: \(error)")
}
print("💉 Loaded .dylib - Ignore any duplicate class warning ^")

Expand All @@ -396,7 +400,7 @@ public class SwiftEval: NSObject {
try injectGenerics(tmpfile: tmpfile, handle: dl)

guard shell(command: """
\(xcodeDev)/Toolchains/XcodeDefault.xctoolchain/usr/bin/nm \(tmpfile).o | grep -E ' S _OBJC_CLASS_\\$_| _(_T0|\\$S).*CN$' | awk '{print $3}' >\(tmpfile).classes
\(xcodeDev)/Toolchains/XcodeDefault.xctoolchain/usr/bin/nm \(tmpfile).o | grep -E ' S _OBJC_CLASS_\\$_| _(_T0|\\$S|\\$s).*CN$' | awk '{print $3}' >\(tmpfile).classes
""") else {
throw evalError("Could not list class symbols")
}
Expand Down
10 changes: 7 additions & 3 deletions InjectionBundle/SwiftInjection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,12 @@ public class SwiftInjection: NSObject {
let classMetadata = unsafeBitCast(newClass, to: UnsafeMutablePointer<ClassMetadataSwift>.self)

// Is this a Swift class?
if (classMetadata.pointee.Data & 0x1) == 1 {
// Swift equivalent of Swizzling
// Reference: https://github.com/apple/swift/blob/master/include/swift/ABI/Metadata.h#L1195
let oldSwiftCondition = classMetadata.pointee.Data & 0x1 == 1
let newSwiftCondition = classMetadata.pointee.Data & 0x3 != 0
let isSwiftClass = newSwiftCondition || oldSwiftCondition
if isSwiftClass {
// Swift equivalent of Swizzling
if classMetadata.pointee.ClassSize != existingClass.pointee.ClassSize {
print("💉 ⚠️ Adding or removing methods on Swift classes is not supported. Your application will likely crash. ⚠️")
}
Expand All @@ -129,7 +133,7 @@ public class SwiftInjection: NSObject {
let vtableLength = Int(existingClass.pointee.ClassSize -
existingClass.pointee.ClassAddressPoint) - vtableOffset

print("💉 Injected '\(NSStringFromClass(oldClass))'")
print("💉 Injected '\(oldClass)'")
memcpy(byteAddr(existingClass) + vtableOffset,
byteAddr(classMetadata) + vtableOffset, vtableLength)
}
Expand Down
4 changes: 2 additions & 2 deletions InjectionIII/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.5</string>
<string>1.5.1</string>
<key>CFBundleVersion</key>
<string>1601</string>
<string>1616</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.developer-tools</string>
<key>LSMinimumSystemVersion</key>
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ from source you'll need to use:

### Available downloads

| Xcode 9.3/4, Xcode 10 |
| Xcode 10.1, Xcode 10.2 |
| ------------- |
| [Mac app store](https://itunes.apple.com/app/injectioniii/id1380446739?mt=12) |

Expand Down

0 comments on commit f05e96c

Please sign in to comment.