首页
社区
课程
招聘
[原创]查找内存中dex数量和位置的方法
发表于: 2016-1-16 11:13 7818

[原创]查找内存中dex数量和位置的方法

2016-1-16 11:13
7818

本人菜鸟一枚,大神飘过。
昨天看到有人问这个问题,这个东西放在硬盘上已经半年了,为了防止发霉,分享一下。
下面这个是去年阿里举办比赛时候有人给出的思路,但是没有给出完整的解决方案。
ibdvm->gdvm-> userDexFiles 可以找到加载的JarFile结构,进而找到dex文件地址

下面是我自己研究源码和汇编得到的解决方案(android 4.x版本):
gdvm是一个导出的结构,userDexFiles在其中的偏移是可以查找的。

在源码中通过对 gDvm.userDexFiles的搜索,锁定了一个函数有对这个的调用,dvmInternalNativeStartup(),在InternalNative.cpp。
导出设备中的libdvm.so文件,在导出表的位置查找dvmInternalNativeStartup()(_Z24dvmInternalNativeStartupv)函数。会发现:
STR.W           R0, [R3,#0x314],我这个版本是+0x314。
这样就可以通过gdvm查找到userDexFiles结构的位置

//DvmGlobals在Globals.h中
gDvm是一个DvmGlobals结构的全局变量。 HashTable*  userDexFiles;
下面是userDexFiles的结构:
typedef struct HashTable {
    int         tableSize;          /* must be power of 2 */
    int         numEntries;         /* current #of "live" entries */
    int         numDeadEntries;     /* current #of tombstone entries */
    HashEntry*  pEntries;           /* array on heap */  +0x0c
    HashFreeFunc freeFunc;
    pthread_mutex_t lock;
} HashTable;

HashEntry*  pEntries存储的是本模块有几个dex模块,这指向一个HashEntry的数组

struct HashEntry {
    u4 hashValue;
    void* data;        //DexOrJar *pDexOrJar
};
下面是DexOrJar 的结构:
typedef struct DexOrJar {
    char*       fileName;
    bool        isDex;
    bool        okayToFree;
    RawDexFile* pRawDexFile;
    JarFile*    pJarFile;    //+0x0c
} DexOrJar;

#这个也是可以查找到pDvmDex
struct RawDexFile {
    char*       cacheFileName;
    DvmDex*     pDvmDex;
};

typedef struct JarFile {
    ZipArchive  archive;
    //MemMapping  map;
    char*       cacheFileName;    //+0x24
    DvmDex*     pDvmDex;        //+0x28      pDvmDex偏移查找方法,dvmJarFileOpen()中可以找到
};

#找到了这个就找了了全部
typedef struct DvmDex {
    /* pointer to the DexFile we're associated with */
    DexFile*            pDexFile;
    /* clone of pDexFile->pHeader (it's used frequently enough) */
    const DexHeader*    pHeader;
    /* interned strings; parallel to "stringIds" */
    struct StringObject** pResStrings;
    /* resolved classes; parallel to "typeIds" */
    struct ClassObject** pResClasses;
    /* resolved methods; parallel to "methodIds" */
    struct Method**     pResMethods;
    /* resolved instance fields; parallel to "fieldIds" */
    /* (this holds both InstField and StaticField) */
    struct Field**      pResFields;
    /* interface method lookup cache */
    struct AtomicCache* pInterfaceCache;
    /* shared memory region with file contents */
    MemMapping          memMap;
    /* lock ensuring mutual exclusion during updates */
    pthread_mutex_t     modLock;
} DvmDex;

struct DexFile {
    /* directly-mapped "opt" header */
    +0x00    const DexOptHeader* pOptHeader;
    /* pointers to directly-mapped structs and arrays in base DEX */
    +0x04    const DexHeader*    pHeader;
    +0x08    const DexStringId*  pStringIds;
    +0x0c    const DexTypeId*    pTypeIds;
    +0x10    const DexFieldId*   pFieldIds;
    +0x14    const DexMethodId*  pMethodIds;
    +0x18    const DexProtoId*   pProtoIds;
    +0x1c    const DexClassDef*  pClassDefs;
    +0x20    const DexLink*      pLinkData;
    /*
     * These are mapped out of the "auxillary" section, and may not be
     * included in the file.
     */
    +0x24    const DexClassLookup* pClassLookup;
    +0x28    const void*         pRegisterMapPool;       // RegisterMapClassPool
    /* points to start of DEX file data */
    +0x2c    const u1*           baseAddr;
    /* track memory overhead for auxillary structures */
    +0x30    int                 overhead;
    /* additional app-specific data structures associated with the DEX */
    //void*               auxData;
};


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 3
支持
分享
最新回复 (6)
雪    币: 269
活跃值: (906)
能力值: ( LV12,RANK:345 )
在线值:
发帖
回帖
粉丝
2
虽然对dex没什么研究,但看着不错赞一个
2016-1-16 11:17
0
雪    币: 5196
活跃值: (3432)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
mk
2016-1-16 11:44
0
雪    币: 341
活跃值: (143)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
4
还不太懂android
2016-1-16 14:03
0
雪    币: 15
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
请问楼主,有没有什么办法用代码找到gDvm.userDexFiles的偏移?不同的系统把libdvm.so拉出来去找太麻烦。
2016-1-25 15:17
0
雪    币: 124
活跃值: (469)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
我也没有找到比较通用的方式,gDvm结构太大了。按版本来应该是没有问题的,收集所有4.x版本的偏移,在代码中判断版本(个人感觉国内优化版的偏移应该跟原版的偏移没有出入,这个没有测试过,仅仅是猜测)。
2016-1-26 14:41
0
雪    币: 15
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
这种方法灵活性太差了,http://bbs.pediy.com/showthread.php?t=207426,这种方法稍微麻烦点,但是应该比较精准。
2016-1-27 14:01
0
游客
登录 | 注册 方可回帖
返回
//