基础库 - 插件体系 - 使用系统预置的 odex

描述:

Android系统ODEX文件格式解析
Android动态加载DEX文件流程分析

LOCAL_DEX_PREOPT
WITH_DEXPREOPT 
WITH_DEXPREOPT_PIC

1、 系统预置的odex,arch选择不对,比如 PposTv 只能在32 bit 下运行
a) 预置的odex:/system/app/PposTv/oat/arm64/PposTv.odex
b) 实际使用的odex:/data/dalvik-cache/arm/system@app@PposTv@PposTv@class.dex
c) 第三方APK(prebuilt)也不对
2、 如果系统已经预置,可以删除APK里面的class.dex,节约存储
a) 需要重签名,只能是自家的应用
b) 顺便so库如果预置的话,也可以从apk删除
c) 另外Zipalign功能好像没有用上(减少so库占用)

备注1:

一个系统预置 odex 的应用 

# dumpsys package com.android.defcontainer 
Key Set Manager: 
  [com.android.defcontainer] 
      Signing KeySets: 1 

Packages: 
  Package [com.android.defcontainer] (42090770): 
    userId=10002 gids=[1028, 1015, 1023, 2001, 1035] 
    pkg=Package{420f2250 com.android.defcontainer} 
    codePath=/system/priv-app/DefaultContainerService.apk 
    resourcePath=/system/priv-app/DefaultContainerService.apk 
    nativeLibraryPath=/data/app-lib/DefaultContainerService 
    versionCode=19 targetSdk=19 
    versionName=4.4.4-1.0.0 
    applicationInfo=ApplicationInfo{420f2300 com.android.defcontainer} 
    flags=[ SYSTEM HAS_CODE ALLOW_CLEAR_USER_DATA PRIVILEGED ] 
    dataDir=/data/data/com.android.defcontainer 
    supportsScreens=[small, medium, large, xlarge, resizeable, anyDensity] 
    timeStamp=2008-08-01 20:00:00 
    firstInstallTime=2017-10-24 17:13:35 
    lastUpdateTime=2008-08-01 20:00:00 
    signatures=PackageSignatures{4204e238 [420faab8]} 
    permissionsFixed=false haveGids=true installStatus=1 
    pkgFlags=[ SYSTEM HAS_CODE ALLOW_CLEAR_USER_DATA PRIVILEGED ] 
    User 0: installed=true blocked=false stopped=false notLaunched=false enabled=0

备注2:

虽然 codePath 还是 apk 文件,但是确实用了预置 odex 作为代码文件 

cat /proc/7646/maps | grep odex 

58726000-5872c000 r--p 00000000 b3:09 1477 /system/priv-app/DefaultContainerService.odex

备注3:

修改 dex文件权限,打印 DexFile 的调用 track 

