EdXposed icon indicating copy to clipboard operation
EdXposed copied to clipboard

[Question] Is it possible to make EdXposed work without Magisk?

Open LuigiVampa92 opened this issue 4 years ago • 42 comments

Hey guys, great thanks for your amazing work. I’m pretty new to EdXposed and I'm sorry to make an issue here but I could not find the answer anywhere else. I am interested - is it possible to make EdXposed work without Magisk?

I know that previous versions of Xposed up to android 8 were flashable and I could just sideload them on device as any other zip file in TWRP. What is the problem to do the same thing with new EdXposed for android 9 and 10?

What I am trying to achieve is to take my OnePlus 5T, flash it with LOS16 and then flash it with EdXposed zip. Currently I can flash the LOS16, flash magisk, and then in Magisk Manager install Riru Core and Riru EdXposed modules (I use RiruCore v21.0 and EdXposed v0.4.6.2 YAHFA). It works perfect. But I would like to try to replace magisk modules with flashable zip files.

I’m not trying to hide the fact of installed EdXposed on device. It’s complitley ok if its files will be persisted and visible in /system. I’m also not worried that I will not be able to pass SafetyNet as well.

I have taken a brief look at the structure of magisk modules. RiruCore module contains modified versions of libmemtrack.so for /system/lib and /system/lib64 and zygote_restart binary. EdXposed module contains a few jars for /system/framework and a few more libs for /system/lib and /system/lib64. I have made a TWRP-flashable zip that replaces libmemtrack.so and puts the necessary files of EdXposed in lib, lib64 and framework. When I load into the system EdXposed Manager shows me a yellow warning saying that "EdXposed is installed but not activated". I have checked the EdXposed Manager app under debugger and XposedApp.getActiveXposedVersion() return -1 (which means that the method call is not hooked by Xposed framework). I have suspicions that it happens because EdXposed tries to locate RIRU_PATH which is /data/misc/riru and because of that it doesn’t work. That RIRU_PATH folder contains only a small pieces of metadata. Nothing seems to be important there except for "zygote_restart" binary. I have tried to create those directories and copy files in /data/misc/riru manually but for some reason my device falls into a bootloop. It happened when I created and copied the files by flashable zip in TWRP and also when I did so by adb shell in normally loaded system.

So, maybe some of you have tried to make the same stuff and succeeded? Or perhaps you know why modifying /data/misc causes the system to bootloop? My final goal is to install EdXposed straight into /system. I will be very grateful for any useful information. Thanks!

LuigiVampa92 avatar May 06 '20 13:05 LuigiVampa92

You're mostly correct, first you need to put files normally unpacked into Magisk directories directly into system. But after that you need to execute installer scripts, which need to be modified to use system paths instead of Magisk. It is of course doable and EdXposed should work, but it's tedious. I understand you want to keep the BL locked, yes?

XspeedPL avatar May 06 '20 13:05 XspeedPL

You're mostly correct, first you need to put files normally unpacked into Magisk directories directly into system. But after that you need to execute installer scripts, which need to be modified to use system paths instead of Magisk. It is of course doable and EdXposed should work, but it's tedious. I understand you want to keep the BL locked, yes?

Thanks for reply. Yes, my final goal is to lock the BL with EdXposed actually installed and working. As far as I can suggest once installed EdXposed will not make any changes to /system directly, only to /data, but data is not processed by verified boot.

It seems that I did the first part by putting EdXposed jars and libs and modified libmemtrack.so into /system but it I don't know where to use that zygote_restart binary. As far as I know, previous versions used modified app_process binaries, but it seems not to be the case of EdXposed for android 9+. Also I'm not sure how can I apply sepolicies from installer scripts, since they use Magisk's su_policy feature and I'm not sure how can I apply that without it. (by applying set_metadata?). So yes, I'm stuck at installer scripts on stage 2 and my poor knowledge of android does not let me even estimate is it possible to do all this staff at all? Maybe it uses some magisk features that cannot be performed without it

LuigiVampa92 avatar May 06 '20 14:05 LuigiVampa92

Good idea, but two questions 1, Riru Core without Magisk 2, SELinux Policy

MlgmXyysd avatar May 06 '20 14:05 MlgmXyysd

