I came across a situation, wherein I would like to know/get a reference to the object on which a certain method was called.
Basically, I am trying to write an xposed module. One of the features of the module is to find out all the URLs being hit by the app over HTTP. To achieve this, my approach is:
I assume that any app (or at least the app in question) would make a call to openConnection() to make an HTTP connection. So, hook the openConnection() method during the app runtime and try to figure out what object was the method called on. Once, object is retrieved, find out the string that was passed to it at object instantiation. This string object would be the URL to which the app wants to make an HTTP connection.
Now I was hoping if there is a way that java reflection can help me achieve the above - find out the object reference and later the string that was passed to it when the object was instantiated.
Example - from the Android world :
URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
Now I want to know if there is a way of knowing that 'url' was the object on which the openConnection() was called. The end goal is that I want to be able to get the string 'myurl' that was passed to URL while creating it's object.
Is there a way I can do this?
I have already gone through this : How do I find the caller of a method using stacktrace or reflection?
But, the above hasn't proved very helpful in my case. Moreover, in the above there are comments that mention that even if I used StackTraceElement, I would not get the name/reference of the object. I would just get the type of the caller instead. And with the called alone, I don't think I would be able to achieve my end goal of finding the 'url' string. Will I?
Using the thisObject should be the way to go.
As an extra idea, perhaps consider using a statically accessible WeakIdentityHashMap so you can store as keys the url objects (param.thisObject) and as values the url strings.
Procedure: 1) Intercept the constructor of URL to register it in the Map 2) retrieve it when opening the connection to get its value.
Why a WeakIdentityHashMap? IdentityHashMap performs reference-equality in place of object-equality. A WeakIdentityHashMap keeps weak references to objects, meaning that if objects are no longer referenced by the original application they can still be garbage collected.
I have been using this in a few Xposed projects.
PS - wrap it with Collections.synchronizedMap if you require thread-safeness