frida 使用记录

frida 一些常用的记录

1.overload 和 overloads 的使用区别

使用overloads

var overloads = SomeClass.someMethod.overloads;
for (var i in overloads) {
    overloads[i].implementation = function() {
        console.log("Hooked: ", arguments);
        return this.overloads[i].apply(this, arguments);
    };
}

** 使用overload**

SomeClass.someMethod.overload('int', 'java.lang.String').implementation = function(intArg, stringArg) {
    console.log("Hooked: ", intArg, stringArg);
    return this.someMethod.overload('int', 'java.lang.String').apply(this, arguments);
};

2.查看当前包名脚本

import frida
import subprocess
subprocess.getoutput("adb forward tcp:27042 tcp:27042")
subprocess.getoutput("adb forward tcp:27043 tcp:27043")
def get_target_pid(app_name):
    rdev = frida.get_remote_device()
    for process in rdev.enumerate_processes():
        print(process.name)
        if process.name == app_name:
            return process.pid
    front_app = rdev.get_frontmost_application()
    print(front_app)
    return None
# com.android.localtransport
#  /data/local/tmp/fs64 -l 0.0.0.0:1234
    # adb forward tcp:1234 tcp:1234
    # frida -H 127.0.0.1:1234 package_name -l hook.js
# target_app_name = "Local News"
# target_app_name = "Translate"

target_pid = get_target_pid("")




3.查看当前安装包

adb shell pm path news.local.latest.newsbreak.free.app

4.frida 常用的两种模式

spawn模式

frida -U -f com.android.localtransport -l hook.js 

attach 附加模式

前台模式
frida -UF  com.android.localtransport -l hook.js 

指定名称
frida -U  com.android.localtransport -l hook.js 指定名称

5.frida-trace 栈跟踪

  frida-trace -UF --runtime=v8 -j '*ud.*!*/isu' -j '*qe*!*/isu'

6.objection 常用的命令

objection -g  包名 explore

常用的指令

Memory 指令
    memory list modules               //枚举当前进程模块
    memory list exports [lib_name]    //查看指定模块的导出函数
    memory list exports libart.so --json /root/libart.json //将结果保存到json文件中
    memory search --string --offsets-only                  //搜索内存

android heap 指令
    //堆内存中搜索指定类的实例, 可以获取该类的实例id
    search instances search instances com.xx.xx.class
     
    //直接调用指定实例下的方法
    android heap execute [ins_id] [func_name]
     
    //自定义frida脚本, 执行实例的方法
    android heap execute [ins_id]

android 指令
    android root disable   //尝试关闭app的root检测
    android root simulate  //尝试模拟root环境
    
    android ui screenshot [image.png]    //截图
    android ui FLAG_SECURE false         //设置FLAG_SECURE权限

内存漫游
    android hooking list classes    //列出内存中所有的类
     
    //在内存中所有已加载的类中搜索包含特定关键词的类
    android hooking search classes [search_name] 
     
    //在内存中所有已加载的方法中搜索包含特定关键词的方法
    android hooking search methods [search_name] 
     
    //直接生成hook代码
    android hooking generate simple [class_name]

hook 方式
    /*
        hook指定方法, 如果有重载会hook所有重载,如果有疑问可以看
        --dump-args : 打印参数
        --dump-backtrace : 打印调用栈
        --dump-return : 打印返回值
    */
    android hooking watch class_method com.xxx.xxx.methodName --dump-args --dump-backtrace --dump-return
     
    //hook指定类, 会打印该类下的所有调用
    android hooking watch class com.xxx.xxx
     
    //设置返回值(只支持bool类型)
    android hooking set return_value com.xxx.xxx.methodName false

Spawn 方式 Hook
    objection -g packageName explore --startup-command '[obejection_command]'

activity 和 service 操作
    android hooking list activities                   //枚举activity
    android intent launch_activity [activity_class]   //启动activity
    android hooking list services                     //枚举services
    android intent launch_service [services_class]    //启动services

任务管理器
    jobs list            // 查看任务列表
    jobs kill [task_id]  // 关闭任务

关闭 app 的 ssl 校验
    android sslpinning disable

监控系统剪贴板
    // 获取Android剪贴板服务上的句柄并每5秒轮询一次用于数据。 
    // 如果发现新数据,与之前的调查不同,则该数据将被转储到屏幕上。
    help android  clipboard

执行命令行
    help android shell_exec [command]

常用算法hook

		md5 hook
        var md = Java.use('java.security.MessageDigest');
        // md.getInstance.overload('java.lang.String', 'java.lang.String').implementation = function (a, b) {
        //     // showStacks();
        //     console.log("======================================");
        //     console.log("算法名1:" + a);
        //     return this.getInstance(a, b);
        // }
        md.getInstance.overload('java.lang.String').implementation = function (a) {
            // showStacks();
            console.log("================start2======================");
            console.log("算法名2:" + a);
            console.log("================end2======================");
            return this.getInstance(a);

        }
        md.digest.overload().implementation = function () {
            //showStacks();
            console.log("======================================");
            var result = this.digest();
            console.log("digest结果5:" + bytesToHex(result));
            return result;
        }
        md.digest.overload('[B').implementation = function (a) {
            showStacks();
            console.log("=================start6=====================");
            console.log("digest参数6:" + bytesToString(a));
            var result = this.digest(a);
            console.log("digest结果7:" + bytesToHex(result));
            console.log("=================end6=====================");
            return result;
        }

        // md.update.overload('[B').implementation = function (a) {
        //     //showStacks();
        //     console.log("======================================");
        //     console.log("update3:" + bytesToString(a))
        //     return this.update(a);
        // }
        // md.update.overload('[B', 'int', 'int').implementation = function (a, b, c) {
        //     //showStacks();
        //     console.log("======================================");
        //     console.log("update4:" + bytesToString(a) + "|" + b + "|" + c);
        //     return this.update(a, b, c);
        // }

hook map

  var TreeMap = Java.use('java.util.TreeMap');
    var Map = Java.use("java.util.Map");

    TreeMap.put.implementation = function (key,value) {
        if(key=="data"){
            console.log(key,value);
        }
        var res = this.put(key,value);
        return res;
    }

Hook StringBuilder

  var StringBuilder = Java.use("java.lang.StringBuilder");
    
    StringBuilder.toString.implementation = function () {
        var res = this.toString();
        console.log(res); 
        return res;
    }

Hook base64

       var Base64Class = Java.use("android.util.Base64");
        Base64Class.encodeToString.overload("[B", "int").implementation = function(a,b){
            var resault = this.encodeToString(a,b);
            console.log(">>> Base64 " + resault);
            if(resault.length <= 20){
                var stackAdd = threadinstance.currentThread().getStackTrace();
                console.log("resault stackAdd is:" + Where(stack));
            }
            return rc;
        }

okhttp3 hook拦截器 - 所有注册拦截器

   var Builder = Java.use('okhttp3.OkHttpClient$Builder');

    Builder.addInterceptor.implementation = function (inter) {
        //console.log("实例化:");

        console.log(JSON.stringify(inter) );
        //console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
        return this.addInterceptor(inter);
    };


    var a = Java.use("cn.shihuo.modulelib.startup.core.c.a");
    a.intercept.implementation = function (chain) {
        var req = chain.request();
                
        var httpUrl = req.url().toString();
        if( httpUrl.indexOf("https://sh-gateway.shihuo.cn/v4/services/sh-goodsapi/app_swoole_shoe/preload/single") != -1 ){
            console.log('执行前',httpUrl);    
        }
        
        var res = this.intercept(chain);
        return res;
    }




	    var a8 = Java.use('cn.shihuo.modulelib.utils.f1.a$a');
    a8.intercept.implementation = function (chain) {
        var request = chain.request();
        var urlString = request.url().toString();

        if(urlString.indexOf("https://sh-gateway.shihuo.cn/v4/services/sh-goodsapi/app_swoole_zone/getAttributes/v")!= -1){
            console.log("拦截器8-->", urlString);
        }


        var response = chain.proceed(request);
        return response;
        //console.log("拦截器",this.b.value);
        //var res = this.intercept(chain);
        //console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
        //return res;
    };
	

java to string

  function mapToString(map) {
            var Map = Java.use('java.util.Map');
            var Set = Java.use('java.util.Set');
            var Iterator = Java.use('java.util.Iterator');
            var result = "{";
            var keySet = map.keySet();
            var it = keySet.iterator();
            while (it.hasNext()) {
                var key = it.next();
                var value = map.get(key);
                result += "\"" + key.toString() + "\": \"" + value.toString() + "\", ";
            }
            // Remove trailing comma and space, if any
            if (result.length > 1) {
                result = result.substring(0, result.length - 2);
            }
            result += "}";
            return result;
        }

        function mapToJson(map) {
            if (map === null || typeof map.entrySet !== 'function') {
                console.error('Invalid map object:', map);
                return '{}';
            }
            var HashMap = Java.use('java.util.HashMap');
            var Iterator = Java.use('java.util.Iterator');
            var JSONObject = Java.use('org.json.JSONObject');

            var json = JSONObject.$new();
            var castedMap = Java.cast(map, HashMap);
            var iterator = castedMap.entrySet().iterator();

            while (iterator.hasNext()) {
                var entry = iterator.next();
                json.put(entry.getKey().toString(), entry.getValue().toString());
            }

            return json.toString();
        };

