rovo89 / Xposed

The native part of the Xposed framework (mainly the modified app_process binary).
Other
7.42k stars 1.47k forks source link

Bootloop on ASUS ME302C / MeMO Pad FHD (x86) #6

Open rovo89 opened 10 years ago

rovo89 commented 10 years ago

http://forum.xda-developers.com/showpost.php?p=46440353 http://forum.xda-developers.com/showpost.php?p=51177359&postcount=9754

D/MountService(  460): volume state changed for /Removable/MicroSD (unmounted -> checking)
D/MountService(  460): sendStorageIntent Intent { act=android.intent.action.MEDIA_CHECKING dat=file:///Removable/MicroSD (has extras) } to UserHandle{-1}
E/Vold    (  138): Filesystem check failed (not an exFAT filesystem)
I/fsck_msdos(  138): ** /dev/block/vold/179:51
I/fsck_msdos(  138): ** Phase 1 - Read FAT (compare skipped)
I/fsck_msdos(  138): Attempting to allocate 7616 KB for FAT
I/DEBUG   (  145): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG   (  145): Build fingerprint: 'asus/WW_epad/ME302C:4.3/JSS15Q/WW_epad-V5.0.16-20140226:user/release-keys'
I/DEBUG   (  145): Revision: '0'
I/DEBUG   (  145): pid: 460, tid: 466, name: Compiler  >>> system_server <<<
I/DEBUG   (  145): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000011
I/DEBUG   (  145):     eax 00000001  ebx 72a22bf0  ecx 413a50d4  edx 7024ff4c
I/DEBUG   (  145):     esi 000000c0  edi 72a22d44
I/DEBUG   (  145):     xcs 00000073  xds 0000007b  xes 0000007b  xfs 00000000  xss 0000007b
I/DEBUG   (  145):     eip 411f0372  ebp 7ae8af20  esp 72a22b20  flags 00210202
I/DEBUG   (  145): 
I/DEBUG   (  145): backtrace:
I/DEBUG   (  145):     #00  pc 00142372  /system/lib/libdvm.so
I/DEBUG   (  145):     #01  pc 0019de89  /system/lib/libdvm.so
I/DEBUG   (  145):     #02  pc 0013b250  /system/lib/libdvm.so
I/DEBUG   (  145):     #03  pc 000e880e  /system/lib/libdvm.so
I/DEBUG   (  145):     #04  pc 0001b55c  /system/lib/libc.so
I/DEBUG   (  145):     #05  pc 0003dcb5  /system/lib/libc.so
I/DEBUG   (  145):     #06  pc 000e85ff  /system/lib/libdvm.so
I/DEBUG   (  145): 
I/DEBUG   (  145): stack:
I/DEBUG   (  145):          72a22ae0  00000000  
I/DEBUG   (  145):          72a22ae4  00000000  
I/DEBUG   (  145):          72a22ae8  00000000  
I/DEBUG   (  145):          72a22aec  00000000  
I/DEBUG   (  145):          72a22af0  00000000  
I/DEBUG   (  145):          72a22af4  00000000  
I/DEBUG   (  145):          72a22af8  00000000  
I/DEBUG   (  145):          72a22afc  00000000  
I/DEBUG   (  145):          72a22b00  00000000  
I/DEBUG   (  145):          72a22b04  00000000  
I/DEBUG   (  145):          72a22b08  00000000  
I/DEBUG   (  145):          72a22b0c  00000000  
I/DEBUG   (  145):          72a22b10  00000000  
I/DEBUG   (  145):          72a22b14  00000000  
I/DEBUG   (  145):          72a22b18  00000000  
I/DEBUG   (  145):          72a22b1c  00000000  
I/DEBUG   (  145):     #00  72a22b20  72a22bf0  [stack:466]
I/DEBUG   (  145):          72a22b24  00000008  
I/DEBUG   (  145):          72a22b28  72a22b4c  [stack:466]
I/DEBUG   (  145):          72a22b2c  72a22b50  [stack:466]
I/DEBUG   (  145):          72a22b30  7d94d25e  /dev/ashmem/dalvik-jit-code-cache (deleted)
I/DEBUG   (  145):          72a22b34  72a22ba4  [stack:466]
I/DEBUG   (  145):          72a22b38  00000001  
I/DEBUG   (  145):          72a22b3c  00000001  
I/DEBUG   (  145):          72a22b40  412a881c  /system/lib/libdvm.so
I/DEBUG   (  145):          72a22b44  72a22c28  [stack:466]
I/DEBUG   (  145):          72a22b48  01040002  
I/DEBUG   (  145):          72a22b4c  7d94d0ac  /dev/ashmem/dalvik-jit-code-cache (deleted)
I/DEBUG   (  145):          72a22b50  00000001  
I/DEBUG   (  145):          72a22b54  00000000  
I/DEBUG   (  145):          72a22b58  00000000  
I/DEBUG   (  145):          72a22b5c  00000000  
I/DEBUG   (  145):          ........  ........
I/DEBUG   (  145):     #01  72a22d80  7ae8af20  
I/DEBUG   (  145):          72a22d84  00000064  
I/DEBUG   (  145):          72a22d88  72a22dfc  [stack:466]
I/DEBUG   (  145):          72a22d8c  72a22e18  [stack:466]
I/DEBUG   (  145):          72a22d90  00000000  
I/DEBUG   (  145):          72a22d94  400c8568  /system/lib/libc.so
I/DEBUG   (  145):          72a22d98  00000000  
I/DEBUG   (  145):          72a22d9c  72a22db0  [stack:466]
I/DEBUG   (  145):          72a22da0  72a22db4  [stack:466]
I/DEBUG   (  145):          72a22da4  798615d0  
I/DEBUG   (  145):          72a22da8  413a50a0  
I/DEBUG   (  145):          72a22dac  41193441  /system/lib/libdvm.so
I/DEBUG   (  145):          72a22db0  00000000  
I/DEBUG   (  145):          72a22db4  00001204  
I/DEBUG   (  145):          72a22db8  00000001  
I/DEBUG   (  145):          72a22dbc  72a22e18  [stack:466]
I/DEBUG   (  145):          ........  ........
I/DEBUG   (  145):     #02  72a22dd0  72a22df0  [stack:466]
I/DEBUG   (  145):          72a22dd4  413a5094  
I/DEBUG   (  145):          72a22dd8  00000007  
I/DEBUG   (  145):          72a22ddc  00000002  
I/DEBUG   (  145):          72a22de0  000000e6  
I/DEBUG   (  145):          72a22de4  00000000  
I/DEBUG   (  145):          72a22de8  00000000  
I/DEBUG   (  145):          72a22dec  41194dbe  /system/lib/libdvm.so
I/DEBUG   (  145):          72a22df0  7024ff4c  /system/framework/core.odex
I/DEBUG   (  145):          72a22df4  00000002  
I/DEBUG   (  145):          72a22df8  7ae8af20  
I/DEBUG   (  145):          72a22dfc  00000000  
I/DEBUG   (  145):          72a22e00  00000000  
I/DEBUG   (  145):          72a22e04  00000000  
I/DEBUG   (  145):          72a22e08  00000000  
I/DEBUG   (  145):          72a22e0c  78ee6870  
I/DEBUG   (  145):          ........  ........

libdvm.so: http://forum.xda-developers.com/showpost.php?p=51192467&postcount=9775

perpe commented 10 years ago

Like wrote at http://forum.xda-developers.com/showpost.php?p=51193327&postcount=9784 Intel made some changes to the dalvik for their ARM emulation. I uploaded the Native.cpp from Android IA for 4.2.2 to https://dl.dropboxusercontent.com/u/18073580/Native.cpp Have a look to the beginning, line 406 and the following to see how houdini hooks into dalvik. (the dvmChangeStatus looks like in AOSP, but this source is for 4.2.2 and sadly not for 4.3) Edit: The device has also a second libdvm.so, for ARM. You can find it at https://dl.dropboxusercontent.com/u/18073580/libdvm.so (not open sourced)

rovo89 commented 10 years ago

Thanks, maybe that will help. I remember that Houdini caused some problems on the Genymotion emulator, but I think I worked around that... Can you tell me where I can find the full source code for their modified Dalvik?

perpe commented 10 years ago

Sure, everything can be found at https://01.org/android-ia/documentation/developers. They have also a gitweb (was not the case in the past, I saw it right now ;)) Genymotion used the 4.2.2 and older binaries, the source on 01.org is for 4.2.2, too. Our MeMO Pad FHD has Android 4.3. It seems that Intel changed the houdini implementation. Intel updated their IA repo on July last year, the MeMO Pad gets monthly updates and most of the time this updates contains modifications in houdini. In all probability you won't find anything helpful there, because it's outdated.

rovo89 commented 10 years ago

Thanks. Too bad that the new version is not open source, that would be really helpful. What I can say already: 00142372 is in function dvmCompileTrace(). That's part of the JIT compiler. I'll try to find out more, but could you try to test it without JIT?

I usually do this with setprop dalvik.vm.execution-mode int:fast or setprop dalvik.vm.execution-mode int:portable, but I also found setprop dalvik.vm.jit.codecachesize 0.

perpe commented 10 years ago

setprop dalvik.vm.execution-mode int:fast works :)

