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

如何获取APK的声明文件大小与总文件大小?附代码验证

APK文件声明大小与总大小解析及获取方案

一、两个大小的定义

  • 总文件大小:APK文件在磁盘上的实际字节数,对应警告中的total file size。这是文件系统层面的真实大小,包含所有内容(包括被追加到文件末尾的额外数据)。
  • 声明文件大小:指APK内部DEX文件头部(DexHeader)中file_size字段的值,对应警告里的Declared filesize。正常情况下,这个值应该等于DEX文件的实际大小,但恶意样本常篡改该字段或在DEX末尾追加数据,导致两者不匹配,从而触发AndroGuard的警告。

二、正确获取两个大小的方法

1. 总文件大小

你用os.path.getsize(apk_file)获取总大小的代码是正确的,该函数直接返回APK文件在磁盘上的物理字节数。

2. 声明文件大小(DEX头部的声明值)

你提供的代码触发KeyError,原因是benign_path[0]不是APK内DEX文件的有效路径。APK中的DEX文件通常命名为classes.dex,部分多DEX的APK会有classes2.dex等。正确的方式是读取DEX文件头部的file_size字段,代码如下:

import os
import zipfile
import struct

def extract_declared_dex_size(apk_path):
    declared_size = None
    with zipfile.ZipFile(apk_path, 'r') as apk_zip:
        # 遍历APK内所有DEX文件
        for entry in apk_zip.namelist():
            if entry.endswith('.dex'):
                with apk_zip.open(entry) as dex_fp:
                    # DexHeader中file_size字段位于偏移0x20,占8字节(小端字节序)
                    dex_fp.seek(0x20)
                    declared_size = struct.unpack('<Q', dex_fp.read(8))[0]
                    # 若只需要第一个DEX的声明大小,可直接break
                    break
    return declared_size

# 示例调用
apk_path = "target_apk.apk"
total_size = os.path.getsize(apk_path)
declared_dex_size = extract_declared_dex_size(apk_path)
print(f"总文件大小: {total_size}")
print(f"DEX声明大小: {declared_dex_size}")

说明:DEX文件头部的file_size字段是8字节无符号长整数,采用小端字节序,偏移量固定为0x20(即从文件开头数第32字节位置),读取该位置的值即可得到声明的DEX大小。

三、针对恶意APK的EDA分析建议

  • 统计触发警告样本中,总大小与DEX声明大小的差值分布,差值较大的样本大概率存在额外恶意载荷。
  • 对比多DEX APK中每个DEX的声明大小与实际大小,构建差异特征用于恶意样本筛选。
  • 对存在异常资源类型的APK,进一步解析AXML结构,排查资源类型篡改的恶意逻辑。

内容的提问来源于stack exchange,提问作者Minwoo Lee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 01:27:35