15

First, let me say that I understand that using PT_DENY_ATTACH as described at: Bugging Debuggers is pretty useless.

However, for the sake of understanding how iOS works, I would still like to know: Is it possible to do something similar when working on a Swift project? Since Objective-C is built upon C, there is a main(int argc, char *argv[]) function that can be leveraged to prevent gdb from attaching to the process.

How would this be done in Swift? I'm mostly trying to understand the application lifecycle in Swift, however, most of the explanations I can find are for ObjC.

Stephen
  • 1,038
  • 9
  • 25
  • 1
    The answer to [this question](http://stackoverflow.com/questions/24020000/subclass-uiapplication-with-swift/24021180#24021180) may be helpful. – ahruss Apr 23 '15 at 15:02
  • That answer is, in fact, quite helpful to understanding. It seems that the lifecycle is the same. However, Swift hides some of the implementation behind the @UIApplicationMain directive. – Stephen Apr 23 '15 at 15:27

1 Answers1

15

Thanks to user ahruss's very helpful link, here's the solution I landed on:

I used the method referenced in this question to create a main.swift file. I then created a c file (and header) containing this method definition:

typedef int (*command_ptr_t)(int _request, pid_t _pid, caddr_t _addr, int _data);

#if !defined(PT_DENY_ATTACH)
#define PT_DENY_ATTACH 31
#endif

//Anti-debug method
void disable_attach() {
    void* handle = dlopen(0, RTLD_GLOBAL | RTLD_NOW);
    command_ptr_t command_ptr = dlsym(handle, "ptrace");
    command_ptr(PT_DENY_ATTACH, 0, 0, 0);
    dlclose(handle);
}

I added the disableAttach.h header file in my bridging header, then called disable_attach() directly above my UIApplicationMain(Process.argc, Process.unsafeArgv, nil, NSStringFromClass(AppDelegate)) call in main.swift.

You should end up with a main.swift file similar to this:

import Foundation
import UIKit

disable_attach()
UIApplicationMain(
    CommandLine.argc,
    UnsafeMutableRawPointer(CommandLine.unsafeArgv)
        .bindMemory(
            to: UnsafeMutablePointer<Int8>.self,
            capacity: Int(CommandLine.argc)),
    nil,
    NSStringFromClass(AppDelegate.self)
)

As I stated previously in a comment, it seems that the lifecycle is the same, but that the @UIApplicationMain directive hides the main file itself.

UPDATE: As of Xcode 10 \ iOS 12, the main.swift file should look like this:

UIApplicationMain(
    CommandLine.argc, CommandLine.unsafeArgv, 
    nil, NSStringFromClass(AppDelegate.self)
)

Thanks to the answers here and here

Stephen
  • 1,038
  • 9
  • 25
  • If I understand what you did correctly, this can still be circumvented - once the attacker finds out what's going on, he'll simply jump over the function call. You can try something more sophisticated, like unobvious crash paths (when you figured out that you're being debugged and want to keep the attacker in the dark about *when exactly* did it happen) combined with unobvious debugger detection like measuring code execution time, or something weird and unexpected like self-debugging. The problem is, anyone tenacious and enough will crack any defence... So be sure not to go too high-profile =) – Mints97 Apr 23 '15 at 20:55
  • @Mints97 You are exactly correct. The PT_DENY_ATTACH method is no longer considered useful ([this link](http://iphonedevwiki.net/index.php/Crack_prevention) lists it as "Deprecated or not working"), however, it made for a good use case to understand the differences between a Swift and an ObjC based iOS application. – Stephen Apr 23 '15 at 21:10
  • @Stephen Is there a solution which is can replace PT_DENY_ATTACH ? – Ryan Heitner Feb 08 '16 at 10:31
  • @RyanHeitner There's not a better solution that I know of. This can be easily worked around, but is at least a deterrent. Best to use a set of solutions to increase your app security and to ensure any sensitive data is encrypted or never stored at all. – Stephen Feb 08 '16 at 17:55
  • Can I publish app to app store with this code? In other words, is it allowed by Apple? – Rohit Kashyap Jun 22 '18 at 07:25
  • Unless rules have changed recently, this code should be accepted in the App Store. – Stephen Jun 22 '18 at 18:59