0

I'm hooking into a method via the Xposed framework for Android. This effectively allows me to inject my own code into another Android app at runtime and have it run just as if the target app was built with it. Fun stuff. While this is how I'm injecting the code, my question should be independent of Xposed as it's using an extension of the standard Java reflection utilities to retrieve the class references I need.

Class targetClass = XposedHelpers.findClass("fullClassName", targetAppClassLoader);
Object timerField = XposedHelpers.getStaticObjectField(targetClass, "targetFieldName");
// This /should/ synchronize with the actual static field not our local representation of it
synchronized (timerField) {
    // Do stuff
}

In the above snippet I'm retrieving a static object field in a class via reflection. Internally, the target app uses synchronized blocks on this field. I need to operate in a similar synchronous manner so I do the same in my own code (link to full code).

Since Java objects are sorta passed by reference I should be retrieving a local reference to the static object in the target app. But do Java synchronized blocks work on reflected objects? And do they work together with non-reflected pre-existing synchronized blocks?

For reference, here is the code for findClass and getStaticObjectField. The former essentially returns a returns a Class<?> from org.external.org.apache.commons.lang3.ClassUtils and the latter (essentially) calls getDeclaredField on the Class<?> parameter, sets the Field to accessible, and returns the result of get(null) on the Field.

Community
  • 1
  • 1
Kevin Mark
  • 1,671
  • 1
  • 21
  • 49

1 Answers1

1

There are some caveats, but the answer is "yes". An object is an object, no matter how you get the reference. If you synchronize on the reference, you are using the same lock as everyone else that synchronizes on the reference.

The most important caveat is that you must be sure it is a reference to the same object. I just glanced at the code in Xposed (cute stuff, btw; will probably fail >= 5.0) and I don't see objects being marshalled/unmarshalled, so it all looks good. If the object on which you are synchronizing is, for instance, Parcelable or a Binder watch out, because there are likely to be several copies of the "same" object.

G. Blake Meike
  • 6,615
  • 3
  • 24
  • 40
  • Good to know. It will definitely fail on >=5.0 since Xposed is currently Dalvik-specific. I'm curious though, what do parts do you find "cute"? – Kevin Mark Dec 30 '14 at 19:11
  • I just got a kick out of reading it. I wouldn't have thought of doing that. Still not sure why I'd want to... Still, definitely clever. – G. Blake Meike Dec 30 '14 at 22:03
  • Gotcha! It's great for when you do not have the ability to run custom Android ROMs or to extend the abilities of closed-source apps. – Kevin Mark Dec 30 '14 at 22:09