AFAIK zygote_restart is put into one of the *bin directories and/or symlinked. Search the repo for references.

Simply running Riru without Magisk is trivial, put files, run modified scripts, done.

As for the sepolicy stuff, the easiest way around, since the guy doesn't care about SN, you could just setenforce 0.

XspeedPL avatar May 06 '20 14:05 XspeedPL

Good idea, but two questions 1, Riru Core without Magisk 2, SELinux Policy

Thanks for reply. That is exactly the trickiest part, I believe

AFAIK zygote_restart is put into one of the *bin directories and/or symlinked. Search the repo for references.

Sounds like a good idea. I will try to do that. Btw is there a way to make a check to be sure that Riru Core works as intended? Can I check it somehow?

As for the sepolicy stuff, the easiest way around, since the guy doesn't care about SN, you could just setenforce 0.

If I get that right there are no tricky se_contexts for Riru Core, just 0 0 0644 for everything. But when it comes to EdXposed there are a dedicated sepolicy.rule file that is applied by Magisk supolicy tool. sepolicy.rule contains this:

allow system_server system_server process {execmem}
allow system_server system_server memprotect {mmap_zero}
allow coredomain coredomain process {execmem}
allow coredomain app_data_file * *
attradd {system_app platform_app} mlstrustedsubject
allow zygote apk_data_file * *

I'm not sure how can I apply it manually. Would be very grateful for some hints. Thank you!

LuigiVampa92 avatar May 06 '20 15:05 LuigiVampa92

Btw is there a way to make a check to be sure that Riru Core works as intended? Can I check it somehow?

There is a Riru companion app that can verify if Riru is loaded.

But when it comes to EdXposed there are a dedicated sepolicy.rule file that is applied by Magisk supolicy tool. sepolicy.rule contains this: [snip] I'm not sure how can I apply it manually.

If you don't want to disable SELinux, you can use the supolicy tool (shipped with Magisk) to apply the policies at runtime, for example using init.d mechanism or similar. Look at old post-fs-data.sh to see how to use it.

XspeedPL avatar May 06 '20 18:05 XspeedPL

There is a Riru companion app that can verify if Riru is loaded.

Thank you. Found and ran that app. Now I have a litmus test for correct Riru Core installation. Going to try it and also try to figure out what to do with SE policies.

Great thanks again for your advices and help guys, going to check all this at weekend

LuigiVampa92 avatar May 06 '20 18:05 LuigiVampa92

Hey guys, I’ve got a certain advance in what I am trying to achieve, but I have got stuck and I'm looking for your advice again.

===

I use Riru Core v21.0 because in further versions the binary is renamed in order to hide from security checks and I just want the simpliest possible case for now.

