




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
!-一、什么是加殼?加殼是在二進制的程序中植入一段代碼,在運行的時候優(yōu)先取得程序的控制權(quán),做一些額外的工作。大多數(shù)病毒就是基于此原理。PCEXE文件加殼的過程如下:精品文檔放心下載二、加殼作用加殼的程序可以有效阻止對程序的反匯編分析,以達到它不可告人的目的。這種技術(shù)也常用來保護軟件版權(quán),防止被軟件破解。精品文檔放心下載三、AndroidDex文件加殼原理PC平臺現(xiàn)在已存在大量的標(biāo)準(zhǔn)的加殼和解殼工具,但是Android作為新興平臺還未謝謝閱讀出現(xiàn)APK加殼工具。AndroidDex文件大量使用引用給加殼帶來了一定的難度,但是從理謝謝閱讀論上講,AndroidAPK加殼也是可行的。在這個過程中,牽扯到三個角色:1、加殼程序:加密源程序為解殼數(shù)據(jù)、組裝解殼程序和解殼數(shù)據(jù)感謝閱讀2、解殼程序:解密解殼數(shù)據(jù),并運行時通過DexClassLoader動態(tài)加載感謝閱讀3、源程序:需要加殼處理的被保護代碼閱讀該文章,需要您對DEX文件結(jié)構(gòu)有所了解,您可以通過以下網(wǎng)址了解相關(guān)信息:感謝閱讀/jiazhijun/article/details/8664778精品文檔放心下載根據(jù)解殼數(shù)據(jù)在解殼程序DEX文件中的不同分布,本文將提出兩種AndroidDex加殼的實現(xiàn)方案。精品文檔放心下載(一)解殼數(shù)據(jù)位于解殼程序文件尾部!-該種方式簡單實用,合并后的DEX文件結(jié)構(gòu)如下。加殼程序工作流程:1、加密源程序APK文件為解殼數(shù)據(jù)2、把解殼數(shù)據(jù)寫入解殼程序Dex文件末尾,并在文件尾部添加解殼數(shù)據(jù)的謝謝閱讀大小。3、修改解殼程序DEX頭中checksum、signature和file_size頭信息。感謝閱讀4、修改源程序AndroidMainfest.xml文件并覆蓋解殼程序感謝閱讀AndroidMainfest.xml文件。解殼DEX程序工作流程:1、讀取DEX文件末尾數(shù)據(jù)獲取借殼數(shù)據(jù)長度。!-2、從DEX文件讀取解殼數(shù)據(jù),解密解殼數(shù)據(jù)。以文件形式保存解密數(shù)據(jù)感謝閱讀a.APK文件3、通過DexClassLoader動態(tài)加載a.apk。感謝閱讀(二)解殼數(shù)據(jù)位于解殼程序文件頭該種方式相對比較復(fù)雜,合并后DEX文件結(jié)構(gòu)如下:精品文檔放心下載加殼程序工作流程:1、加密源程序APK文件為解殼數(shù)據(jù)2、計算解殼數(shù)據(jù)長度,并添加該長度到解殼DEX文件頭末尾,并繼續(xù)解感謝閱讀殼數(shù)據(jù)到文件頭末尾。(插入數(shù)據(jù)的位置為0x70處)!-3、修改解殼程序DEX頭中checksum、signature、file_size、header_size、string_ids_off、type_ids_off、proto_ids_off、field_ids_off、感謝閱讀method_ids_off、class_defs_off和data_off相關(guān)項。分析map_off數(shù)據(jù),謝謝閱讀修改相關(guān)的數(shù)據(jù)偏移量。4、修改源程序AndroidMainfest.xml文件并覆蓋解殼程序AndroidMainfest.xml文件。謝謝閱讀解殼DEX程序工作流程:1、從0x70處讀取解殼數(shù)據(jù)長度。2、從DEX文件讀取解殼數(shù)據(jù),解密解殼數(shù)據(jù)。以文件形式保存解密數(shù)據(jù)感謝閱讀a.APK3、通過DexClassLoader動態(tài)加載a.APK。精品文檔放心下載一、序言在上篇“AndroidAPK加殼技術(shù)方案”(/jiazhijun/article/details/8678399)博文中,根據(jù)加殼數(shù)據(jù)在解殼程序Dex文件所處的位置,我提出了兩種AndroidDex加殼技術(shù)實現(xiàn)方案,本片博文將對方案1代碼實現(xiàn)進行講解。博友可以根據(jù)方案1的代碼實現(xiàn)原理對方案2自行實現(xiàn)。精品文檔放心下載在方案1的代碼實現(xiàn)過程中,各種不同的問題接踵出現(xiàn),最初的方案也在不同問題的出現(xiàn)、解決過程中不斷的得到調(diào)整、優(yōu)化。感謝閱讀本文的代碼實現(xiàn)了對整個APK包的加殼處理。加殼程序不會對源程序有任何的影響。精品文檔放心下載二、代碼實現(xiàn)本程序基于Android2.3代碼實現(xiàn),因為牽扯到系統(tǒng)代碼的反射修改,本程序不保證在其它android版本正常工作,博友可以根據(jù)實現(xiàn)原理,自行實現(xiàn)對其它Android版本的兼容性開發(fā)。謝謝閱讀1、加殼程序流程及代碼實現(xiàn)1、加密源程序APK為解殼數(shù)據(jù)2、把解殼數(shù)據(jù)寫入解殼程序DEX文件末尾,并在文件尾部添加解殼數(shù)據(jù)謝謝閱讀的大小。3、修改解殼程序DEX頭中checksum、signature和file_size頭信息。精品文檔放心下載!-代碼實現(xiàn)如下:[java] viewplaincopypackagecom.android.dexshell;感謝閱讀importjava.io.ByteArrayOutputStream;謝謝閱讀importjava.io.File;importjava.io.FileInputStream;謝謝閱讀importjava.io.FileOutputStream;精品文檔放心下載importjava.io.IOException;謝謝閱讀importjava.security.MessageDigest;感謝閱讀importjava.security.NoSuchAlgorithmException;感謝閱讀importjava.util.zip.Adler32;謝謝閱讀10.publicclassDexShellTool{謝謝閱讀/***@paramargs*/publicstaticvoidmain(String[]args){感謝閱讀//TODOAuto-generatedmethodstub感謝閱讀try{18.FilepayloadSrcFile=newFile("g:/payload.apk");19.FileunShellDexFile=newFile("g:/unshell.dex");20.byte[]payloadArray=encrpt(readFileBytes(payloadSrcFile));21.byte[]unShellDexArray=readFileBytes(unShellDexFile);22.intpayloadLen=payloadArray.length;23.intunShellDexLen=unShellDexArray.length;24.inttotalLen=payloadLen+unShellDexLen+4;25.byte[]newdex=newbyte[totalLen];26.//添加解殼代碼27.System.arraycopy(unShellDexArray,0,newdex,0,unShellDexLen);28.//添加加密后的解殼數(shù)據(jù)29.System.arraycopy(payloadArray,0,newdex,unShellDexLen,30.payloadLen);31.//添加解殼數(shù)據(jù)長度32.System.arraycopy(intToByte(payloadLen),0,newdex,totalLen-4,4);33.//修改DEXfilesize文件頭34.fixFileSizeHeader(newdex);35.//修改DEXSHA1文件頭36.fixSHA1Header(newdex);37.//修改DEXCheckSum文件頭38.fixCheckSumHeader(newdex);!-39.40.41.Stringstr="g:/classes.dex";42.Filefile=newFile(str);43.if(!file.exists()){44.file.createNewFile();45.}46.47.FileOutputStreamlocalFileOutputStream=newFileOutputStream(str);48.localFileOutputStream.write(newdex);49.localFileOutputStream.flush();50.localFileOutputStream.close();51.52.}catch(Exceptione){54. //TODOAuto-generatedcatchblock感謝閱讀55. e.printStackTrace();}}58.//直接返回數(shù)據(jù),讀者可以添加自己加密方法privatestaticbyte[]encrpt(byte[]srcdata){精品文檔放心下載returnsrcdata;}63.64.privatestaticvoidfixCheckSumHeader(byte[]dexBytes){謝謝閱讀Adler32adler=newAdler32();感謝閱讀adler.update(dexBytes,12,dexBytes.length-12);謝謝閱讀longvalue=adler.getValue();謝謝閱讀intva=(int)value;byte[]newcs=intToByte(va);感謝閱讀byte[]recs=newbyte[4];謝謝閱讀for(inti=0;i<4;i++){謝謝閱讀73. recs[i]=newcs[newcs.length-1-i];感謝閱讀74. System.out.println(Integer.toHexString(newcs[i]));謝謝閱讀}System.arraycopy(recs,0,dexBytes,8,4);感謝閱讀System.out.println(Long.toHexString(value));精品文檔放心下載System.out.println();}80.81.!-publicstaticbyte[]intToByte(intnumber){精品文檔放心下載byte[]b=newbyte[4];for(inti=3;i>=0;i--){感謝閱讀85.b[i]=(byte)(number%256);86.number>>=8;}returnb;}90.91.privatestaticvoidfixSHA1Header(byte[]dexBytes)謝謝閱讀93. throwsNoSuchAlgorithmException{謝謝閱讀MessageDigestmd=MessageDigest.getInstance("SHA-1");感謝閱讀md.update(dexBytes,32,dexBytes.length-32);感謝閱讀byte[]newdt=md.digest();感謝閱讀System.arraycopy(newdt,0,dexBytes,12,20);感謝閱讀Stringhexstr="";for(inti=0;i<newdt.length;i++){精品文檔放心下載100. hexstr+=Integer.toString((newdt[i]&0xff)+0x100,16)精品文檔放心下載101. .substring(1);}System.out.println(hexstr);精品文檔放心下載}105.106.privatestaticvoidfixFileSizeHeader(byte[]dexBytes){精品文檔放心下載byte[]newfs=intToByte(dexBytes.length);感謝閱讀System.out.println(Integer.toHexString(dexBytes.length));精品文檔放心下載byte[]refs=newbyte[4];精品文檔放心下載for(inti=0;i<4;i++){精品文檔放心下載114. refs[i]=newfs[newfs.length-1-i];感謝閱讀}System.arraycopy(refs,0,dexBytes,32,4);感謝閱讀}119.120.privatestaticbyte[]readFileBytes(Filefile)throwsIOException{謝謝閱讀byte[]arrayOfByte=newbyte[1024];謝謝閱讀ByteArrayOutputStreamlocalByteArrayOutputStream=newByteArrayOutputStream();精品文檔放心下載FileInputStreamfis=newFileInputStream(file);謝謝閱讀!-while(true){126.inti=fis.read(arrayOfByte);127.if(i!=-1){128.localByteArrayOutputStream.write(arrayOfByte,0,i);129.}else{130.returnlocalByteArrayOutputStream.toByteArray();131.}}}}2、解殼程序流程及代碼實現(xiàn)在解殼程序的開發(fā)過程中需要解決如下幾個關(guān)鍵的技術(shù)問題:感謝閱讀(1)解殼代碼如何能夠第一時間執(zhí)行?Android程序由不同的組件構(gòu)成,系統(tǒng)在有需要的時候啟動程序組件。因此謝謝閱讀解殼程序必須在Android系統(tǒng)啟動組件之前運行,完成對解殼數(shù)據(jù)的解殼及APK文件的動態(tài)加載,否則會使程序出現(xiàn)加載類失敗的異常。精品文檔放心下載Android開發(fā)者都知道Applicaiton做為整個應(yīng)用的上下文,會被系統(tǒng)第一時間調(diào)用,這也是應(yīng)用開發(fā)者程序代碼的第一執(zhí)行點。因此通過感謝閱讀對 AndroidMainfest.xml的application的配置可以實現(xiàn)解殼代碼第一時間運行。謝謝閱讀[html] viewplaincopy<applicationandroid:icon="@drawable/ic_launcher"謝謝閱讀android:label="@string/app_name"感謝閱讀android:theme="@style/AppTheme"android:name="<spanstyle="color:rgb(255,0,0);"><em><strong>com.android.dexunshell.ProxyApplication</strong></em></span>">謝謝閱讀</application>(2)如何替換回源程序原有的Application?精品文檔放心下載當(dāng)在AndroidMainfest.xml文件配置為解殼代碼的Application時。源程序原精品文檔放心下載有的Applicaiton將被替換,為了不影響源程序代碼邏輯,我們需要在解殼代碼運行完成后,替換回源程序原有的Application對象。我們通過在AndroidMainfest.xml文件感謝閱讀!-中配置原有Applicaiton類信息來達到我們 的目的。解殼程序要在運行完畢后通精品文檔放心下載過創(chuàng)建配置的Application對象,并通過反射修改回原Application。精品文檔放心下載[html]viewplaincopy<applicationandroid:icon="@drawable/ic_launcher"精品文檔放心下載android:label="@string/app_name"感謝閱讀android:theme="@style/AppTheme"android:name="<em><strong><spanstyle="color:rgb(255,0,0);">com.android.dexunshell.ProxyApplication</span></strong></em>">感謝閱讀<spanstyle="color:rgb(255,0,0);"><em><strong><metadataandroid:name="APPLICATION_CLASS_NAME"android:value="com.***.Application"/></strong></em></span>精品文檔放心下載</application>(3)如何通過DexClassLoader實現(xiàn)對apk代碼的動態(tài)加載。謝謝閱讀我們知道DexClassLoader加載的類是沒有組件生命周期的,也就是說即使感謝閱讀DexClassLoader通過對APK的動態(tài)加載完成了對組件類的加載, 當(dāng)系統(tǒng)啟動謝謝閱讀該組件時,還會出現(xiàn)加載類失敗的異常。為什么組件類被動態(tài)加載入虛擬機,但系統(tǒng)卻出現(xiàn)加載類失敗呢?精品文檔放心下載通過查看Android源代碼我們知道組件類的加載是由另一個ClassLoader感謝閱讀來完成的,DexClassLoader和系統(tǒng)組件ClassLoader并不存在關(guān) 系,系統(tǒng)感謝閱讀組件ClassLoader當(dāng)然找不到由DexClassLoader加載的類,如果把系統(tǒng)組件ClassLoader精品文檔放心下載的parent修改成DexClassLoader,我們就可 以實現(xiàn)對apk代碼的動態(tài)加載。精品文檔放心下載(4)如何使解殼后的APK資源文件被代碼動態(tài)引用。謝謝閱讀代碼默認引用的資源文件在最外層的解殼程序中,因此我們要增加系統(tǒng)的資源加載路徑來實現(xiàn)對借殼后APK文件資源的加載。精品文檔放心下載解殼實現(xiàn)代碼:[java]viewplaincopypackagecom.android.dexunshell;精品文檔放心下載importjava.io.BufferedInputStream;謝謝閱讀importjava.io.ByteArrayInputStream;謝謝閱讀importjava.io.ByteArrayOutputStream;謝謝閱讀!-importjava.io.DataInputStream;謝謝閱讀importjava.io.File;importjava.io.FileInputStream;精品文檔放心下載importjava.io.FileOutputStream;謝謝閱讀importjava.io.IOException;謝謝閱讀importjava.lang.ref.WeakReference;精品文檔放心下載importjava.util.ArrayList;精品文檔放心下載importjava.util.HashMap;importjava.util.Iterator;謝謝閱讀importjava.util.zip.ZipEntry;謝謝閱讀importjava.util.zip.ZipInputStream;感謝閱讀importdalvik.system.DexClassLoader;精品文檔放心下載importandroid.app.Application;謝謝閱讀importandroid.content.pm.ApplicationInfo;感謝閱讀importandroid.content.pm.PackageManager;精品文檔放心下載importandroid.content.pm.PackageManager.NameNotFoundException;精品文檔放心下載importandroid.os.Bundle;publicclassProxyApplicationextendsApplication{精品文檔放心下載25.26.privatestaticfinalStringappkey="APPLICATION_CLASS_NAME";感謝閱讀privateStringapkFileName;感謝閱讀privateStringodexPath;privateStringlibPath;31.32.protectedvoidattachBaseContext(Contextbase){精品文檔放心下載super.attachBaseContext(base);精品文檔放心下載try{36.Fileodex=this.getDir("payload_odex",MODE_PRIVATE);37.Filelibs=this.getDir("payload_lib",MODE_PRIVATE);38.odexPath=odex.getAbsolutePath();39.libPath=libs.getAbsolutePath();40.apkFileName=odex.getAbsolutePath()+"/payload.apk";41.FiledexFile=newFile(apkFileName);42.if(!dexFile.exists())43.dexFile.createNewFile();44.//讀取程序classes.dex文件45.byte[]dexdata=this.readDexFileFromApk();46.//分離出解殼后的apk文件已用于動態(tài)加載47.this.splitPayLoadFromDex(dexdata);48.//配置動態(tài)加載環(huán)境49.ObjectcurrentActivityThread=RefInvoke.invokeStaticMethod(!-50."android.app.ActivityThread","currentActivityThread",51.newClass[]{},newObject[]{});52.StringpackageName=this.getPackageName();53.HashMapmPackages=(HashMap)RefInvoke.getFieldOjbect(54."android.app.ActivityThread",currentActivityThread,55."mPackages");56.WeakReferencewr=(WeakReference)mPackages.get(packageName);57.DexClassLoaderdLoader=newDexClassLoader(apkFileName,odexPath,58.libPath,(ClassLoader)RefInvoke.getFieldOjbect(59."android.app.LoadedApk",wr.get(),"mClassLoader"));60.RefInvoke.setFieldOjbect("android.app.LoadedApk","mClassLoader",61.wr.get(),dLoader);62.63.}catch(Exceptione){65. //TODOAuto-generatedcatchblock感謝閱讀66. e.printStackTrace();}}69.70.publicvoidonCreate(){{73.74.75.//如果源應(yīng)用配置有Appliction對象,則替換為源應(yīng)用Applicaiton,以便不影響源程序邏輯。76.StringappClassName=null;77.try{78.ApplicationInfoai=this.getPackageManager()79..getApplicationInfo(this.getPackageName(),80.PackageManager.GET_META_DATA);81.Bundlebundle=ai.metaData;82.if(bundle!=null83.&&bundle.containsKey("APPLICATION_CLASS_NAME")){84.appClassName=bundle.getString("APPLICATION_CLASS_NAME");85.}else{86.return;87.}88.}catch(NameNotFoundExceptione){!-89.//TODOAuto-generatedcatchblock90.e.printStackTrace();91.}92.93.94.ObjectcurrentActivityThread=RefInvoke.invokeStaticMethod(95."android.app.ActivityThread","currentActivityThread",96.newClass[]{},newObject[]{});97.ObjectmBoundApplication=RefInvoke.getFieldOjbect(98."android.app.ActivityThread",currentActivityThread,99."mBoundApplication");100.ObjectloadedApkInfo=RefInvoke.getFieldOjbect(101."android.app.ActivityThread$AppBindData",102.mBoundApplication,"info");103.RefInvoke.setFieldOjbect("android.app.LoadedApk","mApplication",104.loadedApkInfo,null);105.ObjectoldApplication=RefInvoke.getFieldOjbect(106."android.app.ActivityThread",currentActivityThread,107."mInitialApplication");108.ArrayList<Application>mAllApplications=(ArrayList<Application>)RefInvoke12.oke113.114.115.nvoke116.",20.121.fo,25.
.getFieldOjbect("android.app.ActivityThread",currentActivityThread,"mAllApplications");感謝閱讀mAllApplications.remove(oldApplication);精品文檔放心下載ApplicationInfoappinfo_In_LoadedApk=(ApplicationInfo)RefInv謝謝閱讀.getFieldOjbect("android.app.LoadedApk",loadedApkInfo,感謝閱讀"mApplicationInfo");ApplicationInfoappinfo_In_AppBindData=(ApplicationInfo)RefI謝謝閱讀.getFieldOjbect("android.app.ActivityThread$AppBindData謝謝閱讀mBoundApplication,"appInfo");appinfo_In_LoadedApk.className=appClassName;appinfo_In_AppBindData.className=appClassName;Applicationapp=(Application)RefInvoke.invokeMethod(謝謝閱讀"android.app.LoadedApk","makeApplication",loadedApkIn感謝閱讀newClass[]{boolean.class,Instrumentation.class},newObject[]{false,null});謝謝閱讀RefInvoke.setFieldOjbect("android.app.ActivityThread",感謝閱讀"mInitialApplication",currentActivityThread,app);精品文檔放心下載!-126.127.128.HashMapmProviderMap=(HashMap)RefInvoke.getFieldOjbect(129."android.app.ActivityThread",currentActivityThread,130."mProviderMap");131.Iteratorit=mProviderMap.values().iterator();132.while(it.hasNext()){133.ObjectproviderClientRecord=it.next();134.ObjectlocalProvider=RefInvoke.getFieldOjbect(135."android.app.ActivityThread$ProviderClientRecord",136.providerClientRecord,"mLocalProvider");137.RefInvoke.setFieldOjbect("android.content.ContentProvider",138."mContext",localProvider,app);139.}140.app.onCreate();}}privatevoidsplitPayLoadFromDex(byte[]data)throwsIOException{精品文檔放心下載byte[]apkdata=decrypt(data);感謝閱讀intablen=apkdata.length;謝謝閱讀byte[]dexlen=newbyte[4];感謝閱讀System.arraycopy(apkdata,ablen-4,dexlen,0,4);感謝閱讀ByteArrayInputStreambais=newByteArrayInputStream(dexlen);感謝閱讀DataInputStreamin=newDataInputStream(bais);精品文檔放心下載intreadInt=in.readInt();精品文檔放心下載System.out.println(Integer.toHexString(readInt));謝謝閱讀byte[]newdex=newbyte[readInt];精品文檔放心下載System.arraycopy(apkdata,ablen-4-readInt,newdex,0,readInt);感謝閱讀Filefile=newFile(apkFileName);感謝閱讀try{158.FileOutputStreamlocalFileOutputStream=newFileOutputStream(file);謝謝閱讀159. localFileOutputStream.write(newdex);謝謝閱讀160. localFileOutputStream.close();謝謝閱讀161.162.}catch(IOExceptionlocalIOException){感謝閱讀164. thrownewRuntimeException(localIOException);謝謝閱讀}!-166.167.ZipInputStreamlocalZipInputStream=newZipInputStream(謝謝閱讀169. newBufferedInputStream(newFileInputStream(file)));精品文檔放心下載while(true){171.ZipEntrylocalZipEntry=localZipInputStream.getNextEntry();172.if(localZipEntry==null){173.localZipInputStream.close();174.break;175.}176.Stringname=localZipEntry.getName();177.if(name.startsWith("lib/")&&name.endsWith(".so")){178.FilestoreFile=newFile(libPath+"/"179.+name.substring(name.lastIndexOf('/')));180.storeFile.createNewFile();181.FileOutputStreamfos=newFileOutputStream(storeFile);182.byte[]arrayOfByte=newbyte[1024];183.while(true){184.inti=localZipInputStream.read(arrayOfByte);185.if(i==-1)186.break;187.fos.write(arrayOfByte,0,i);188.}189.fos.flush();190.fos.close();191.}192.localZipInputStream.closeEntry();}localZipInputStream.close();謝謝閱讀}privatebyte[]readDexFileFromApk()throwsIOException{精品文檔放心下載ByteArrayOutputStreamdexByteArrayOutputStream=newByteArrayOutputStream();謝謝閱讀ZipInputStreamlocalZipInputStream=newZipInputStream(感謝閱讀203. newBufferedInputStream(newFileInputStream(謝謝閱讀204. this.getApplicationInfo().sourceDir)));謝謝閱讀while(true){206. ZipEntrylocalZipEntry=localZipInputStream.getNextEntry();精品文檔放心下載207. if(localZipEntry==null){精品文檔放心下載208. localZipInputStream.close();精品文檔放心下載!-209.break;210.}211.if(localZipEntry.getName().equals("classes.dex")){212.byte[]arrayOfByte=newbyte[1024];213.while(true){214.inti=localZipInputStream.read(arrayOfByte);215.if(i==-1)216.break;217.dexByteArrayOutputStream.write(arrayOfByte,0,i);218.}219.}220.localZipInputStream.closeEntry();}localZipInputStream.close();感謝閱讀returndexByteArrayOutputStream.toByteArray();精品文檔放心下載}225.226.////直接返回數(shù)據(jù),讀者可以添加自己解密方法privatebyte[]decrypt(byte[]data){精品文檔放心下載returndata;}[java] viewplaincopypackagecom.android.dexunshell;謝謝閱讀importjava.io.BufferedInputStream;謝謝閱讀importjava.io.ByteArrayInputStream;謝謝閱讀importjava.io.ByteArrayOutputStream;精品文檔放心下載importjava.io.DataInputStream;感謝閱讀importjava.io.File;importjava.io.FileInputStream;謝謝閱讀importjava.io.FileOutputStream;精品文檔放心下載importjava.io.IOException;精品文檔放心下載importjava.lang.ref.WeakReference;謝謝閱讀importjava.util.ArrayList;謝謝閱讀importjava.util.HashMap;importjava.util.Iterator;精品文檔放心下載importjava.util.zip.ZipEntry;精品文檔放心下載importjava.util.zip.ZipInputStream;精品文檔放心下載importdalvik.system.DexClassLoader;感謝閱讀importandroid.app.Application;精品文檔放心下載importandroid.content.pm.ApplicationInfo;感謝閱讀!-importandroid.content.pm.PackageManager;謝謝閱讀importandroid.content.pm.PackageManager.NameNotFoundException;精品文檔放心下載importandroid.os.Bundle;publicclassProxyApplicationextendsApplication{精品文檔放心下載25.26.<spanstyle="white-space:pre"></span>privatestaticfinalStringappkey="APPLICATION_CLASS_NAME";精品文檔放心下載<spanstyle="white-space:pre"></span>privateStringapkFileName;感謝閱讀<spanstyle="white-space:pre"></span>privateStringodexPath;謝謝閱讀<spanstyle="white-space:pre"></span>privateStringlibPath;精品文檔放心下載31.32.<spanstyle="white-space:pre"></span>protectedvoidattachBaseContext(Contextbase){謝謝閱讀<spanstyle="white-space:pre"></span>super.attachBaseContext(base);精品文檔放心下載35.<spanstyle="white-space:pre"></span>try{36.<spanstyle="white-space:pre"></span>Fileodex=this.getDir("payload_odex",MODE_PRIVATE);37.<spanstyle="white-space:pre"></span>Filelibs=this.getDir("payload_lib",MODE_PRIVATE);38.<spanstyle="white-space:pre"></span>odexPath=odex.getAbsolutePath();39.<spanstyle="white-space:pre"></span>libPath=libs.getAbsolutePath();40.<spanstyle="white-space:pre"></span>apkFileName=odex.getAbsolutePath()+"/payload.apk";41.<spanstyle="white-space:pre"></span>FiledexFile=newFile(apkFileName);42.<spanstyle="white-space:pre"></span>if(!dexFile.exists())43.<spanstyle="white-space:pre"></span>dexFile.createNewFile();44.<spanstyle="white-space:pre"></span>//讀取程序classes.dex文件45.<spanstyle="white-space:pre"></span>byte[]dexdata=this.readDexFileFromApk();46.<spanstyle="white-space:pre"></span>//分離出解殼后的apk文件已用于動態(tài)加載47.<spanstyle="white-space:pre"></span>this.splitPayLoadFromDex(dexdata);48.<spanstyle="white-space:pre"></span>//配置動態(tài)加載環(huán)境49.<spanstyle="white-space:pre"></span>ObjectcurrentActivityThread=RefInvoke.invokeStaticMethod(50.<spanstyle="white-space:pre"></span>"android.app.ActivityThread","currentActivityThread",!-51.<spanstyle="white-space:pre"></span>newClass[]{},newObject[]{});52.<spanstyle="white-space:pre"></span>StringpackageName=this.getPackageName();53.<spanstyle="white-space:pre"></span>HashMapmPackages=(HashMap)RefInvoke.getFieldOjbect(54.<spanstyle="white-space:pre"></span>"android.app.ActivityThread",currentActivityThread,55.<spanstyle="white-space:pre"></span>"mPackages");56.<spanstyle="white-space:pre"></span>WeakReferencewr=(WeakReference)mPackages.get(packageName);57.<spanstyle="white-space:pre"></span>DexClassLoaderdLoader=newDexClassLoader(apkFileName,odexPath,58.<spanstyle="white-space:pre"></span>libPath,(ClassLoader)RefInvoke.getFieldOjbect(59.<spanstyle="white-space:pre"></span>"android.app.LoadedApk",wr.get(),"mClassLoader"));60.<spanstyle="white-space:pre"></span>RefInvoke.setFieldOjbect("android.app.LoadedApk","mClassLoader",61.<spanstyle="white-space:pre"></span>wr.get(),dLoader);62.63.64.<spanstyle="white-space:pre"></span>}catch(Exceptione){65.<spanstyle="white-space:pre"></span>//TODOAuto-generatedcatchblock66.<spanstyle="white-space:pre"></span>e.printStackTrace();67.<spanstyle="white-space:pre"></span>}<spanstyle="white-space:pre"></span>}感謝閱讀<spanstyle="white-space:pre"></span>publicvoidonCreate(){感謝閱讀72.<spanstyle="white-space:pre"></span>{73.74.75.<spanstyle="white-space:pre"></span>//如果源應(yīng)用配置有Appliction對象,則替換為源應(yīng)用Applicaiton,以便不影響源程序邏輯。76.<spanstyle="white-space:pre"></span>StringappClassName=null;77.<spanstyle="white-space:pre"></span>try{78.<spanstyle="white-space:pre"></span>ApplicationInfoai=this.getPackageManager()79.<spanstyle="white-space:pre"></span>.getApplicationInfo(this.getPackageName(),80.<spanstyle="white-space:pre"></span>PackageManager.GET_META_DATA);!-81.<spanstyle="white-space:pre"></span>Bundlebundle=ai.metaData;82.<spanstyle="white-space:pre"></span>if(bundle!=null83.<spanstyle="white-space:pre"></span>&&bundle.containsKey("APPLICATION_CLASS_NAME")){84.<spanstyle="white-space:pre"></span>appClassName=bundle.getString("APPLICATION_CLASS_NAME");85.<spanstyle="white-space:pre"></span>}else{86.<spanstyle="white-space:pre"></span>return;87.<spanstyle="white-space:pre"></span>}88.<spanstyle="white-space:pre"></span>}catch(NameNotFoundExceptione){89.<spanstyle="white-space:pre"></span>//TODOAuto-generatedcatchblock90.<spanstyle="white-space:pre"></span>e.printStackTrace();91.<spanstyle="white-space:pre"></span>}92.93.94.<spanstyle="white-space:pre"></span>ObjectcurrentActivityThread=RefInvoke.invokeStaticMethod(95.<spanstyle="white-space:pre"></span>"android.app.ActivityThread","currentActivityThread",96.<spanstyle="white-space:pre"></span>newClass[]{},newObject[]{});97.<spanstyle="white-space:pre"></span>ObjectmBoundApplication=RefInvoke.getFieldOjbect(98.<spanstyle="white-space:pre"></span>"android.app.ActivityThread",currentActivityThread,99.<spanstyle="white-space:pre"></span>"mBoundApplication");100.<spanstyle="white-space:pre"></span>ObjectloadedApkInfo=RefInvoke.getFieldOjbect(101.<spanstyle="white-space:pre"></span>"android.app.ActivityThread$AppBindData",102.<spanstyle="white-space:pre"></span>mBoundApplication,"info");103.<spanstyle="white-space:pre"></span>RefInvoke.setFieldOjbect("android.app.LoadedApk","mApplication",104.<spanstyle="white-space:pre"></span>loadedApkInfo,null);105.<spanstyle="white-space:pre"></span>ObjectoldApplication=RefInvoke.getFieldOjbect(106.<spanstyle="white-space:pre"></span>"android.app.ActivityThread",currentActivityThread,!-107.<spanstyle="white-space:pre"></span>"mInitialApplication");108.<spanstyle="white-space:pre"></span>ArrayList<Application>mAllApplications=(ArrayList<Application>)RefInvoke109.<spanstyle="white-space:pre"></span>.getFieldOjbect("android.app.ActivityThread",110.<spanstyle="white-space:pre"></span>currentActivityThread,"mAllApplications");111.<spanstyle="white-space:pre"></span>mAllApplications.remove(oldApplication);112.<spanstyle="white-space:pre"></span>ApplicationInfoappinfo_In_LoadedApk=(ApplicationInfo)RefInvoke113.<spanstyle="white-space:pre"></span>.getFieldOjbect("android.app.LoadedApk",loadedApkInfo,114.<spanstyle="white-space:pre"></span>"mApplicationInfo");115.<spanstyle="white-space:pre"></span>ApplicationInfoappinfo_In_AppBindData=(ApplicationInfo)RefInvoke116.<spanstyle="white-space:pre"></span>.getFieldOjbect("android.app.ActivityThread$AppBindData",117.<spanstyle="white-space:pre"></span>mBoundApplication,"appInfo");118.<spanstyle="white-space:pre"></span>appinfo_In_LoadedApk.className=appClassName;119.<spanstyle="white-space:pre"></span>appinfo_In_AppBindData.className=appClassName;120.<spanstyle="white-space:pre"></span>Applicationapp=(Application)RefInvoke.invokeMethod(121.<spanstyle="white-space:pre"></span>"android.app.LoadedApk","makeApplication",loadedApkInfo,122.<spanstyle="white-space:pre"></span>newClass[]{boolean.class,Instrumentation.class},123.<spanstyle="white-space:pre"></span>newObject[]{falsenull});124.<spanstyle="white-space:pre"></span>RefInvoke.setFieldOjbect("android.app.ActivityThread",125.<spanstyle="white-space:pre"></span>"mInitialApplication",currentActivityThread,app);126.127.128.<spanstyle="white-space:pre"></span>HashMapmProviderMap=(HashMap)RefInvoke.getFieldOjbect(129.<spanstyle="white-space:pre"></span>"android.app.ActivityThread",currentActivityThread,!-130.<spanstyle="white-space:pre"></span>"mProviderMap");131.<spanstyle="white-space:pre"></span>Iteratorit=mProviderMap.values().iterator();132.<spanstyle="white-space:pre"></span>while(it.hasNext()){133.<spanstyle="white-space:pre"></span>ObjectproviderClientRecord=it.next();134.<spanstyle="white-space:pre"></span>ObjectlocalProvider=RefInvoke.getFieldOjbect(135.<spanstyle="white-space:pre"></span>"android.app.ActivityThread$ProviderClientRecord",136.<spanstyle="white-space:pre"></span>providerClientRecord,"mLocalProvider");137.<spanstyle="white-space:pre"></span>RefInvoke.setFieldOjbect("android.content.ContentProvider",138.<spanstyle="white-space:pre"></span>"mContext",localProvider,app);139.<spanstyle="white-space:pre"></span>}140.<spanstyle="white-space:pre"></span>app.onCreate();141.<spanstyle="white-space:pre"></span>}<spanstyle="white-space:pre"></span>}謝謝閱讀<spanstyle="white-space:pre"></span>privatevoidsplitPayLoadFromDex(byte[]data)throwsIOException{感謝閱讀<spanstyle="white-space:pre"></span>byte[]apkdata=decrypt(data);謝謝閱讀147.<spanstyle="white-space:pre"></span>intablen=apkdata.length;148.<spanstyle="white-space:pre"></span>byte[]dexlen=newbyte[4];<spanstyle="white-space:pre"></span>System.arraycopy(apkdata,ablen精品文檔放心下載4,dexlen,0,4);<spanstyle="white-space:pre"></span>ByteArrayInputStreambais=new感謝閱讀ByteArrayInputStream(dexlen);感謝閱讀<spanstyle="white-space:pre"></span>DataInputStreamin=newDataInputStream(bais);精品文檔放心下載152.<spanstyle="white-space:pre"> </span>intreadInt=in.readInt();謝謝閱讀<spanstyle="white-space:pre"></span>System.out.println(Integer.toHexString(readInt));謝謝閱讀<spanstyle="white-space:pre"></span>byte[]newdex=newbyte[readInt];謝謝閱讀<spanstyle="white-space:pre"></span>System.arraycopy(apkdata,ablen-4-readInt,newdex,0,readInt);感謝閱讀<spanstyle="white-space:pre"></span>Filefile=newFile(apkFileName);感謝閱讀157.<spanstyle="white-space:pre"> </span>try{精品文檔放心下載!-158.<spanstyle="white-space:pre"></span>FileOutputStreamlocalFileOutputStream=newFileOutputStream(file);159.<spanstyle="white-space:pre"></span>localFileOutputStream.write(newdex);160.<spanstyle="white-space:pre"></span>localFileOutputStream.close();161.162.<spanstyle="white-space:pre"></span>}catch(IOExceptionlocalIOException){謝謝閱讀164.<spanstyle="white-space:pre"></span>thrownewRuntimeException(localIOException);165.<spanstyle="white-space:pre"></span>}166.167.<spanstyle="white-space:pre"></span>ZipInputStreamlocalZipInputStream=newZipInputStream(謝謝閱讀169.<spanstyle="white-space:pre"></span>newBufferedInputStream(newFileInputStream(file)));170.<spanstyle="white-space:pre"></span>while(true){171.<spanstyle="white-space:pre"></span>ZipEntrylocalZipEntry=localZipInputStream.getNextEntry();172.<spanstyle="white-space:pre"></span>if(localZipEntry==null){173.<spanstyle="white-space:pre"></span>localZipInputStream.close();174.<spanstyle="white-space:pre"></span>break;175.<spanstyle="white-space:pre"></span>}176.<spanstyle="white-space:pre"></span>Stringname=localZipEntry.getName();177.<spanstyle="white-space:pre"></span>if(name.startsWith("lib/")&&name.endsWith(".so")){178.<spanstyle="white-space:pre"></span>FilestoreFile=newFile(libPath+"/"179.<spanstyle="white-space:pre"></span>+name.substring(name.lastIndexOf('/')));180.<spanstyle="white-space:pre"></span>storeFile.createNewFile();181.<spanstyle="white-space:pre"></span>FileOutputStreamf
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 交通信號控制系統(tǒng)操作規(guī)程
- 三農(nóng)村電商售后服務(wù)與客戶關(guān)系管理實戰(zhàn)指南
- 安裝光伏發(fā)電劃算不
- 汽車 充電樁 新能源
- 課題研究可行性分析格式模板
- 項目進度管理與風(fēng)險控制的工作計劃
- 三農(nóng)產(chǎn)品三農(nóng)村市場風(fēng)險防控方案
- 消防中級監(jiān)控練習(xí)試題及答案
- 中級養(yǎng)老護理練習(xí)試題
- 茶藝師復(fù)習(xí)測試題
- 機械工程原理真題集
- 2025年甘肅甘南州國控資產(chǎn)投資管理集團有限公司面向社會招聘工作人員12人筆試參考題庫附帶答案詳解
- 《心肌缺血心電圖》課件
- 2025年中國建筑股份有限公司招聘筆試參考題庫含答案解析
- 持續(xù)葡萄糖監(jiān)測臨床應(yīng)用專家共識2024解讀
- DB33T 2157-2018 公共機構(gòu)綠色數(shù)據(jù)中心建設(shè)與運行規(guī)范
- 健康促進機關(guān)創(chuàng)建培訓(xùn)
- Unit3TheworldofScience大單元教學(xué)設(shè)計-高中英語
- 中國心力衰竭患者高鉀血癥管理專家共識2024解讀
- DB51T 990-2020 小型泵站設(shè)計規(guī)程
- 護患溝通技巧課件
評論
0/150
提交評論