使用dex2jar读取APK遇‘not support magic’异常的解决咨询
解决直接用dex2jar读取APK文件抛出
not support magic异常的问题 你遇到的核心问题很明确:DexFileReader只能直接读取原始的DEX/ODEX文件,而APK本质是一个ZIP压缩包,它的开头字节是ZIP格式的magic(PK\x03\x04),完全不符合DEX的magic标识(dex\n),这就是为什么源码里的magic匹配失败,抛出了not support magic异常。
wiki里的示例没提这一步,是因为它默认你操作的是已经从APK中提取出来的独立DEX文件,不是APK本身。
要成功读取APK里的DEX内容,你需要先从APK这个ZIP包中提取出内部的DEX文件,再传给DexFileReader。具体步骤如下:
步骤1:从APK中提取DEX文件
APK作为ZIP包,内部会包含一个或多个DEX文件(比如标准的classes.dex,multidex应用会有classes2.dex、classes3.dex等)。你可以用Java自带的ZipFile或ZipInputStream来遍历并读取这些DEX条目。
步骤2:用DexFileReader读取提取出的DEX内容
将提取到的DEX文件的字节流转换成byte[]或ByteBuffer,再传入DexFileReader的构造函数即可。
完整示例代码
import com.googlecode.d2j.reader.DexFileReader; import com.googlecode.d2j.reader.DexFileReader.ClassHandler; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; public class ApkDexParser { public static void main(String[] args) { // 替换为你的APK文件路径 File apkFile = new File("/path/to/your/app.apk"); try (ZipFile zipFile = new ZipFile(apkFile)) { // 遍历APK内的所有文件条目 zipFile.stream().forEach(zipEntry -> { // 筛选出所有DEX文件 if (zipEntry.getName().endsWith(".dex") && !zipEntry.isDirectory()) { processDexEntry(zipFile, zipEntry); } }); } catch (IOException e) { e.printStackTrace(); } } private static void processDexEntry(ZipFile zipFile, ZipEntry dexEntry) { try (InputStream dexInputStream = zipFile.getInputStream(dexEntry)) { // 将DEX文件读取为字节数组 byte[] dexBytes = dexInputStream.readAllBytes(); // 初始化DexFileReader DexFileReader dexReader = new DexFileReader(dexBytes); // 示例:读取并打印所有类名 System.out.println("=== 读取DEX文件: " + dexEntry.getName() + " ==="); dexReader.accept((ClassHandler) clazz -> { System.out.println("类全限定名: " + clazz.getName()); return true; // 返回true继续遍历下一个类 }); } catch (Exception e) { System.err.println("处理DEX文件失败: " + dexEntry.getName()); e.printStackTrace(); } } }
额外说明
- 如果你担心
readAllBytes()处理大DEX文件时内存占用过高,可以改用ByteBuffer来包装输入流,或者分块读取后传入DexFileReader(不过DexFileReader的构造函数支持直接传入File,但那是针对独立的DEX文件,不是ZIP里的条目)。 - 确保你的项目已经正确引入了dex2jar的依赖(比如Maven依赖
com.googlecode.dex2jar:dex2jar:2.1,版本可以根据需要调整)。 - 部分APK可能会对DEX文件进行加密或混淆,但这属于特殊情况,常规APK的DEX都是可以直接提取读取的。
内容的提问来源于stack exchange,提问作者Nick Cardoso
相关产品推荐
相关产品推荐