So I have made these steps to install Riru Core in /system:

  • I have checked the Riru companion app code (https://github.com/RikkaApps/Riru) and I have noticed that in helper.cpp/init() it checks existence of /system/lib64/libmemtrack_real.so in procs. So I took original /system/lib/libmemtrack.so and /system/lib64/libmemtrack.so from system.img and renamed them into /system/lib/libmemtrack_real.so and /system/lib64/libmemtrack_real.so respectively
  • I took Riru’s modified libmemtrack.so libs and placed them into /system/lib and /system/lib64 instead of original ones
  • I have took "zygote_restart_arm64" for my architecture, renamed it into just "zygote_restart", put it into /system/bin, and gave it 0700 permissions
  • Since magisk executes zygote_restart binary on post-fs, I have made an additional script /system/etc/init/riru.rc with following content:
on post-fs-data
    start zygote_restart

service zygote_restart /system/bin/zygote_restart
    user root
    group root
    oneshot
    disabled

It does basically the same thing as magisk’s post-fs-data.sh

After that I run the Riru companion app and it seems to work well. The output is the same when I install RiruCore and EdXposed as magisk modules and everything truly looks fine with this step:

Riru Unknown (version code 33) found.
Native methods of Zygote class replaced.

nativeForkAndSpecialize calls count: 45
nativeForkSystemServer calls count: 1
nativeSpecializeAppProcess calls count: 0

Everything looks fine :D

===

Now since EdXposed requires complicated se policies to be applied I have decided to turn SELinux off for the test. For that I have made a script in /system/etc/init.d/08setperm with following content:

#!/system/bin/sh

setenforce 0

It puts SELinux into permissive mode on system boot and I get a notification from LOS "Trust" that "SELinux is not enforcing, your security has been weakened" right after system has launched. getenforce also returns Permissive. So, everything looks fine with this step as well.

===

Now I take EdXposed-YAHFA-v0.4.6.2.4529.-release, and copy its jars into /system/framework and its libs into /system/lib and /system/lib64 respectively. I also manually added the following values to /system/build.props:

dalvik.vm.dex2oat-filter=quicken
dalvik.vm.dex2oat-flags=--inline-max-code-units=0

When I run EdXposed Manager it still gives me a yellow warning that tells "EdXposed is installed but not active" and tells me to check logs. I have checked in debugger, the XposedApp.getActiveXposedVersion() method is still not hooked by Xposed and returns default -1 value.

===

So the final result is still the same: EdXposed does not work (methods are not hooked), modules do not work as well (I tried to run XPrivacyLua), also no edxposed manager logs are saved into /data/user_de/0/org.meowcat.edxposed.manager/log (I think that I need to have magisk installed on the device to make them actually save)

===

Well. Here is where I have got stuck this time. So I wanted to ask you guys:

  1. What could go wrong?
  2. Is there a way I can get more debug info from Riru Core and EdXposed? Maybe I can build these libs and jars from source with some flags or modifications that will allow me to see more info about what is happening inside?

Thank you again for your great help! Without you I would stuck at the very beginning :) I will be very grateful for any useful information

LuigiVampa92 avatar May 12 '20 23:05 LuigiVampa92

Seems like you didn't register the EdXposed module with Riru. One of the install scripts puts the module information to /data/misc/riru

XspeedPL avatar May 13 '20 02:05 XspeedPL

Thanks for reply, @XspeedPL !

That is true. For now I used to avoid to use /data/misc/riru directory at all. I’m afraid that problem could be deeper than that. /data/misc/riru contains nothing but small metadata, mostly magisk modules versions and definitions. The only important thing there is zygote_restart but I successfully managed to move it to /system/bin. Riru core itself seems to work fine without /data/mis/riru and I have found no mentions of this directory in EdXposed code. Looks like EdXposed does not care about this directory as well. It just utilises modified libmemtrack and Zygote hook methods. As far as I can get EdXposed does not rely on any files in /data/misc/riru.

But what I truly could miss is the fact that Riru Core naturally searches for something in that directory. I haven’t looked carefully at Riru code yet but probably it can contain some mechanisms to restrict usage of modified libmemtrack only to whitelist modules and others get unmodified libmemtrack_real instead.

I will check it out. Thank you

LuigiVampa92 avatar May 13 '20 06:05 LuigiVampa92

Actually just took a brief look at Riru Core code, especially at redirect_memtrack.cpp and it seems that you are right. The problem is that Riru Core puts libmemtrack inside /data/misc/riru and expects to find it there in runtime. It uses this location when decides whether it should redirect calls to original libmemtrack to modified libmemtrack or not. So in my case there is nothing there and that's why all calls do not route to modified libmemtrack, so EdXposed manager is present in /system/framework but cannot access modified Riru's libmemtrack!

I gonna test it out at weekend but it seems that all I need to do is to modify paths in cpp code of Riru core and build modified libmemtrack from source

LuigiVampa92 avatar May 13 '20 07:05 LuigiVampa92

@LuigiVampa92 no you cannot avoid that, Riru read /data/misc/riru to load modules

MlgmXyysd avatar May 13 '20 07:05 MlgmXyysd

So I actually made it, guys.

I have took Riru core v21.2 code and changed it a little to make it use no configs at all but instead to load required modules manually. Basically just removed anything related to reading configs, removed load_modules() function and added function load_module(const char* module_name, int module_api_level). Also removed the logic of renaming libmemtrack_real.so since I don't hide from SafetyNet. In the end I have built a modified libmemtrack.so that does not rely on configs and loads the only module - edxp.

