如何实现PT_DENY_ATTACH(iOS中的反调试)
PT_DENY_ATTACH是一种反调试功能,有助于防止调试器连接到应用程序。以下代码可以在main()中实现,以防止GDB附加到应用程序:如何实现PT_DENY_ATTACH(iOS中的反调试),ios,ibm-mobilefirst,Ios,Ibm Mobilefirst,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() {
#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
}}
#导入
#进口
typedef int(*ptrace_ptr_t)(int请求、pid_t_pid、caddr_t_addr、int数据);
#定义PT_DENY_ATTACH 31
void disable_gdb(){
void*handle=dlopen(0,RTLD_全局| RTLD_现在);
ptrace_ptr_t ptrace_ptr=dlsym(手柄,“ptrace”);
ptrace_ptr(PT_DENY_ATTACH,0,0,0);
dlclose(手柄);
}
int main(int argc,char*argv[]){
@自动释放池{
#ifdef调试
//无所事事
#否则
禁用_gdb();
#恩迪夫
}}
注意:根据此工具的wiki页面,它已被禁用,不得使用:
重要提示:这个把戏已经被海盗利用过了。不要依赖它
假设您指的是在MobileFirst Studio 7.1中创建的混合应用程序,那么这与任何其他iOS应用程序都没有什么不同
混合应用程序的最终结果仍然是一个Xcode项目,您可以在Xcode中打开它来构建应用程序。这意味着您需要将代码放在Xcode项目中的同一位置,就像这是一个常规的Xcode项目一样(事实上是这样)。正如@Idan Adar所指出的那样。-这个技巧是可行的,但如果您想在任何教育或其他目的中尝试,您可以尝试执行以下操作:
#define SOME
#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
#定义一些
#进口
#导入“AppDelegate.h”
#如果有的话
#进口
#进口
typedef int(*ptrace_ptr_t)(int请求、pid_t pid、caddr_t addr、int数据);
#如果!已定义(PT_DENY_ATTACH)
#定义PT_DENY_ATTACH 31
#endif/!已定义(PT_DENY_ATTACH)
void disable_gdb();
int main(int argc,char*argv[])
{
//禁用_gdb();
@自动释放池{
返回UIApplicationMain(argc、argv、nil、NSStringFromClass([AppDelegate类]);
}
}
void disable_gdb()
{
void*handle=dlopen(0,RTLD_全局| RTLD_现在);
ptrace_ptr_t ptrace_ptr=dlsym(手柄,“ptrace”);
ptrace_ptr(PT_DENY_ATTACH,0,0,0);
dlclose(手柄);
}
int main3(int argc,char*argv[])
{
返回-1;
}
#否则
int main(int argc,char*argv[])
{
@自动释放池{
返回UIApplicationMain(argc、argv、nil、NSStringFromClass([AppDelegate类]);
}
}
#恩迪夫
-关于伙计们,有一些好的开始点这是真的,这个技巧已经被解决了,可以通过重写绕过,但是看看 在这里,来自iphonedevwiki.net的家伙们展示了另一种在汇编中实现相同功能的方法,使得修补变得更加困难。因此,要绕过此程序集实现,必须对Mach-O二进制文件进行解密并覆盖函数的实现,例如,攻击者可以将函数中的所有程序集指令仅与不起任何作用的
nop
指令交换。但如果您混淆了组装例程,攻击者将更难识别正在发生的事情,因此只有最有经验的人才能绕过它
对于那些不知道如何在Swift 5项目中编写汇编的人,以下是您需要做的事情:
C
文件+头disable\u debuggers\u advanced.c
和disable\u debuggers\u advanced.h
禁用调试器\u advanced.c
中添加以下内容:#包括“禁用调试高级.h”
void mRiYXNnZnZmZGF2Ym(){
//不需要对这些字符串进行编码,因为它们将被直接编译,它们不会出现在二进制文件的“数据”段中。
__asm(
“mov r0,#31\n”//set#定义PT#u DENY#u连接(31)到r0
“移动r1,#0\n”//clear r1
“移动r2,#0\n”//clear r2
“mov r3,#0\n”//clear r3
“mov ip,#26\n”//将指令指针设置为syscal 26
“svc#0x80\n”//svc(以前的SWI)生成一个主管调用。主管调用通常用于从操作系统请求特权操作或访问系统资源
);
}
禁用调试器\u advanced.h
中添加以下内容:
#ifndef禁用\u调试\u高级\u h
#定义禁用调试高级
#包括
/**
原始名称:`disable_gdb_advanced()`
此函数使进程通过以下方式拒绝调试器的附加请求:
模拟macOS上已有的功能:
ptrace(PT_DENY_ATTACH,0,0,0);
通过直接用汇编语言实现。
这种禁用调试程序的方法为攻击者所熟知,但他们无法轻松绕过它
因为它是内核内存空间的一部分。
请注意,这将使XCode无法将其调试程序连接到进程,
所以只在发布版本中运行它。
资料来源:https://iphonedevwiki.net/index.php/Crack_prevention#PT_DENY_ATTACH
*/
void mRiYXNnZnZmZGF2Ym(void)uuuu属性uuu((始终在线));
#endif/*禁用调试高级*/
#包括“disable_debug_advanced.h”
添加到桥接头中,如果您的项目还没有桥接头,则添加桥接头\uuuu属性((总是内联的))
部分和奇怪的名称,那是因为我们希望函数尽可能隐藏。如果您不熟悉函数内联,您可以观看我关于函数内联的视频,在那里我对它进行了深入的描述,或者您可以阅读。即使这是一个速度编译器优化,它也可以给我们带来好处,因为如果您从多个位置调用它,攻击者将更难修补所有函数体
#import "AppDelegate.h"
#import "Application.h"
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/sysctl.h>
#include <stdlib.h>
typedef int (*PYStdWriter)(void *, const char *, int);
static PYStdWriter _oldStdWrite;
#define PT_DENY_ATTACH 31
int __pyStderrWrite(void *inFD, const char *buffer, int size)
{
if ( strncmp(buffer, "AssertMacros:", 13) == 0 ) {
return 0;
}
return _oldStdWrite(inFD, buffer, size);
}
static int is_debugger_present(void)
{
int name[4];
struct kinfo_proc info;
size_t info_size = sizeof(info);
info.kp_proc.p_flag = 0;
name[0] = CTL_KERN;
name[1] = KERN_PROC;
name[2] = KERN_PROC_PID;
name[3] = getpid();
if (sysctl(name, 4, &info, &info_size, NULL, 0) == -1) {
perror("sysctl");
exit(-1);
}
return ((info.kp_proc.p_flag & P_TRACED) != 0);
}
int main(int argc, char *argv[]) {
#ifdef DEBUG
_oldStdWrite = stderr->_write;
stderr->_write = __pyStderrWrite;
@autoreleasepool {
return UIApplicationMain(argc, argv, NSStringFromClass([Application class]), NSStringFromClass([AppDelegate class]));
}
#else
//Anti Debugging Code
//https://coredump.gr/articles/ios-anti-debugging-protections-part-2/
//ptrace(PT_DENY_ATTACH, 0, 0, 0);
printf("Looping forever");
fflush(stdout);
while (1)
{
sleep(1);
if (is_debugger_present())
{
//[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"isAntiDebug"];
printf("Debugger detected! Terminating...\n");
return -1;
}
printf(".");
fflush(stdout);
_oldStdWrite = stderr->_write;
stderr->_write = __pyStderrWrite;
@autoreleasepool {
//[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"isAntiDebug"];
int retVal = UIApplicationMain(argc, argv, NSStringFromClass([Application class]), NSStringFromClass([AppDelegate class]));
return retVal;
}
}
#endif
}
#if defined (__arm64__)
__asm(
"mov x0, #26\n" // ptrace
"mov x1, #31\n" // PT_DENY_ATTACH
"mov x2, #0\n"
"mov x3, #0\n"
"mov x16, #0\n"
"svc #128\n"
);