【安卓逆向】Frida入门与常用备忘-创新互联

【安卓逆向】Frida入门与常用备忘
      • 前置知识
        • 什么是hook?
        • hook的作用
        • 常见的逆向工具
      • Frida使用入门
        • 简介与资料参考备忘
        • 前置环境配置
        • 执行hook
        • 常用hook脚本/API

成都创新互联公司主营阜城网站建设的网络公司,主营网站建设方案,App定制开发,阜城h5微信小程序搭建,阜城网站营销推广欢迎阜城等地区企业咨询前置知识 什么是hook?

hook,译为“钩子”,是指将方法/函数勾住,勾住后我们可以做一些我们想做的事情。实际上我们可以通过一些工具,可以把我们java、native层面的方法/函数调用给“勾住了”,或者直接理解为监听,我们可以监听到调用方法,方法的传参,以及修改方法的返回值等等

hook的作用

了解这些工具,可以帮助我们更好的去定位问题、进行debug,甚至可以对一些app进行破解修改

常见的逆向工具
工具/方法作用java层native层SDK集成是否需要root备注其他
JADX反编译查看源码支持不支持加固的apk需要先脱壳
apktool反编译/回编 APK修改smail码
epic/sandhookapp集成SDK进行代码hook支持支持需要不需要xposed框架,不同的系统API不一致需要适配
xposed插件在集成了xposed框架的安卓环境上进行hook支持不支持不需要需要需要root,其他同上
frida在root的安卓环境下,对java/native 直接进行二进制hook支持支持需要需要需要root环境,python环境
Frida使用入门 简介与资料参考备忘

frida是一款二进制hook框架,支持java/native层hook,需要root环境,因为是二进制内存hook,可以实现直接hook当前进程,无需集成SDK甚至不需要重启进程

  • Frida官网
  • github地址
  • Frida安装教程
  • js脚本API文档
前置环境配置
  • 安装python3及pip环境
  • 使用pip安装frida库与工具
// 安装特定版本 pip install frida==版本号
 pip install frida
 pip install frida-tools
 // 网络不好使用镜像库
 pip install firda -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
 // 查看当前frida版本
 frida --version
  • 若使用模拟器,则进行端口转发(默认端口)
adb forward tcp:27042 tcp:27042
adb forward tcp:27043 tcp:27043
  • 根据当前设备/模拟器架构,官网下载 对应的frida-server,push到于设备/模拟器上的目录并授予可执行权限
# 这里放于 /data/local/tmp
  adb push E:\frida-server /data/local/tmp/frida-server
  # 进入adb shell
  adb shell
  # 以管理员权限访问
  su
  # 进入frida-server目录
  cd /data/local/tmp
  # 提供权限
  chmod 777 frida-server
  # 运行frida-server
  ./frida-server
  • 运行frida-server后保持窗口 此时服务开启,开启新的窗口检测是否成功
# 命令成功输出进程列表
frida-ps -U

# 根据包名连接目标进程
frida -U -f com.xxx.xxx

在这里插入图片描述

执行hook
  • python脚本执行hook,样板代码如下
import frida, sys

def on_message(message, data):
    if message['type'] == 'send':
        print("[*] {0}".format(message['payload']))
    else:
        print(message)

jscode = """
Java.perform(() =>{
  // Function to hook is defined here
  const MainActivity = Java.use('com.example.seccon2015.rock_paper_scissors.MainActivity');

  // Whenever button is clicked
  const onClick = MainActivity.onClick;
  onClick.implementation = function (v) {
    // Show a message to know that the function got called
    send('onClick');

    // Call the original onClick handler
    onClick.call(this, v);

    // Set our values after running the original onClick handler
    this.m.value = 0;
    this.n.value = 1;
    this.cnt.value = 999;

    // Log to the console that it's done, and we should have the flag!
    console.log('Done:' + JSON.stringify(this.cnt));
  };
});
"""

#  pid or package name
process = frida.get_usb_device().attach(13347) 
script = process.create_script(jscode)
script.on('message', on_message)
print('[*] Running CTF')
script.load()
sys.stdin.read())
script = process.create_script(jscode)
script.on('message', on_message)
print('[*] Running CTF')
script.load()
sys.stdin.read()
  • 直接注入js脚本
frida -U [pid|packagename] -l test.js
常用hook脚本/API
  • 测试代码类
public class TestStaticClass {public static int count = 0;
    private static String TAG = "TestStaticClass";

    public static String getCountString(){Log.i(TAG, "call testMethod");
        return "count:" + count;
    }

    public static void addCount(){count++;
    }

    public static String getCountString(int input){return "getCountString:" + input;
    }

    public static String getCountString(int[] input){return "getCountString:" + Arrays.toString(input);
    }

    public void testStack(){Log.i(TAG, "call testStack");
    }

}
  • 获取java类并构建新对象
方法含义其他
$new新建对象
$init构造函数
const JavaString = Java.use('java.lang.String');
var exampleString1 = JavaString.$new('Hello World, this is an example string in Java.');
  • 获取类与静态函数方法调用

    Java.perform(() =>{const TestStaticClass = Java.use("com.hjl.nativetest.TestStaticClass");
     TestStaticClass.count.value = 1; //访问静态变量
     TestStaticClass.addCount();   //hook静态函数直接调用
    });
  • hook方法打印方法值并修改返回值

    Java.perform(() =>{// 获取类
     const TestStaticClass = Java.use("com.hjl.nativetest.TestStaticClass");
     // 获取方法
     const getCountString = TestStaticClass.getCountString;  
     // hook方法
     getCountString.implementation = function () {// 当方法调用时 
      send('call getCountString');
    
      // 调用原方法获取结果
      var result = getCountString.call(this);
    
      console.log("getCountString:" + result);
      // 返回自定义的结果 
      return "hook return String";
    };
    
    // 获取重载方法
    // 基础类型直接填,数组以类似JNI的签名形式如[I ,类型填完整类
    const getCountString2 = TestStaticClass.getCountString.overload('int')
    getCountString2.implementation = function (data) {// 打印原始输入参数
      send('call getCountString:' + data);
    
      // 调用原方法获取结果
      var result = getCountString2.call(this,data);
      console.log("getCountString:" + result);
      // 返回自定义的结果
      return "hook return String";
    };
    });
  • 获取调用栈

    Java.perform(() =>{const TestStaticClass = Java.use("com.hjl.nativetest.TestStaticClass");
    const Exception = Java.use('java.lang.Exception');
    const Log = Java.use('android.util.Log');
    
    const testStack = TestStaticClass.testStack
    testStack.implementation = function () {console.log(stackTraceHere());
    };
    
    function stackTraceHere() {return Log.getStackTraceString(Exception.$new());
    }
    });

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


本文标题:【安卓逆向】Frida入门与常用备忘-创新互联
标题URL:http://myzitong.com/article/cddoee.html