Frida Casting object to List of Strings - javascript

I have been trying to print out the contents of a list when hooking an android app with Frida but am not having any luck.
The object I want to hook in Java looks like this
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.util.List;
public final class Hello extends HelloParent{
#JsonIgnore
public final List sampleList;
}
There aren't any getters for this public object so I have to resort to using another object (Let's call the object "Bye")'s method (byeMethodB) to monitor this value.
This is what my frida-script looks like:
setTimeout(function() {
Java.perform(function(){
Java.use("Bye").byeMethodA.implementation = function(){
try{
//Returns a Hello object
var helloObject = Java.cast(this.byeMethodB(),Java.use("Hello"))
printListContent(Java.cast(helloObject.sampleList,Java.use("java.util.List"))))
}catch(err){
console.log(err)
}
}
})
},1000)
function printListContent(list){
var listIter = list.iterator()
while(listIter.hasNext()){
console.log(listIter.next())
}
}
Without casting the "helloObject.sampleList" object to a list, the output looks like this:
[object Object]
So I am sure it is not null
If I cast using Java.cast(helloObject.sampleList,Java.use("java.util.List")),
I get the following error:
I have also tried:
Java.cast(helloObject.sampleList,Java.use("java.util.List<>"))
(I am pretty sure its a String)
Java.cast(helloObject.sampleList,Java.use("java.util.List<String>"))
Java.cast(helloObject.sampleList,Java.use("java.util.List<java.lang.String>"))
Java.cast(helloObject.sampleList,Java.use("[String"))
Java.cast(helloObject.sampleList,Java.use("[Ljava.lang.String"))
It is not going well at all. Would appreciate some help

In Frida accessing fields is not identical as in Java. If you execute helloObject.sampleList in Frida you are getting the JavaScript object that describes the field, not the field value itself.
If you want the field value you have to execute helloObject.sampleList.value.
Therefore the following code should work:
Java.cast(helloObject.sampleList.value, Java.use("java.util.List"));
Generics only exists at compile time but frida is working at run-time. Therefore java.util.List<> and the other class names with angle bracket will never work.

Related

How to pass object to client using Websockets? (use object class from js file in html script)

In my index.js I have a class
class Digit() {
//construct
add() {
//do whatever
}
}
and
let C = new Digit();
I pass this to the client using
WS.send(JSON.stringify(C))
which is recieved/interpreted in index.html. This all works perfectly and the issue is not with this proccess.
However when I try to use C.add(), I get the TypeError: function add does not exist. In my eyes either the error is that there is no 'context' for the class and thus the methods cannot be accessed, there is some namespace error, or JSON.stringify cannot properly send objects of custom classes. So how do I fix this error?

How to select a property of an Object containing a class

Is it possible to select a property from an object containing a class like this below?
//Object
const voices = {
fmsynth: Tone.FMSynth,
amsynth: Tone.AMSynth,
synth: Tone.Synth
}
//my function to select the above synths
switch_synth(synth_id) {
const synth = new Tone.PolySynth(voices[synth_id], 6).toDestination();
console.log(voices[synth_id]);
}
Yes, as long as you call it with the appropriate key
In your code, call voices["fmsynth"] or even voices.fmsynth, to get Tone.FMSynth.
So your code seems to be doing the right thing, as long as you are calling switch_synth with an appropriate synth_id, e.g.
switch_synth("fmsynth")
Are you getting an error, and if so, what error?

get a variable value from a method at runtime with frida

I'm completely beginner to frida.
I've this final method which belongs to class say X.
I want to extract the value of token variable -> result.getToken() when i hook frida to the android app which contains that class at runtime.
can anyone complete this code with javascript API of frida to get the value of token variable ?
Java.perform(function () {
Java.choose("com.xx.xx", {
onMatch: function (inst) {
//.................................
}
});
console.log("Done");
});
then i'll use --> frida -U -f "xxx.apk" -l test.js
thank you so much for help !!
Java.choose is in most cases the wrong approach because that only lists the existing instances of a class, so you can only hook a method if there is already an instance loaded into memory.
The common way is to hook the method itself so that all existing and newly created instances use your hook.
var classInstanceIdResult = Java.use('com.google.firebase.iid.InstanceIdResult');
var getTokenMethod = classInstanceIdResult.getToken.overload();
// replace the getToken() method with out own implementation
getTokenMethod.implementation = function () {
// call the orignal method
var ret = getTokenMethod.call(this);
// do something with ret
console.log("Token: " + ret);
return ret;
}
BTW: The code for hooking a Java method can simply be generated by using Jadx-Gui. Just decompile the APK, select the method and let Jadx generate the Frida code snipped necessary to hook the method (see context menu of the method).

Send Object from Javascript to Kotlin using Webview

I have loaded a webpage using WebView component and added a JavascriptInterface. Please check the code below,
val webview = WebView(this)
setContentView(webview)
webview.settings.javaScriptEnabled = true
webview.loadUrl(HOME_PAGE_URL)
webview.addJavascriptInterface(JavascriptInterface(),”javascript_bridge”)
And when I call the invoke from Javascript using window.javascript_bridge.showToast(“Information Saved”);
private inner class JavascriptInterface
{
#android.webkit.JavascriptInterface
fun showToast(text: String?)
{
Log.d("WEBVIEW", text);
}
}
I am able to call the method from Javascript to Kotlin without any trouble.
But now I want to pass an Object from Javascript to Kotlin like below,
var info = {
message: “Information Saved”,
ID: 123456
}
And when I call the invoke from Javascript using window.javascript_bridge.showToast(info);
I tried to change to the data type to Any, but the value passed from Javascript is null
private inner class JavascriptInterface
{
#android.webkit.JavascriptInterface
fun showToast(text: Any?)
{
Log.d("WEBVIEW", text.toString());
}
}
As far as i know, the javaScript interface methods only accepts primitive types of data as parameters (as discussed on this question).
If you still want to achieve that, you may serialize the object (to JSON format, for instance) in the javaScript and then Deserialize it in Java.
Hope it helps :)

Axios generic Post returns wrong type in TypeScript

I am trying to return a typed object using the Axios API. I am using the generic type to declare that I am returning an instance of GetSliceResponse but unfortunately Axios seems to still return an object of type any.
My code looks like this
export class GetSliceResponse
{
Success: boolean;
}
Axios.post<GetSliceResponse>("myurl/Get", request).then(o => {
var expectedResult = (new GetSliceResponse()) instanceof GetSliceResponse;
//expectedResult = true;
var unexpectedResult = o.data instanceof GetSliceResponse;
//unexpectedResult = false;
});
The Http response is exactly what you would expect:
{"Success":false}
As the above code illustrates I can correctly create an instance of my type using the new syntax but the Axios data property appears unaffected by the type declaration.
Just because something has the same properties as the class does not mean it is an instance of the class. In your case the response from the server is probably parsed using JSON.parse which will create simple objects. Only objects created using new GetSliceResponse will actually be instances of the class.
The type parameter to the post method is meant to help describe the shape of the response but will not actually change the runtime behavior (nor could it, genetics are erased during compilation).
This being said, you can still access the properties of the object as if the object was an instance of the class, the only thing that will not work is instanceof and don't expect any method to be present.
If you want to make sure nobody uses instanceof by mistake you can make the type am interface instead.
If you really need the class you can create an instance using new and use Object.assign to assign all fields
export class GetSliceResponse
{
Success: boolean;
}
Axios.post<GetSliceResponse>("myurl/Get", request).then(o => {
o = Object.assign(new GetSliceResponse(), o);
});

Categories

Resources