06-05 13:32:23.716 15619 15619 E AndroidRuntime: Caused by: java.lang.ClassNotFoundException: Didn't find class "com.pptv.wallpaperplayer.WallpaperPlayerService" on path: DexPathList[[zip file "/system/framework/framework-pptv.jar", zip file "/data/app/com.pptv.wallpaperplayer-1.apk"],nativeLibraryDirectories=[/data/app-lib/com.pptv.wallpaperplayer-1, /system/lib, /vendor/lib, /system/lib/egl]] 
06-05 13:32:23.716 15619 15619 E AndroidRuntime: at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56) 
06-05 13:32:23.716 15619 15619 E AndroidRuntime: at java.lang.ClassLoader.loadClass(ClassLoader.java:497) 
06-05 13:32:23.716 15619 15619 E AndroidRuntime: at java.lang.ClassLoader.loadClass(ClassLoader.java:457) 
06-05 13:32:23.716 15619 15619 E AndroidRuntime: at android.app.ActivityThread.handleCreateService(ActivityThread.java:2540) 
06-05 13:32:23.716 15619 15619 E AndroidRuntime: ... 10 more 
06-05 13:32:23.716 15619 15619 E AndroidRuntime: Suppressed: java.io.IOException: unable to open DEX file 
06-05 13:32:23.716 15619 15619 E AndroidRuntime: at dalvik.system.DexFile.openDexFileNative(Native Method) 
06-05 13:32:23.716 15619 15619 E AndroidRuntime: at dalvik.system.DexFile.openDexFile(DexFile.java:296) 
06-05 13:32:23.716 15619 15619 E AndroidRuntime: at dalvik.system.DexFile.<init>(DexFile.java:80) 
06-05 13:32:23.716 15619 15619 E AndroidRuntime: at dalvik.system.DexFile.<init>(DexFile.java:59) 
06-05 13:32:23.716 15619 15619 E AndroidRuntime: at dalvik.system.DexPathList.loadDexFile(DexPathList.java:263) 
06-05 13:32:23.716 15619 15619 E AndroidRuntime: at dalvik.system.DexPathList.makeDexElements(DexPathList.java:230) 
06-05 13:32:23.716 15619 15619 E AndroidRuntime: at dalvik.system.DexPathList.<init>(DexPathList.java:112) 
06-05 13:32:23.716 15619 15619 E AndroidRuntime: at dalvik.system.BaseDexClassLoader.<init>(BaseDexClassLoader.java:48) 
06-05 13:32:23.716 15619 15619 E AndroidRuntime: at dalvik.system.PathClassLoader.<init>(PathClassLoader.java:65) 
06-05 13:32:23.716 15619 15619 E AndroidRuntime: at android.app.ApplicationLoaders.getClassLoader(ApplicationLoaders.java:57) 
06-05 13:32:23.716 15619 15619 E AndroidRuntime: at android.app.LoadedApk.getClassLoader(LoadedApk.java:318) 
06-05 13:32:23.716 15619 15619 E AndroidRuntime: at android.app.LoadedApk.makeApplication(LoadedApk.java:500) 
06-05 13:32:23.716 15619 15619 E AndroidRuntime: at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4301) 
06-05 13:32:23.716 15619 15619 E AndroidRuntime: at android.app.ActivityThread.access$1500(ActivityThread.java:135) 
06-05 13:32:23.716 15619 15619 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256) 
06-05 13:32:23.716 15619 15619 E AndroidRuntime: ... 8 more

备注4:

好像是native层在计算 dex 路径,上层没有传优化文件路径。但是没有找到直接代码。

备注5:

出现一个问题: 
06-28 13:20:40:277 29343 29375 D PluginManager: loadPlugins: start delayed com.pptv.hooray.watcher 
06-28 13:20:40:349 29343 29375 W Plugin: start 
06-28 13:20:40:349 29343 29375 W Plugin: java.lang.IllegalArgumentException: optimizedDirectory not readable/writable: /system/wplayerplugins 
06-28 13:20:40:349 29343 29375 W Plugin: at dalvik.system.DexPathList.<init>(DexPathList.java:104) 
06-28 13:20:40:349 29343 29375 W Plugin: at dalvik.system.BaseDexClassLoader.<init>(BaseDexClassLoader.java:48) 
06-28 13:20:40:349 29343 29375 W Plugin: at dalvik.system.DexClassLoader.<init>(DexClassLoader.java:57) 
06-28 13:20:40:349 29343 29375 W Plugin: at com.pptv.base.plugin.PluginClassLoader.<init>(PluginClassLoader.java:55) 
06-28 13:20:40:349 29343 29375 W Plugin: at com.pptv.base.plugin.PluginClassLoader.<init>(PluginClassLoader.java:50) 
06-28 13:20:40:349 29343 29375 W Plugin: at com.pptv.base.plugin.Plugin.start(Plugin.java:273) 
06-28 13:20:40:349 29343 29375 W Plugin: at com.pptv.base.plugin.PluginManager$1.run(PluginManager.java:153) 
06-28 13:20:40:349 29343 29375 W Plugin: at com.pptv.player.WallpaperContext$1.run(WallpaperContext.java:440) 
06-28 13:20:40:349 29343 29375 W Plugin: at android.os.Handler.handleCallback(Handler.java:733) 
06-28 13:20:40:349 29343 29375 W Plugin: at android.os.Handler.dispatchMessage(Handler.java:95) 
06-28 13:20:40:349 29343 29375 W Plugin: at android.os.Looper.loop(Looper.java:136) 
06-28 13:20:40:349 29343 29375 W Plugin: at android.os.HandlerThread.run(HandlerThread.java:61) 

