SecurityKit

Icon copy

概述

SecurityKit 是一个轻量级、易于使用的 Swift 库,它根据 OWASP MASVS 标准的 v8 章节,帮助保护 iOS 应用,提供高级的安全和防篡改层。

安装

SecurityKit 可通过 Swift Package Manager 获取。

Swift Package Manager 是一种用于自动化 Swift 代码分发的工具,并已集成到 swift 编译器中。

一旦你设置好了你的 Swift 包,添加 SecurityKit 作为依赖项就像将其添加到你的 Package.swiftdependencies 值中一样简单。

dependencies: [
    .package(url: "https://github.com/FuturraGroup/SecurityKit.git", .branch("main"))
]

用法

更新 Info.plist

为了使越狱检测能够正确工作,你需要更新你的主 Info.plist。

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>cydia</string>
    <string>undecimus</string>
    <string>sileo</string>
    <string>zbra</string>
    <string>filza</string>
</array>

越狱检测

if SecurityKit.isJailBroken() {
    print("This device is jailbroken")
} else {
    print("This device is not jailbroken")
}
let jailbreakStatus = SecurityKit.isJailBrokenWithErrorMessage()
if jailbreakStatus.jailbroken {
    print("This device is jailbroken")
    print("Because: \(jailbreakStatus.errorMessage)")
} else {
    print("This device is not jailbroken")
}
let jailbreakStatus = SecurityKit.isJailBrokenWithErrorDetects()
if jailbreakStatus.jailbroken {
    print("This device is jailbroken")
    print("The following checks failed: \(jailbreakStatus.errorDetects)")
}

模拟器检测

if SecurityKit.isSimulator() {
    print("app is running on the simulator")
} else {
    print("app is not running on the simulator")
}

反向工程工具检测

if SecurityKit.isReverseEngineered() {
    print("This device has reverse engineering tools")
} else {
    print("This device does not have reverse engineering tools")
}
let reStatus = SecurityKit.isReverseEngineeredWithErrorDetect()
if reStatus.reverseEngineered {
    print("SecurityKit: This device has evidence of reverse engineering")
    print("SecurityKit: The following detects failed: \(reStatus.errorDetect)")
}

调试器检测

let isDebugged: Bool = SecurityKit.isDebugged()
SecurityKit.denyDebugger()
let isNotLaunchD: Bool = SecurityKit.isParentPidUnexpected()
func denyDebugger() {
    // add a breakpoint at here to test
}

typealias FunctionType = @convention(thin) ()->()

let func_denyDebugger: FunctionType = denyDebugger   // `: FunctionType` is a must
let func_addr = unsafeBitCast(func_denyDebugger, to: UnsafeMutableRawPointer.self)
let hasBreakpoint: Bool = SecurityKit.hasBreakpointAt(func_addr, functionSize: nil)
// Set a breakpoint at the testWatchpoint function
func testWatchpoint() -> Bool{
    // lldb: watchpoint set expression ptr
    var ptr = malloc(9)
    // lldb: watchpoint set variable count
    var count = 3
    return SecurityKit.hasWatchpoint()
}

完整性检测

if SecurityKit.isTampered(
    [.bundleID("com.app.bundle"),
     .mobileProvision("your-mobile-provision-sha256-value")]
).result {
    print("SecurityKit: I have been Tampered.")
} else {
    print("SecurityKit: I have not been Tampered.")
}
// Manually verify SHA256 hash value of a loaded dylib
if let hashValue = SecurityKit.getMachOFileHashValue(.custom("SecurityKit")),
   hashValue == "6d8d460b9a4ee6c0f378e30f137cebaf2ce12bf31a2eef3729c36889158aa7fc" {
    print("SecurityKit: I have not been Tampered.")
} else {
    print("SecurityKit: I have been Tampered.")
}
if let loadedDylib = SecurityKit.findLoadedDylibs() {
    print("SecurityKit: Loaded dylibs: \(loadedDylib)")
}

MSHookFunction 检测

func denyDebugger() { ... }

typealias FunctionType = @convention(thin) ()->()

let func_denyDebugger: FunctionType = denyDebugger // `: FunctionType` is must
let func_addr = unsafeBitCast(func_denyDebugger, to: UnsafeMutableRawPointer.self)
let isMSHooked: Bool = SecurityKit.isMSHooked(func_addr)
func denyDebugger(value: Int) { ... }

typealias FunctionType = @convention(thin) (Int)->()

let funcDenyDebugger: FunctionType = denyDebugger
let funcAddr = unsafeBitCast(funcDenyDebugger, to: UnsafeMutableRawPointer.self)

if let originalDenyDebugger = SecurityKit.denyMSHook(funcAddr) {
    // Call orignal function with 1337 as Int argument
    unsafeBitCast(originalDenyDebugger, to: FunctionType.self)(1337)
} else {
    denyDebugger()
}

FishHook 检测

SecurityKit.denySymbolHook("$s10Foundation5NSLogyySS_s7CVarArg_pdtF") // Foudation's NSlog of Swift
NSLog("Hello Symbol Hook")

SecurityKit.denySymbolHook("abort")
abort()
for i in 0..<_dyld_image_count() {
    if let imageName = _dyld_get_image_name(i) {
        let name = String(cString: imageName)
        if name.contains("SecurityKit"), let image = _dyld_get_image_header(i) {
            SecurityKit.denySymbolHook("dlsym", at: image, imageSlide: _dyld_get_image_vmaddr_slide(i))
            break
        }
    }
}

RuntimeHook 检测

class SomeClass {
    @objc dynamic func someFunction() { ... }
}

let dylds = ["SecurityKit", ...]

let isRuntimeHook: Bool = SecurityKit.isRuntimeHook(
    dyldAllowList: dylds,
    detectionClass: SomeClass.self,
    selector: #selector(SomeClass.someFunction),
    isClassMethod: false
)

系统代理和 VPN 检测

let isProxied: Bool = SecurityKit.isProxied()

锁定模式检测

let isLockdownModeEnable: Bool = SecurityKit.isLockdownModeEnable()

贡献

欢迎为改进做出贡献。 请随时提交 pull request 以帮助扩展该库。如果您有任何问题、功能建议或错误报告,请将其发送到 Issues

许可证

MIT License

Copyright (c) 2025 Futurra Group

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.