rovo89 commented 10 years ago

So without JIT, Xposed is working fine?

perpe commented 10 years ago

I don't know, if fine. Haven't test it much, but the stuck on boot logo in gone away. Android starts and Xposed Installer, say it's installed :+1:

rovo89 commented 10 years ago

Ok, I'm pretty sure know what the issue is. I need to reset the code cache after placing hooks. This is done by setting gDvmJit.codeCacheFull = true. This member has offset +0x78 in AOSP. However, I checked in another function that is using this member in libdvm.so that the offset in this ROM is +0x98.

The crashing statement is cmp edx, [eax+10h], with eax being 1 (so it tries to access memory address 0x11, which doesn't exist). A few lines before, eax is set to the value at 0x2F70D8, which is gDvmJit+0x78. So it seems to be expecting some kind of pointer there, but Xposed writes 1 (true) to this address - the 1 you see in the crash.

I will send you test version where I hard-code the offset to +0x98. If that works, I will have to find indicators when to use which offset.

perpe commented 10 years ago

I tested a little bit now, gravity box works. :-) setprop dalvik.vm.jit.codecachesize 0 was the only one of the three commands, that doesn't work. Ok, I'm ready to test it ;-)

Vielen Dank :-)

rovo89 commented 10 years ago

That sounds good! It's ok that this command doesn't work, I just found it in the documentation when I looked up how to disable JIT (as I didn't remember the command).

Here is the test version: https://www.dropbox.com/s/fvt08kqx5bhnxqa/XposedInstaller_2.5-beta2%2BASUS.apk Please make sure to hit install/update again, it should be app_process version 51. Afterwards, please reboot to reset the properties.

perpe commented 10 years ago

Installed and works, without help from adb, without disabling jit :+1: Fantastic!

rovo89 commented 10 years ago

Ok, that's great! It won't be part of version 2.5 though as I still need to detect which offset to use (unfortunately, variable names etc. aren't available in the compiled library). Afterwards, I need to test it very carefully. As you saw, a wrong offset leads to bootloops and if the +0x98 offset is applied to any other ROMs, then it will crash there.

perpe commented 10 years ago

That's ok, I and other MeMO Pad owners can live with an unoffcial version. In my opinion, it's a good choice to wait a little bit and be careful. There are other x86 devices, we don't know if they have the same problems. At the moment only the MeMO Pad FHD and Dell Venue Tablets are udated to 4.3 The ASUS Fonepads and the Samsung Galaxy Tab 3 10.1 are stlll on 4.2.2. These tablet could have the same problem with 4.3, if they get updated. So, it would be the best to wait and test, if they need the same offset.

rovo89 commented 10 years ago

Actually there were already bootloops with this phone on Android 4.2.2. That version also had the extended dvmChangeStatus() function, which is not part of Intel's source code.

perpe commented 10 years ago

I haven't test it with Android 4.2.2. Others reported that it works with 4.2.2 and haven't updated to 4.3, they don't want to lose xposed ;) We got a lot of 4.2.2 updates, maybe it doesn't work on every 4.2.2 version for the MeMO Pad FHD. I'm pretty sure that it works with the firmware version 4.7.3, last Android 4.2.2 version was firmware 4.7.7. If it is necessary, I can downgrade to test, which version works and which don't.

perpe commented 10 years ago

I have downgraded to version 4.2.2 (firmware 4.7.3) Both versions of xposed (2.5beta and the modified one for this tablet) are working. Has the modified one a securtiy feature to only set the offset on the 5.0.16 ROM? Or can we assume that 4.7.3 is compatible with the offset 0x98? If you need some additional logs, libdvm.so form 4.7.3 firmware, I can upload them somewhere.

rovo89 commented 10 years ago

Could you send me the libdvm.so for this older ROM as well? Then I can check which offset it uses. It's possible that it uses offset 0x78, but writing 1 to 0x98 doesn't cause any visible/severe effects. Yet it would mean that the JIT cache isn't reset, so hooks may or may not be called, and that maybe 1 will have other effects that you just didn't notice yet. Or maybe the older ROM just doesn't have JIT compiled in/enabled.

In any case, it's good if I can compare the libdvm.so's to find out how I can distinguish between them.

perpe commented 10 years ago

You can find it at https://dl.dropboxusercontent.com/u/18073580/libdvm473-logs.tar.gz The logcat with xposed version .50 and .51 are in the archive, too.

perpe commented 10 years ago

I wrote a thread in the german community and attached the modified version. I hope, this is OK for you. ( http://www.android-hilfe.de/root-custom-roms-modding-fuer-asus-memo-pad-fhd-10/549916-xposed-me302c-version.html#post7366980) Dropbox isn't a good hoster for frequently downloaded files. It could happen, that they block file sharing for that account. Some other files for the MeMO Pad got over 5000 downloads. I don't want that your account gets overwhelmed.

rovo89 commented 10 years ago

Alles klar, danke!

rovo89 commented 10 years ago

I checked the offset in the 4.7.3 file. It's 0x94, so neither version is good. It just doesn't seem to destroy anything. So I have to find a way to determine the offset dynamically... or if that is not possible, hardcode certain ROMs that have modified this structure.

rovo89 commented 10 years ago

Area around the definition of the codeCacheFull member:

    /* Compiled code cache */
    void* codeCache;

    /*
     * This is used to store the base address of an in-flight compilation whose
     * class object pointers have been calculated to populate literal pool.
     * Once the compiler thread has changed its status to VM_WAIT, we cannot
     * guarantee whether GC has happened before the code address has been
     * installed to the JIT table. Because of that, this field can only
     * been cleared/overwritten by the compiler thread if it is in the
     * THREAD_RUNNING state or in a safe point.
     */
    void *inflightBaseAddr;

    /* Translation cache version (protected by compilerLock */
    int cacheVersion;

    /* Bytes used by the code templates */
    unsigned int templateSize;

    /* Bytes already used in the code cache */
    unsigned int codeCacheByteUsed;

    /* Number of installed compilations in the cache */
    unsigned int numCompilations;

    /* Flag to indicate that the code cache is full */
    bool codeCacheFull;

    /* Page size  - 1 */
    unsigned int pageSizeMask;

    /* Lock to change the protection type of the code cache */
    pthread_mutex_t    codeCacheProtectionLock;

    /* Number of times that the code cache has been reset */
    int numCodeCacheReset;
rovo89 commented 10 years ago

codeCache, pageSizeMask and codeCacheProtectionLock might be candidates to check in order to find the offset at runtime.

codeCache is allocated with mmap/ashmem_create_region. There is a note that the address can be found in /proc/$pid/maps, but it doesn't exist in the Zygote process. Maybe JIT isn't initialized yet at that point?

pageSizeMask would be a great value to compare because the value is static: gDvmJit.pageSizeMask = getpagesize() - 1; So we could start at offset 0x78, check whether the next 4 bytes have the correct value and otherwise check the same for the next bytes. Potential problem: Alignment of variables. bool should be just one byte, however the members are usually aligned on 4 bytes for better performance. Not sure if every compiler does this the same way though.

codeCacheProtectionLock is declared as a mutex. Maybe this kind of object has a special memory signature that makes it possible to recognize it as such.

perpe commented 10 years ago

I looked into the libdvm.so of the other firmwares with objdump. The really old one have a different dvmChangeStatus than in http://forum.xda-developers.com/showpost.php?p=46440353:

0009e100 <_Z15dvmChangeStatusP6Thread12ThreadStatusb>:
   9e100:   8d 64 24 c4             lea    -0x3c(%esp),%esp
   9e104:   89 74 24 30             mov    %esi,0x30(%esp)
   9e108:   8b 74 24 40             mov    0x40(%esp),%esi
   9e10c:   89 5c 24 2c             mov    %ebx,0x2c(%esp)
   9e110:   89 6c 24 38             mov    %ebp,0x38(%esp)
   9e114:   e8 18 30 f9 ff          call   31131 <inflateEnd@plt+0xad>
   9e119:   81 c3 db ae 14 00       add    $0x14aedb,%ebx
   9e11f:   85 f6                   test   %esi,%esi
   9e121:   89 7c 24 34             mov    %edi,0x34(%esp)
   9e125:   8b 6c 24 44             mov    0x44(%esp),%ebp
   9e129:   0f b6 54 24 48          movzbl 0x48(%esp),%edx
   9e12e:   0f 84 c2 00 00 00       je     9e1f6 <_Z15dvmChangeStatusP6Thread12ThreadStatusb+0xf6>
...

I uploaded it to https://dl.dropboxusercontent.com/u/18073580/libdvm462.so (it's the same libdvm.so in three different firmware versions 4.5.7, 4.6.1, 4.6.2)

rovo89 commented 10 years ago

You have just used different parameters, here is the same file dumped with objdump -d -C -M intel libdvm462.so:

0009e100 <dvmChangeStatus(Thread*, ThreadStatus, bool)>:
   9e100:       8d 64 24 c4             lea    esp,[esp-0x3c]
   9e104:       89 74 24 30             mov    DWORD PTR [esp+0x30],esi
   9e108:       8b 74 24 40             mov    esi,DWORD PTR [esp+0x40]
   9e10c:       89 5c 24 2c             mov    DWORD PTR [esp+0x2c],ebx
   9e110:       89 6c 24 38             mov    DWORD PTR [esp+0x38],ebp
   9e114:       e8 18 30 f9 ff          call   31131 <inflateEnd@plt+0xad>
   9e119:       81 c3 db ae 14 00       add    ebx,0x14aedb
   9e11f:       85 f6                   test   esi,esi
   9e121:       89 7c 24 34             mov    DWORD PTR [esp+0x34],edi
   9e125:       8b 6c 24 44             mov    ebp,DWORD PTR [esp+0x44]
   9e129:       0f b6 54 24 48          movzx  edx,BYTE PTR [esp+0x48]
   9e12e:       0f 84 c2 00 00 00       je     9e1f6 <dvmChangeStatus(Thread*, ThreadStatus, bool)+0xf6>

Anyway, this function is no longer a problem because I don't use it anymore since some rewrite in version 2.4. The only pending thing now is getting the offset dynamically, then it should work.

By the way, the offset in this file is also 0x94.

ghost commented 10 years ago

they updated the source for kitkat baytrail maybe it can get fixed now.... https://github.com/android-ia

rovo89 commented 10 years ago

Thanks! The reason for the crashes is already known, see my analysis above. I could even post a working test very. The difficulty is to find the correct offset at runtime, because unfortunately the field names are only known at compile time and they are mapped to offsets. If some vendors decide to introduce new fields, the offsets are no longer valid. So I need to find a heuristic to determine the offset which works on these devices AND all devices which don't have this issue.

ghost commented 10 years ago

yeah sorry i read that after, i was just excited to finally see new source drop from android-ia, thanks.

molchanoviv commented 10 years ago

My ME300C still goes to bootloop on a v58. Android version is 4.3. Build version is 5.0.21

rovo89 commented 10 years ago

My ME300C still goes to bootloop on a v58. Android version is 4.3. Build version is 5.0.21

Are you aware that support for these ROMs requires you to create a configuration file? Please see the FAQ on XDA for details.

molchanoviv commented 10 years ago

Yep. Adding dalvik.vm.execution-mode int:fast to /system/build.prop works. Thanks

rovo89 commented 10 years ago

That's actually a workaround for a different issue (I meant the one where you create a file called jit_reset_offset), but glad it works anyway.

molchanoviv commented 10 years ago

Can you post here a link to the method with jit_reset_offset? I didn't find anything about it so I used a solution for Aliyun OS.