JS破解&&Android逆向

Android的加壳与脱壳 之 修改源码实现Dalvik通用脱壳

2020-08-06  本文已影响0人  Sharkchilli

前言

本文将基于Android4.4.2_r1修改其源码实现通用脱壳解决方案。其原理就是源程序自己在脱壳调用DexClassLoader时,会将dex或者odex映射到内存中,我们只需要找到这个映射内存的地址和dex大小就可以将其从内存中dump下来。本文将在Android源码中修改代码进行内存dump。
此次我将对以下方法进行修改从而抠出内存中的文件
dvmDexFileOpenPartial
dexFileParse
为什么是这两个函数,请查看我之前写的文章

源码下载

这个真是搞死我了,最后是用了别人的虚拟机镜像。自己的磁盘没办法分出这么大的空间来,下次可以用外置硬盘或者笔记本进行源码下载。具体下载可以查看清华大学开源软件镜像站的aosp。

源码修改

dexFileParse
/dalvik/libdex/DexFile.cpp

//add
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
/*
 * Parse an optimized or unoptimized .dex file sitting in memory.  This is
 * called after the byte-ordering and structure alignment has been fixed up.
 *
 * On success, return a newly-allocated DexFile.
 */
DexFile* dexFileParse(const u1* data, size_t length, int flags)
{
    char dexfilepath[100]={0};
    int pid=getpid();
    sprintf(dexfilepath,"/sdcard/%d_%d_dexFileParse_shark.dex",length,pid);
    //fopen
    int fd=open(dexfilepath,O_CREAT|O_RDWR,0666);
    if(fd>0)
    {
        write(fd,data,length);
        close(fd);
    }
    DexFile* pDexFile = NULL;
    const DexHeader* pHeader;
    const u1* magic;
    ...
}

dvmDexFileOpenPartial
/dalvik/vm/DvmDex.cpp

#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int dvmDexFileOpenPartial(const void* addr, int len, DvmDex** ppDvmDex)
{
    char dexfilepath[100]={0};
    int pid=getpid();
    sprintf(dexfilepath,"/sdcard/%d_%d_dvmDexFileOpenPartial_shark.dex",len,pid);
    //fopen
    int fd=open(dexfilepath,O_CREAT|O_RDWR,0666);
    if(fd>0)
    {
            write(fd,addr,len);
            close(fd);
    }

    
    
    DvmDex* pDvmDex;
    DexFile* pDexFile;
    int parseFlags = kDexParseDefault;
    int result = -1;

    /* -- file is incomplete, new checksum has not yet been calculated
    if (gDvm.verifyDexChecksum)
        parseFlags |= kDexParseVerifyChecksum;
    */

    pDexFile = dexFileParse((u1*)addr, len, parseFlags);
    if (pDexFile == NULL) {
        ALOGE("DEX parse failed");
        goto bail;
    }
    pDvmDex = allocateAuxStructures(pDexFile);
    if (pDvmDex == NULL) {
        dexFileFree(pDexFile);
        goto bail;
    }

    pDvmDex->isMappedReadOnly = false;
    *ppDvmDex = pDvmDex;
    result = 0;

bail:
    return result;
}

就是在这两个函数开头加了我们内存拷贝到文件的代码,很简单应该都看的懂的

编译源码

下载专用的二进制源码
https://developers.google.com/android/drivers 下载了相应的二进制驱动

image.png
运行后,会提示你查看证书,按Enter键一行行的查看,出现下面的输入提示时,输入 I ACCEPT,解压到了vendor 目录下。其它两个自解压脚本也是这样执行
设置环境
使用 build目录中的envsetup.sh 脚本初始化环境
source build/envsetup.sh
image.png
选择目标
lunch
image.png
官方给出了一份自己出厂设备的代号和编译配置选项
image.png
我们用的设备是NEXUS 5 ,所以lanch 编译配置为aosp_hammerhead-userdebug
image.png
编译代码
time make -j4

这里线程根据自己的cpu而定

刷机

手机连接到设备后,使用以下命令进入fastboot

adb reboot bootloader

参考

Android系统源码编译及刷机实战

上一篇 下一篇

猜你喜欢

热点阅读