ElderDrivers / EdXposed

Elder driver Xposed Framework.
https://edxp.meowcat.org/
GNU General Public License v3.0
5.42k stars 625 forks source link

[Question/Feature] Hooking ROM source directly #793

Open mostanes opened 3 years ago

mostanes commented 3 years ago

Hi guys,

Thank you for your great work. I've successfully tested and used EdXposed on my phone, especially with XPrivacyLua and FakeGApps. I've been recently building my phone's ROM myself (using phh's GSI patches on top of AOSP and, more recently, Lineage sources) and I was wondering if it is possible to patch the sources with hooks directly, so that I could use Xposed modules without needing to do the Riru voodoo around zygote? I believe this would make EdXposed more stable and, possibly even stealthier (for SafetyNet purposes), if implemented with that in mind. To do this, where in the source tree should I start digging? I suppose I should expose an interface similar to YAHFA/SandHook (where is that interface defined?) and rewrite the upper bits of EdXposed (where are those?) to link XposedBridge with the rom builtin implementation. I've read the wiki here and poked a bit through the tree, but it wasn't very illuminating.

I think #532 and #725 might also be relevant.

kotori2 commented 3 years ago

It's easy to do if you want to keep Riru in your system, just place the files and SELinux policy then all done. But if you want to remove Riru, AOSP modification is required. You should implement your own Riru API such as calling EdXposed forkAndSpecializePre in Zygote's forkAndSpecialize, which was not that hard if you had experiences with AOSP. Also you need to implement a SELinux-free file reading API, aka rirud.

Anyway the most unstable part of EdXposed is not Riru API, but ART hooks. We don't have much open source projects to rely on so that's annoying.

kotori2 commented 3 years ago

Also #725 only means I want to merge everything in 1 dex and 1 so file, which could reduce installer complexity.

mostanes commented 3 years ago

But if you want to remove Riru, AOSP modification is required. You should implement your own Riru API such as calling EdXposed forkAndSpecializePre in Zygote's forkAndSpecialize, which was not that hard if you had experiences with AOSP. Also you need to implement a SELinux-free file reading API, aka rirud.

Yup, the point is to modify AOSP and place system hooks directly in AOSP code (via some delegate or inheritance or some other method, depending on coding effort and performance), so that I'll get rid of Riru, and, at least for hooks in AOSP code, also YAHFA/SandHook.

kotori2 commented 3 years ago

Yup, the point is to modify AOSP and place system hooks directly in AOSP code

As far as I could tell, if you just want to hook specific code in AOSP, the best choice (most stable) is to embed a list of callbacks directly in AOSP. Otherwise you can't get rid of ART hooks.

mostanes commented 3 years ago

I was hoping for something more generic. Callbacks are a pain in that sense (technically, it might be possible to have some script that adds a callback to every function in the system libraries, but it ain't pretty). I think it's also possible (except for static methods) to make sure that classes and methods aren't final and, when a hook is needed (at runtime), sub-classing and overriding the methods (via some java reflection library). Which should be more resilient than trampolines (that AFAIK are used by those 2 art hooking libraries). The injection of instances might be tricky though. This way, it should be rather generic (with callbacks left only for static methods and other trickier cases).

XspeedPL commented 3 years ago

Even if you include the libraries in the Android framework without modifications to the app process binary it won't do anything. I think #532 is as far as you can get right now. Applying Xposed modules like patches onto apk files statically is also not possible, because most modules apply hooks dynamically at runtime. Other than that you could look into Virtual Xposed that supposedly does similar stuff, but I never analyzed it.

mostanes commented 3 years ago

I think #532 is as far as you can get right now. Applying Xposed modules like patches onto apk files statically is also not possible, because most modules apply hooks dynamically at runtime.

As I said above, point was to change AOSP to have an Xposed-like interface for extensions. It is not the Xposed modules that are applied statically, but the function signatures in the framework are changed such that hooking is possible without doing voodoo on the jit output and stepping on ART's toes.

For third party apps, that's (very) hard. It is still very much doable, because we build ART, but it is far from easy. Basically ART would need to be rewritten to weave Xposed callbacks (on demand, by re-jitting) into the apps and I'm definitely not looking at that yet.

For AOSP code, which is under our control, it should be doable without having to work against ART (the unmodified one). For example, through the inheritance technique, by replacing the objects passed around (exactly how I don't yet know, but I'm thinking of a few strategically placed callbacks or directly for static objects), the methods can be overridden at will (assuming classes and methods are not final -- this needs to be changed in AOSP code). Then, the new hooking framework can create a hook dynamically by replacing the object with an instance of a subclass that has the target method overridden to call the Xposed module.

XspeedPL commented 3 years ago

As soon as you need more than static entry points for a predefined list of hooks, you need some kind of voodoo.

The only non-voodoo idea I get is to create a sophisticated installer that could patch and recompile source framework libs with "modding API" hooks planted on the fly, taking SDK level and OEM changes into consideration in its method searching logic. Still, not fun, and not rewarding. I'd stick with Xposed.