安卓 dex 通用脱壳技术研究

【安卓 dex 通用脱壳技术研究】亦余心之所善兮,虽九死其犹未悔。这篇文章主要讲述安卓 dex 通用脱壳技术研究相关的知识,希望能为你提供帮助。

/*         此为DexHunter实现的主要功能,进行内存dump,将class_def_items中dump出classdef和extra部分 */ void*  DumpClass(void  *parament) {     while  (timer_flag)  {             sleep(5);     }    DvmDex*  pDvmDex=((struct  arg*)parament)-> pDvmDex;   //pDvmDex代表一个dex文件     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");     //构造classdef文件路径      FILE  *fp  =  fopen(path,  "wb+");     strcpy(path,dumppath);     strcat(path,"extra");   //构造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;   //dex文件的Header域,class_defs_size,标示了class_def域有几个class_def_item     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++)  //遍历所有class_def_item     {             bool  need_extra=false;             ClassObject  *  clazz=NULL;             const  u1*  data=https://www.songbingjia.com/android/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); //First Step:class加载 if (!clazz) { continue; } ALOGI("GOT  IT  class:  %s",descriptor);             if  (!dvmIsClassInitialized(clazz))  {    //Second  Step:class初始化,遍历所有类进行初始化                     if(dvmInitClass(clazz)){    //与dvmIsClassInitialized()函数共同完成初始化                             ALOGI("GOT  IT  init:  %s",descriptor);                     }             }                                   if(pClassDef-> classDataOff< start  ||  pClassDef-> classDataOff> end)             {                     need_extra=true;     //是不是需要extra这一块,当存在class_data_off不在dex范围内时,就需要             }            data=https://www.songbingjia.com/android/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)  {                                     //如果code_item_off不在dex文件范围内,则写入extra;   fp1为extra的句柄                                     //这里使用的是slider.pptx,中的第二种方案,见p42                                     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);         //目前已经准备好了part1,classdef,data和extra  4部分文件     strcpy(path,dumppath);     strcat(path,"whole.dex");   //组合4部分,并写入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  end----------------------//


    推荐阅读