文章目录

debugserver 连接APP

  • $sh usbLogin.sh链接手机,root# cd /Developer/usr/bin可以看的目录下有个debugserver,在链接之前可以$ps -A查看进程。
$ ./debugserver *:12346 -a WeChat
  • root# ./debugserver运行debugserver
  • *:端口号:使用手机的某个端口提供服务
  • -a 进程:连接的APP (进程ID,进程名称–MachO文件的名称)

LLDB 启动

LLDB 启动原理

  • XCode安装程序包里==/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport==目录下,每个版本有个DeveloperDiskImage.dmg安装包,联机调试的时候会安装到手机
    越狱开发笔记(五)—— ptrace反调试&反反调试-LMLPHP
  • $lldb开启LLDB
  • lldb连接debugserver,debugserver选择性调试某个App
(lldb) process connect connect://手机IP地址:debugserver服务的端口

连接成功,程序就被断住的。

LLDB下断点

  • 查看手机砸壳状态root# Clutch -i;砸壳root# Clutch -b 2,其中“2”为查看的标示。

  • 拷贝MachO文件WeChat.decrypted到电脑桌面$class-dump -H WeChat.decrypted -o ./Headers/

  • $sh usbLogin.sh链接手机,root# cycript -p WeChat进入cycript(如果连不了去(lldb) command + c),cy# @import test加载命令查看当前视图cy# currentVC()

  • 用Hopper软件分析MachO文件WeChat.decrypted, 找当前视图类的onNext方法的地址,加上(lldb) image list查看到的进程地址(lldb) b 0x1027DA3A8下断点,(lldb) breakpoint list可以查看到新下断点。(lldb) po $x0输入即下断点的类

  • (lldb) exit退出LLDB

命令行工具的权限文件

  • 拷贝debugserver,查看文件类型$file debugserver其为可执行二进制文件

  • 导出权限文件$ldid -e 可执行文件 > 文件名称.entitlement

  • 打开.entitlement文件添加两个关键字段:
    get-task-allow YES
    task_for_pid-allow YES

  • 签名权限$ldid -Sdebugserver.entitlement debugserver

  • 拷贝debugserver到root的==/Device/usr/bin==目标了下root# debugserver执行

可执行文件

  • 创建Single View App,删除界面相关文件,并对main.m删除不需要的代码,添加printf语句,编译找到可执行文件,拷贝到手机==/usr/bin==目录,$ sh usbLogin链接手机,到目录下./文件名执行,发现root# Permission denied并没有权限,root# chmod +x 文件名加上权限,便可以执行。
  • 命令行参数,其实就是可执行文件的argv[],其中argv[0]=文件名

反调试ptrace

  • debugserver用ptrace(process trace进程跟踪)函数,它提供了一个监听控制另外一个进程,并且可以检查被控制进程的内容和寄存器里面的数据。具体可参照《程序员的自我修养》一书
  • 新建命令行工程,#import <sys/ptrace.h>输入ptrace函数,去头文件,拷贝头文件内容。张贴到Single View App工程的MyPtraceHeader.h
  • 调用ptrace函数ptrace(PT_DENY_ATTACH, 0, 0, 0),此时可以联机编译,但是运行会崩溃。但是我们发现,越狱手机可以直接运行,并且控制台设备正常输出内容。这是因为此时此程序不能被Xcode附加调试。同样$sh usbConnet$sh usbLogin链接手机,root# debugserver *:12346 -a 进程ID出现Segmentation fault。支付宝、微信做了类似的防护。

破解ptrace反调试

  • 添加framework,注入动态库,hook ptrace方法
  • 因为ptrace是系统函数,会保留函数符号,需要重新绑定。在注入代码里#import fishHook.h
  • 定义指针,保存原理的函数地址,定义自己的函数,在+load时交换,即hook。
//定义指针,保存原来的函数地址
int (*ptrace_p)(int _request, pid_t _pid, caddr_t _addr, int _data);

//定义自己的函数
int my_ptrace(int _request, pid_t _pid, caddr_t _addr, int _data){
    if (_request != PT_DENY_ATTACH) {//如果不是拒绝连接,就保持调用
        return ptrace_p(PT_DENY_ATTACH,_pid,_addr,_data);
    }
    //如果是拒绝加载,就不执行直接return
    return 0;
}

+(void)load
{
    //交换
    struct rebinding ptraceBd;//fishHook的绑定结构体
    ptraceBd.name = "ptrace";//函数名称
    ptraceBd.replacement = my_ptrace;//新函数地址
    ptraceBd.replaced = (void *)&ptrace_p;//原始函数地址的指针
    //弄一个数组,放fishHook的绑定结构体
    struct rebinding bindings[] = {ptraceBd};
    //fishHook的重绑定函数
    rebind_symbols(bindings, 1);
}
  • 注入后又可以正常运行调试了。支付宝,微信如果只是这样的防护那也太low了。你是对的,通过framework防护调试,此方法失效。道高一尺,魔高一丈,神高于一切!

通过framework防护调试

  • 动态库加载顺序,决定调用顺序。并且在应用程序调用之前。
  • 将反调试内容放置framework,就能防止别人破坏反调试,达到调试应用的目的。
  • 通过fishHook反Hook,就是使用最快调用,达到调用自己的目的。通过ptrace,反调用,达到防护效果,使用了一样的原理。
03-11 14:47