如何实现PT_DENY_ATTACH(iOS中的反调试)

问题描述 投票:2回答:3

PT_DENY_ATTACH是一种反调试功能,可帮助防止调试程序附加到应用程序。以下代码可以在main()中实现,以防止GDB附加到应用程序。 :

#import <dlfcn.h>
#import <sys/types.h>
typedef int (*ptrace_ptr_t)(int _request, pid_t _pid, caddr_t _addr, int _data);
#define PT_DENY_ATTACH 31
void disable_gdb() {
void* handle = dlopen(0, RTLD_GLOBAL | RTLD_NOW);
ptrace_ptr_t ptrace_ptr = dlsym(handle, "ptrace");
ptrace_ptr(PT_DENY_ATTACH, 0, 0, 0);
dlclose(handle);
}
int main(int argc, char *argv[]) {
@autoreleasepool {
#ifdef DEBUG
//do nothing
#else
disable_gdb();
#endif
}}
ios ibm-mobilefirst
3个回答
1
投票

伙计们确实这个技巧已经解决了,可以通过覆盖来绕过但是看看that

来自iphonedevwiki.net的人们正在展示另一种在程序集中实现相同功能的方法,这使得修补起来更加困难。因此,要绕过此程序集实现,必须对Mach-O二进制文件进行解密并覆盖函数的实现,例如,攻击者可以仅使用nop指令从函数交换所有汇编指令。但是如果你对你的程序集进行模糊处理,那么攻击者就会更难识别正在发生的事情,所以只有最有经验的人才能绕过它。

对于那些不知道如何在Swift 5项目中编写程序集的人,以下是您需要做的事情:

  1. 创建一个新的C文件+标题
  2. 让我们命名为disable_debuggers_advanced.cdisable_debuggers_advanced.h
  3. disable_debuggers_advanced.c中添加以下内容:
#include "disable_debug_advanced.h"

void mRiYXNnZnZmZGF2Ym() {

    // No Need to encode these strings, because they will be directly compiled, they are not going to be present in the 'DATA' segment of the binary.
    __asm (
           "mov r0, #31\n" // set #define PT_DENY_ATTACH (31) to r0
           "mov r1, #0\n"   // clear r1
           "mov r2, #0\n"   // clear r2
           "mov r3, #0\n"   // clear r3
           "mov ip, #26\n"  // set the instruction pointer to syscal 26
           "svc #0x80\n"    // SVC (formerly SWI) generates a supervisor call. Supervisor calls are normally used to request privileged operations or access to system resources from an operating system
           );
}

  1. disable_debuggers_advanced.h中添加以下内容:

#ifndef disable_debug_advanced_h
#define disable_debug_advanced_h

#include <stdio.h>


/**
 Original name: `disable_gdb_advanced()`

 This function makes the process deny the attaching request by debugers by
 simulating what is already available on macOS:

 ptrace(PT_DENY_ATTACH, 0, 0, 0);

 by implementing it directly in assembly language.

 This method of disabling debugers is well known to attackers but there is nothing they can do to easily bypass it
 because it is a part of the kernel memory space.

 Please note that this will make XCode not being able to attach its debuger to the process too,
 so run it only in release builds.

 source: https://iphonedevwiki.net/index.php/Crack_prevention#PT_DENY_ATTACH
 */
void mRiYXNnZnZmZGF2Ym(void) __attribute__((always_inline));

#endif /* disable_debug_advanced_h */

  1. 如果您的项目还没有,请将#include "disable_debug_advanced.h"添加到您的桥接头和桥接头。

现在您可以调用此函数来禁用调试器。

请注意,这将破坏XCode调试器,因此仅在发布版本上使用它

如果你想知道__attribute__((always_inline))部分和它的奇怪名称,因为我们希望尽可能隐藏我们的函数。如果你不熟悉函数内联,你可以观看我关于here函数的视频,我会深入描述它,或者你可以在wikipedia about it中阅读。即使认为它是速度编译器优化,它也可以给我们带来好处,因为如果你从多个位置调用它,攻击者将很难在应用程序中修补所有功能正文副本。

名称是这样写的,因为这个内联只是编译器的一个提示,不能保证它会发生。如果它没有发生并且我们的二进制文件的TEXT段中明确定义了禁用调试器的功能,我们希望它至少具有混淆的名称,这样就没有人可以通过读取它的汇编标签来猜测它的作用。

在我看来,即使在创建UIApplication对象之前,也应将其称为顶级函数。

为了做到这一点:

  1. 将新文件添加到Swift项目并将其命名为“main.swift”(名称是重要的)
  2. AppDelegates类定义中删除@UIApplicationMain标记。
  3. 在您的main.swift文件中写下以下内容:

mRiYXNnZnZmZGF2Ym() // disable debuggers

// initialises the UIApplication and fires the event loop.
// This function never returns!
UIApplicationMain(CommandLine.argc, CommandLine.unsafeArgv, nil, NSStringFromClass(AppDelegate.self))

如果你想看一个如何在main.swift中执行顶级代码的视频,你可以看到我在this video上执行它

为了使它更加模糊和更难破解,可以使用像this one Movfuscator这样的组装混淆器,这样只有少数人能够识别这些汇编指令的含义。


0
投票

注意:根据此工具的wiki页面,它已经成为万能的,不能使用:

重要提示:这个技巧已经被海盗解决了。不要依赖它!

假设您指的是在MobileFirst Studio 7.1中创建的混合应用程序 - 这与其他任何iOS应用程序没有什么不同。

Hybrid应用程序的最终结果仍然是您在Xcode中打开以构建应用程序的Xcode项目。这意味着您需要将代码放在Xcode项目中的相同位置,就好像这是一个常规的Xcode项目(它是),根据wiki page for PT_DENY_ATTACH


0
投票

正如@Idan Adar所说 - 这个技巧是有效的,但是如果你想在任何教育或其他目的中尝试它,你可以尝试做以下事情:

  1. 为你的app添加define以允许你运行和调试,如果需要的话 #define SOME
  2. 在main.m中添加以下代码 #define SOME #import <UIKit/UIKit.h> #import "AppDelegate.h" #ifdef SOME #import <dlfcn.h> #import <sys/types.h> typedef int (*ptrace_ptr_t)(int request, pid_t pid, caddr_t addr, int data); #if !defined(PT_DENY_ATTACH) #define PT_DENY_ATTACH 31 #endif // !defined(PT_DENY_ATTACH) void disable_gdb(); int main(int argc, char *argv[]) { // disable_gdb(); @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } void disable_gdb() { void* handle = dlopen(0, RTLD_GLOBAL | RTLD_NOW); ptrace_ptr_t ptrace_ptr = dlsym(handle, "ptrace"); ptrace_ptr(PT_DENY_ATTACH, 0, 0, 0); dlclose(handle); } int main3(int argc, char *argv[]) { return -1; } #else int main(int argc, char *argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } #endif

Here - 一些好的开始

© www.soinside.com 2019 - 2024. All rights reserved.