Android native反调试方式及使用IDA绕过反调试

2023-05-16

    0x00

     为了避免我们的so文件被动态分析,我们通常在so中加入一些反调试代码,常见的Android native反调试方法有以下几种。

     1、直接调用ptrace(PTRACE_TRACEME, 0, 0, 0),参考Android Native反调试。

     2、根据上面说的/proc/$pid/status中TracerPid行显示调试程序的pid的原理, 可以写一个方法检查下这个值, 如果!=0就退出程序。参考Android Native反调试,用JNI实现APK的反调试。

     3、检查代码执行的间隔时间,参考Android应用方法隐藏及反调试技术浅析的0×03反调试初探。

     4、检测手机上的一些硬件信息,判断是否在调试器中,参考Android应用方法隐藏及反调试技术浅析0×03反调试初探。


   0x01

    那么我们如何过掉这些反调试呢?

    我们以阿里比赛第二题为例,参考安卓动态调试七种武器之孔雀翎 – Ida Pro。

    我们讲解两种方式:

    1、Ida Patch so

    2、Ida动态修改内存数据和寄存器数值

  

    我们首先讲解Ida Patch so,有几处都可以patch。我们从易到难依次讲解。

    第一处:

    我们在JNI_ONLOAD下断点,如下图:


     依次单步执行到BLX R7


    我们发现当执行完这步后,我们的ida就退出了,说明反调试代码是从这个入口进入执行的。那么我们只要把这个入口给NOP掉,就可以绕过反调试了。

    Patch so就是修改so中的二进制代码,然后再重新签名生成新的apk。Patch so,需要修改的本地so中的代码,而不是内存中的,所以我们需要通过上图内存中指令地址减去so在内存中的基地址来获取这条指令在本地so文件中的偏移。那么so在内存中的基地址怎么获取呢?按Crtl+s。


     我们看到libcrackme.so的基地址是AB732000,用BLX R7的地址AB733C58减去AB732000,等于1C58。

     然后我们双开ida,在另一个ida中打开libcrackme.so,按G,然后输入1C58,果然我们调到了BLX R7的位置,如下图:


    下面就要把这行代码NOP,可以修改为00 00 00 00,也可以修改为00 00 A0 E1。


    修改后点击右键,applay change。然后重新签名生成apk,再次运行apk,ida调试时就没有反调试的干扰了。


    第二处:

    我们按F7进入BLX R7的内部执行,如下图:


    是创建了一个线程去执行反调试,这里有个小技巧,如果我们想回到刚才的函数BLX R7,怎么办呢?选择寄存器LR,然后点击右键选择Jump即可,同理选择PC是跳到当前的位置。


    这个线程执行的函数体是sub_AB7336A4,如下图:


    sub_AB7336A4函数体如下:


   这个方法循环执行sub_AB73330C。我们进入sub_AB73330C,怀疑这里就是真正检查是否处于调试状态的地方,但是代码经过了严重的混淆,所以找不到反调试的代码。

   那怎么办呢?在0x00中我们谈到了常见的反调试代码,最常见的是第二种方式,第二种方式检查的过程中会调用fopen,所以我们在libc的fopen方法下断点,来是哪个函数调用的fopen,基本上就可以断定这个函数是反调试代码。

   

   首先我们需要找到fopen的位置,按Alt+T,然后输入fopen关键字,如下图:


    找到fopen后,代码是这样的:


   此时按P,就可以变成代码形式。如下图,在fopen处下断点。

   点击F9,继续运行,我们看到程序停在fopen处,此时LR就是刚刚我们谈到的sub_AB73330C,如下图:


   所以我们可以确定sub_AB73330C就是进行反调试的代码。我们可以看到这个函数是被sub_AB7336A4调用的。


    点击右侧的CODE XREF:sub_AB7336A4就能进入到调用sub_AB73330C的地方。在sub_AB7336A4函数上按F5,就能看到对应的C语言代码。如下:


    可见程序是在sub_AB73330C循环检测是否被反调试的。

    此时我们可以用和第一处一样的方式,找到本地so中对应的方法,然后Patch so,Nop掉对应的方法,然后重新签名,重新运行。


    第三处:

    其实第三处和第二处原理是一样的,只不过这里不使用Nop了,sub_AB73330C开始和结束的汇编代码如下:

    开始时:



    结束时:


     所以我们可以把AB733310的代码修改为AB73363C处的代码,不执行任何操作,直接返回。


   0x02

    Ida动态修改内存数据和寄存器数值

    我们看到反调试方法第二点,代码如下:

void be_attached_check()
{
    try
    {
        const int bufsize = 1024;
        char filename[bufsize];
        char line[bufsize];
        int pid = getpid();
        sprintf(filename, "/proc/%d/status", pid);
        FILE* fd = fopen(filename, "r");
        if (fd != nullptr)
        {
            while (fgets(line, bufsize, fd))
            {
                if (strncmp(line, "TracerPid", 9) == 0)
                {
                    int statue = atoi(&line[10]);
                    LOGD("%s", line);
                    if (statue != 0)
                    {
                        LOGD("be attached !! kill %d", pid);
                        fclose(fd);
                        int ret = kill(pid, SIGKILL);
                    }
                    break;
                }
            }
            fclose(fd);
        } else
        {
            LOGD("open %s fail...", filename);
        }
    } catch (...)
    {

    }

}
     我们发现该程序会用fopen ()打开/proc/[pid]/status这个文件,随后会用fgets()和strcmp()来比较,于是我们在 strcmp()处下个断点,然后让hex view的数据与R0同步。每次点击继续,我们都会看到strstr传入的参数。当传入的参数变为TracerPid:XXXX的时候我们停一下。因为在正常情况下,TracerPid的值应该是0。但是当被调试的时候就会变成调试器的pid。

    我们在strcmp下断点:


    程序会在此处断下,当我们发现R0地址中的内容为TracerPid:XXXX时,我们停一下,如下图:


    R0的里面存的地址是AB731B25,里面的内容为,如下图:


   我们可以通过修改内存值的方式来过掉这一次反调试。


   把TracerPid改为0,如下图:


    然后点击Apply changes。这样就可以过掉这次反调试。我们在前面也看到了,程序是在一个循环中进行反调试检查,所以这样的方试只是过了其中一次反调试。

   不推荐使用这种方式,最好使用Patch So的方式。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android native反调试方式及使用IDA绕过反调试 的相关文章

  • android studio 最新3.0 kotlin与databinding 结合使用报错。

    最近android studio 3 0更新 xff0c 迫不及待将项目中的代码向kotlin转 其中转到有databinding的时候遇到报错 xff1a Unresolved reference databinding 找到网上解决办法
  • AS--›Android Studio内存大小设置和插件推荐(2021-1-14更新)

    调整AS的占用内存 多开工程毫无压力 AS 3 5 的版本 已经支持通过设置界面修改内存大小了 但是 旧方法依旧有效 文章目录 Windows修改方法MAC修改方法插件推荐 ignore A Search with GithubTransl
  • android Camera预览界面拉伸问题解决

    问题现象 项目中的扫一扫界面打开以后 xff0c 扫描二维码的界面显示的二维码被拉伸 xff0c 图片如下 xff1a 问题原因 通常 xff0c 拍照预览页面的视图拉伸主要与下面两个因素有关 xff1a Surfaceview的大小Cam
  • 什么是 AOP,AOP 的作用是什么?

    分析 amp 回答 AOP的介绍 AOP全称 xff08 Aspect Oriented Programming xff09 面向切片编程的简称 AOP面向方面编程基于IoC xff0c 是对OOP的有益补充 xff1b AOP利用一种称为
  • Ubuntu图形界面卡死的解决方法

    转到字符界面 xff1a Ctrl 43 Alt 43 F1 查看进程 xff1a ps t tty7 找到Xorg进程的PID号xxx xff0c 如992 杀死进程Xorg xff1a kill xxx xff08 这里是kill 99
  • 笔记本电脑电源指示灯亮但是黑屏开不了机(或者成功开机之后发现很卡顿)的解决方法

    问题描述 本人电脑是联想拯救者Y7000P xff0c 性能如下 近期遇到一个问题 xff0c 笔记本电脑开机的之后 xff0c 突然出现卡顿 xff0c 不管是打开浏览器还是打开软件 xff0c 都要等上几秒钟 xff0c 连刷新都要等一
  • windows下的WSL开发环境配置以及相关工具、插件

    最近在自己的X1上捣鼓Django框架的编程 xff0c windows环境使用起来确实让人痛苦 xff0c 因此决定还是在Linux系统下进行Django框架的编程 xff0c 跟朋友交流了一下 xff0c 最终敲定了以下方案并把中间使用
  • 最全spring框架工作流程

    Spring执行流程 xff1a 用户发起请求到前端控制器 xff08 DispatcherServlet xff09 xff0c 该控制器会过滤出哪些请求可以访问Servlet 哪些不能访问 就是url pattern的作用 xff0c
  • python多线程爬虫教学,清晰易懂。

    首先需要知道什么是多线程 xff0c 多线程的作用 首先举个例子 xff0c 并发和并行 xff1a 并发 xff1a 并发 xff0c 在操作系统中 xff0c 是指一个时间段中有几个程序都处于已启动运行到运行完毕之间 xff0c 且这几
  • ubuntu 下ethtool安装

    1 xff0c 下载安装包 xff1a ethtool 2 6 37 tar xff0c 将其放入自己的路径下 xff0c 解压 xff1a tar xvf ethtool 2 6 37 tar 2 cd ethtool 2 6 37 执行
  • 第四章_表达式_4.9 sizeof 运算符

    4 9 sizeof 运算符 4 9 sizeof 运算符 4 9 sizeof 运算符 sizeof运算符返回一条表达式或一个类型名字所占的字节数 sizeof运算符满足右结合律 xff0c 其所得的值是一个size t类型的常量表达式
  • 初探ViewBinding

    视图访问的方式有常用的findViewById xff0c ButterKnife等多种方式 xff0c 这些方式的各方面对比如下 如上图所示 xff0c 在简明 编译安全和编译速度上都各有优势 xff0c 那么有没有一种方式可以一石 34
  • Kotlin--›Android 超轻,超好用,超简洁,超超超级RecyclerView分割线ItemDecoration封装

    需求分析 如图所示的 101 共2人 这一行 顶部有 一块白色区域 可以当做是分割线101 共2人 这一行 底部有一个很细的分割线 差不多撑满了一行人物信息 这一行 首次出现时 只有底部有分割线 而且还是 非撑满一行的效果人物信息 这一行
  • Linux系统网络配置详解

    1 当一台Linux虚拟机刚创建完成是无法上网 xff0c 所以需要我们去配置网络 2 右击虚拟界面 xff0c 点击打开终端 3 查看虚拟机的网关 xff08 1 xff09 点击VMware Workstation左上角的编辑 xff0
  • Linux的sed命令详解大全

    Linux的sed命令详解大全 一 sed命令介绍二 sed 的运行模式三 sed的相关选项四 sed基本用法1 sed语法2 sed的查看功能 查看passwd文件的第5到第8行内容 查看passwd文件中以roo开头的行 忽略大小写 x
  • Linux下shell脚本之双色球摇号脚本

    Linux下shell脚本之双色球摇号脚本 一 脚本要求二 脚本内容三 运行脚本 一 脚本要求 二 脚本内容 三 运行脚本 一 脚本要求 1 编写脚本Lottery sh 模拟摇号过程 2 6位数红色球随机生成 xff0c 不能重复 xff
  • 华为云计算基础之Fusion Compute介绍

    华为云计算基础之Fusion Compute介绍 一 Fusion compute 1 FusionCompute解释 2 FusionCompute特性 3 华为FusionSphere 4 华为云计算各组件关系 5 华为fusionco
  • 【Zabbix实战之部署篇】kubernetes集群搭建Zabbix监控平台

    kubernetes集群搭建Zabbix监控平台 一 zabbix介绍 1 zabbix简介 2 zabbix特点 3 zabbix的主要功能 4 zabbix架构图 二 检查本地k8s环境 1 检查系统pod运行状态 2 检查node节点
  • Linux系统之时间同步方法

    Linux系统之时间同步方法 一 使用NTP服务时间同步1 安装ntp2 启动ntp服务3 查看ntp服务4 修改ntp conf文件5 重启服务6 检查同步状态 二 使用ntpdate同步1 使用ntpd命令同步2 查看时间 三 处理nt
  • 猿创征文 | 国产数据库之openGauss的单机主备部署及快速入门

    猿创征文 国产数据库之openGauss的单机主备部署及快速入门 一 openGauss介绍 1 openGauss简介 2 openGauss特点 3 openGauss的逻辑架构图 二 环境检查 1 节点规划 2 操作系统版本 三 安装

随机推荐