分享

dex2jar在dex和jar转换时加入

 quasiceo 2015-06-20

[原]dex2jar在dex和jar转换时加入 -d 参数的异常处理

2014-6-16阅读221 评论0

最近在做一个android项目,由于项目需要。在对生成的源apk文件做单独的处理。大致流程为解压apk,生成dex文件,将dex文件转为jar。修改jar后,再将jar转为dex文件。

将dex转为jar需要使用命令:java -Xms512m -Xmx1024m -classpath dex2jar.jar com.googlecode.dex2jar.tools.Dex2jarCmd -o classes.jar classes.dex

但是该命令关闭了debug模式,用JclassLib查看生成的classes.jar文件,发现没有LocalVariableTable和LineNumberTable两个属性值。

LocalVariableTable是本地变量表,对于我这个项目而言,没有实际意义。但是LineNumberTable没有的话,导致的结果是如果有异常抛出,无法查看行数。

于是,我使用了java -Xms512m -Xmx1024m -classpath dex2jar.jar com.googlecode.dex2jar.tools.Dex2jarCmd  -d -o classes.jar classes.dex,加入了-d的参数。

生成了新的jar包文件,查看有本地变量属性和行数。

但是,再次将jar包转为dex时,命令:java -Xms512m -Xmx1024m -classpath dex2jar.jar com.googlecode.dex2jar.tools.Jar2Dex -o /classes.dex classes.jar。

由于dex2jar需要先走读一次代码,发现在某个接口时直接抛出异常:local variable type mismatch: attempt to set or access a value of type java.lang.Object using a local variable of type int. This is symptomatic of .class transformation tools that ignore local variable information. int型和object类型不匹配。

这个问题,我查找了很长的时间。对于同样地出问题的接口,里面有一句 byte[] test = new byte[1024]。修改位byte[] test = null。就可以编译通过。

另外,保持如上改动不边,移除掉异常捕获的代码(采用throw的方式),也可以让在jar转为dex的时候,通过。

由于类似的异常问题,在其他接口中也存在,因此只能从dex2jar的源码下手,计划移除掉LocalVariableTable属相。

在使用JclassLib对比了生成的jar和原生jar(使用eclipse直接让项目生成jar),对比出问题的接口,发现dexJar和原生Jar差别很大。可能由于编码指令不同,dexJar的code使用了非常多的goto跳转。逐行分析了dexJar的code,发现该code和LocalVariableTable不匹配,code中定义的某个int型变量,在LocalVariableTable中查看周期发现为Object类型。

因此我分析原因为,由于dexJar的code和LocalVariableTable不匹配,导致后面在将jar转为dex的时候,走读代码时,需要校验两者,无法通过,因此才抛出了上述问题。

通过查看dex2jar的源码,发现LocalVariableTable和LineNumberTable是同时收到-d参数控制(这两个属相在同一个java文件中实现),感兴趣的可以去看看

com.googlecode.dex2jar.reader.DexDebugInfoReader.java ,只要注释掉visitLocalVariable接口的调用,其他地方不用修改,这样就可以关闭LocalVariableTable,而同时LineNumberTable正常。

已经在我的项目中验证过。有需要的可以试试我这个方法,记的加上 -d 参数。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多