Frida JS执行HTTP请求遇NetworkOnMainThreadException问题求助
解决Frida Hook中Android网络请求的主线程限制问题
核心原因
你遇到的android.os.NetworkOnMainThreadException是因为Android系统禁止主线程执行网络IO操作,而你Hook的com.ex.MediaPlayMgr.play方法刚好运行在主线程中,直接在Hook代码里发起HTTP请求就会触发这个异常。
解决方案:后台线程同步执行网络请求
要在Frida JS中安全获取自定义InputStream,需要把网络请求放到后台线程执行,同时通过同步机制等待请求完成,再替换原方法的参数。以下是可行的代码示例:
示例代码(使用Java线程+CountDownLatch同步)
Java.perform(() => { const MediaPlayMgr = Java.use('com.ex.MediaPlayMgr'); const CountDownLatch = Java.use('java.util.concurrent.CountDownLatch'); const OkHttpClient = Java.use('okhttp3.OkHttpClient'); const Request = Java.use('okhttp3.Request'); const ResponseBody = Java.use('okhttp3.ResponseBody'); MediaPlayMgr.play.overload('java.io.InputStream', 'java.lang.String').implementation = function(inputStream, str) { console.log('进入play方法'); let customInputStream = null; const latch = CountDownLatch.$new(1); // 启动后台线程执行网络请求 const thread = Java.use('java.lang.Thread').$new({ run: function() { try { console.log('step3: 开始执行网络请求'); // 构建OkHttp请求 const client = OkHttpClient.$new(); const request = Request.Builder.$new().url('你的目标URL').build(); const response = client.newCall(request).execute(); if (response.isSuccessful()) { customInputStream = response.body().byteStream(); console.log('step4: 网络请求完成,获取到输入流'); } } catch (e) { console.error('网络请求出错:', e.message); // 异常时 fallback 到原输入流 customInputStream = inputStream; } finally { latch.countDown(); // 通知主线程请求完成 } } }); thread.start(); // 等待后台线程完成 latch.await(); // 替换输入流,调用原方法 return this.play(customInputStream, str); }; });
关键注意点
- 使用
CountDownLatch实现主线程和后台线程的同步,确保在获取到自定义流之后再执行原方法逻辑。 - 异常处理要做好,避免因为网络请求失败导致原方法无法执行,可在异常时 fallback 到原输入流。
- 如果你用
java.net.HttpURLConnection,替换线程内的网络请求代码即可,逻辑是一样的:// HttpURLConnection 版本的网络请求代码 const URL = Java.use('java.net.URL'); const HttpURLConnection = Java.use('java.net.HttpURLConnection'); const url = URL.$new('你的目标URL'); const conn = url.openConnection(); conn.setRequestMethod('GET'); customInputStream = conn.getInputStream(); - 确保目标应用已经申请了
android.permission.INTERNET权限,否则会出现权限错误。
额外提示
如果Hook的方法本身是异步执行的,也可以考虑用Android的Handler将网络请求抛到后台HandlerThread,但上述同步等待的方式更通用,能保证替换流的逻辑和原方法执行顺序一致。
内容的提问来源于stack exchange,提问作者kenshin
相关产品推荐
相关产品推荐

