很多越狱手机是通过加载插件的方式来实现代码注入。主要是使用DYLD_INSERT_LIBRARIES 动态插入,这个主要bundle id 获取进程, 插入动态库!
在dyld的源码中会通过hasRestrictedSegment函数判断是否限制其链接插件行为,这里可以在Xcode中设置参数
-Wl,-sectcreate,__RESTRICT,__restrict,/dev/null
来实现
image.png
编译后可以查看Mach-o文件 image.png
多了这一段。
防 LLDB 调试 lldb 之所以能够调试手机上的 app, 原因在于 xcode 连接手机后, 在手机上安装了 debugsever,我们可以通过 ptrace (process trace) 进程跟踪 来监控lldb调试。
此函数提供了一个进程, 监听控制另外一个进程, 并且可以检测被控制进程的内存的寄存器里面的数据! 它可以用来实现断点调试和系统调用跟踪.
debugserve r的实现就是基于 ptrace (OSX).
在使用前我先在main函数中引入#include<dlfcn.h>,具体代码
#include<dlfcn.h>
typedef int(*ptrace_ptr_t)(int _request,pid_t_pid,caddr_t_addr,int_data);
//void* dlopen(const char* pathname,intmode );
#if !defined(PT_DENY_ATTACH)
#define PT_DENY_ATTACH 31
#endif // !defined(PT_DENY_ATTACH)
void disable_gdb() {
// RTLD_LAZY:在dlopen返回前,对于动态库中存在的未定义的变量(如外部变量extern,也可以是函数)不执行解析,就是不解析这个变量的地址。
//
// RTLD_NOW:与上面不同,他需要在dlopen返回前,解析出每个未定义变量的地址,如果解析不出来,在dlopen会返回NULL,错误为:
//
// : undefined symbol: xxxx.......
//
// RTLD_GLOBAL:它的含义是使得库中的解析的定义变量在随后的随后其它的链接库中变得可以使用。
//dlopen加载动态库
void* handle =dlopen(0,RTLD_GLOBAL|RTLD_NOW);
//获取函数地址
ptrace_ptr_t ptrace_ptr =dlsym(handle,"ptrace");
//参数1:ptrace要做的事情
//第二个参数指明了要操作进程的PID
//第三个和第四个取决于第一个参数
ptrace_ptr(PT_DENY_ATTACH,0,0,0);
dlclose(handle);
}
然后在main函数中引用下就好
int main(int argc, char * argv[]) {
NSString * appDelegateClassName;
#ifndef DUBUG
disable_gdb();
#endif
@autoreleasepool {
// Setup code that might create autoreleased objects goes here.
appDelegateClassName = NSStringFromClass([AppDelegate class]);
}
return UIApplicationMain(argc, argv, nil, appDelegateClassName);
}
这样就可以阻止其断点调试了。
网友评论