Android 4.1 动态加载APK中的资源

*** is not owned by the current user. Shared storage cannot protect your application from code injection attacks.
起因由于上面Log中的一段Exception
发现这个问题源于动态加载APK中的函数和资源,在4.1之前的Android系统,均能正常使用,发现升级到4.1之后会有这个Exception报出;
 
所谓动态加载,就是手机本地有一个APK包,用户不需要执行安装过程,程序就可以解包并运行APK中的函数和调取资源。很多场景会用到,比如一些游戏组件,插件,皮肤等等;
 
动态加载其中一个过程就是将APK解包,即将class.dex从APK中解压出来,这样才能通过java的反射调用到其中的方法。
 
解包过程中一定会调用这个方法
01
02
03
04
05
06
07
08
09
10
11
12
static public DexFile loadDex(String sourcePathName, String outputPathName,
  int flags) throws IOException {
 
/*
  * TODO: we may want to cache previously-opened DexFile objects.
  * The cache would be synchronized with close(). This would help
  * us avoid mapping the same DEX more than once when an app
  * decided to open it multiple times. In practice this may not
  * be a real issue.
  */
  return new DexFile(sourcePathName, outputPathName, flags);
  }
问题就出现在这里,查看4.1的源码,发现Google基于安全考虑在DexFile这个函数中增加了一个验证文件归属权的步骤。
 
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
private DexFile(String sourceName, String outputName, int flags) throws IOException {
  if (outputName != null) {
  try {
  String parent = new File(outputName).getParent();
if (Libcore.os.getuid() != Libcore.os.stat(parent).st_uid) { //就是这里
  //4.1增加了一个验证目录uid与当前进程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
  }
  }
 
mCookie = openDexFile(sourceName, outputName, flags);
  mFileName = sourceName;
  guard.open( "close" );
  //System.out.println("DEX FILE cookie is " + mCookie);
  }
 
解决方法,参数outputPathName一定要是运行程序本身的私有地址,通过
01
getDir( "dexfile" , 0)

方法来获取这个dex文件存储位置就可以解决这个问题。

http://timcho.net/2013/01/16/android_4_1_dong_tai_jia_zai_apk_zhong_de_zi_yuan/

猜你喜欢

转载自mycoding.iteye.com/blog/1852986