Skip to content

Commit

Permalink
Merge pull request #3 from omochi/swifty-type
Browse files Browse the repository at this point in the history
Swift的によい型を使う
  • Loading branch information
tarunon committed May 22, 2019
2 parents b11e025 + c66ce0b commit 70b0e9b
Showing 1 changed file with 23 additions and 22 deletions.
45 changes: 23 additions & 22 deletions Sources/XCTAssertAutolayout/Core/CFunctionInjector.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,26 @@

import Foundation

// dlfcn.h
// #define RTLD_DEFAULT ((void *) -2) /* Use default search algorithm. */
let RTLD_DEFAULT = UnsafeMutableRawPointer(bitPattern: -2)

enum CFunctionInjector {
private enum injected_functions {
private static var storage: [Int: __int64_t] = [:]
private static func key(from origin: UnsafeMutablePointer<__int64_t>) -> Int {
return Int(bitPattern: origin)
}
fileprivate static func assert_function_not_injected(_ origin: UnsafeMutablePointer<__int64_t>) {
assert(!storage.keys.contains(key(from: origin)))
private static var storage: [UnsafeMutableRawPointer: Int64] = [:]
fileprivate static func assert_function_not_injected(_ origin: UnsafeMutableRawPointer) {
assert(!storage.keys.contains(origin))
}
fileprivate static func stack_injected_function(_ origin: UnsafeMutablePointer<__int64_t>, _ new_address: __int64_t) {
storage[key(from: origin)] = origin.pointee
origin.pointee = new_address
fileprivate static func stack_injected_function(_ origin: UnsafeMutableRawPointer, _ new_instruction: Int64) {
let originI64 = origin.assumingMemoryBound(to: Int64.self)
storage[origin] = originI64.pointee
originI64.pointee = new_instruction
}
fileprivate static func pop_injected_function(_ origin: UnsafeMutablePointer<__int64_t>) {
guard let original_offset = storage.removeValue(forKey: key(from: origin)) else { return }
origin.pointee = original_offset
fileprivate static func pop_injected_function(_ origin: UnsafeMutableRawPointer) {
guard let original_instruction = storage.removeValue(forKey: origin) else { return }

let originI64 = origin.assumingMemoryBound(to: Int64.self)
originI64.pointee = original_instruction
}
}

Expand All @@ -35,11 +39,10 @@ enum CFunctionInjector {
/// - Parameters:
/// - symbol: c function name.
/// - target: c function pointer.
static func inject(_ symbol: UnsafePointer<Int8>!, _ target: UnsafeRawPointer) {
static func inject(_ symbol: String, _ target: UnsafeRawPointer) {
assert(Thread.isMainThread)

let RTLD_DEFAULT = UnsafeMutableRawPointer(bitPattern: -2)
guard let origin = dlsym(RTLD_DEFAULT, symbol)?.assumingMemoryBound(to: __int64_t.self) else { return }
guard let origin = dlsym(RTLD_DEFAULT, symbol) else { return }
injected_functions.assert_function_not_injected(origin)

// make the memory containing the original function writable
Expand All @@ -52,12 +55,11 @@ enum CFunctionInjector {
// Calculate the relative offset needed for the jump instruction.
// Since relative jumps are calculated from the address of the next instruction,
// 5 bytes must be added to the original address (jump instruction is 5 bytes).
let offset = __int64_t(Int(bitPattern: target)) - (__int64_t(Int(bitPattern: origin)) + 5 * __int64_t(MemoryLayout.size(ofValue: CChar())))


let offset = Int(bitPattern: target) - (Int(bitPattern: origin) + 5)

// Set the first instruction of the original function to be a jump to the replacement function.
// 0xe9 is the x86 opcode for an unconditional relative jump.
let instruction = 0xe9 | offset << 8
let instruction: Int64 = 0xe9 | Int64(offset) << 8

injected_functions.stack_injected_function(origin, instruction)
}
Expand All @@ -66,11 +68,10 @@ enum CFunctionInjector {
/// Ref: https://github.com/thomasfinch/CRuntimeFunctionHooker/blob/master/inject.c
///
/// - Parameter symbol: c function name.
static func reset(_ symbol: UnsafePointer<Int8>!) {
static func reset(_ symbol: String) {
assert(Thread.isMainThread)

let RTLD_DEFAULT = UnsafeMutableRawPointer(bitPattern: -2)
guard let origin = dlsym(RTLD_DEFAULT, symbol)?.assumingMemoryBound(to: __int64_t.self) else { return }
guard let origin = dlsym(RTLD_DEFAULT, symbol) else { return }

injected_functions.pop_injected_function(origin)
}
Expand Down

0 comments on commit 70b0e9b

Please sign in to comment.