Skip to content

Conversation

@JingMatrix
Copy link
Owner

Manual library path injection via LD_LIBRARY_PATH has become unreliable due to symbol mismatches in core libraries (e.g., libc++) between the system and APEX partitions. Recent updates to liblog and libbase (in Android 16) have resulted in missing symbols like __hash_memory or fmt when the ART APEX binaries are forced to load system-partition shims.

This commit switches the wrapper to execute the runtime APEX linker directly (/apex/com.android.runtime/bin/linker64). By passing the dex2oat binary to the linker via /proc/self/fd/, the linker can properly initialize internal namespaces and resolve dependencies from the correct APEX and bootstrap locations.

Changes:

  • Replace fexecve(stock_fd) with execve(apex_linker).
  • Remove manual LD_LIBRARY_PATH construction.
  • Update sepolicy to allow dex2oat to execute the system linker.

Manual library path injection via LD_LIBRARY_PATH has become unreliable due to symbol mismatches in core libraries (e.g., libc++) between the system and APEX partitions. Recent updates to liblog and libbase (in Android 16) have resulted in missing symbols like `__hash_memory` or `fmt` when the ART APEX binaries are forced to load system-partition shims.

This commit switches the wrapper to execute the runtime APEX linker directly (/apex/com.android.runtime/bin/linker64). By passing the dex2oat binary to the linker via /proc/self/fd/, the linker can properly initialize internal namespaces and resolve dependencies from the correct APEX and bootstrap locations.

Changes:
- Replace fexecve(stock_fd) with execve(apex_linker).
- Remove manual LD_LIBRARY_PATH construction.
- Update sepolicy to allow dex2oat to execute the system linker.
@JingMatrix
Copy link
Owner Author

@sekaiacg, @mineketchup, @grandpajive
Please test the latest CI builds to see if dex2oat related problems are solved.

In Release builds, libc uses SIMD (NEON) instructions. To achieve high throughput, the __memcpy_a53 routine reads memory in 16-byte or 32-byte chunks (using LDRD or VLD1).

We also enble debug logs to track potential issues.
@sekaiacg
Copy link

sekaiacg commented Jan 23, 2026

https://github.com/JingMatrix/LSPosed/actions/runs/21269130798

debug version:

logcat | grep dex2oat
01-23 10:10:42.006  2032  3127 V installd: Running /apex/com.android.art/bin/dex2oat64 in=base.apk out=/data/app/~~Tv3_PmACzMOFlGKA6X7myw==/com.bit747.clipboardfilter-ddprIDgpEy6elDAypQSSxw==/oat/arm64/base.odex
01-23 10:10:42.013 14264 14264 D LSPosedDex2Oat: dex2oat.cpp:94#int main(int, char **): dex2oat wrapper ppid=2032
01-23 10:10:42.014  2257  2458 D LSPosedDex2Oat: Sent fd of /apex/com.android.art/bin/dex2oat64
01-23 10:10:42.014 14264 14264 D LSPosedDex2Oat: dex2oat.cpp:123#int main(int, char **): sock: xgmesoa14so27j8nkfxu8cgok7q9pe23 6
01-23 10:10:42.014 14264 14264 D LSPosedDex2Oat: dex2oat.cpp:153#int main(int, char **): Executing via linker: /apex/com.android.runtime/bin/linker64 /proc/self/fd/6
01-23 10:10:42.031 14264 14264 V LSPlt   : match hook info /apex/com.android.art/bin/dex2oat64:19 72373f7000 72373f8000-e5000
01-23 10:10:42.031 14264 14264 V LSPlt   : match hook info /apex/com.android.art/bin/dex2oat64:19 72373f3000 72373f7000-e2000
01-23 10:10:42.031 14264 14264 V LSPlt   : match hook info /apex/com.android.art/bin/dex2oat64:19 7237339000 72373f3000-28000
01-23 10:10:42.031 14264 14264 V LSPlt   : match hook info /apex/com.android.art/bin/dex2oat64:19 7237311000 7237339000-0
01-23 10:10:42.101 14264 14264 I 6       : dex2oat took 67.582ms (52.467ms cpu) (threads: 6) arena alloc=0B (0B) java alloc=80KB (82128B) native alloc=2207KB (2260288B) free=500KB (512704B)

