Created
August 31, 2024 12:53
-
-
Save FrankSpierings/6caa692a2c5fc10663176ce9aa78e646 to your computer and use it in GitHub Desktop.
Override Android WebView to include a custom JavaScript handler
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Java.perform(() => { | |
// Register a new WebAppInterface Javascript environment | |
const WebView = Java.use('android.webkit.WebView'); | |
const WebAppInterface = Java.registerClass({ | |
name: 'com.evil.WebAppInterface', | |
fields: { | |
mContext: 'android.content.Context', | |
}, | |
methods: { | |
$init: [{ | |
argumentTypes: ['android.content.Context'], | |
implementation(context) { | |
console.log("Initializing", context); | |
this.mContext.value = context; | |
} | |
}], | |
// Example export | |
showToast: [{ | |
returnType: 'void', | |
argumentTypes: ['java.lang.String'], | |
implementation(message) { | |
const Toast = Java.use('android.widget.Toast'); | |
// console.log(this.mContext.value, message, Toast.LENGTH_SHORT.value); | |
Toast.makeText.overload('android.content.Context', 'java.lang.CharSequence', 'int').call(Toast, this.mContext.value, message.toString(), Toast.LENGTH_SHORT.value).show(); | |
} | |
}] | |
} | |
}); | |
// Hook into the main activity to get the context | |
const Activity = Java.use('android.app.Activity'); | |
Activity.onCreate.overload('android.os.Bundle').implementation = function(savedInstanceState) { | |
// Call the super | |
this.onCreate(savedInstanceState); | |
// Access the context | |
const context = this; | |
console.log('Context:', context); | |
const webappinterface = WebAppInterface.$new(context); | |
// Hook loadUrl calls, to dynamically add our JavaScript environment | |
WebView.loadUrl.overload('java.lang.String').implementation = function (url) { | |
console.log('Adding JavaScript interface to webview, navigating to:', url); | |
this.addJavascriptInterface(webappinterface, "AndroidInterface"); | |
return this.loadUrl(url); | |
} | |
}; | |
// Intercepting calls to WebViews to instruct the existince of @JavascriptInterface | |
const Executable = Java.use('java.lang.reflect.Executable'); | |
Executable.isAnnotationPresent.implementation = function (clazz) { | |
const name = clazz.getName(); | |
console.log('Class:', name); | |
if (name === "android.webkit.JavascriptInterface") { | |
console.log("Overriding; Instruct code the annotation IS there"); | |
return true; | |
} | |
return this.isAnnotationPresent(clazz); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment