Skip to content

Commit 2cccc5c

Browse files
ha-jatheDeniZ
authored andcommitted
feat: debugger detection added
* add DebuggerDetection.swift * add DebuggerDetection to ThreatDetectionCenter * add debugger detection view to SecurityToolkitExample * add documentation for isDebuggerAttached * fix typo: isDebuggerAttached -> isDebuggerDetected * Comment made even more clear * hasTracerFlagSet() additionally made private * No explicit Darwin import needed and therefore rmd no explicit Darwin import needed and therefore removed * Use of optional bool for isDebuggerDetected return Use of optional bool for public function isDebuggerDetected. This decision is the result of a joint discussion that took place in the associated PR #10 : #10 Motivation: No exception should be thrown. It should be communicated that something went wrong in the decision-making process and that no clear statement can be made. Decision: We now return nil in an unclear case. nil: The detection process did not produce a definitive result. This could happen due to system limitations, lack of required permissions, or other undefined conditions.
1 parent 8dc8ac8 commit 2cccc5c

File tree

4 files changed

+52
-0
lines changed

4 files changed

+52
-0
lines changed

SecurityToolkitExample/SecurityToolkitExample/Resources/en.lproj/Localizable.strings

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
"threat.hooks.description" = "Intercept system or application calls and then modify them (modify the return value of a function call for example)";
66
"threat.simulator.title" = "Simulator";
77
"threat.simulator.description" = "Running the application in a simulator";
8+
"threat.debugger.title" = "Debugger";
9+
"threat.debugger.description" = "A tool that allows developers to inspect and modify the execution of a program in real-time, potentially exposing sensitive data or allowing unauthorized control.";
810

911
// MARK: Threat List
1012
"threat.list.title" = "Protection";

SecurityToolkitExample/SecurityToolkitExample/Sources/ThreatStatus.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ struct ThreatStatus: Hashable {
2222
description: R.string.localizable.threatSimulatorDescription(),
2323
isDetected: ThreatDetectionCenter.isSimulatorDetected
2424
),
25+
ThreatStatus(
26+
title: R.string.localizable.threatDebuggerTitle(),
27+
description: R.string.localizable.threatDebuggerDescription(),
28+
isDetected: ThreatDetectionCenter.isDebuggerDetected
29+
),
2530
]
2631
}
2732

Sources/DebuggerDetection.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import Foundation
2+
3+
// MARK: - Internal
4+
internal final class DebuggerDetection {
5+
6+
static func threatDetected() -> Bool? {
7+
hasTracerFlagSet()
8+
}
9+
}
10+
11+
// MARK: - Private
12+
fileprivate extension DebuggerDetection {
13+
14+
/// Check P_TRACED flag from Darwin Kernel
15+
/// if the process is traced
16+
private static func hasTracerFlagSet() -> Bool? {
17+
var info = kinfo_proc()
18+
var mib: [Int32] = [CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()] // Kernel info, process info, specific process by PID, get current process ID
19+
var size = MemoryLayout.stride(ofValue: info)
20+
21+
let unixStatusCode = sysctl(&mib, u_int(mib.count), &info, &size, nil, 0)
22+
23+
return unixStatusCode == 0 ? (info.kp_proc.p_flag & P_TRACED) != 0 : nil
24+
}
25+
}

Sources/ThreatDetectionCenter.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,21 @@ public final class ThreatDetectionCenter {
1414
SimulatorDetection.threatDetected()
1515
}
1616

17+
/// Will check if your application is being traced by a debugger.
18+
///
19+
/// - Returns:
20+
/// `true`: If a debugger is detected.
21+
/// `false`: If no debugger is detected.
22+
/// `nil`: The detection process did not produce a definitive result. This could happen due to system limitations, lack of required permissions, or other undefined conditions.
23+
///
24+
/// A debugger is a tool that allows developers to inspect and modify the execution of a program in real-time, potentially exposing sensitive data or allowing unauthorized control.
25+
///
26+
/// ## Notes
27+
/// Please note that Apple itself may require a debugger for the app review process.
28+
public static var isDebuggerDetected: Bool? {
29+
DebuggerDetection.threatDetected()
30+
}
31+
1732

1833
// MARK: - Async Threat Detection
1934

@@ -22,6 +37,7 @@ public final class ThreatDetectionCenter {
2237
case rootPrivileges
2338
case hooks
2439
case simulator
40+
case debugger
2541
}
2642

2743
/// Stream that contains possible threats that could be detected
@@ -40,6 +56,10 @@ public final class ThreatDetectionCenter {
4056
continuation.yield(.simulator)
4157
}
4258

59+
if DebuggerDetection.threatDetected() ?? false {
60+
continuation.yield(.debugger)
61+
}
62+
4363
continuation.finish()
4464
}
4565
}

0 commit comments

Comments
 (0)