Skip to content

Commit a0e55d0

Browse files
committed
refactor
1 parent c09d534 commit a0e55d0

File tree

4 files changed

+70
-75
lines changed

4 files changed

+70
-75
lines changed

Sources/SwiftHook/SwiftHook+function.swift

Lines changed: 34 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -17,50 +17,27 @@ extension SwiftHook {
1717
_ first: String,
1818
_ second: String,
1919
isMangled: Bool
20-
) -> Bool {
21-
if isMangled {
22-
return exchangeFuncImplementationMangled(first, second)
23-
} else {
24-
return exchangeFuncImplementationDeMangled(first, second)
25-
}
26-
}
27-
}
28-
29-
extension SwiftHook {
30-
private static func exchangeFuncImplementationMangled(
31-
_ first: String,
32-
_ second: String
33-
) -> Bool {
34-
var firstSymbol: UnsafeMutableRawPointer?
35-
var secondSymbol: UnsafeMutableRawPointer?
36-
37-
for i in 0..<_dyld_image_count() {
38-
let dylib = _dyld_get_image_name(i)
39-
guard let handle = dlopen(dylib, RTLD_NOW) else {
40-
continue
41-
}
42-
if firstSymbol == nil {
43-
firstSymbol = dlsym(handle, first.cString(using: .utf8))
44-
}
45-
if secondSymbol == nil {
46-
secondSymbol = dlsym(handle, second.cString(using: .utf8))
47-
}
48-
49-
if firstSymbol != nil && secondSymbol != nil { break }
50-
}
20+
) throws {
21+
var isSucceeded = false
5122

52-
return exchangeFuncImplementation(
23+
isSucceeded = try _exchangeFuncImplementation(
5324
first,
5425
second,
55-
firstSymbol,
56-
secondSymbol
26+
isMangled: isMangled
5727
)
28+
29+
if isSucceeded { return }
30+
31+
throw SwiftHookError.failedToExchangeFuncImplementation
5832
}
33+
}
5934

60-
private static func exchangeFuncImplementationDeMangled(
35+
extension SwiftHook {
36+
private static func _exchangeFuncImplementation(
6137
_ first: String,
62-
_ second: String
63-
) -> Bool {
38+
_ second: String,
39+
isMangled: Bool
40+
) throws -> Bool {
6441
var first: String = first
6542
var second: String = second
6643

@@ -69,23 +46,39 @@ extension SwiftHook {
6946

7047
for i in 0..<_dyld_image_count() {
7148
let machO = MachOImage(ptr: _dyld_get_image_header(i))
72-
if let symbol = machO.symbol(named: first, mangled: false) {
49+
if let symbol = machO.symbol(
50+
named: first,
51+
mangled: isMangled
52+
) {
7353
firstSymbol = .init(
7454
mutating: machO.ptr.advanced(by: symbol.offset)
7555
)
7656
first = String(cString: symbol.nameC + 1)
7757
}
78-
if let symbol = machO.symbol(named: second, mangled: false) {
58+
if let symbol = machO.symbol(
59+
named: second,
60+
mangled: isMangled
61+
) {
7962
secondSymbol = .init(
8063
mutating: machO.ptr.advanced(by: symbol.offset)
8164
)
8265
second = String(cString: symbol.nameC + 1)
8366
}
8467

85-
8668
if firstSymbol != nil && secondSymbol != nil { break }
8769
}
8870

71+
if firstSymbol == nil && secondSymbol == nil {
72+
throw SwiftHookError.firstAndSecondSymbolAreNotFound
73+
}
74+
75+
if firstSymbol == nil {
76+
throw SwiftHookError.firstSymbolIsNotFound
77+
}
78+
if secondSymbol == nil {
79+
throw SwiftHookError.secondSymbolIsNotFound
80+
}
81+
8982
return exchangeFuncImplementation(
9083
first,
9184
second,
@@ -94,6 +87,7 @@ extension SwiftHook {
9487
)
9588
}
9689

90+
@discardableResult
9791
private static func exchangeFuncImplementation(
9892
_ first: String,
9993
_ second: String,
@@ -124,4 +118,3 @@ extension SwiftHook {
124118
return false
125119
}
126120
}
127-

Sources/SwiftHook/SwiftHook+method.swift

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//
44
//
55
// Created by p-x9 on 2023/12/22.
6-
//
6+
//
77
//
88

99
import Foundation
@@ -31,6 +31,8 @@ extension SwiftHook {
3131
for: `class`
3232
)
3333
if isSucceeded { return }
34+
35+
throw SwiftHookError.failedToExchangeMethodImplementation
3436
}
3537
}
3638

@@ -103,21 +105,3 @@ extension SwiftHook {
103105
return true
104106
}
105107
}
106-
107-
@discardableResult
108-
func swizzle(class: AnyClass, orig origSelector: Selector, hooked hookedSelector: Selector) -> Bool {
109-
guard let origMethod = class_getInstanceMethod(`class`, origSelector),
110-
let hookedMethod = class_getInstanceMethod(`class`, hookedSelector) else {
111-
return false
112-
}
113-
114-
let didAddMethod = class_addMethod(`class`, origSelector,
115-
method_getImplementation(hookedMethod),
116-
method_getTypeEncoding(hookedMethod))
117-
if didAddMethod {
118-
class_replaceMethod(`class`, hookedSelector, method_getImplementation(origMethod), method_getTypeEncoding(origMethod))
119-
return true
120-
}
121-
method_exchangeImplementations(origMethod, hookedMethod)
122-
return true
123-
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//
2+
// SwiftHookError.swift
3+
//
4+
//
5+
// Created by p-x9 on 2024/01/08.
6+
//
7+
//
8+
9+
import Foundation
10+
11+
public enum SwiftHookError: Error {
12+
case failedToExchangeFuncImplementation
13+
case firstSymbolIsNotFound
14+
case secondSymbolIsNotFound
15+
case firstAndSecondSymbolAreNotFound
16+
17+
case failedToExchangeMethodImplementation
18+
}

Tests/SwiftHookTests/SwiftHookTests.swift

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,73 +9,73 @@ final class SwiftHookTests: XCTestCase {
99
_ = disableExclusivityChecking
1010
}
1111

12-
func testExchangeFunc() {
12+
func testExchangeFunc() throws {
1313
if setjump(&buf) != 0 {
1414
return
1515
}
1616

1717
// XXXXhook_assertionFailure ⇔ _assertionFailure
18-
print(SwiftHook.exchangeFuncImplementation(
18+
try SwiftHook.exchangeFuncImplementation(
1919
"$s14SwiftHookTests25XXXXhook_assertionFailure__4file4line5flagss5NeverOs12StaticStringV_A2ISus6UInt32VtF",
2020
"$ss17_assertionFailure__4file4line5flagss5NeverOs12StaticStringV_A2HSus6UInt32VtF",
2121
isMangled: true
22-
))
22+
)
2323

2424
var optional: Int?
2525
let forceUnwrapped = optional!
2626
}
2727

28-
func testExchangeDemangledFunc() {
28+
func testExchangeDemangledFunc() throws {
2929
if setjump(&buf) != 0 {
3030
return
3131
}
3232

3333
// XXXXhook_assertionFailure ⇔ _assertionFailure
34-
print(SwiftHook.exchangeFuncImplementation(
34+
try SwiftHook.exchangeFuncImplementation(
3535
"SwiftHookTests.XXXXhook_assertionFailure(_: Swift.StaticString, _: Swift.StaticString, file: Swift.StaticString, line: Swift.UInt, flags: Swift.UInt32) -> Swift.Never",
3636
"Swift._assertionFailure(_: Swift.StaticString, _: Swift.StaticString, file: Swift.StaticString, line: Swift.UInt, flags: Swift.UInt32) -> Swift.Never",
3737
isMangled: false
38-
))
38+
)
3939

4040
var optional: Int?
4141
let forceUnwrapped = optional!
4242
}
4343
}
4444

4545
extension SwiftHookTests {
46-
func testExchangeFuncInSelfImage() {
46+
func testExchangeFuncInSelfImage() throws {
4747
if setjump(&buf) != 0 {
4848
return
4949
}
5050

5151
// hook_assertionFailure ⇔ XXXXhook_assertionFailure
52-
print(SwiftHook.exchangeFuncImplementation(
52+
try SwiftHook.exchangeFuncImplementation(
5353
"$s14SwiftHookTests21hook_assertionFailure__4file4line5flagss5NeverOs12StaticStringV_SSAISus6UInt32VtF",
5454
"$s14SwiftHookTests25XXXXhook_assertionFailure__4file4line5flagss5NeverOs12StaticStringV_SSAISus6UInt32VtF",
5555
isMangled: true
56-
))
56+
)
5757

5858
hook_assertionFailure("aaa", "bbbb", flags: 0)
5959
}
6060

61-
func testExchangeDemangledFuncInSelfImage() {
61+
func testExchangeDemangledFuncInSelfImage() throws {
6262
if setjump(&buf) != 0 {
6363
return
6464
}
6565

6666
// hook_assertionFailure ⇔ XXXXhook_assertionFailure
67-
print(SwiftHook.exchangeFuncImplementation(
67+
try SwiftHook.exchangeFuncImplementation(
6868
"SwiftHookTests.hook_assertionFailure(_: Swift.StaticString, _: Swift.String, file: Swift.StaticString, line: Swift.UInt, flags: Swift.UInt32) -> Swift.Never",
6969
"SwiftHookTests.XXXXhook_assertionFailure(_: Swift.StaticString, _: Swift.String, file: Swift.StaticString, line: Swift.UInt, flags: Swift.UInt32) -> Swift.Never",
7070
isMangled: false
71-
))
71+
)
7272

7373
hook_assertionFailure("aaa", "bbbb", flags: 0)
7474
}
7575
}
7676

7777
extension SwiftHookTests {
78-
func testExchangeStructFunction() {
78+
func testExchangeStructFunction() throws {
7979
let item = StructItem()
8080

8181
print(item.printA())
@@ -84,11 +84,11 @@ extension SwiftHookTests {
8484
XCTAssertEqual(item.printB(), "B")
8585

8686
// printA ⇔ printB
87-
print(SwiftHook.exchangeFuncImplementation(
87+
try SwiftHook.exchangeFuncImplementation(
8888
"SwiftHookTests.StructItem.printA() -> Swift.String",
8989
"SwiftHookTests.StructItem.printB() -> Swift.String",
9090
isMangled: false
91-
))
91+
)
9292

9393
print(item.printA())
9494
print(item.printB())

0 commit comments

Comments
 (0)