release version:

logcat | grep dex2oat                                                                                                 
01-23 10:01:02.348 13930 13930 F libc    : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x7026600000 in tid 13930 (dex2oat), pid 13930 (dex2oat)
01-23 10:01:02.446 13985 13985 F DEBUG   : pid: 13930, tid: 13930, name: dex2oat  >>> /apex/com.android.runtime/bin/linker64 <<<
01-23 10:02:02.014  2045  2060 V installd: Running /apex/com.android.art/bin/dex2oat64 in=base.apk out=/data/app/~~VGAKTumQ5tCYmkhYMFahSw==/com.bit747.clipboardfilter-aOiYN9ihb3L82VInGSSsZA==/oat/arm64/base.odex
01-23 10:02:02.021 18146 18146 W dex2oat64: type=1400 audit(0.0:1884): avc: denied { read } for name="u:object_r:vendor_default_prop:s0" dev="tmpfs" ino=23805 scontext=u:r:dex2oat:s0 tcontext=u:object_r:vendor_default_prop:s0 tclass=file permissive=0
01-23 10:02:02.024 18146 18146 D LSPosedDex2Oat: dex2oat.cpp:94#int main(int, char **): dex2oat wrapper ppid=2045
01-23 10:02:02.024 18146 18146 D LSPosedDex2Oat: dex2oat.cpp:123#int main(int, char **): sock: m25nre2l86xwa97yz8xd2aute5wn5zb6 6
01-23 10:02:02.024 18146 18146 D LSPosedDex2Oat: dex2oat.cpp:153#int main(int, char **): Executing via linker: /apex/com.android.runtime/bin/linker64 /proc/self/fd/6
01-23 10:02:02.037 18146 18146 W linker64: type=1400 audit(0.0:1885): avc: denied { read } for name="u:object_r:vendor_default_prop:s0" dev="tmpfs" ino=23805 scontext=u:r:dex2oat:s0 tcontext=u:object_r:vendor_default_prop:s0 tclass=file permissive=0
01-23 10:02:02.125 18146 18146 F libc    : Fatal signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x6f91c00000 in tid 18146 (dex2oat), pid 18146 (dex2oat)
01-23 10:02:02.158 18156 18156 F DEBUG   : pid: 18146, tid: 18146, name: dex2oat  >>> /apex/com.android.runtime/bin/linker64 <<<

problem not solved.
log: LSPosed_2026-01-23T10_03_06.130294.zip
The problem only occurs in the release version.

It seems that the PLT return value could be wrong on certain devices for the debug build.
@JingMatrix
Copy link
Owner Author

JingMatrix commented Jan 23, 2026

It turns out that PLT hooks didn't return correctly the key_value_store size:

