You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:25:31