分析Dexhunter

来源:互联网 发布:金和网络 陈耀泉 编辑:程序博客网 时间:2024/05/24 06:05

—–我又回来csdn开始记流水账了

源码位置:https://github.com/zyq8709/DexHunter
配置工具:

4.4.3版本的nexus5手机
下载好的源码和编译环境

我们先谈用法:

置换源码中的dalvik\vm\native\dalvik_system_DexFile.cpp文件然后 make libdvm 编译 用生成的libdvm.so替换系统中的/system/lib/libdvm.so即可导入dexname文件 并push到data目录下 并chmod 777dexname里面写的是加载dex的位置 和输出脱壳的dex的位置
这是dexhunter里面改变的代码dalvik_system_DexFile.cpp

加入的第一段代码

#include <asm/siginfo.h>#include "libdex/DexClass.h"#include <sys/stat.h>#include <fcntl.h>#include <sys/mman.h>static char dexname[100]={0};static char dumppath[100]={0};static bool readable=true;static pthread_mutex_t read_mutex;static bool flag=true;static pthread_mutex_t mutex;static bool timer_flag=true;static timer_t timerId;struct arg{    DvmDex* pDvmDex;    Object * loader;}param;void timer_thread(sigval_t){    timer_flag=false;    timer_delete(timerId);    ALOGI("GOT IT time up");}void* ReadThread(void *arg){    FILE *fp = NULL;    while (dexname[0]==0||dumppath[0]==0) {        fp=fopen("/data/dexname", "r");        if (fp==NULL) {            sleep(1);            continue;        }        fgets(dexname,99,fp);        dexname[strlen(dexname)-1]=0;        fgets(dumppath,99,fp);        dumppath[strlen(dumppath)-1]=0;        fclose(fp);        fp=NULL;    }    struct sigevent sev;    sev.sigev_notify=SIGEV_THREAD;    sev.sigev_value.sival_ptr=&timerId;    sev.sigev_notify_function=timer_thread;    sev.sigev_notify_attributes = NULL;    timer_create(CLOCK_REALTIME,&sev,&timerId);    struct itimerspec ts;    ts.it_value.tv_sec=5;    ts.it_value.tv_nsec=0;    ts.it_interval.tv_sec=0;    ts.it_interval.tv_nsec=0;    timer_settime(timerId,0,&ts,NULL);    return NULL;}void ReadClassDataHeader(const uint8_t** pData,        DexClassDataHeader *pHeader) {    pHeader->staticFieldsSize = readUnsignedLeb128(pData);    pHeader->instanceFieldsSize = readUnsignedLeb128(pData);    pHeader->directMethodsSize = readUnsignedLeb128(pData);    pHeader->virtualMethodsSize = readUnsignedLeb128(pData);}void ReadClassDataField(const uint8_t** pData, DexField* pField) {    pField->fieldIdx = readUnsignedLeb128(pData);    pField->accessFlags = readUnsignedLeb128(pData);}void ReadClassDataMethod(const uint8_t** pData, DexMethod* pMethod) {    pMethod->methodIdx = readUnsignedLeb128(pData);    pMethod->accessFlags = readUnsignedLeb128(pData);    pMethod->codeOff = readUnsignedLeb128(pData);}DexClassData* ReadClassData(const uint8_t** pData) {    DexClassDataHeader header;    if (*pData == NULL) {        return NULL;    }    ReadClassDataHeader(pData,&header);    size_t resultSize = sizeof(DexClassData) + (header.staticFieldsSize * sizeof(DexField)) + (header.instanceFieldsSize * sizeof(DexField)) + (header.directMethodsSize * sizeof(DexMethod)) + (header.virtualMethodsSize * sizeof(DexMethod));    DexClassData* result = (DexClassData*) malloc(resultSize);    if (result == NULL) {        return NULL;    }    uint8_t* ptr = ((uint8_t*) result) + sizeof(DexClassData);    result->header = header;    if (header.staticFieldsSize != 0) {        result->staticFields = (DexField*) ptr;        ptr += header.staticFieldsSize * sizeof(DexField);    } else {        result->staticFields = NULL;    }    if (header.instanceFieldsSize != 0) {        result->instanceFields = (DexField*) ptr;        ptr += header.instanceFieldsSize * sizeof(DexField);    } else {        result->instanceFields = NULL;    }    if (header.directMethodsSize != 0) {        result->directMethods = (DexMethod*) ptr;        ptr += header.directMethodsSize * sizeof(DexMethod);    } else {        result->directMethods = NULL;    }    if (header.virtualMethodsSize != 0) {        result->virtualMethods = (DexMethod*) ptr;    } else {        result->virtualMethods = NULL;    }    for (uint32_t i = 0; i < header.staticFieldsSize; i++) {        ReadClassDataField(pData, &result->staticFields[i]);    }    for (uint32_t i = 0; i < header.instanceFieldsSize; i++) {        ReadClassDataField(pData, &result->instanceFields[i]);    }    for (uint32_t i = 0; i < header.directMethodsSize; i++) {        ReadClassDataMethod(pData, &result->directMethods[i]);    }    for (uint32_t i = 0; i < header.virtualMethodsSize; i++) {        ReadClassDataMethod(pData, &result->virtualMethods[i]);    }    return result;}void writeLeb128(uint8_t ** ptr, uint32_t data){    while (true) {        uint8_t out = data & 0x7f;        if (out != data) {            *(*ptr)++ = out | 0x80;            data >>= 7;        } else {            *(*ptr)++ = out;            break;        }    }}uint8_t* EncodeClassData(DexClassData *pData, int& len){    len=0;    len+=unsignedLeb128Size(pData->header.staticFieldsSize);    len+=unsignedLeb128Size(pData->header.instanceFieldsSize);    len+=unsignedLeb128Size(pData->header.directMethodsSize);    len+=unsignedLeb128Size(pData->header.virtualMethodsSize);    if (pData->staticFields) {        for (uint32_t i = 0; i < pData->header.staticFieldsSize; i++) {            len+=unsignedLeb128Size(pData->staticFields[i].fieldIdx);            len+=unsignedLeb128Size(pData->staticFields[i].accessFlags);        }    }    if (pData->instanceFields) {        for (uint32_t i = 0; i < pData->header.instanceFieldsSize; i++) {            len+=unsignedLeb128Size(pData->instanceFields[i].fieldIdx);            len+=unsignedLeb128Size(pData->instanceFields[i].accessFlags);        }    }    if (pData->directMethods) {        for (uint32_t i=0; i<pData->header.directMethodsSize; i++) {            len+=unsignedLeb128Size(pData->directMethods[i].methodIdx);            len+=unsignedLeb128Size(pData->directMethods[i].accessFlags);            len+=unsignedLeb128Size(pData->directMethods[i].codeOff);        }    }    if (pData->virtualMethods) {        for (uint32_t i=0; i<pData->header.virtualMethodsSize; i++) {            len+=unsignedLeb128Size(pData->virtualMethods[i].methodIdx);            len+=unsignedLeb128Size(pData->virtualMethods[i].accessFlags);            len+=unsignedLeb128Size(pData->virtualMethods[i].codeOff);        }    }    uint8_t * store = (uint8_t *) malloc(len);    if (!store) {        return NULL;    }    uint8_t * result=store;    writeLeb128(&store,pData->header.staticFieldsSize);    writeLeb128(&store,pData->header.instanceFieldsSize);    writeLeb128(&store,pData->header.directMethodsSize);    writeLeb128(&store,pData->header.virtualMethodsSize);    if (pData->staticFields) {        for (uint32_t i = 0; i < pData->header.staticFieldsSize; i++) {            writeLeb128(&store,pData->staticFields[i].fieldIdx);            writeLeb128(&store,pData->staticFields[i].accessFlags);        }    }    if (pData->instanceFields) {        for (uint32_t i = 0; i < pData->header.instanceFieldsSize; i++) {            writeLeb128(&store,pData->instanceFields[i].fieldIdx);            writeLeb128(&store,pData->instanceFields[i].accessFlags);        }    }    if (pData->directMethods) {        for (uint32_t i=0; i<pData->header.directMethodsSize; i++) {            writeLeb128(&store,pData->directMethods[i].methodIdx);            writeLeb128(&store,pData->directMethods[i].accessFlags);            writeLeb128(&store,pData->directMethods[i].codeOff);        }    }    if (pData->virtualMethods) {        for (uint32_t i=0; i<pData->header.virtualMethodsSize; i++) {            writeLeb128(&store,pData->virtualMethods[i].methodIdx);            writeLeb128(&store,pData->virtualMethods[i].accessFlags);            writeLeb128(&store,pData->virtualMethods[i].codeOff);        }    }    free(pData);    return result;}uint8_t* codeitem_end(const u1** pData){    uint32_t num_of_list = readUnsignedLeb128(pData);    for (;num_of_list>0;num_of_list--) {        int32_t num_of_handlers=readSignedLeb128(pData);        int num=num_of_handlers;        if (num_of_handlers<=0) {            num=-num_of_handlers;        }        for (; num > 0; num--) {            readUnsignedLeb128(pData);            readUnsignedLeb128(pData);        }        if (num_of_handlers<=0) {            readUnsignedLeb128(pData);        }    }    return (uint8_t*)(*pData);}void* DumpClass(void *parament){  while (timer_flag) {      sleep(5);  }  DvmDex* pDvmDex=((struct arg*)parament)->pDvmDex;  Object *loader=((struct arg*)parament)->loader;  DexFile* pDexFile=pDvmDex->pDexFile;  MemMapping * mem=&pDvmDex->memMap;  u4 time=dvmGetRelativeTimeMsec();  ALOGI("GOT IT begin: %d ms",time);  char *path = new char[100];  strcpy(path,dumppath);  strcat(path,"classdef");  FILE *fp = fopen(path, "wb+");  strcpy(path,dumppath);  strcat(path,"extra");  FILE *fp1 = fopen(path,"wb+");  uint32_t mask=0x3ffff;  char padding=0;  const char* header="Landroid";  unsigned int num_class_defs=pDexFile->pHeader->classDefsSize;  uint32_t total_pointer = mem->length-uint32_t(pDexFile->baseAddr-(const u1*)mem->addr);  uint32_t rec=total_pointer;  while (total_pointer&3) {      total_pointer++;  }  int inc=total_pointer-rec;  uint32_t start = pDexFile->pHeader->classDefsOff+sizeof(DexClassDef)*num_class_defs;  uint32_t end = (uint32_t)((const u1*)mem->addr+mem->length-pDexFile->baseAddr);  for (size_t i=0;i<num_class_defs;i++)   {      bool need_extra=false;      ClassObject * clazz=NULL;      const u1* data=NULL;      DexClassData* pData = NULL;      bool pass=false;      const DexClassDef *pClassDef = dexGetClassDef(pDvmDex->pDexFile, i);      const char *descriptor = dexGetClassDescriptor(pDvmDex->pDexFile,pClassDef);      if(!strncmp(header,descriptor,8)||!pClassDef->classDataOff)      {          pass=true;          goto classdef;      }      clazz = dvmDefineClass(pDvmDex, descriptor, loader);      if (!clazz) {         continue;      }      ALOGI("GOT IT class: %s",descriptor);      if (!dvmIsClassInitialized(clazz)) {          if(dvmInitClass(clazz)){              ALOGI("GOT IT init: %s",descriptor);          }      }      if(pClassDef->classDataOff<start || pClassDef->classDataOff>end)      {          need_extra=true;      }      data=dexGetClassData(pDexFile,pClassDef);      pData = ReadClassData(&data);      if (!pData) {          continue;      }      if (pData->directMethods) {          for (uint32_t i=0; i<pData->header.directMethodsSize; i++) {              Method *method = &(clazz->directMethods[i]);              uint32_t ac = (method->accessFlags) & mask;              ALOGI("GOT IT direct method name %s.%s",descriptor,method->name);              if (!method->insns||ac&ACC_NATIVE) {                  if (pData->directMethods[i].codeOff) {                      need_extra = true;                      pData->directMethods[i].accessFlags=ac;                      pData->directMethods[i].codeOff=0;                  }                  continue;              }              u4 codeitem_off = u4((const u1*)method->insns-16-pDexFile->baseAddr);              if (ac != pData->directMethods[i].accessFlags)              {                  ALOGI("GOT IT method ac");                  need_extra=true;                  pData->directMethods[i].accessFlags=ac;              }              if (codeitem_off!=pData->directMethods[i].codeOff&&((codeitem_off>=start&&codeitem_off<=end)||codeitem_off==0)) {                  ALOGI("GOT IT method code");                  need_extra=true;                  pData->directMethods[i].codeOff=codeitem_off;              }              if ((codeitem_off<start || codeitem_off>end) && codeitem_off!=0) {                  need_extra=true;                  pData->directMethods[i].codeOff = total_pointer;                  DexCode *code = (DexCode*)((const u1*)method->insns-16);                  uint8_t *item=(uint8_t *) code;                  int code_item_len = 0;                  if (code->triesSize) {                      const u1 * handler_data = dexGetCatchHandlerData(code);                      const u1** phandler=(const u1**)&handler_data;                      uint8_t * tail=codeitem_end(phandler);                      code_item_len = (int)(tail-item);                  }else{                      code_item_len = 16+code->insnsSize*2;                  }                  ALOGI("GOT IT method code changed");                  fwrite(item,1,code_item_len,fp1);                  fflush(fp1);                  total_pointer+=code_item_len;                  while (total_pointer&3) {                      fwrite(&padding,1,1,fp1);                      fflush(fp1);                      total_pointer++;                  }              }          }      }      if (pData->virtualMethods) {          for (uint32_t i=0; i<pData->header.virtualMethodsSize; i++) {              Method *method = &(clazz->virtualMethods[i]);              uint32_t ac = (method->accessFlags) & mask;              ALOGI("GOT IT virtual method name %s.%s",descriptor,method->name);              if (!method->insns||ac&ACC_NATIVE) {                  if (pData->virtualMethods[i].codeOff) {                      need_extra = true;                      pData->virtualMethods[i].accessFlags=ac;                      pData->virtualMethods[i].codeOff=0;                  }                  continue;              }              u4 codeitem_off = u4((const u1 *)method->insns - 16 - pDexFile->baseAddr);              if (ac != pData->virtualMethods[i].accessFlags)              {                  ALOGI("GOT IT method ac");                  need_extra=true;                  pData->virtualMethods[i].accessFlags=ac;              }              if (codeitem_off!=pData->virtualMethods[i].codeOff&&((codeitem_off>=start&&codeitem_off<=end)||codeitem_off==0)) {                  ALOGI("GOT IT method code");                  need_extra=true;                  pData->virtualMethods[i].codeOff=codeitem_off;              }              if ((codeitem_off<start || codeitem_off>end)&&codeitem_off!=0) {                  need_extra=true;                  pData->virtualMethods[i].codeOff = total_pointer;                  DexCode *code = (DexCode*)((const u1*)method->insns-16);                  uint8_t *item=(uint8_t *) code;                  int code_item_len = 0;                  if (code->triesSize) {                      const u1 *handler_data = dexGetCatchHandlerData(code);                      const u1** phandler=(const u1**)&handler_data;                      uint8_t * tail=codeitem_end(phandler);                      code_item_len = (int)(tail-item);                  }else{                      code_item_len = 16+code->insnsSize*2;                  }                  ALOGI("GOT IT method code changed");                  fwrite(item,1,code_item_len,fp1);                  fflush(fp1);                  total_pointer+=code_item_len;                  while (total_pointer&3) {                      fwrite(&padding,1,1,fp1);                      fflush(fp1);                      total_pointer++;                  }              }          }      }classdef:       DexClassDef temp=*pClassDef;       uint8_t *p = (uint8_t *)&temp;       if (need_extra) {           ALOGI("GOT IT classdata before");           int class_data_len = 0;           uint8_t *out = EncodeClassData(pData,class_data_len);           if (!out) {               continue;           }           temp.classDataOff = total_pointer;           fwrite(out,1,class_data_len,fp1);           fflush(fp1);           total_pointer+=class_data_len;           while (total_pointer&3) {               fwrite(&padding,1,1,fp1);               fflush(fp1);               total_pointer++;           }           free(out);           ALOGI("GOT IT classdata written");       }else{           if (pData) {               free(pData);           }       }       if (pass) {           temp.classDataOff=0;           temp.annotationsOff=0;       }       ALOGI("GOT IT classdef");       fwrite(p, sizeof(DexClassDef), 1, fp);       fflush(fp);  }  fclose(fp1);  fclose(fp);  strcpy(path,dumppath);  strcat(path,"whole.dex");  fp = fopen(path,"wb+");  rewind(fp);  int fd=-1;  int r=-1;  int len=0;    char *addr=NULL;  struct stat st;  strcpy(path,dumppath);  strcat(path,"part1");  fd=open(path,O_RDONLY,0666);  if (fd==-1) {      return NULL;  }  r=fstat(fd,&st);    if(r==-1){        close(fd);        return NULL;  }  len=st.st_size;  addr=(char*)mmap(NULL,len,PROT_READ,MAP_PRIVATE,fd,0);  fwrite(addr,1,len,fp);  fflush(fp);  munmap(addr,len);  close(fd);  strcpy(path,dumppath);  strcat(path,"classdef");  fd=open(path,O_RDONLY,0666);  if (fd==-1) {      return NULL;  }  r=fstat(fd,&st);    if(r==-1){        close(fd);        return NULL;  }  len=st.st_size;  addr=(char*)mmap(NULL,len,PROT_READ,MAP_PRIVATE,fd,0);  fwrite(addr,1,len,fp);  fflush(fp);  munmap(addr,len);  close(fd);  strcpy(path,dumppath);  strcat(path,"data");  fd=open(path,O_RDONLY,0666);  if (fd==-1) {      return NULL;  }  r=fstat(fd,&st);    if(r==-1){        close(fd);        return NULL;  }  len=st.st_size;  addr=(char*)mmap(NULL,len,PROT_READ,MAP_PRIVATE,fd,0);  fwrite(addr,1,len,fp);  fflush(fp);  munmap(addr,len);  close(fd);  while (inc>0) {      fwrite(&padding,1,1,fp);      fflush(fp);      inc--;  }  strcpy(path,dumppath);  strcat(path,"extra");  fd=open(path,O_RDONLY,0666);  if (fd==-1) {      return NULL;  }  r=fstat(fd,&st);    if(r==-1){        close(fd);        return NULL;  }  len=st.st_size;  addr=(char*)mmap(NULL,len,PROT_READ,MAP_PRIVATE,fd,0);  fwrite(addr,1,len,fp);  fflush(fp);  munmap(addr,len);  close(fd);  fclose(fp);  delete path;  time=dvmGetRelativeTimeMsec();  ALOGI("GOT IT end: %d ms",time);  return NULL;}