[ 2026-01-23T10:01:02.029    50315: 13930: 13930 D/LSPosedDex2Oat  ] dex2oat.cpp:94#int main(int, char **): dex2oat wrapper ppid=2045
[ 2026-01-23T10:01:02.030    50315: 13930: 13930 D/LSPosedDex2Oat  ] dex2oat.cpp:123#int main(int, char **): sock: m25nre2l86xwa97yz8xd2aute5wn5zb6 6
[ 2026-01-23T10:01:02.030    50315: 13930: 13930 D/LSPosedDex2Oat  ] dex2oat.cpp:153#int main(int, char **): Executing via linker: /apex/com.android.runtime/bin/linker64 /proc/self/fd/6
[ 2026-01-23T10:01:02.088    50315: 13930: 13930 D/LSPosedDex2Oat  ] oat_hook.cpp:125#void register_hook(dev_t, ino_t, const char *, void *, void **): RegisterHook: _ZNK3art9OatHeader20GetKeyValueStoreSizeEv, 0x70b3299620, 0x70b32a7fe0
[ 2026-01-23T10:01:02.088    50315: 13930: 13930 D/LSPosedDex2Oat  ] oat_hook.cpp:125#void register_hook(dev_t, ino_t, const char *, void *, void **): RegisterHook: _ZNK3art9OatHeader16GetKeyValueStoreEv, 0x70b3299914, 0x70b32a7fe8
[ 2026-01-23T10:01:02.346    50315: 13930: 13930 D/LSPosedDex2Oat  ] oat_hook.cpp:99#uint8_t *new__ZNK3art9OatHeader16GetKeyValueStoreEv(void *): OatHeader::GetKeyValueStore() called on object at 0xb4000070263a2000
[ 2026-01-23T10:01:02.346    50315: 13930: 13930 D/LSPosedDex2Oat  ] oat_hook.cpp:102#uint8_t *new__ZNK3art9OatHeader16GetKeyValueStoreEv(void *): KeyValueStore via hook: [addr: 0xb4000070263a2048, size: 2019913825]
[ 2026-01-23T10:01:02.346    50315: 13930: 13930 D/LSPosedDex2Oat  ] oat_hook.cpp:47#bool ModifyStoreInPlace(uint8_t *, uint32_t): Parameter found at offset 3041.
[ 2026-01-23T10:01:02.346    50315: 13930: 13930 D/LSPosedDex2Oat  ] oat_hook.cpp:69#bool ModifyStoreInPlace(uint8_t *, uint32_t): No padding found. Removing parameter and shifting memory.
[ 2026-01-23T10:01:02.348    50315: 13930: 13930 F/libc            ] Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x7026600000 in tid 13930 (dex2oat), pid 13930 (dex2oat)
[ 2026-01-23T10:01:02.446    50315: 13985: 13985 F/DEBUG           ] *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
[ 2026-01-23T10:01:02.446    50315: 13985: 13985 F/DEBUG           ] Build fingerprint: 'Xiaomi/cmi/cmi:13/TKQ1.221114.001/V816.0.5.0.TJACNXM:user/release-keys'
[ 2026-01-23T10:01:02.446    50315: 13985: 13985 F/DEBUG           ] Revision: '0'
[ 2026-01-23T10:01:02.446    50315: 13985: 13985 F/DEBUG           ] ABI: 'arm64'
[ 2026-01-23T10:01:02.446    50315: 13985: 13985 F/DEBUG           ] Timestamp: 2026-01-23 10:01:02.421029208+0800
[ 2026-01-23T10:01:02.446    50315: 13985: 13985 F/DEBUG           ] Process uptime: 1s
[ 2026-01-23T10:01:02.446    50315: 13985: 13985 F/DEBUG           ] ZygotePid: 1188
[ 2026-01-23T10:01:02.446    50315: 13985: 13985 F/DEBUG           ] Cmdline: /apex/com.android.runtime/bin/linker64 /proc/self/fd/6 --zip-fd=8 --zip-location=base.apk --oat-fd=9 --oat-location=/data/app/~~oY3DBxEHC-bevhBfubjiVg==/com.bit747.clipboardfilter-WymIdNvkzHPU2JnrHg6CLQ==/oat/arm64/base.odex --input-vdex-fd=-1 --output-vdex-fd=10 --profile-file-fd=12 --swap-fd=11 --classpath-dir=/data/app/~~oY3DBxEHC-bevhBfubjiVg==/com.bit747.clipboardfilter-WymIdNvkzHPU2JnrHg6CLQ== --class-loader-context=PCL[]{} --compact-dex-level=none --instruction-set=arm64 --instruction-set-features=default --instruction-set-variant=kryo300 --compiler-filter=speed-profile --compilation-reason=install --cpu-set=0,1,2,3,4,5,6,7 --max-image-block-size=524288 --resolve-startup-const-strings=true --generate-mini-debug-info --runtime-arg -Xtarget-sdk-version:30 --runtime-arg -Xhidden-api-policy:enabled -j6 --runtime-arg -Xms64m --runtime-arg -Xmx512m --inline-max-code-units=0
[ 2026-01-23T10:01:02.446    50315: 13985: 13985 F/DEBUG           ] pid: 13930, tid: 13930, name: dex2oat  >>> /apex/com.android.runtime/bin/linker64 <<<
[ 2026-01-23T10:01:02.446    50315: 13985: 13985 F/DEBUG           ] uid: 50315
[ 2026-01-23T10:01:02.446    50315: 13985: 13985 F/DEBUG           ] signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0000007026600000
[ 2026-01-23T10:01:02.446    50315: 13985: 13985 F/DEBUG           ]     x0  0000000000000001  x1  b400007026207050  x2  0000000000000002  x3  0fffffffffffffff
[ 2026-01-23T10:01:02.446    50315: 13985: 13985 F/DEBUG           ]     x4  0000000000000000  x5  0000000000000000  x6  2f323832301f1f2f  x7  7f7f7f7f7f7f7f7f
[ 2026-01-23T10:01:02.446    50315: 13985: 13985 F/DEBUG           ]     x8  0000000000000000  x9  782b14536e9a98a2  x10 00000000000000cf  x11 0000000000000001
[ 2026-01-23T10:01:02.446    50315: 13985: 13985 F/DEBUG           ]     x12 0000007fd81c4934  x13 0000000000000005  x14 0000000000000000  x15 00000070af87aa02
[ 2026-01-23T10:01:02.446    50315: 13985: 13985 F/DEBUG           ]     x16 0000000000000001  x17 00000070af945c88  x18 00000070b7138000  x19 0000000078657047
[ 2026-01-23T10:01:02.446    50315: 13985: 13985 F/DEBUG           ]     x20 b4000070265fffe6  x21 00000000783f90a9  x22 b40000709e9f90a9  x23 b4000070263a2c43
[ 2026-01-23T10:01:02.446    50315: 13985: 13985 F/DEBUG           ]     x24 00000070b32a7fd8  x25 0000000000000000  x26 0000000000000000  x27 b40000702622c500
[ 2026-01-23T10:01:02.446    50315: 13985: 13985 F/DEBUG           ]     x28 00000070b3701000  x29 0000007fd81c6e30
[ 2026-01-23T10:01:02.446    50315: 13985: 13985 F/DEBUG           ]     lr  00000070b3299b64  sp  0000007fd81c6db0  pc  00000070b3299b70  pst 0000000020001000
[ 2026-01-23T10:01:02.446    50315: 13985: 13985 F/DEBUG           ] backtrace:
[ 2026-01-23T10:01:02.446    50315: 13985: 13985 F/DEBUG           ]   NOTE: Function names and BuildId information is missing for some frames due
  NOTE: to unreadable libraries. For unwinds of apps, only shared libraries
  NOTE: found under the lib/ directory are readable.
  NOTE: On this device, run setenforce 0 to make the libraries readable.
  NOTE: Unreadable libraries:
  NOTE:   /data/adb/modules/zygisk_lsposed/bin/liboat_hook64.so
