简介

Frida是一个动态代码插桩框架,可以将JavaScript或一些自定义的函数库注入到现有的正在运行的二进制文件中,可以注入的系统有Windows,macOS,GNU / Linux,iOS,Android和QNX上的本机应用程序,注入后可以进行进行一些额外的操作:

  • 访问进程内存,可以通过该方式打印一些特有的加密数据,比如一些加盐算法的salt
  • 在应用程序运行时覆盖函数,执行一些hack逻辑
  • 从导入的类调用函数
  • 在堆上查找对象实例并使用
  • Hook、跟踪和拦截函数等

    frida提供的一些工具

  1. firda-ps ```bash

    通过 USB 连接 并列出所有正在运行的进程

    $ frida-ps -U

列出所有正在运行的app

$ frida-ps -Ua

列出所有安装的app

$ frida-ps -Uai

连接到指定的设备上

$ frida-ps -D 0216027d1d6d3a03

  1. 2. frida-cli
  2. ```bash
  3. # 通过use连接并启动Chorme
  4. $ frida -U Chorme
  5. # 通过frida连接到本机正在运行的QQ应用上
  6. $ frida QQ
  7. ____
  8. / _ | Frida 12.4.8 - A world-class dynamic instrumentation toolkit
  9. | (_| |
  10. > _ | Commands:
  11. /_/ |_| help -> Displays the help system
  12. . . . . object? -> Display information about 'object'
  13. . . . . exit/quit -> Exit
  14. . . . .
  15. . . . . More info at http://www.frida.re/docs/home/
  16. [Local::QQ]->
  17. # 通过frida连接到本机正在运行的QQ应用上并运行hack.js
  18. $ frida QQ -l hack.js
  19. # 通过usb连接到手机连接到正在运行的com.example.test应用上并运行hack.js
  20. $ frida -u com.example.test -l hack.js
  21. # 通过usb连接到手机连接到正在运行的com.example.test应用上并运行hack.js,debug代表以调试模式运行应用
  22. $ frida -u com.example.test -l hack.js --debug
  23. # 通过usb连接到手机连接,启动名为com.example.test的应用,并运行hack.js
  24. $ frida -u -f com.example.test -l hack.js --no-pause
  1. firda-trace ```bash

    打印所有正则匹配到的recv和send的接口调用,并打印当前调用到的堆栈信息

    $ frida-trace -i “recv“ -i “send“ QQ

打印出QQ上所有用object-c写的drawRect开头的函数,并打印当前调用到的堆栈信息

$ frida-trace -m “-[NSView drawRect:]” QQ

启动手机QQ并打印内存中所有正则匹配到的libcommonCrypto*的接口调用

$ frida-trace -U -f com.tencent.mobileqq -I “libcommonCrypto*”

  1. 4. frida-kill
  2. ```bash
  3. # 连接手机并结束某个pid的进程
  4. $ frida-kill -D 1d07b5f6a7a72552aca8ab0e6b706f3f3958f63e 5029

frida提供的Java接口

  • Java.available 判断当前java虚拟机是否成功加载

    1. if(Java.available){
    2. Java.perform(function () {
    3. //do something
    4. }
    5. }else{
    6. console.log("Error Jvm not init")
    7. }
  • Java.enumerateLoadedClasses(callbacks) 枚举当前加载的所有类并执行回调

    1. Java.enumerateLoadedClasses(
    2. {
    3. // 类被加载时回调,会传入类的完成类名,可以通过Java.use()获取类,并通过类的函数名来hack函数,所有该类的实例都会被注入hack的代码
    4. "onMatch": function(className){
    5. console.log(className)
    6. var classNeedHook=""
    7. if(className==classNeedHook){
    8. var Cls=Java.use(className);
    9. Cls.function.implementation = function () {
    10. console.log("you have been hacked!!")
    11. };
    12. }
    13. },
    14. // 所有类都被加载完成时调用,可以在这里执行类加载之后的hack操作
    15. "onComplete":function(){}
    16. }
    17. )
  • Java.use(className) 通过类名获取类对象的JavaScript包装,可以通过$new来新建对象,通过$dispose来销毁对象,也可以进行函数的hack操作,如上

    1. Java.choose(className, callbacks)
    2. Java.cast(handle, klass)
  • Java.scheduleOnMainThread(fn),在主线程中执行函数,可以用于执行ui操作

  • Java.choose(className, callbacks)扫描并枚举堆栈中类的实例,对扫描出的实例都会执行回调,该方式可以调用类的private函数

    1. Java.choose("com.example.test.MainActivity" , {
    2. onMatch : function(instance){ //该类有多少个实例,该回调就会被触发多少次
    3. console.log("Found instance: "+instance);
    4. console.log("Result of func: " + instance.func());
    5. },
    6. onComplete:function(){}
    7. });
  • Java.cast(handle, klass)把对象实例转换成指定的类型,可以配合Java.choose使用

    1. var StringClass=Java.use("java.lang.String");
    2. var NewTypeClass=Java.cast(variable,StringClass);
  • 通过javaScriptWrapper调用函数时,需要注意重载的问题 ``` var MainActivity =Java.use(“com.example.MainActivity”) MainActivity.test.overload(“java.lang.String”).implementation = function(s) { console.log(s) }

MainActivity.test.overload(“int”).implementation = function(i) { console.log(i) }

  1. - 类的构造函数,新建对象

var utilCls =Java.use(“com.exapmle.Utils”) utilCls.$init.implementation=function(){ consloe.log(“hook Constructor”); } var util=utilCls.$new(); console.log(util.toString());

  1. <a name="Mcc4f"></a>
  2. # 使用
  3. 以下操作均在mac+android系统上进行
  4. <a name="Bcd3W"></a>
  5. ## 安装frida-server并启动
  6. 1. 在本机上安装frida
  7. ```bash
  8. # 最新的frida需要python3以上的支持
  9. pip install frida
  10. pip install frida-tools
  1. 下载对应版本的frida-server文件,这里下载的是最新版frida-server-12.4.8-android-arm64.xz,在安卓设备上安装并启动frida-server

    1. $ adb push frida-server-10.0.1-android-arm /data/local/tmp/frida-server
    2. $ adb shell
    3. $ adb push frida-server /data/local/tmp/
    4. $ adb shell su #如果有root权限的话
    5. $ adb shell "chmod 755 /data/local/tmp/frida-server"
    6. $ adb shell "/data/local/tmp/frida-server &"
  2. mac系统下查看frida是否成功启动,查看usb连接设备中运行的进程 ```bash $ frida-ps -U PID Name


698 adbd 2113 android.process.acore 2247 android.process.media …..

  1. 然后就可以开做上面可以做的事情,enjoy it
  2. <a name="VIcK4"></a>
  3. ## 编写脚本(这里只写个demo举例,实际的hack可能需要配合源码服用
  4. 先来一个简单的安卓代码
  5. ```java
  6. public class MainActivity extends AppCompatActivity {
  7. private TextView textView;
  8. @Override
  9. protected void onCreate(Bundle savedInstanceState) {
  10. super.onCreate(savedInstanceState);
  11. setContentView(R.layout.activity_main);
  12. setText("今天天气真不错");
  13. }
  14. private boolean setText(String text){
  15. textView =findViewById(R.id.tv);
  16. textView.setText("今天天气真不错");
  17. }
  18. }

新建一个文件,叫做hack.js

  1. if(Java.available){
  2. setTimeout(function() { //防止Frida超时导致异常
  3. Java.perform(function(){
  4. var MainActivity = Java.use("com.example.test.MainActivity");
  5. MainActivity.setText.implementation=function(text){
  6. console.log(text);
  7. this.setText("you hace been hacked!!!")
  8. }
  9. }),0
  10. }
  11. }

执行命令

  1. frida -u -f com.example.test -l hack.js

就可以看到文本已经变成了you hace been hacked!!!

对App的一些hack思路(只有思路,不同app方式可能不同

一些在对接口做了加密的app,会在本地存储一些加盐算法的salt,一般分为两类
第一类 直接在java层存放salt和加密算法的的,嗯,怎么说呢,这类app简直就是大门敞开型的,直接反编译+跟踪查看代码即可
第二类 将加密算法存在ndk层,无法通过反编译直接取得加密算法的,可用以下方式

  1. 抓包(http和https的抓包自行google),获取加密后的密钥关键字
  2. 反编译app,一般在network相关的包中可以看到这个sign的生成方式
  3. 跟踪下去,直到ndk层,这时的代码已经没发再阅读和跟踪,但是可以直到大概的方法名
  4. 使用ida进行反汇编,找到上述函数所在的so文件,可以进行检索上面找到的函数名
  5. 继续查找相关的地址调用,找到相应的函数,如果salt写在里面,可以直接拿到;一般salt是在外面通过参数传进来的,这时候需要通过frida来打印堆栈信息获取
  6. 通过frida编写脚本,查找上述函数,输出函数内部调用信息
  7. 获取salt和算法,然后,嘿嘿嘿~