首页
社区
课程
招聘
[原创]frida-server运行报错问题的解决
发表于: 2023-4-4 22:31 31419

[原创]frida-server运行报错问题的解决

2023-4-4 22:31
31419

刚刚开始学Android逆向,发现Frida是个好东西,于是赶紧下载研究一番。
下载源码编译,切换到最新版16.0.11, 编译之前注意先更新nodejs

然后执行

就可以成功生成frida-server以及frida相关tools,于是push到手机上执行

报错了...额,继续往下试试

把手机上的名为com.example.myapplication的demo app放到前台,然后注入一个helloword级别的js

然后执行

咳,出师不利,不过反正我也是做c++开发的,虽然不懂javascript, 连蒙带猜也能看个差不多,那就研究研究报错原因吧。

从现有信息来看,第一怀疑对象应该是那个报错"Error: Java API not available", 也指明了报错位置at _checkAvailable (frida/nodemodules/frida-java-bridge/index.js:298:1) at .perform (frida/node_modules/frida-java-bridge/index.js:203:1)\n ,那就在源码里搜索下。
发现这个index.js位于build/tmp-android-arm64/frida-gum/bindings/gumjs/node_modules/frida-java-bridge目录,
然后看下perform实现

这个函数第一行就是_checkAvailable,跟进去看看

果然报错就是在这里,那么关键的判断就是available了,再跳过去看看

那么只有一种可能,就是getApi()返回为null,再跟进去看看,这个getApi的有几层跳转如下

看代码的意思是进程内没找到加载的libart.so或者libdvm.so,真奇怪了,你可是android进程,没有虚拟机咋跑的?

那就看下这个进程加载了什么,首先找到进程id

然后检查下maps

果然没有,见鬼了,我把maps的输出保存下来,在编辑器里查看才发现了端倪,原来进程加载的so里有一个libartd.so,因为这个手机是pixel5,系统是我自己下载AOSP编译的,选择的是eng版,这样编出来的系统so都是debug版,也就意味着后缀都有一个d,难怪frida找不到。

知道了原因,那解决方案就简单了,把那段查找libart.so的代码改成查找libartd.so即可。不过还有一个问题,这个frida-java-bridge是编译的时候从网上下载的,我们本地修改会被覆盖,那么就得研究下frida的编译系统了,让它使用我们本地的frida-java-bridge。

首先在源码里搜索frida-java-bridge,果不其然,是在一个generate-runtime.py里面,代码如下

看来是编译的时候,用npm install -E把frida-java-bridge下载下来了,那么接下来就是要把这个依赖项改成我们本地的。
首先下载一个到本地

然后全局查找libart.so,改成libartd.so
改代码

这时候需要用到npm link把我们本地的frida-java-bridge注册到系统中

然后要让frida中的编译脚本指向我们这个,也就是不要用npm install了,需要改成npm link, 修改generate-runtime.py代码如下
runtime

然后再重新编译, 生成后推到手机执行
无报错

果然没有报错了,非常完美!

wget -qO- https://deb.nodesource.com/setup_16.x | sudo -E bash -
sudo apt-get install -y nodejs
wget -qO- https://deb.nodesource.com/setup_16.x | sudo -E bash -
sudo apt-get install -y nodejs
make core-android-arm64
make tools-linux-x86_64 PYTHON=$HOME/miniconda3/bin/python
make core-android-arm64
make tools-linux-x86_64 PYTHON=$HOME/miniconda3/bin/python
redfin:/data/local/tmp # ./frida-server                                                      
{"type":"error","description":"Error: Java API not available","stack":"Error: Java API not available\n    at _checkAvailable (frida/node_modules/frida-java-bridge/index.js:298:1)\n    at _.perform (frida/node_modules/frida-java-bridge/index.js:203:1)\n    at /internal-agent.js:490:6","fileName":"frida/node_modules/frida-java-bridge/index.js","lineNumber":298,"columnNumber":1}
redfin:/data/local/tmp # ./frida-server                                                      
{"type":"error","description":"Error: Java API not available","stack":"Error: Java API not available\n    at _checkAvailable (frida/node_modules/frida-java-bridge/index.js:298:1)\n    at _.perform (frida/node_modules/frida-java-bridge/index.js:203:1)\n    at /internal-agent.js:490:6","fileName":"frida/node_modules/frida-java-bridge/index.js","lineNumber":298,"columnNumber":1}
 
setTimeout(
    function() {
        Java.perform(function() {
            console.log("Hello frida!")
        })
    }
)
 
//test.js
setTimeout(
    function() {
        Java.perform(function() {
            console.log("Hello frida!")
        })
    }
)
 
//test.js
(base) /data/code/OpenSource/crack/frida/build/frida-linux-x86_64/bin (16.0.11 ✔) ./frida -U -l ../../../../frida_script/test.js com.example.myapplication
     ____
    / _  |   Frida 16.0.11 - A world-class dynamic instrumentation toolkit
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at https://frida.re/docs/home/
   . . . .
   . . . .   Connected to AOSP on redfin (id=0A051FDD4003BW)