[ 2026-01-23T10:01:02.446    50315: 13985: 13985 F/DEBUG           ]       #00 pc 0000000000033b70  /data/adb/modules/zygisk_lsposed/bin/liboat_hook64.so

The decimal value 2019913825 is 0x78657041 in hexadecimal.
When converted to ASCII (little-endian), this spells: apex.

@JingMatrix JingMatrix linked an issue Jan 23, 2026 that may be closed by this pull request
1 task
@JingMatrix
Copy link
Owner Author

@sekaiacg Please test again the latest CI build, and send me logs even if the problem is solved.

@JingMatrix JingMatrix linked an issue Jan 23, 2026 that may be closed by this pull request
1 task
@sekaiacg
Copy link

@sekaiacg Please test again the latest CI build, and send me logs even if the problem is solved.

The problem is solved.
log: LSPosed_2026-01-23T11_36_52.755136.zip

@sekaiacg
Copy link

sekaiacg commented Jan 23, 2026

@JingMatrix

$ logcat | grep dex2oat                                                                           
01-23 14:21:20.749  2011  2011 V installd: Running /apex/com.android.art/bin/dex2oat64 in=base.apk out=/data/app/~~h1R84tIbCL74sMv4xcoztw==/com.bit747.clipboardfilter-HsN2LnTTMA7kLldQN7er6w==/oat/arm64/base.odex
01-23 14:21:20.758 14825 14825 D LSPosedDex2Oat: dex2oat.cpp:94#int main(int, char **): dex2oat wrapper ppid=2011
01-23 14:21:20.761 14825 14825 D LSPosedDex2Oat: dex2oat.cpp:123#int main(int, char **): sock: ia4edfivi4yoltlj7hv233sxxe28ifsx 6
01-23 14:21:20.761 14825 14825 D LSPosedDex2Oat: dex2oat.cpp:153#int main(int, char **): Executing via linker: /apex/com.android.runtime/bin/linker64 /proc/self/fd/6
01-23 14:21:20.833 14825 14825 I 6       : dex2oat took 55.206ms (48.430ms cpu) (threads: 6) arena alloc=0B (0B) java alloc=96KB (98512B) native alloc=2335KB (2391408B) free=504KB (516752B)
$ strings /data/app/~~h1R84tIbCL74sMv4xcoztw==/com.bit747.clipboardfilter-HsN2LnTTMA7kLldQN7er6w==/oat/arm64/base.odex
/proc/self/fd/6 --zip-fd=8 --zip-location=base.apk --oat-fd=9 --oat-location=/data/app/~~h1R84tIbCL74sMv4xcoztw==/com.bit747.clipboardfilter-HsN2LnTTMA7kLldQN7er6w==/oat/arm64/base.odex --input-vdex-fd=-1 --output-vdex-fd=10 --profile-file-fd=12 --swap-fd=11 --classpath-dir=/data/app/~~h1R84tIbCL74sMv4xcoztw==/com.bit747.clipboardfilter-HsN2LnTTMA7kLldQN7er6w== --class-loader-context=PCL[]{} --compact-dex-level=none --instruction-set=arm64 --instruction-set-features=default --instruction-set-variant=kryo300 --compiler-filter=speed-profile --compilation-reason=install --cpu-set=0,1,2,3,4,5,6,7 --max-image-block-size=524288 --resolve-startup-const-strings=true --generate-mini-debug-info --runtime-arg -Xtarget-sdk-version:30 --runtime-arg -Xhidden-api-policy:enabled -j6 --runtime-arg -Xms64m --runtime-arg -Xmx512m --inline-max-code-units=0

oathook is not working, it appears in the release version: --inline-max-code-units=0
This is suspicious: /proc/self/fd/6
log: LSPosed_2026-01-23T14_22_04.151792.zip

@JingMatrix
Copy link
Owner Author

Please upload your odex file for me to do more analysis.

@sekaiacg
Copy link

Please upload your odex file for me to do more analysis.

odex: base_odex.zip

We should also patch the cmdline path.

Hence, it is better to work through all the store.
@JingMatrix
Copy link
Owner Author

@sekaiacg Please test the latest CI build again.

@JingMatrix JingMatrix linked an issue Jan 23, 2026 that may be closed by this pull request
1 task
@JingMatrix JingMatrix changed the title Use runtime apex linker to resolve library mismatches Refactor dex2oat wrapper to solve long-standing issues Jan 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants