Skip to content
This repository has been archived by the owner on Jun 1, 2023. It is now read-only.

Add required Samsung framework changes to the bridge #59

Closed
wanam opened this issue Aug 24, 2015 · 83 comments
Closed

Add required Samsung framework changes to the bridge #59

wanam opened this issue Aug 24, 2015 · 83 comments

Comments

@wanam
Copy link

wanam commented Aug 24, 2015

Hi @rovo89 ,

I think you are aware of the unofficial port of Xposed to the Galaxy S6: http://forum.xda-developers.com/xposed/unofficial-xposed-samsung-lollipop-t3180960.

To get this to work with Aosp Art, i made some changes to "core-libart.jar" and "conscrypt.jar", i'm thinking about porting my changes on the XposedBridge to avoid changing both files.

As a first step i'm taking "consrypt.jar" as example, i'm just hooking some methods on it to disable some security checks (mdpp and some white-listing) and add some missing crypto algos, this way i will avoid overriding the whole file on Samsung Roms, if this is possible can you point me where/when i should implement those hooks?

I tried inside "de.robv.android.xposed.initForZygote" and at the end of "handleBindApplication" but this does not seems to work.

Thanks.

@wanam wanam changed the title Disable Samsung Art Mdpp Add required Samsung changes to the bridge Aug 24, 2015
@wanam wanam changed the title Add required Samsung changes to the bridge Add required Samsung framework changes to the bridge Aug 24, 2015
@rovo89
Copy link
Owner

rovo89 commented Aug 25, 2015

Can you be a bit more specific? What are you trying to hook, how does it fail (e.g. any exceptions)?

By the way, I came across some older attempts of mine to get ART working on Samsung. Some of the enhancements might be useful for you and arter, so I'll send you an email.

@wanam
Copy link
Author

wanam commented Aug 25, 2015

I appreciate your help.

I'm trying to hook some native mdpp checks to disable it, here are my hooks: http://pastebin.com/9LCU2Wp1

If put those hook on the "initForZygote", it fails with a not found crypto digests, i don't know when they are loaded, i tried to load my hooks on a module while loading the package "android" or "com.android.org.conscrypt" but it seems to late as the hooks are never fired again.

@rovo89
Copy link
Owner

rovo89 commented Aug 26, 2015

it fails with a not found crypto digests

What's the exact exception you get? Does it fail when you try to hook the methods, when the hook is executed or as a side-effect of the hook being called?

Just some comments on your code:

The hook for setMDPP looks a bit strange. You override the first parameter, but then set a result, which will prevent the method from being called. If you just want to override the parameter value, leave out the second line. If you don't want the method to called, use returnConstant. If you want to override the parameter and want the method to be called and want to change the result, you have to move the setResult call to afterHookedMethod.

For the constructor hook, you should use findAndHookConstructor instead of hooking all constructors and just doing something when the parameter types match.

@wanam
Copy link
Author

wanam commented Aug 26, 2015

Thanks for tips,

I'm running now my hooks on initForZygote before and out of "systemMain" hook and it seems to run better now (updated my changes: http://pastebin.com/9LCU2Wp1).

The "not found crypto implementation" was caused by:

"mProfider.put("SecureRandom.SHA1PRNG", prefix + "OpenSSLRandom");"