加入的第二段代码

//------------------------added begin----------------------//    int uid=getuid();    if (uid) {        if (readable) {            pthread_mutex_lock(&read_mutex);            if (readable) {                readable=false;                pthread_mutex_unlock(&read_mutex);                pthread_t read_thread;                pthread_create(&read_thread, NULL, ReadThread, NULL);            }else{                pthread_mutex_unlock(&read_mutex);            }        }    }    if(uid&&strcmp(dexname,"")){        char * res=strstr(pDexOrJar->fileName, dexname);        if (res&&flag) {            pthread_mutex_lock(&mutex);            if (flag) {                flag = false;                pthread_mutex_unlock(&mutex);                DexFile* pDexFile=pDvmDex->pDexFile;                MemMapping * mem=&pDvmDex->memMap;                char * temp=new char[100];                strcpy(temp,dumppath);                strcat(temp,"part1");                FILE *fp = fopen(temp, "wb+");                const u1 *addr = (const u1*)mem->addr;                int length=int(pDexFile->baseAddr+pDexFile->pHeader->classDefsOff-addr);                fwrite(addr,1,length,fp);                fflush(fp);                fclose(fp);                strcpy(temp,dumppath);                strcat(temp,"data");                fp = fopen(temp, "wb+");                addr = pDexFile->baseAddr+pDexFile->pHeader->classDefsOff+sizeof(DexClassDef)*pDexFile->pHeader->classDefsSize;                length=int((const u1*)mem->addr+mem->length-addr);                fwrite(addr,1,length,fp);                fflush(fp);                fclose(fp);                delete temp;                param.loader=loader;                param.pDvmDex=pDvmDex;                pthread_t dumpthread;                dvmCreateInternalThread(&dumpthread,"ClassDumper",DumpClass,(void*)&param);                                         }else{                pthread_mutex_unlock(&mutex);            }        }    }//------------------------added end----------------------//
0 0
原创粉丝点击