备注6:

        if (outputName != null) { 
            try { 
                String parent = new File(outputName).getParent(); 
                if (Libcore.os.getuid() != Libcore.os.stat(parent).st_uid) { 
                    throw new IllegalArgumentException("Optimized data directory " + parent 
                            + " is not owned by the current user. Shared storage cannot protect" 
                            + " your application from code injection attacks."); 
                } 
            } catch (ErrnoException ignored) { 
                // assume we'll fail with a more contextual error later 
            } 
        } 

备注7:

Android 5.0 以上,ART 虚拟机 

std::vector<std::unique_ptr<const DexFile>> ClassLinker::OpenDexFilesFromOat( 
    const char* dex_location, const char* oat_location, 
    std::vector<std::string>* error_msgs) { 

dex_location 是 apk 路径 
oat_location 是外面传的优化文件路径 

bool OatFileAssistant::DexFilenameToOdexFilename(const std::string& location, 
    InstructionSet isa, std::string* odex_filename, std::string* error_msg) { 

  // The odex file name is formed by replacing the dex_location extension with 
  // .odex and inserting an oat/<isa> directory. For example: 
  // location = /foo/bar/baz.jar 
  // odex_location = /foo/bar/oat/<isa>/baz.odex 

备注8:

Android 4.4 情形: 

Case 1: 
系统预置了 hooray odex 
 ll /system/wplayerplugins/ 
-rw-r--r-- root root 44444 2008-08-01 20:00 com.pptv.ads.apk 
-rw-r--r-- root root 13402482 2008-08-01 20:00 com.pptv.gstplayer.apk 
-rw-r--r-- root root 26079 2008-08-01 20:00 com.pptv.hooray.watcher.apk 
-rw-r--r-- root log 21472 2008-08-01 20:00 com.pptv.hooray.watcher.odex 

缓存目录生产了新的 dex 文件 
ll /data/wplayerplugins/com.pptv.hooray.watcher/dex/ 
-rw-r--r-- system system 21792 2018-06-29 10:08 com.pptv.hooray.watcher.dex 

使用的缓存目录的 dex 
5a89d000-5a89e000 r--p 00000000 b3:0a 748 /data/wplayerplugins/com.pptv.hooray.watcher/dex/com.pptv.hooray.watcher.dex 

说明:这里系统预置的 odex 不匹配(因为 framework.jar 更新过),所以没有使用。

备注9:

Case 2: 

拷贝,更新预置的 odex 
cp /data/wplayerplugins/com.pptv.hooray.watcher/dex/com.pptv.hooray.watcher.dex /system/wplayerplugins/com.pptv.hooray.watcher.odex 

使用的是预置的 odex 
5a9d8000-5a9d9000 r--p 00000000 b3:09 14 /system/wplayerplugins/com.pptv.hooray.watcher.odex

备注10:

Case 3: 

将 odex 移动到 app 目录 
mv /system/wplayerplugins/com.pptv.hooray.watcher.odex /system/app/ 

使用的缓存目录的 dex 
cat /proc/13465/maps | grep hoo 
5a89d000-5a89e000 r--p 00000000 b3:0a 748 /data/wplayerplugins/com.pptv.hooray.watcher/dex/com.pptv.hooray.watcher.dex 

缓存目录的 dex 文件没有更新 
ll /data/wplayerplugins/com.pptv.hooray.watcher/dex/ 
-rw-r--r-- system system 21792 2018-06-29 10:08 com.pptv.hooray.watcher.dex 

备注11:

Case 4: 

将 odex 移动回来到 wplayerplugins 目录 
mv /system/app/com.pptv.hooray.watcher.odex /system/wplayerplugins/ 

删除缓存目录 
rm -rf /data/wplayerplugins/com.pptv.hooray.watcher/ 

缓存目录没有生成新的 dex 文件 
ll /data/wplayerplugins/com.pptv.hooray.watcher/dex/ 

使用的是预置的 odex 
cat /proc/14271/maps | grep hoo 
5a8d6000-5a8d7000 r--p 00000000 b3:09 14 /system/wplayerplugins/com.pptv.hooray.watcher.odex 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fighting Horse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值