逆向-hook-inline(frida)

搬砖

frida编译

1.原始frida编译

编译先看:https://frida.re/docs/building/

编译环境补充

  • sudo apt-get install build-essential curl git lib32stdc++-9-dev
    libc6-dev-i386 nodejs npm python3-dev python3-pip

不出意外的话应该会报错

问题一:没有ANDROID_NDK_ROOT

解决办法:我是从Android studio中Android sdk选项卡中安装指定报错版本的ndk,然后配置ANDROID_NDK_ROOT环境变量

  • export ANDROID_NDK_ROOT=/home/cozy/Android/Sdk/ndk/25.2.9519653
  • export PATH=$ANDROID_NDK_ROOT:$PATH

问题二:没有node环境

虽然安装了nodejs,但是可能版本不对也会提示编译失败

  1. npm doctor #查看项目使用的nodejs版本
  2. curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash #使用nvm来安装nodejs
  3. nvm install v20.11.1 #我这里用的是v20.11.1

2.定制库hluwa

在frida源码同级目录下,clone hluwa代码.当然这里只适配到frida 15.0.4

  1. git clone https://github.com/hluwa/Patchs.git
  2. git checkout 15.0.4
  3. git submodule update –recursive
  4. git am ../../Patchs/strongR-frida/frida-core/*.patch
  5. make core-android-arm64

我本人应为下载 frida==16.2.1, Patchs脚本只支持到15.0.4,所以就手动复制,顺便熟悉下魔改点

3. frida检测点

简单检测

一般检查主要是通过frida关键词特征

  1. 查看/proc/pid/maps,查看这个文件中frida关键词
  2. 读取/proc/pid/maps映射内存,从内存中检测“frida:rpc”类似关键词,不过内存中之只搜索到frida-agent
  3. 查看/proc/self/task/pid/status, 从对现场描述文件中查找frida相关进程,如 gmain gum-js-loop pool-frida 线程名称
  4. 读取readlink /proc/self/fd/XXX,从frida通过管道建立双向通信角度检测frida
  5. 检查端口和tmp目录

高级检查

我个人认为高级点检查点如下:

  1. 对核心native文件checksum检查,主要是对与maps文件中存在 r*xp 权限的so文件做checksum检查(注入文件前后checksum大小不一样)
  2. [] 从内核角度对linehook检测,可先看第四点

4. frida-gum内核学习

Frida inline hook 的执行流程

5. anti-frida

  • []直接干掉检测线程
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    // 先找到__pthread_start,再patch 
    // arm64-android14
    function hook_pthread_create() {
    var libc = Process.findModuleByName("libc.so");
    var addr_pthread_create = libc.base.add(0xCB5D8); // __pthread_start
    Interceptor.attach(addr_pthread_create, {
    onEnter: function (args) {
    var enter = args[0].add(12 * 8).readPointer() console.log("thread start:" + addr2nice(enter))
    }
    });
    }

    function patch_func_nop(addr) { // C0 03 5F D6
    Memory.patchCode(addr, 4, function (code) { code.writeByteArray([0xC0, 0x03, 0x5F, 0xD6]);
    }); }
    patch_func_nop(base.add(0x44dd4));
  1. []直接干掉检测线程
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26

    function hook_pthread_create() {
    console.log("libmsaoaidsec.so --- " + Process.findModuleByName("libmsaoaidsec.so").base)
    Interceptor.attach(Module.findExportByName("libc.so", "pthread_create"), {
    onEnter(args) {
    let func_addr = args[2]
    console.log("The thread function address is " + func_addr)
    }
    })
    }

    function nop(addr) {
    Memory.patchCode(ptr(addr), 4, code => {
    const cw = new ThumbWriter(code, { pc: ptr(addr) });
    cw.putNop();
    cw.putNop();
    cw.flush();
    });
    }

    function bypass(){
    let module = Process.findModuleByName("libmsaoaidsec.so")
    nop(module.base.add(0x10AE4))
    nop(module.base.add(0x113F8))
    }