格式化打印堆栈

    function showStacks() {
        var Exception = Java.use("java.lang.Exception");
        var ins = Exception.$new("Exception");
        var straces = ins.getStackTrace();

        if (undefined == straces || null == straces) {
            return;
        }

        console.log("============================= Stack strat=======================");
        console.log("");

        for (var i = 0; i < straces.length; i++) {
            var str = "   " + straces[i].toString();
            console.log(str);
        }
        console.log("============================= Stack end=======================\r\n");
        Exception.$dispose();
    }

调用非实例方法

     Java.choose('com.apm.insight.k.j', {
                onMatch: function (instance) {
                    // 对于每一个找到的实例,调用其 sayHello 方法
                    console.log(111)
                    var res = instance.a();
        
                    console.log("aid:",res);
                },
                onComplete: function () {
                    console.log('Enumeration complete.');
                }
            });

frida dump脱壳

请运行需要脱壳的APK
frida-dexdump -FU -d -o .

frida-trace md5分析,里面的 /* TID 0x3fc8 */ 代表同一个线程

frida-trace -UF  -j 'java.security.MessageDigest!digest'
{
  /**
   * Called synchronously when about to call MessageDigest.digest.
   *
   * @this {object} - The Java class or instance.
   * @param {function} log - Call this function with a string to be presented to the user.
   * @param {array} args - Java method arguments.
   * @param {object} state - Object allowing you to keep state across function calls.
   */
  onEnter(log, args, state) {
        //将byte[]转成String的方法
        function bytesToString(arr) {
          var str = '';
          arr = new Uint8Array(arr);
          for (var i in arr) {
              str += String.fromCharCode(arr[i]);
          }
          return str;
      }

    if (args.length > 0 ) {
      if (args.length == 1) {
        log(`arg0:}`, bytesToString(args[0]));
      }
    }
    log(`MessageDigest.digest(${args.map(JSON.stringify).join(', ')})`);
  },

  /**
   * Called synchronously when about to return from MessageDigest.digest.
   *
   * See onEnter for details.
   *
   * @this {object} - The Java class or instance.
   * @param {function} log - Call this function with a string to be presented to the user.
   * @param {NativePointer} retval - Return value.
   * @param {object} state - Object allowing you to keep state across function calls.
   */
  onLeave(log, retval, state) {
    function bytesToHex(arr) {
      var str = '';
      var k, j;
      for (var i = 0; i < arr.length; i++) {
          k = arr[i];
          j = k;
          if (k < 0) {
              j = k + 256;
          }
          if (j < 16) {
              str += "0";
          }
          str += j.toString(16);
      }
      return str;
  }
    if (retval !== undefined) {
      var md5 = bytesToHex(retval);
      log(`<= ${JSON.stringify(retval)},md5: ${md5} `);
    }
  }
}

类型重载

overload 函数中来指定方法重载:

基本类型:

boolean: 布尔值,true 或 false
byte: 8位整数
char: 字符
short: 16位整数
int: 32位整数
long: 64位整数
float: 32位浮点数
double: 64位浮点数
对象类型:

java.lang.String: 字符串
java.lang.Object: 对象
java.lang.Integer: 整数对象
java.lang.Long: 长整数对象
java.lang.Boolean: 布尔对象
...以及其他任何 Java 类
数组类型:

[B: byte 数组
[C: char 数组
[D: double 数组
[F: float 数组
[I: int 数组
[J: long 数组
[S: short 数组
[Z: boolean 数组
[Ljava.lang.String;: 字符串数组
[Ljava.lang.Object;: 对象数组

调用加载dex

function testDex(){
    var ddex = Java.openClassFile("/data/local/tmp/Md5Util.dex");
    Java.perform(function () {
        ddex.load();
        var Md5Util = Java.use("com.example.jnitest.Md5Util");
       var res =  Md5Util.reverseToSendA('V@]EAASB\u0012WZF\u0012e,a$7(&am2(3.\u0003');
       console.log("结果:",res);
    });

}

java打包成dex

javac -source 1.8 -target 1.8 Md5Util.java
mkdir -p com/example/jnitest
mv Md5Util.class com/example/jnitest/
jar cf Md5Util.jar com
/Users/admin/Library/Android/sdk/build-tools/30.0.3/dx --dex --output=Md5Util.dex Md5Util.jar

查看apk 支持的架构

/Users/admin/Library/Android/sdk/build-tools/30.0.3/aapt dump badging /Users/admin/go/reverse/kanxue/课件资料/3月-Frida高级逆向/课时3/xman.apk | grep native-code

查看手机架构

 adb shell getprop ro.product.cpu.abi

其他


https://blog.csdn.net/weixin_38927522/article/details/127120012

mac ida64 打开报错的解决办法

sudo xattr -rd com.apple.quarantine /Users/admin/go/reverse/tool/IDA\ Pro\ 7.0/ida64.app

数据类型

frida 使用记录_第1张图片

你可能感兴趣的:(android,frida)