EdXposed now runs well on my device. I have tested a few modules and they all function correctly. There are also no troubles when I wipe data partition in recovery mode. The system recovers well and EdXposed works there again with no trouble.

The only downside is that I have to set SELinux permissive on boot with init.d script, otherwise the system will not boot. I guess that if I want to run it with SELinux enforcing I will have to build the ROM myself, because I haven't managed to find tools that would allow to patch se policies without using magisk.

Thank you again for your help guys!

LuigiVampa92 avatar May 18 '20 06:05 LuigiVampa92

So I actually made it, guys.

I have took Riru core v21.2 code and changed it a little to make it use no configs at all but instead to load required modules manually. Basically just removed anything related to reading configs, removed load_modules() function and added function load_module(const char* module_name, int module_api_level). Also removed the logic of renaming libmemtrack_real.so since I don't hide from SafetyNet. In the end I have built a modified libmemtrack.so that does not rely on configs and loads the only module - edxp.

EdXposed now runs well on my device. I have tested a few modules and they all function correctly. There are also no troubles when I wipe data partition in recovery mode. The system recovers well and EdXposed works there again with no trouble.

The only downside is that I have to set SELinux permissive on boot with init.d script, otherwise the system will not boot. I guess that if I want to run it with SELinux enforcing I will have to build the ROM myself, because I haven't managed to find tools that would allow to patch se policies without using magisk.

Thank you again for your help guys!

Hello been following this and there is likely many others also interested in this also, can you consider releasing your method as a fork? Thanks

msgpo avatar May 20 '20 16:05 msgpo

Hello, @msgpo . Thank you for the interest. I actually plan to publish everything required to build up a TWRP flashable zip that contains Riru Core and EdXposed but for now I haven't managed to find a way to patch se policies and make SELinux stay in enforcing mode. I plan to take a look at magisk's supolicy tool source code and the code that Piotr advised me to see in a message above. I will see if anything can be done with this. Making SELinux enforcing is an important thing and I wouldn't like to publish the final result without it. I will make Riru Core fork soon, but until that problem with se policies for EdXposed will be solved it will be pretty much useless. As it often happens I have unfortunately much less time to work with it than I would like to, but I'm trying to do my best and hope to reach a complete success as soon as I can

LuigiVampa92 avatar May 20 '20 21:05 LuigiVampa92

@LuigiVampa92 Thanks for the reply. Also please keep in mind when you publish that not everyone use SELinux enforcing or even at all, using Tomoyo or other alternatives, so maybe you can point that out when released. Is there a way to try what you have succeeded with so far? I think that can be sufficient enough for me to work with, thanks

msgpo avatar May 21 '20 13:05 msgpo

Hey guys, I have made a repo that contains this flashable EdXposed build that we have been discussing in this thread. So if someone interested please take a look and try :)

https://github.com/LuigiVampa92/System_EdXposed_install

To my own surprise I actually managed to achieve enforcing SELinux mode. I have took the source code of Magisk's supolicy tool, made a binary that patches existing sepolicy with only those 6 rules that EdXposed requires for correct work and run this binary on boot. It injects necessary rules before any app process starts and everything works just fine.

I also managed to lock the bootloader on my OnePlus 5T with LineageOS 16 and EdXposed installed.

@msgpo I have made an option to build a zip with permissive SELinux mode if necessary. You can choose the required mode by setting param on build script. Check it out

Unfortunately, I had to apply rules or set permissive mode by init.d script. I haven't managed to make a .rc script that would do the same, and I'm not sure that it is possible without making your own build with your own custom .te file that will contain the rules for SELinux. It means that if a ROM doesn't have init.d support then it's impossible to use this "system" EdXposed on it. It's not that good because I think that most stock ROMs do not have init.d support, but I'm not sure if there is another way. I have tested everything on LineageOS 16 that has init.d support

LuigiVampa92 avatar May 27 '20 00:05 LuigiVampa92

So far so good, thanks!

msgpo avatar May 28 '20 19:05 msgpo

Unfortunately, I had to apply rules or set permissive mode by init.d script.

You may be able to try to permanently patch the precompiled_sepolicy file in your shell script, using the magiskinit binary to do that. Something like (but the rules ofc):