i commented this line as it seems this algo implementation is not loaded yet or not existing (logs:http://pastebin.com/hyQFMNGz):

E/AndroidRuntime( 6364): java.lang.RuntimeException: java.security.NoSuchAlgorithmException: SecureRandom SHA1PRNG implementation not found: java.lang.ClassNotFoundException: AndroidOpenSSLOpenSSLRandom

I need some time to figure out what's wrong with those algos, but it seems the hooks on the bridge are working well.

Thanks for your help.

@wanam
Copy link
Author

wanam commented Aug 26, 2015

I managed to hook all required methods for both files "core-libart.jat" and "conscrypt.jar" with no issues (my changes: http://pastebin.com/9LCU2Wp1), but i still have 2 problems to get rid of the modified "core-libart.jat":

1- I need to add a declaration for 2 additional fields on "java.lang.DexCache":

String[] literals;
Object z_padding;

1- I need to support some Samsung native methods at low level, my knowledge on low level devs is limitted, so i just need some help with the declaration of bellow native methods on android_art, just an empty declaration just to satisfy the link as i will hook them later:

  • dalvik.system.PathClassLoader

    private static native PathClassLoader openNative(String paramString1, String paramString2, ClassLoader paramClassLoader);

  • java.lang.reflect.ArtField

    private native String getNameNative();
    private native Class<?> getTypeNative();

  • java.lang.reflect.ArtMethod

    private native String getNameNative();

  • java.lang.Class

    private native Field getDeclaredFieldInternalNative(String paramString);
    private native Field getFieldNative(String paramString);
    private native Method getMethodNative(String paramString, Class<?>[] paramArrayOfClass, boolean paramBoolean);

Thanks again for you help.

@rovo89
Copy link
Owner

rovo89 commented Aug 27, 2015

I have already implemented the native methods regarding reflection some time ago. I will send you the files, but my requirement would be that the changes required for Samsung ROMs will be open-source. I believe that this is one of reasons why Xposed is so successful and also you wouldn't have been able to create your fork without it.

@wanam
Copy link
Author

wanam commented Aug 27, 2015

Great, of course all my changes will be open source.

Thank you.

@rovo89
Copy link
Owner

rovo89 commented Aug 27, 2015

Ok, I was just wondering because https://github.com/wanam/android_art seems to contain just one Samsung-related commit. I made way more changes to libart and it still didn't work because it can't decode .odex.xz files (yet?). Also, I remember that you had various issues and crashes while getting it to run, but don't see how those were solved.

Anyway, here are my changes, based on AOSP 5.0: https://www.dropbox.com/sh/cj59tyovuuf2cpm/AACIp4qxxNRHUxH_W18PwGD0a?dl=0

  1. A utility method to detect whether we're on a Samsung ROM or not. It probably needs to check in more detail as there are now modified ROMs which are closer to AOSP. Also, it might be better to inline this if possible (maybe moving the check to a different method to reduce the size of the inlined method).
  2. Patch to read Samsung's modified OAT format.
  3. Patch to consider the additonal String.clear() method that Samsung has implemented.
  4. Patch to use the correct offsets in the DexCache class. As you mentioned, Samsung has added two fields, but IIRC, they're just needed by Java code (or not at all?).
  5. Patch to ignore the --art-fd parameter in dex2oat. Meanwhile, this would just trigger a warning, but even that should be avoided.
  6. Implementation of Samsung's native methods in the Class, ArtMethod, ArtField and Runtime classes. Additional review of the implementation (based on the AOSP 5.0 Java code) is very welcome. So you can throw away your hooks for those methods, which I would avoid anyway.

As you can see, the intention was to build one set of libraries that will work on Samsung and non-Samsung ROMs, including completely stock (odex'ed) ROMs. Not sure if that's realistic, as @arter97 has merged many more commits. We would have to review their necessity and impact on other ROMs, but I have very limited time to work on Xposed for the few next weeks.

My attempts to make Xposed compatible with Samsung stopped at the point where .odex.xz and .art files would have to be used. The .art file might be ignored (maybe?), so I hope this won't be much harder than supporting .odex.gz files, which I hope to finish relatively soon. Anyway, it would be a big step forward even if the ROM just had to be de-odex'ed, but not changed otherwise.

Please keep me updated how things work out.

@arter97
Copy link

arter97 commented Aug 27, 2015

odex.gz support can be found at CyanogenMod, maybe you can take a look at.
And I recently noticed that Samsung's newest firmwares start to have no compression over odex.

You can do xz stuffs later(as I don't see that as an emergency development-breaker).

And yes, none of my other commits are relavant than String.clear and ignoring arguments.

@arter97
Copy link

arter97 commented Aug 27, 2015

And as I mentioned to @wanam, you need to take more core-libart.jar and rip it open.
Samsung's ART is seriously fragmented.

So far I can test with S4, Note 3, S5, S6 and Note 5.
Compatibility checks must be done, feel free to ask me for spin a test build :)

@rovo89
Copy link
Owner

rovo89 commented Aug 27, 2015

odex.gz support can be found at CyanogenMod, maybe you can take a look at.

Only for patchoat, not for dex2oat. But yes, I'm basing my work on those commits, which are actually unmerged contributions to AOSP by Intel.

So with what you said, it sounds like a universal version might be possible - even it might be weeks or months ahead. Great!

@arter97
Copy link

arter97 commented Aug 27, 2015

And btw, art-fd is not the only flag you should ignore.
arter97/android_art@eed2177
See? Fragmentation.

S series, Note series, A series, J series..
Argh, headache.

My decision to include core-libart.jar has solved most of the fragmentation, thankfully. I was actually quite surprised to see no one complaining major issues such as boot.

@wanam
Copy link
Author

wanam commented Aug 27, 2015

@arter97 i think the flags are not a big problem, since we can ignore them, but some devices may have additional native methods like "Runtime_appStartupBegin/End" that @rovo89 already added on his patches, those methods exist on some devices only (and not on 5.1.1 builds as i know).

@rovo89 Thanks for the patches, i will see how i can use them and report back.

@rovo89
Copy link
Owner

rovo89 commented Aug 27, 2015

Well, basically I do ignore them meanwhile: rovo89/android_art@afd9bd1
I prefer to keep warnings though, and explicitely ignore certain arguments that are known to cause much log spam.

Sure, the variants might be a problem. But as long as they're just there or not, an existence check (or ignoring NoSuchMethodException) would be easy to do.

@arter97
Copy link

arter97 commented Aug 27, 2015

Plus, I can almost swear I saw backwards-incompatible libcore(core-libart.jar) changes which I don't see it'll be easy to cope both scenario with single binary.

In any cases, I'm not here to drag you guys down. Just a friendly "FYI" :)

@wanam
Copy link
Author

wanam commented Aug 27, 2015

It's all about trying to minimize (if we can't eliminate) hard-coded changes on the framework, i hate playing with Smali, it was my main reason of switching to xposed, let's hope :) .

@wanam
Copy link
Author

wanam commented Aug 27, 2015

Ok, it seems to boot fine with stock framework files and @rovo89 patches :)
I just removed two native methods "Runtime_appStartupBegin/End" from the patch and added a new one on the PathClassLoader.

I didn't use the oat_format patch, i don't know if we need it with a deodexed Rom.

@rovo89
Copy link
Owner

rovo89 commented Aug 27, 2015

Cool! I assume your other changes from http://pastebin.com/9LCU2Wp1 are still required, minus those that are now implemented natively? And the PathClassLoader implementation is just empty?

If I had known that, I could have published those patches half a year ago, but I got stuck with the xz decoding (as I was looking for a solution that works on stock) and also wasn't sure how many other issues would occur.

By the way, is the call to restoreUnsupportedServices() really needed when the services aren't removed before? And do you know why these FIPS/MDPP-related methods are incompatible with AOSP ART? Is the implementation for nativeCheckWhitelist() missing or more?

I didn't use the oat_format patch, i don't know if we need it with a deodexed Rom.

I would have thought so, as boot.oat is precompiled on every ROM as far as I know. Or does deodexing move the individual dex files back to their jar?

@rovo89
Copy link
Owner

rovo89 commented Aug 27, 2015

Oh, and as I mentioned before: The utility method probably has to be improved. Not sure how to handle ROMs that have a modified core-libart.jar. They might not work correctly with these patches, not sure. So maybe a bitmask or different return values are required to keep it all compatible.

@wanam
Copy link
Author

wanam commented Aug 27, 2015

Indeed i removed my native hooks on ArtField/ArtMethod/Class/PathClassLoader.

But i kept my mdpp/fips hooks, as they are still required, i have no idea why the Checkmdpp/nativeCheckWhitelist/CheckFipsMode are crashing, there are no helpful logs, they were main cause of the boot.art crashes i had in the past, the logs i was getting were just misleading.

The call to restoreUnsupportedServices() is required after the constructor because these services are not default inserted, they are marked as unsupported on the constructor.

I will give a try to see what happens on odexed Rom if get some free time this weekend.

Edit: the new method on PathClassLoader returns null to force the use of the default Aosp PathClassLoader constructor on the framework side.

@wanam
Copy link
Author

wanam commented Aug 27, 2015

So i tested the same xposed version with oat_format patch on Odexed OH2 (5.1.1) and got a boot-loop with a strange permission error: http://pastebin.com/2bBPt0Xu.

@arter97
Copy link

arter97 commented Aug 27, 2015

The mdpp stuffs are related to Knox. It somehow checks ART binary and rejects it if it's not stock.

@rovo89
Copy link
Owner

rovo89 commented Aug 28, 2015

@wanam I have seen such permission errors before. The system tries to load the file, but sees that there's no compiled file yet, so it calls dex2oat. Problem is that it can only do that with the current UID and permissions (system_server in this case), not via installd which runs as root. So the missing permission is for writing to the Dalvik cache.

Anyway, the fact that it has to compile at this point is just a consequence of a previous failure to compile the same file. Can you check if there's another dex2oat call for this file? Also, are these files compressed?

@wanam
Copy link
Author

wanam commented Aug 28, 2015

It says (full logs: http://pastebin.com/w3HmzK7A):

W/installd( 2966): Skip dexopt becuase we have precompiled the apk in /system/framework/arm64/services.odex
W/installd( 2966): Skip dexopt becuase we have precompiled the apk in /system/framework/arm64/ethernet-service.odex
W/installd( 2966): Skip dexopt becuase we have precompiled the apk in /system/framework/arm64/wifi-service.odex
I/InstallerConnection( 3833): disconnecting...
E/installd( 2966): eof
E/installd( 2966): failed to read size
I/installd( 2966): closing connection

The odex files are not compressed.

@arter97
Copy link

arter97 commented Aug 28, 2015

Btw guys, where should I be looking at for latest Samsung sources you guys are working on?

@wanam
Copy link
Author

wanam commented Aug 28, 2015

I committed my Bridge changes: wanam@eca7063

Some specific Note5 hooks are included in my commit, but still untested (i don't own the device to test them).

I didn't make any other changes to android_art, i will commit @rovo89 patches to my repo (https://github.com/wanam/android_art) soon.

@arter97
Copy link

arter97 commented Aug 29, 2015

Now I'm catching up with the party.
Fantastic work, you guys have really pulled this off.

Now it seems like all I can help is go check some cross-device's compatibility :)

@rovo89
Copy link
Owner

rovo89 commented Sep 8, 2015

@wanam Most likely, you will also need to add a check here (maybe restructuring the lines added for Xposed a bit): https://github.com/rovo89/android_art/blob/xposed-lollipop-mr1/dex2oat/dex2oat.cc#L1543
Maybe it would also make sense to add a new function to utils.cc to check for odex'ed / gzipped / renamed odex files and return the one that matches (or nullptr otherwise).

@arter97 Yes, odex files need to be recompiled, otherwise they're too optimized and many hooks won't work or are unreliable (e.g. because some methods will be inlined or called directly).

@arter97
Copy link

arter97 commented Sep 8, 2015

I'm surprised that odex actually can be recompiled lol.
Anyways, shouldn't we solve the odex formatting recognition first than the installd/dex2oat issue?

@rovo89
Copy link
Owner

rovo89 commented Sep 8, 2015

I'm surprised that odex actually can be recompiled lol.

Normally, they can't be recompiled, this is something that I have added for Xposed. They contain the dex file, but the code is pre-optimized (just like the odex files on Dalvik).

Anyways, shouldn't we solve the odex formatting recognition first than the installd/dex2oat issue?

Not sure what "odex formatting recognition" means. If you're referring to the issue with your boot.oat - that's exactly caused by the optimized code, which contains exactly two statements that ART's method verifier can't handle because it's an edge case. The format can be read just fine and all methods except for this one can be recompiled. I'm working on a work-around for your issue, but that's no reason to stop working on other frontiers. This could actually happen on any other ROM as well, given that the code is complex enough.

@wanam
Copy link
Author

wanam commented Sep 8, 2015

I just tried it and it seems to boot fine on odexed OH8, but with a low space issue :) , i will give an other try with the interpret-only filter.

@wanam
Copy link
Author

wanam commented Sep 8, 2015

Tried the interpret-only filter with no success, dalvik-cache went down 600MB, but still getting the "not enough space for sustem"!

No idea what is triggering this message.

@rovo89
Copy link
Owner

rovo89 commented Sep 9, 2015

No idea what is triggering this message.

I don't know this either... But good to know that it works in general. Now we just need to know in which cases the files have to be renamed...

@arter97
Copy link

arter97 commented Sep 9, 2015

That space issue actually happened to me when messing around the compiler
for ART, though I honestly don't remember what exactly it was.

On Wed, Sep 9, 2015 at 4:45 PM, rovo89 [email protected] wrote:

No idea what is triggering this message.

I don't know this either... But good to know that it works in general. Now
we just need to know in which cases the files have to be renamed...


Reply to this email directly or view it on GitHub
#59 (comment).

@wanam
Copy link
Author

wanam commented Sep 9, 2015

@arter97 i don't think so, the same patch works fine with my deodexed OH8, and it's not generating any errors on the xposed logs, it fixes by the way the gms bug rovo89/android_art#15.

But yes maybe it's my C coding to be blamed, the last time i C codded was more than 10 years ago :) , here are my changes :

diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 74a692d..d732037 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -660,7 +660,7 @@ static size_t OpenDexFiles(const std::vector<const char*>& dex_filenames,
       continue;
     }
     std::unique_ptr<File> file;
-    if (EndsWith(dex_filename, ".oat") || EndsWith(dex_filename, ".odex")) {
+    if (EndsWith(dex_filename, ".oat") || EndsWith(dex_filename, ".odex") || EndsWith(dex_filename, ".sam.xposed")) {
       file.reset(OS::OpenFileForReading(dex_filename));
       if (file.get() == nullptr) {
         LOG(WARNING) << "Failed to open file '" << dex_filename << "': " << strerror(errno);
@@ -1542,7 +1542,7 @@ static int dex2oat(int argc, char** argv) {
     if (dex_filenames.empty()) {
       odex_filename = DexFilenameToOdexFilename(zip_location, instruction_set);
       if (!OS::FileExists(odex_filename.c_str())) {
-        odex_filename += ".gz.xposed";
+        odex_filename = GetRenamedOdexFileName(odex_filename);
       }
       if (OS::FileExists(odex_filename.c_str())) {
         LOG(INFO) << "Using '" << odex_filename << "' instead of file descriptor";
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 5fb3082..96d7d49 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -626,7 +626,9 @@ bool ClassLinker::GenerateOatFile(const char* dex_filename,

   std::string odex_filename(DexFilenameToOdexFilename(dex_filename, kRuntimeISA));
   std::string dex_file_option("--dex-file=");
-  dex_file_option += OS::FileExists(odex_filename.c_str()) ? odex_filename : dex_filename;
+  const char* android_data = GetAndroidData();
+  const std::string dalvik_cache_root(StringPrintf("%s/dalvik-cache/", android_data));
+  dex_file_option += (StartsWith(oat_cache_filename, dalvik_cache_root.c_str()) && OS::FileExists(odex_filename.c_str())) ? odex_filename : dex_filename;

   std::string oat_fd_option("--oat-fd=");
   StringAppendF(&oat_fd_option, "%d", oat_fd);
diff --git a/runtime/utils.cc b/runtime/utils.cc
index adc701f..120dd00 100644
--- a/runtime/utils.cc
+++ b/runtime/utils.cc
@@ -1398,4 +1398,18 @@ bool IsSamsungROM() {
   return result;
 }

+std::string GetRenamedOdexFileName(std::string odex_filename) {
+  std::string filename (odex_filename + ".gz.xposed");
+  if (OS::FileExists(filename.c_str())) {
+    return filename;
+  } else {
+    filename = odex_filename + ".sam.xposed";
+    if (OS::FileExists(filename.c_str())) {
+      return filename;
+    }
+  }
+
+  return odex_filename;
+}
+
 }  // namespace art
diff --git a/runtime/utils.h b/runtime/utils.h
index c2bf395..7c1d7d9 100644
--- a/runtime/utils.h
+++ b/runtime/utils.h
@@ -559,6 +559,9 @@ using UniqueCPtr = std::unique_ptr<T, FreeDelete>;

 bool IsSamsungROM();

+// Returns renamed odex file name if exists
+std::string GetRenamedOdexFileName(std::string odex_filename);
+
 }  // namespace art

 #endif  // ART_RUNTIME_UTILS_H_

@wanam
Copy link
Author

wanam commented Sep 9, 2015

@rovo89 I think there are only two cases for now for the renaming, check if odexes are gz compressed (and maybe xz later, this case should support TW and others), if not then check if TW.

@wanam
Copy link
Author

wanam commented Sep 9, 2015

I'm getting this error:

E/dex2oat ( 3726): Verification failed on class android.view.ViewDebug in /system/framework/framework.jar:classes2.dex because: Verifier rejected class android.view.ViewDebug due to bad method void android.view.ViewDebug.dump_s(android.view.View, boolean, boolean, java.io.OutputStream)

and this one:

F/art (12352): art/runtime/gc/space/image_space.cc:354] Unable to read image header for /system/framework/boot.art at /system/framework/arm/boot.art

Just before the low space error:

E/Icing (11364): Not enough disk space for indexing
I/Icing (11364): Internal init done: storage state 2

So i guess the last one is just a side effect as @arter97 said.

Logs: https://www.dropbox.com/s/9j3gmoegmsmqa23/log-odex-low-space.tar.gz?dl=0
Arm boot.art: https://www.dropbox.com/s/kd0t0tsl8kva4vq/boot.art.arm.tar.gz?dl=0

@rovo89
Copy link
Owner

rovo89 commented Sep 10, 2015

@arter97 I could recompile your boot.oat after this commit: rovo89/android_art@c6341dc

@wanam I hope this will also fix the other issues... but I don't really see the relation.
Regarding the renamed files: I think I would name them ".odex.xposed", similar to ".odex.gz.xposed". No idea for which other ROMs this will be needed, so ".sam.xposed" might be misleading. If you haven't published a version with that rename so far, please consider dropping the ".sam" so we don't have too many cases in the future. My implementation would probably be slightly different, but yours looks fine as well.

@wanam
Copy link
Author

wanam commented Sep 10, 2015

Great i will the new commits soon.
I will use your renaming format.

@wanam
Copy link
Author

wanam commented Sep 10, 2015

I tried your v74 commits on odexed OH8, the boot.art dexopting seems to be fixed, but i'm getting 2 new errors with SystemUI and AdvSoundDetector2015 with a low space at the end:

I/dex2oat ( 5801): Verification error in android.support.v4.app.NotificationCompatBase$Action android.support.v4.app.NotificationCompat$Action$1.build(int, java.lang.CharSequence, android.app.PendingIntent, android.os.Bundle, android.support.v4.app.RemoteInputCompatBase$RemoteInput[])
I/dex2oat ( 5801): android.support.v4.app.NotificationCompatBase$Action android.support.v4.app.NotificationCompat$Action$1.build(int, java.lang.CharSequence, android.app.PendingIntent, android.os.Bundle, android.support.v4.app.RemoteInputCompatBase$RemoteInput[]) failed to verify: android.support.v4.app.NotificationCompatBase$Action android.support.v4.app.NotificationCompat$Action$1.build(int, java.lang.CharSequence, android.app.PendingIntent, android.os.Bundle, android.support.v4.app.RemoteInputCompatBase$RemoteInput[]): [0x4] returning 'Reference: android.support.v4.app.NotificationCompat$Action', but expected from declaration 'Reference: android.support.v4.app.NotificationCompatBase$Action'
I/dex2oat ( 5801): Verification error in android.support.v4.app.NotificationCompatBase$Action[] android.support.v4.app.NotificationCompat$Action$1.newArray(int)
I/dex2oat ( 5801): android.support.v4.app.NotificationCompatBase$Action[] android.support.v4.app.NotificationCompat$Action$1.newArray(int) failed to verify: android.support.v4.app.NotificationCompatBase$Action[] android.support.v4.app.NotificationCompat$Action$1.newArray(int): [0x4] returning 'Reference: android.support.v4.app.NotificationCompat$Action[]', but expected from declaration 'Reference: android.support.v4.app.NotificationCompatBase$Action[]'
E/dex2oat ( 5801): Verification failed on class android.support.v4.app.NotificationCompat$Action$1 in /system/priv-app/SystemUI/SystemUI.apk because: Verifier rejected class android.support.v4.app.NotificationCompat$Action$1 due to bad method android.support.v4.app.NotificationCompatBase$Action[] android.support.v4.app.NotificationCompat$Action$1.newArray(int)

and:

I/dex2oat ( 7280): /system/bin/dex2oat --zip-fd=11 --zip-location=/system/app/AdvSoundDetector2015/AdvSoundDetector2015.apk --oat-fd=12 --art-fd=-1 --compress-image --oat-location=/data/dalvik-cache/arm/system@app@AdvSoundDetector2015@[email protected] --instruction-set=arm --instruction-set-features=div --runtime-arg -Xms64m --runtime-arg -Xmx512m --compiler-filter=balanced --swap-fd=13
E/dex2oat ( 7280): Failed to open dex from file descriptor for zip file '/system/app/AdvSoundDetector2015/AdvSoundDetector2015.apk': Entry not found

Here are the failed files: https://www.dropbox.com/s/oc07yc3x2rqc1z1/AdvSound%2BSystemUI.tar.gz?dl=0

Here are the logs: https://www.dropbox.com/s/r2yzkg7jd1e10vd/log11092015.txt.tar.gz?dl=0

@wanam
Copy link
Author

wanam commented Sep 11, 2015

@rovo89 i replaced both failed files (SystemUI and AdvSoundDetector2015) with a deodexed ones, just verify if they are the real source of this issue, unfortunately no.

I still get this error:

F/art (10310): art/runtime/gc/space/image_space.cc:362] Unable to read image header for /system/framework/boot.art at /system/framework/arm/boot.art

@arter97
Copy link

arter97 commented Sep 13, 2015

Probably this is off-topic, but starting with Android 5.1, Samsung decided to preopt apks also in /system/container, which I don't think AOSP can understand.

Should we need to worry about that, or is it outside of where Xposed is touching?

@wanam
Copy link
Author

wanam commented Sep 13, 2015

I don't think it's something we should worry about, we can remove them anyway if we can't use nor need them.

@wanam
Copy link
Author

wanam commented Sep 14, 2015

I got many low space reports on some Deodexed TW Roms where the Rom maker left odexed framework inside and they got it fixed by removing arm/arm64 folders, that's why i'm convinced this issue is caused by ReadSpecificImageHeader failing at https://github.com/rovo89/android_art/blob/xposed-lollipop-mr1/runtime/gc/space/image_space.cc#L382 :

F/art (10310): art/runtime/gc/space/image_space.cc:362] Unable to read image header for /system/framework/boot.art at /system/framework/arm/boot.art

I checked the image header magic/version of "boot.art" and it seems correct: "art\n12\0".

@rovo89 Do you have any idea what may cause this issue? should i debug those elements verification? https://github.com/rovo89/android_art/blob/xposed-lollipop-mr1/runtime/image.cc#L52

@wanam
Copy link
Author

wanam commented Sep 15, 2015

I did a few more debugging and found that the image header fails exactly at https://github.com/wanam/android_art/blob/xposed-lollipop-mr1/runtime/image.cc#L95
Ignoring this check let the Rom boot up on odexed OH8 with no space nor FC issues, but both compilation errors of SystemUI and AdvSoundDetector2015 are still there (logs on my previous post).

This has been tested without Knox apps nor built-in Facebook, Microsoft ones.

@wanam
Copy link
Author

wanam commented Sep 15, 2015

@rovo89 here are the offsets i'm getting with odexed OH8:
image_begin_ = 1879048192
image_roots_ = 0034664448
oat_file_begin_= 1913176064

I think image_roots_ is the wrong one, it should be and offset between image_begin and oat_file_begin_.

@rovo89
Copy link
Owner

rovo89 commented Sep 30, 2015

Maybe Samsung stores additional information in the image, just like they do for oat files (wanam/android_art@4358b59)?

We could either try to find out more details, or try to avoid this check completely. Can you try to change https://github.com/wanam/android_art/blob/xposed-lollipop-mr1/runtime/runtime.cc#L693 to must_relocate_ = false and see if that helps?

@wanam
Copy link
Author

wanam commented Sep 30, 2015

Yes, forcing must_relocate_ = false fixes this issue without the need to ignore the check.

@rovo89
Copy link
Owner

rovo89 commented Sep 30, 2015

OK. This will obviously need good testing on 5.0 and 5.1 to ensure that there are no side-effects, especially after clearing the Dalvik cache. I'll add this change locally.

@rovo89
Copy link
Owner

rovo89 commented Oct 3, 2015

Class.getPublicFieldRecursive() is now implemented as a native method in AOSP: https://android.googlesource.com/platform/art/+/72f9075e92cfc4632d6c50f282a0f6319b718882%5E!/
Maybe worth to review my implementation, even though the master branch might differ a lot from 5.0/5.1.

@wanam
Copy link
Author

wanam commented Oct 13, 2015

As you said there are a lot of differences between the master branch and LL releases, but at least i will try to modify your implementation to follow their search order: current class, interfaces, then super classes.

What do you think about this?

static mirror::ArtField* getPublicFieldRecursive(mirror::Class* c, const StringPiece& name) {

  while (c != nullptr) {

    // Search current class
    mirror::ArtField* result = getDeclaredFieldInternal(c, name);
    if (result != nullptr && result->IsPublic())
      return result;

    // Search iftable which has a flattened and uniqued list of interfaces
    int32_t iftable_count = c->GetIfTableCount();
    mirror::IfTable* iftable = c->GetIfTable();
    for (int32_t i = 0; i < iftable_count; i++) {
      mirror::ArtField* result = getPublicFieldRecursive(iftable->GetInterface(i), name);
      if (result != nullptr && result->IsPublic())
        return result;
    }

    // We don't try the superclass if we are an interface.
    if(c->IsInterface()){
      break;
    }

    // Get the next class.
    c = c->GetSuperClass();

  }
  return nullptr;
}

@wanam
Copy link
Author

wanam commented Oct 13, 2015

I tried the above modification and it seems to work great, but i can't confirm if it has any performance improvements.

I actually still have 2 "minor" issues with stock TW 5.1.1 Roms:
1- Dex2oat executed with a wrong arm mode for AdvSoundDetector2015.apk:

/system/bin/dex2oat --zip-fd=11 --zip-location=/system/app/AdvSoundDetector2015/AdvSoundDetector2015.apk --oat-fd=12 --art-fd=-1 --compress-image --oat-location=/data/dalvik-cache/arm/system@app@AdvSoundDetector2015@[email protected] --instruction-set=arm --instruction-set-features=div --runtime-arg -Xms64m --runtime-arg -Xmx512m --swap-fd=13
E/dex2oat ( 6560): Failed to open dex from file descriptor for zip file '/system/app/AdvSoundDetector2015/AdvSoundDetector2015.apk': Entry not found
E/installd( 2967): DexInv: --- END '/system/app/AdvSoundDetector2015/AdvSoundDetector2015.apk' --- status=0x0100, process failed

Its odex file is an arm64 file, but the dex2oat is executed somehow with the instruction-set arm, so it can't locate the file in the correct folder, Samsung bug? any idea how can i handle it? can i check just the second folder if not found in the first one? https://github.com/wanam/android_art/blob/xposed-lollipop-mr1/dex2oat/dex2oat.cc#L1667

2- Compilation error on SystemUI bundled support-v4:

I/dex2oat ( 5641): android.support.v4.app.NotificationCompatBase$Action[] android.support.v4.app.NotificationCompat$Action$1.newArray(int) failed to verify: android.support.v4.app.NotificationCompatBase$Action[] android.support.v4.app.NotificationCompat$Action$1.newArray(int): [0x4] returning 'Reference: android.support.v4.app.NotificationCompat$Action[]', but expected from declaration 'Reference: android.support.v4.app.NotificationCompatBase$Action[]'
E/dex2oat ( 5641): Verification failed on class android.support.v4.app.NotificationCompat$Action$1 in /system/priv-app/SystemUI/SystemUI.apk because: Verifier rejected class android.support.v4.app.NotificationCompat$Action$1 due to bad method android.support.v4.app.NotificationCompatBase$Action[] android.support.v4.app.NotificationCompat$Action$1.newArray(int)

SystemUI odex file: https://www.dropbox.com/s/i5kqim4w3j307iw/systemui-odex-arm64.zip?dl=0

@wanam
Copy link
Author

wanam commented Oct 16, 2015

@rovo89

I think the point (1) on my above comment does not need to be fixed on the Xposed level, i renamed the odex folder "AdvSoundDetector2015/arm64" to "AdvSoundDetector2015/arm" and it got compiled with no issues, this app has a depending lib32 native libraries too, so i guess it's just a FW packaging bug on the Samsung side.

For the second point, it seems related to a RETURN_OBJECT verification for arrays, i will try this: https://android.googlesource.com/platform/art/+/16f149c2cb43a14d8f33d7d0fa36cd784e900f07

@wanam
Copy link
Author

wanam commented Oct 18, 2015

Sadly this modification (https://android.googlesource.com/platform/art/+/16f149c2cb43a14d8f33d7d0fa36cd784e900f07) didn't help much, taking a look at http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.0.1_r1/android/support/v4/app/NotificationCompat.java#2114, the return type is "android.support.v4.app.NotificationCompat$Action[]" i don't know why it is expecting the extended class "android.support.v4.app.NotificationCompatBase$Action[]".

I committed also a modification wanam/android_art@6e564a6 of "getPublicFieldRecursive" that seems to work great here.
Sorry for the edits, something is wrong with the threading on this recursive implementation, so i went back to the first one i post above.

@wanam
Copy link
Author

wanam commented Nov 23, 2015

Closing this issue as most of the issues with Samsung Roms have been fixed.
The last one reported on the proper repo: rovo89/android_art#20

@wanam wanam closed this as completed Nov 23, 2015
@Bluscream
Copy link

Please make XPosed for Touchwiz happen <3

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants