note Slow Binder Call
3 views
164b14e0...
Description
use StrictMode.noteSlowCall to mark common slow binder call on main thread(IActivityManager, IPackageManager, IConnectivityManager)
How to Use
Download the script and run it with Frida CLI:
Download ScriptThen run with Frida:
frida -U -f YOUR_PACKAGE_NAME -l note-slow-binder-call.js
Replace YOUR_PACKAGE_NAME with the target app's package name.
Source Code
JavaScript
Java.perform(function() {
const strictmode = Java.use('android.os.StrictMode')
//【Note Slow Call】
// 1. ContextWrapper(cover IActivityManager 80% slow binder call)
const contextWrapper = Java.use("android.content.ContextWrapper")
// 1.1 sendBroadcast
contextWrapper.sendBroadcast.overload('android.content.Intent').implementation = function(intent) {
strictmode.noteSlowCall("sendBroadcast(Intent)")
return this.sendBroadcast(intent);
}
contextWrapper.sendBroadcast.overload('android.content.Intent', 'java.lang.String').implementation = function(intent, permission) {
strictmode.noteSlowCall("sendBroadcast(Intent, String)")
this.sendBroadcast(intent, permission)
}
contextWrapper.sendBroadcast.overload('android.content.Intent', 'java.lang.String', 'android.os.Bundle').implementation = function(intent, permission, bundle) {
strictmode.noteSlowCall("sendBroadcast(Intent, String, Bundle)")
return this.sendBroadcast(intent, permission, bundle)
}
// 1.2 registerReceiver
contextWrapper.registerReceiver.overload('android.content.BroadcastReceiver', 'android.content.IntentFilter', 'java.lang.String', 'android.os.Handler').implementation = function(recv, filter, permission, handler) {
strictmode.noteSlowCall("registerReceiver(BroadcastReceiver, IntentFilter, String, Handler)")
return this.registerReceiver(recv, filter, permission, handler)
}
contextWrapper.registerReceiver.overload('android.content.BroadcastReceiver', 'android.content.IntentFilter', 'java.lang.String', 'android.os.Handler', 'int').implementation = function(recv, filter, permission, handler, flags) {
strictmode.noteSlowCall("registerReceiver(BroadcastReceiver, IntentFilter, String, Handler, int)")
return this.registerReceiver(recv, filter, permission, handler, flags)
}
contextWrapper.registerReceiver.overload('android.content.BroadcastReceiver', 'android.content.IntentFilter', 'int').implementation = function(recv, filter, flags) {
strictmode.noteSlowCall("registerReceiver(BroadcastReceiver, IntentFilter, int)")
return this.registerReceiver(recv, filter, flags)
}
contextWrapper.registerReceiver.overload('android.content.BroadcastReceiver', 'android.content.IntentFilter').implementation = function(recv, filter) {
strictmode.noteSlowCall("registerReceiver(BroadcastReceiver, IntentFilter)")
return this.registerReceiver(recv, filter)
}
// 1.3 updateServiceGroup
contextWrapper.updateServiceGroup.overload('android.content.ServiceConnection', 'int', 'int').implementation = function(conn, group, importance) {
strictmode.noteSlowCall("updateServiceGroup(ServiceConnection, group, importance)")
return this.updateServiceGroup(conn, group, importance)
}
// 1.4 startService
contextWrapper.startService.overload('android.content.Intent').implementation = function(intent) {
strictmode.noteSlowCall("startService(Intent)")
return this.startService(intent)
}
// 1.5 bindService
contextWrapper.bindService.overload('android.content.Intent', 'android.content.ServiceConnection', 'int').implementation = function(service, conn, flags) {
strictmode.noteSlowCall("bindService(Intent, ServiceConnection, int)")
return this.bindService(service, conn, flags)
}
contextWrapper.bindService.overload('android.content.Intent', 'android.content.ServiceConnection', 'android.content.Context$BindServiceFlags').implementation = function(service, conn, flags) {
strictmode.noteSlowCall("bindService(Intent, ServiceConnection, Context.BindServiceFlags)")
return this.bindService(service, conn, flags)
}
contextWrapper.bindService.overload('android.content.Intent', 'int', 'java.util.concurrent.Executor', 'android.content.ServiceConnection').implementation = function(intent, flags, executor, conn) {
strictmode.noteSlowCall("bindService(Intent, int, Executor, ServiceConnection)")
return this.bindService(intent, flags, executor, conn)
}
contextWrapper.bindService.overload('android.content.Intent', 'android.content.Context$BindServiceFlags', 'java.util.concurrent.Executor', 'android.content.ServiceConnection').implementation = function(intent, flags, executor, conn) {
strictmode.noteSlowCall("bindService(Intent, Context.BindServiceFlags, Executor, ServiceConnection)")
return this.bindService(intent, flags, executor, conn)
}
// 1.6 unbindService
contextWrapper.unbindService.overload('android.content.ServiceConnection').implementation = function(conn) {
strictmode.noteSlowCall("unbindService(ServiceConnection)")
return this.unbindService(conn)
}
// 2. PackageManager(cover IPackageManager 80% slow binder call)
const packageManager = Java.use("android.content.pm.PackageManager")
// 2.1 getApplicationInfo
packageManager.getApplicationInfo.overload('java.lang.String', 'int').implementation = function(name, flags) {
strictmode.noteSlowCall("getApplicationInfo(String, int)")
return this.getApplicationInfo(name, flags)
}
packageManager.getApplicationInfo.overload('java.lang.String', 'android.content.pm.PackageManager$ApplicationInfoFlags').implementation = function(name, flags) {
strictmode.noteSlowCall("getApplicationInfo(ApplicationInfoFlags, int)")
return this.getApplicationInfo(name, flags)
}
// 2.2 getPackageInfo
packageManager.getPackageInfo.overload('java.lang.String', 'int').implementation = function(packageName, flags) {
strictmode.noteSlowCall("getPackageInfo(String, int)")
return this.getPackageInfo(packageName, flags)
}
packageManager.getPackageInfo.overload('java.lang.String', 'android.content.pm.PackageManager$PackageInfoFlags').implementation = function(packageName, flags) {
strictmode.noteSlowCall("getPackageInfo(String, PackageInfoFlags)")
return this.getPackageInfo(packageName, flags)
}
packageManager.getPackageInfo.overload('android.content.pm.VersionedPackage', 'android.content.pm.PackageManager$PackageInfoFlags').implementation = function(versionedPackage, flags) {
strictmode.noteSlowCall("getPackageInfo(VersionedPackage, PackageInfoFlags)")
return this.getPackageInfo(versionedPackage, flags)
}
packageManager.getPackageInfo.overload('android.content.pm.VersionedPackage', 'int').implementation = function(versionedPackage, flags) {
strictmode.noteSlowCall("getPackageInfo(VersionedPackage, int)")
return this.getPackageInfo(versionedPackage, flags)
}
// 2.3 getActivityInfo
packageManager.getActivityInfo.overload("android.content.ComponentName", "int").implementation = function(componentName, flags) {
strictmode.noteSlowCall("getActivityInfo(ComponentName, int)")
return this.getActivityInfo(componentName, flags)
}
packageManager.getActivityInfo.overload("android.content.ComponentName", "android.content.pm.PackageManager$ComponentInfoFlags").implementation = function(componentName, flags) {
strictmode.noteSlowCall("getActivityInfo(ComponentName, ComponentInfoFlags)")
return this.getActivityInfo(componentName, flags)
}
// 2.4 queryIntentActivities
packageManager.queryIntentActivities.overload('android.content.Intent', 'android.content.pm.PackageManager$ResolveInfoFlags').implementation = function(intent, flags) {
strictmode.noteSlowCall("queryIntentActivities(Intent, ResolveInfoFlags)")
return this.queryIntentActivities(intent, flags)
}
packageManager.queryIntentActivities.overload('android.content.Intent', 'int').implementation = function(intent, flags) {
strictmode.noteSlowCall("queryIntentActivities(Intent, int)")
return this.queryIntentActivities(intent, flags)
}
// 2.5 queryIntentServices
packageManager.queryIntentServices.overload('android.content.Intent', 'int').implementation = function(intent, flags) {
strictmode.noteSlowCall("queryIntentServices(Intent, int)")
return this.queryIntentServices(intent, flags)
}
packageManager.queryIntentServices.overload('android.content.Intent', 'android.content.pm.PackageManager$ResolveInfoFlags').implementation = function(intent, flags) {
strictmode.noteSlowCall("queryIntentServices(Intent, ResolveInfoFlags)")
return this.queryIntentServices(intent, flags)
}
// 3 android.net.ConnectivityManager
const connectivityManager = Java.use("android.net.ConnectivityManager")
// 3.1 getActiveNetworkInfo
connectivityManager.getActiveNetworkInfo.implementation = function() {
strictmode.noteSlowCall("getActiveNetworkInfo()")
return this.getActiveNetworkInfo()
}
// 3.2 getNetworkInfo
connectivityManager.getNetworkInfo.overload('int').implementation = function(networkType) {
strictmode.noteSlowCall("getNetworkInfo(int)")
return this.getNetworkInfo(networkType)
}
connectivityManager.getNetworkInfo.overload('android.net.Network').implementation = function(network) {
strictmode.noteSlowCall("getNetworkInfo(Network)")
return this.getNetworkInfo(network)
}
// 3.3 getNetworkCapabilities(Network network)
connectivityManager.getNetworkCapabilities.overload('android.net.Network').implementation = function(network) {
strictmode.noteSlowCall("getNetworkCapabilities(Network)")
return this.getNetworkCapabilities(network)
}
// 3.4 getActiveNetwork
connectivityManager.getActiveNetwork.implementation = function() {
strictmode.noteSlowCall("getActiveNetwork()")
return this.getActiveNetwork()
}
// 【enable StrictMode】
// Looper, Handler, Runnable to enable StrictMode on mainthread
const looperClz = Java.use('android.os.Looper')
const handlerClz = Java.use('android.os.Handler')
const runnableIntf = Java.use('java.lang.Runnable')
// StrictMode and related classes to turn on StrictMode
const tpBuilder = Java.use('android.os.StrictMode$ThreadPolicy$Builder')
const androidBlockGuardPolicy = Java.use('android.os.StrictMode$AndroidBlockGuardPolicy')
var mainLooper = looperClz.getMainLooper()
var handler = handlerClz.$new(mainLooper)
/* used to debug noteSlowCall, comment out
strictmode.noteSlowCall.implementation = function(name) {
this.noteSlowCall(name)
}
strictmode.tooManyViolationsThisLoop.implementation = function() {
var ret = this.tooManyViolationsThisLoop()
return ret
}
androidBlockGuardPolicy.onNoteSlowCall.implementation = function(name) {
return this.onNoteSlowCall()
}
*/
// register new Runnable class to enable StrictMode
// if "Error: java.io.IOException: Permission denied" happens, adb shell setenforce 0 to turn off selinux
var runnableClz = Java.registerClass({
name: 'EnforceStrictModeRunnable',
implements: [runnableIntf],
methods: {
run: function() {
// enable log and flash screen for thread policy
const tp = tpBuilder.$new().detectCustomSlowCalls().penaltyLog().penaltyFlashScreen().build()
strictmode.setThreadPolicy(tp)
}
}
});
// post runnable class to main looper to enable strictmode
handler.post(runnableClz.$new());
})
Comments