Failed to spawn: cannot read properties of undefined (reading 'getRunningAppProcesses')
(base) /data/code/OpenSource/crack/frida/build/frida-linux-x86_64/bin (16.0.11 ✔) ./frida -U -l ../../../../frida_script/test.js com.example.myapplication
     ____
    / _  |   Frida 16.0.11 - A world-class dynamic instrumentation toolkit
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at https://frida.re/docs/home/
   . . . .
   . . . .   Connected to AOSP on redfin (id=0A051FDD4003BW)
Failed to spawn: cannot read properties of undefined (reading 'getRunningAppProcesses')
 
perform (fn) {
   this._checkAvailable();
 
   if (!this._isAppProcess() || this.classFactory.loader !== null) {
     try {
       this.vm.perform(fn);
     } catch (e) {
       Script.nextTick(() => { throw e; });
     }
   } else {
     this._pendingVmOps.push(fn);
     if (this._pendingVmOps.length === 1) {
       this._performPendingVmOpsWhenReady();
     }
   }
 }
perform (fn) {
   this._checkAvailable();
 
   if (!this._isAppProcess() || this.classFactory.loader !== null) {
     try {
       this.vm.perform(fn);
     } catch (e) {
       Script.nextTick(() => { throw e; });
     }
   } else {
     this._pendingVmOps.push(fn);
     if (this._pendingVmOps.length === 1) {
       this._performPendingVmOpsWhenReady();
     }
   }
 }
_checkAvailable () {
  if (!this.available) {
    throw new Error('Java API not available');
  }
}
_checkAvailable () {
  if (!this.available) {
    throw new Error('Java API not available');
  }
}
get available () {
  return this._tryInitialize();
}
 
_tryInitialize () {
  if (this._initialized) {
    return true;
  }
 
  if (this._apiError !== null) {
    throw this._apiError;
  }
 
  let api;
  try {
    api = getApi();
    this.api = api;
  } catch (e) {
    this._apiError = e;
    throw e;
  }
  if (api === null) {
    return false;  //只有这里返回为false
  }
 
  const vm = new VM(api);
  this.vm = vm;
 
  Types.initialize(vm);
  ClassFactory._initialize(vm, api);
  this.classFactory = new ClassFactory();
 
  this._initialized = true;
 
  return true;
}
get available () {
  return this._tryInitialize();
}
 
_tryInitialize () {
  if (this._initialized) {
    return true;
  }
 
  if (this._apiError !== null) {
    throw this._apiError;
  }
 
  let api;
  try {
    api = getApi();
    this.api = api;
  } catch (e) {
    this._apiError = e;
    throw e;
  }
  if (api === null) {
    return false;  //只有这里返回为false
  }
 
  const vm = new VM(api);
  this.vm = vm;
 
  Types.initialize(vm);
  ClassFactory._initialize(vm, api);
  this.classFactory = new ClassFactory();
 

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
最新回复 (7)
雪    币: 545
活跃值: (449)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
为啥我发的贴一直是待验证啊?
2023-4-5 00:25
0
雪    币: 29177
活跃值: (63586)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
3
madsu 为啥我发的贴一直是待验证啊?
新人发帖需要版主审核验证显示,现在可以了
2023-4-5 09:50
0
雪    币: 545
活跃值: (449)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
Editor 新人发帖需要版主审核验证显示,现在可以了
可以了,感谢版主
2023-4-5 10:45
0
雪    币: 545
活跃值: (449)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5

https://www.52pojie.cn/thread-1652946-1-1.html


后面准备研究研究这个,借宝地收藏一下,话说看雪怎么收藏外部资料呢?

最后于 2023-4-5 12:19 被madsu编辑 ,原因:
2023-4-5 12:17
0
雪    币: 2428
活跃值: (10698)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
我很早之前就注册了,上一年年底发帖,也是待验证,验证了几个月有一篇文章发出去了,但是还有一篇还是待验证,不知道是不是在等年终奖才能发,所以,我决定,未来都不会再发帖。
2023-4-6 09:43
0
雪    币: 545
活跃值: (449)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
你瞒我瞒 我很早之前就注册了,上一年年底发帖,也是待验证,验证了几个月有一篇文章发出去了,但是还有一篇还是待验证,不知道是不是在等年终奖才能发,所以,我决定,未来都不会再发帖。
我刚注册,后来看了下版规才知道需要审核,不过版主也很快给我通过了,看雪移动端相关版块人气远远不如PC版块,还是要多多发贴啊
2023-4-6 10:26
0
雪    币: 206
活跃值: (1175)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
2023-4-6 20:30
0
游客
登录 | 注册 方可回帖
返回
//