ptrace反调试

一、iOS调试

iOS调试里面非常常见的就是LLDB调试,LLDB是Xcode自带的调试工具,既可以本地调试Mac应用程序,也可以远程调试iPhone应用程序。当我们使用Xcode调试手机应用程序时,Xcode会将debugsever文件复制到手机中,以便在手机上启动一个服务,等待Xcode进行远程调试,接着通过LLDB把调试指令发给手机的debugServer,进行一系列调试。所谓反调试,就是防止第三方动态查看调试自己的App

debugserver在Mac上的路径(以iOS12.1系统为例):

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/12.1\ \(16B91\)/DeveloperDiskImage.dmg

/usr/bin/debugserver(DeveloperDiskImage.dmg映像内部路径)

debugserver在iOS设备上的路径:

/Developer/usr/bin

二、认识ptrace

为了方便应用软件的开发和调试,Unix(iOS是类Uinx)的早期版本就提供了一种对运行中的进程进行跟踪和控制的手段,那就是系统调用ptrace。通过ptrace,可以对另一个进程实现调试跟踪,并且可以检测被控制进程的内存和寄存器里面的数据,它是通过调试器附加的形式进行调试的。

三、关于系统调用

系统调用指的是运行在用户空间的程序向操作系统内核请求需要更高权限运行的服务。系统调用提供用户程序与操作系统之间的接口。大多数系统交互式操作需求在内核态运行。如设备IO操作或者进程间通信。
它是一个系统提供的很强大的底层服务,我们用户层的框架是构建在system call之上的。

可以通过命令查看系统提供给用户的系统调用数:

sudo dtrace -ln 'syscall:::entry' | wc -l

系统调用个数

命令中有个叫dtrace的东西,我们wiki之简单先了解一下Dtrace

DTrace is a comprehensive dynamic tracing framework created by Sun Microsystems for troubleshooting kernel and application problems on production systems in real time. Originally developed for Solaris, it has since been released under the free Common Development and Distribution License (CDDL) and has been ported to several other Unix-like systems.

DTrace是Sun Microsystems创建的一个全面的动态跟踪框架,用于实时诊断生产系统上的内核和应用程序问题。它最初是为Solaris开发的,后来在免费的公共开发和发行许可(CDDL)下发布,并被移植到其他几个类unix系统。

DTrace can be used to get a global overview of a running system, such as the amount of memory, CPU time, filesystem and network resources used by the active processes. It can also provide much more fine-grained information, such as a log of the arguments with which a specific function is being called, or a list of the processes accessing a specific file.

DTrace可以用于获得一个正在运行的系统的全局概览,例如活动进程使用的内存量、CPU时间、文件系统和网络资源。它还可以提供更细粒度的信息,例如调用特定函数的参数的日志,或者访问特定文件的进程的列表。

三、梳理关系

前文提到了LLDB、debugserver、ptrace、dtrace,我们来通过一个小试验理清它们之间的关系,如下:

  • 先通过命令创建出一个dtrace引用,并且让其对系统调用ptrace进行监控(从dtrace上面的第二段简介可知)

sudo dtrace -qn 'syscall::ptrace:entry { printf("%s(%d, %d, %d, %d) from %s\n", probefunc, arg0, arg1, arg2, arg3, execname); }'

注意必须关闭SIP(system integrity protection)

此时dtrace会进入等待状态,等待系统调用ptrace执行。

  • 新建终端窗口尝试对某进程进行LLDB附加调试


    LLDB附加

我这里对本机运行的QQ进程LLDB调试附加:lldb -p 971

  • 查看dtrace端输出:


    dtrace端输出

可以看到系统调用了ptrace,来自debugserver,从打印信息上看我们可以这样理解,LLDB发送调试指令给debugserver,debugserver调起系统调用ptrace并附加到指定进程上。

  • 进一步查看debugserver,利用命令pgrep debugserver获取debugserver进程号(PID),查看进程信息:
    查看debugserver进程
debugserver父进程

可以看到确确实实是lldb调起了debugserver进程,总结一下整个附加调试器的流程:lldb -> debugserver ->ptrace

四、重点研究系统调用ptrace

  • 新建工程查看ptrace定义
    在iOS App工程下我试过#import <sys/ptrace.h>报错,需要新建一个命令行工程,然后#import,主要目的是为了定位到头文件查看信息,为了不让读者操作麻烦,我直接给出该文件路径:/usr/include/sys/ptrace.h
    1.png
2.png
3.png
  • 解析ptrace函数
    函数原型:int ptrace(int _request, pid_t _pid, caddr_t _addr, int _data);
    参数1:表明ptrace要做的事情 (可以往回查看一下dtrace窗口输出,ptrace第一个参数是14,对应宏定义PT_ATTACHEXC,看到注释,就是我们附加调试到正在运行的进程的意思)。
    参数2:进程号PID
    参数3:地址
    参数4:数据
    参数3、4根据参数1决定,具体含义没有深究。

ptrace提供了一个非常有用的参数,那就是PT_DENY_ATTACH,如果我们可以人为地传入这个值给第一个参数,那么就不是可以中断lldb调试了吗?没错,ptrace反调试的原理就是如此!

五、编写ptrace反调试函数

ptrace反调试的实现形式有多种,可以看一下反调试与绕过的奇淫技巧,这里我做了两次反调试,详细看注释:

//
//  main.m
//  Test
//
//  Created by Kinken_Yuen on 2018/12/9.
//  Copyright © 2018年 Kinken_Yuen. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "MyPtrace.h"
#import <dlfcn.h>

int main(int argc, char * argv[]) {
    
    /**
     反调试
     */
    #ifndef PT_DENY_ATTACH
    #define PT_DENY_ATTACH 31
    #endif
    //第一次,通过符号直接调用ptrace
    typedef int (*ptrace_ptr_t)(int _request, pid_t _pid, caddr_t _addr, int _data);
    ptrace(PT_DENY_ATTACH, 0, 0, 0);
    
    //第二次,通过dlopen,dlsym调用
    void *handle = dlopen(0, RTLD_GLOBAL | RTLD_NOW);
    ptrace_ptr_t ptrace_ptr = (ptrace_ptr_t)dlsym(handle, "ptrace");
    ptrace_ptr(PT_DENY_ATTACH,0,0,0);
    
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

Xcode运行工程之后手机上的App直接闪退,Xcode显示了停止运行,反调试成功,当然这是比较初级的反调试,很容易反反调试,日后再深入学习。
Demo

六、总结

  • 理解lldb调试原理,了解debugserver

  • 理解系统调用ptrace,反调试原理

  • 思考如何反反调试,如何增强自己的ptrace反调试?

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容