mount -orw,remount /vendor
magiskpolicy --load /vendor/etc/selinux/precompiled_sepolicy --save /vendor/etc/selinux/precompiled_sepolicy "allow init domain process { noatsecure }" "allow init secd process { noatsecure }"
mount -oro,remount /vendor

Edit. I forgot to mention, this works on an xperia firmware, I'm not sure on others.

serajr avatar Jun 30 '20 16:06 serajr

Unfortunately, I had to apply rules or set permissive mode by init.d script.

You may be able to try to permanently patch the precompiled_sepolicy file in your shell script, using the magiskinit binary to do that. Something like (but the rules ofc):

mount -orw,remount /vendor
magiskpolicy --load /vendor/etc/selinux/precompiled_sepolicy --save /vendor/etc/selinux/precompiled_sepolicy "allow init domain process { noatsecure }" "allow init secd process { noatsecure }"
mount -oro,remount /vendor

Edit. I forgot to mention, this works on an xperia firmware, I'm not sure on others.

Same here thanks.

msgpo avatar Jul 06 '20 23:07 msgpo

@LuigiVampa92 Could you please share the modified Riru? I'm trying migrate EdXposed into my ROM directly.

imReker avatar Sep 18 '20 09:09 imReker

keep going,respect

saymyname77 avatar Sep 23 '20 07:09 saymyname77

@google-mirror hello, thanks for the interest to this topic. In case of normally installing magisk, riru-core and riru-edxposed erasing data partition will erase magisk modules configs and riru modules configs that stored in /data and because of that system will bootloop (seems that magiskinit will not be able to handle the situation). In the approach I used I took riru-core code and deleted everything that is related to parsing configs and initialising modules, added manual initialisation of riru-edxposed straight from the code (I don't use other riru modules anyway). So the result is that after I installed system edxposed and relocked the bootloader, data partition is wiped but that's ok, because it doesn't affect neither system nor installed edxposed. You can also make "factory reset" (or wipe data partition because it is technically the same) as much as you like in future

LuigiVampa92 avatar Dec 16 '20 09:12 LuigiVampa92

Once the bootloader is relocked, dm-verity is enforced. You have to sign boot image with device's oem keys or avb_custom_key, otherwise you will bootloop. Note that user-settable root of trust is not implemented for most of the devices.

google-mirror avatar Dec 16 '20 09:12 google-mirror

@google-mirror true, but OnePlus devices are (if I get that right) the only ones except Google Pixels that allow to use avb_custom_key embedded inside /boot partition. That is what I do in my case, I embed avb_custom_key, resign boot.img and it works. Not sure it is possible on other vendors. Actually the fact it was possible on OnePlus is the reason I started this thread :)

In the end you get a "yellow state" at verified boot. It tells that "device has installed an unknown operating system" but the bootloader is locked

LuigiVampa92 avatar Dec 16 '20 09:12 LuigiVampa92

Personally I really dislike breaking system-less stuffs so I will most probably not working on this, but fell free to open a PR.

kotori2 avatar Dec 17 '20 18:12 kotori2

@kotori2 sorry, I'm afraid I misunderstood you. But just in case, the thing I have been discussing in this thread is not something I intended to get merged into EdXposed master, it was made just for myself and it can be useful only for people that would like to make their own system builds with EdXposed embedded. I agree that for general use it is much more simple and convenient to use it systemless-ly, as as a magisk module, just as it works right now

LuigiVampa92 avatar Dec 18 '20 14:12 LuigiVampa92

Hello. I just got a new Android TV box (Minix Neo U22) that has Android 9 and is rooted (but without Magisk or superSu) - just comes with a switch to turn root on/off. I would love to be able to add EdXposed and wonder if the flashable zip mentioned in this thread will work. Thanks for any help/tips.

whitedavidp avatar Jan 18 '21 20:01 whitedavidp

@whitedavidp it's not like any of us can test this for you. Make a nandroid backup, and try flashing it. If it goes wrong restore the backup. What else do you expect lol

XspeedPL avatar Jan 18 '21 20:01 XspeedPL

I pretty much thought that. I just wanted to be sure I was understanding the purpose and intent of the reference project. Thanks

whitedavidp avatar Jan 18 '21 20:01 whitedavidp