反调试、反反调试
debugserver
//Mac位置
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/9.1/DeveloperDiskImage.dmg/usr/bin/debugserver
//手机位置,必须越狱才看得到,通过Xcode安装上去的
Device/Developer/usr/bin
//手机Developer文件下是只读的
//如果想调试越狱.用电脑上的LLDB链接设备上的debugserver
-
手机上的debugserver先链接某一个APP,提供一个端口给外面。LLDB再链接debugserver
//连接手机 $ sh login.sh $ cd /Developer/usr/bin/ $ ls DTDeviceArbitration XcodeDeviceMonitor iprofiler ScreenShotr debugserver xctest //查看使用方法 $ ./debugserver debugserver-@(#)PROGRAM:debugserver PROJECT:debugserver-340.3.51.1 for arm64. Usage: debugserver host:port [program-name program-arg1 program-arg2 ...] debugserver /path/file [program-name program-arg1 program-arg2 ...] debugserver host:port --attach=<pid> debugserver /path/file --attach=<pid> debugserver host:port --attach=<process_name> debugserver /path/file --attach=<process_name> //手机端连接app $ ./debugserver *:12346 -a WeChat debugserver-@(#)PROGRAM:debugserver PROJECT:debugserver-340.3.51.1 for arm64. Attaching to process WeChat... Listening to port 12346 for a connection from *... //Mac端 //进入lldb $ lldb //连接debugserver.敲完以后程序会卡住 //做完端口映射以后可以把172.17.10.14改成localhost $ process connect connect://172.17.10.14:12346 Process 516 stopped * thread #1, stop reason = signal SIGSTOP frame #0: 0x000000019b0a4a40 libsystem_kernel.dylib`mach_msg_trap + 8 libsystem_kernel.dylib`mach_msg_trap: -> 0x19b0a4a40 <+8>: ret libsystem_kernel.dylib`mach_msg_overwrite_trap: 0x19b0a4a44 <+0>: mov x16, #-0x20 0x19b0a4a48 <+4>: svc #0x80 0x19b0a4a4c <+8>: ret //连接成功,暂停状态,程序就被断住的. Target 0: (WeChat) stopped. //continue一下 $ c //退出,app会被杀掉 $ exit
手机端
- debugserver 连接APP $ debugserver *:端口号 -a 进程
*:端口号
- 使用手机的某个端口提供服务
-a 进程
- 连接的APP (进程ID,进程名称–MachO文件的名称)
命令行工具的权限文件
-
导出权限文件
$ ldid -e 可执行文件 > 文件名称.entitlement
-
两个关键字段/权限
get-task-allow task_for_pid-allow
-
签名权限
$ ldid -S权限文件 可执行文件
-
Developer/usr/bin只读。直接放在usr/bin
反调试Ptrace
-
process trace 进程跟踪
-
此函数提供了一个进程监听控制另外一个进程,并且可以检测被控制进程的内容和寄存器里面的数据!它可以用来实现断点调试和系统调用跟踪。debugserver就是用的它
-
iOS中没有提供相关的头,不是私有api,可以使用
-
创建mac应用导入<sys/ptrace.h>,导出
/* arg1:ptrace要做的事情 arg2:要操作进程的ID arg3(地址) arg4(数据): 取决于arg1 PT_DENY_ATTACH 拒绝连接 */ ptrace(PT_DENY_ATTACH, 0, 0, 0); //Xcode无法调试。debugserver也无法调试
反Ptrace
-
注入动态库
// 怎么破?? 调用 ptrace(系统函数??) 保留函数符号 // 重新绑定!! -- fishHook #import "injectCode.h" #import "fishhook.h" #import "MyPtraceHeader.h" @implementation injectCode //定义指针,保存原来的函数地址 int (*ptrace_p)(int _request, pid_t _pid, caddr_t _addr, int _data); //定义自己的函数 int myPtrace(int _request, pid_t _pid, caddr_t _addr, int _data){ //不是拒绝连接就保留 if (_request != PT_DENY_ATTACH) { return ptrace_p(_request, _pid, _addr, _data); } //如果是拒绝加载!不予理会!! return 0; } +(void)load { // NSLog(@"injectCode来了!!"); //交换! struct rebinding ptraceBd;//fishhook的绑定结构体 ptraceBd.name = "ptrace";//函数符号 ptraceBd.replacement = myPtrace;//新函数的地址 ptraceBd.replaced = (void *)&ptrace_p;//原始函数地址的指针 //弄一个数组,放fishhook的绑定结构体 struct rebinding bindings[] = {ptraceBd}; //fishHook的重绑定函数!! rebind_symbols(bindings, 1); }
通过framework防护调试
-
第一个调用自己的动态库
-
再反:MachO,注入命令行工具,实现原理