-1

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?

Community
  • 1
  • 1
qre0ct
  • 5,680
  • 10
  • 50
  • 86
  • 1
    What other instance could `openConnection` be called on? – Andy Turner Dec 02 '15 at 10:51
  • @AndyTurner I get your point. But, I would like to have a reference to the object itself so I could retrieve the string that was passed during URL object instantiation. – qre0ct Dec 02 '15 at 10:54
  • I think you need to clarify your question. I deleted my answer accordingly. – Tunaki Dec 02 '15 at 11:04
  • @AndyTurner thanks for the pointer. Added more details to the question. Hope this helps in clarifying what exactly am I looking out for. – qre0ct Dec 02 '15 at 11:15

2 Answers2

1

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

4knahs
  • 629
  • 4
  • 14
0

Ok. So specifically for the above case, (xposed module), the answer was on xposed_dev_tutorial itself. I overlooked it perhaps.

So if the method was called with myClock.updateClock(), then param.thisObject would be myClock.

So, even in my case, using param.thisObject i was able to retrieve the reference to the 'url' object. And then the URL class has a toString() which I used retrieve the url string being passed to it at the time of instantiation.

Any better answers are still welcome, especially if someone could point how can reflection be used to achieve the same (that is if it can be at all of course).

qre0ct
  • 5,680
  • 10
  • 50
  • 86