├── .gitignore ├── .idea ├── dictionaries │ └── Administrator.xml ├── gradle.xml ├── misc.xml ├── modules.xml └── runConfigurations.xml ├── Any ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── makelove │ │ └── test │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── makelove │ │ │ └── test │ │ │ ├── MainActivity.java │ │ │ ├── bean │ │ │ ├── ClassDataItem.java │ │ │ ├── ClassDefItem.java │ │ │ ├── CodeItem.java │ │ │ ├── Dex.java │ │ │ ├── DexData.java │ │ │ ├── EncodedField.java │ │ │ ├── EncodedMethod.java │ │ │ ├── FieldIdsItem.java │ │ │ ├── HeaderType.java │ │ │ ├── MapItem.java │ │ │ ├── MapList.java │ │ │ ├── MethodIdsItem.java │ │ │ ├── ProtoIdsItem.java │ │ │ ├── StringDataItem.java │ │ │ ├── StringIdsItem.java │ │ │ ├── TypeIdsItem.java │ │ │ ├── TypeList.java │ │ │ └── getData.java │ │ │ └── utils │ │ │ ├── DexHander.java │ │ │ ├── DexUtilis.java │ │ │ ├── LogUtils.java │ │ │ ├── PermissionCallBack.java │ │ │ ├── PermissionUtils.java │ │ │ └── Utils.java │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── makelove │ └── test │ └── ExampleUnitTest.java ├── Dex.png ├── README.md ├── app ├── .gitignore ├── CMakeLists.txt ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── makelove │ │ └── dex │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── cpp │ │ └── native-lib.cpp │ ├── java │ │ └── com │ │ │ └── makelove │ │ │ └── dex │ │ │ ├── Bean │ │ │ └── struct │ │ │ │ ├── AnnotationsDirectoryItem.java │ │ │ │ ├── ClassDataItem.java │ │ │ │ ├── ClassDefItem.java │ │ │ │ ├── CodeItem.java │ │ │ │ ├── DexFile.h │ │ │ │ ├── EncodedField.java │ │ │ │ ├── EncodedMethod.java │ │ │ │ ├── FieldIdsItem.java │ │ │ │ ├── HeaderType.java │ │ │ │ ├── MapItem.java │ │ │ │ ├── MapList.java │ │ │ │ ├── MethodIdsItem.java │ │ │ │ ├── ProtoIdsItem.java │ │ │ │ ├── StringDataItem.java │ │ │ │ ├── StringIdsItem.java │ │ │ │ ├── TypeIdsItem.java │ │ │ │ └── TypeList.java │ │ │ ├── MainActivity.java │ │ │ └── utils │ │ │ ├── DexUtilis.java │ │ │ ├── LogUtils.java │ │ │ ├── ParseDexUtils.java │ │ │ ├── PermissionCallBack.java │ │ │ ├── PermissionUtils.java │ │ │ └── Utils.java │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── makelove │ └── dex │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /.idea/dictionaries/Administrator.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | Android 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 49 | 50 | 51 | 52 | 53 | 1.8 54 | 55 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /Any/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /Any/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 26 5 | 6 | 7 | 8 | defaultConfig { 9 | applicationId "com.makelove.test" 10 | minSdkVersion 21 11 | targetSdkVersion 26 12 | versionCode 1 13 | versionName "1.0" 14 | 15 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 16 | 17 | } 18 | 19 | buildTypes { 20 | release { 21 | minifyEnabled false 22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 23 | } 24 | } 25 | 26 | } 27 | 28 | dependencies { 29 | implementation fileTree(dir: 'libs', include: ['*.jar']) 30 | 31 | implementation 'com.android.support:appcompat-v7:27.1.1' 32 | implementation 'com.android.support.constraint:constraint-layout:1.1.3' 33 | testImplementation 'junit:junit:4.12' 34 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 35 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 36 | } 37 | -------------------------------------------------------------------------------- /Any/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /Any/src/androidTest/java/com/makelove/test/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.makelove.test; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.makelove.test", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Any/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Any/src/main/java/com/makelove/test/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.makelove.test; 2 | 3 | import android.Manifest; 4 | import android.content.pm.PackageManager; 5 | import android.support.annotation.NonNull; 6 | import android.support.v4.app.ActivityCompat; 7 | import android.support.v7.app.AppCompatActivity; 8 | import android.os.Bundle; 9 | import android.widget.Toast; 10 | 11 | import com.makelove.test.bean.Dex; 12 | import com.makelove.test.utils.DexHander; 13 | import com.makelove.test.utils.DexUtilis; 14 | import com.makelove.test.utils.PermissionCallBack; 15 | import com.makelove.test.utils.PermissionUtils; 16 | 17 | public class MainActivity extends AppCompatActivity implements PermissionCallBack { 18 | 19 | private static String[] PERMISSIONS={ 20 | Manifest.permission.READ_EXTERNAL_STORAGE, 21 | Manifest.permission.WRITE_EXTERNAL_STORAGE, 22 | }; 23 | 24 | @Override 25 | protected void onCreate(Bundle savedInstanceState) { 26 | super.onCreate(savedInstanceState); 27 | setContentView(R.layout.activity_main); 28 | 29 | PermissionUtils.initPermission(this,PERMISSIONS,this); 30 | 31 | 32 | 33 | } 34 | 35 | /** 36 | * 对Dex进行处理修改 37 | */ 38 | private void DexProcessing() { 39 | String path = DexUtilis.getSDPath() + "/" + "File2bytes" ; 40 | 41 | byte[] srcByte = DexUtilis.File2bytes(path+ "/" + "classes.dex"); 42 | 43 | DexHander dexHander = new DexHander(); 44 | 45 | Dex dex = dexHander.SetDex(srcByte); 46 | 47 | byte[] bytes = dex.setDebugInfoZero(); 48 | 49 | DexUtilis.byte2File(bytes,path,"SucessClasses.dex"); 50 | } 51 | 52 | 53 | @Override 54 | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 55 | super.onRequestPermissionsResult(requestCode, permissions, grantResults); 56 | int count=0; 57 | switch (requestCode) { 58 | case 1: 59 | for (int i = 0; i < grantResults.length; i++) { 60 | if (grantResults[i] != PackageManager.PERMISSION_GRANTED) { 61 | //判断是否勾选禁止后不再询问 62 | boolean showRequestPermission = ActivityCompat. 63 | shouldShowRequestPermissionRationale(this, permissions[i]); 64 | if (showRequestPermission) { 65 | return; 66 | } else { 67 | Toast.makeText(getApplicationContext(), "权限",Toast.LENGTH_LONG).show(); 68 | } 69 | }else { 70 | //拿到 权限 71 | count++; 72 | } 73 | 74 | } 75 | if(count==grantResults.length){ 76 | //全部拿到 77 | DexProcessing(); 78 | }else { 79 | //没有全部拿到 80 | // ToastUtils.showToast(this,getString(R.string.asdfasd)); 81 | // System.exit(0); 82 | } 83 | //初始化推送 84 | break; 85 | 86 | } 87 | } 88 | @Override 89 | public void getPermission(boolean isGet) { 90 | if(isGet){ 91 | DexProcessing(); 92 | } 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /Any/src/main/java/com/makelove/test/bean/ClassDataItem.java: -------------------------------------------------------------------------------- 1 | package com.makelove.test.bean; 2 | 3 | import com.makelove.test.utils.Utils; 4 | 5 | public class ClassDataItem { 6 | 7 | /** 8 | * uleb128 unsigned little-endian base 128 9 | struct class_data_item 10 | { 11 | uleb128 static_fields_size; 12 | uleb128 instance_fields_size; 13 | uleb128 direct_methods_size; 14 | uleb128 virtual_methods_size; 15 | encoded_field static_fields [ static_fields_size ]; 16 | encoded_field instance_fields [ instance_fields_size ]; 17 | encoded_method direct_methods [ direct_method_size ]; 18 | encoded_method virtual_methods [ virtual_methods_size ]; 19 | } 20 | */ 21 | 22 | //uleb128只用来编码32位的整型数 23 | public byte[] static_fields_size; 24 | public byte[] instance_fields_size; 25 | public byte[] direct_methods_size; 26 | public byte[] virtual_methods_size; 27 | 28 | //记录 上面 个个leb128数据的 长度 29 | // public int static_fields_size_length; 30 | // public int instance_fields_size_length; 31 | // public int direct_methods_size_length; 32 | // public int virtual_methods_size_length; 33 | 34 | 35 | 36 | 37 | 38 | public EncodedField[] static_fields; 39 | public EncodedField[] instance_fields; 40 | public EncodedMethod[] direct_methods; 41 | public EncodedMethod[] virtual_methods; 42 | 43 | /** 44 | * 将direct_methods 和 virtual_methods 45 | * 的Debug_info数据都是设置成0 46 | * @param src 47 | * @return 48 | */ 49 | public byte[] setDebugZero(byte[] src){ 50 | byte[] foundation=null; 51 | for(int i=0;i getClassDataItem(byte[] src){ 63 | // 64 | // } 65 | 66 | 67 | 68 | 69 | 70 | // 所属类型 是否是public 71 | // public final static int 72 | // ACC_PUBLIC = 0x00000001, // class, field, method, ic 73 | // ACC_PRIVATE = 0x00000002, // field, method, ic 74 | // ACC_PROTECTED = 0x00000004, // field, method, ic 75 | // ACC_STATIC = 0x00000008, // field, method, ic 76 | // ACC_FINAL = 0x00000010, // class, field, method, ic 77 | // ACC_SYNCHRONIZED = 0x00000020, // method (only allowed on natives) 78 | // ACC_SUPER = 0x00000020, // class (not used in Dalvik) 79 | // ACC_VOLATILE = 0x00000040, // field 80 | // ACC_BRIDGE = 0x00000040, // method (1.5) 81 | // ACC_TRANSIENT = 0x00000080, // field 82 | // ACC_VARARGS = 0x00000080, // method (1.5) 83 | // ACC_NATIVE = 0x00000100, // method 84 | // ACC_INTERFACE = 0x00000200, // class, ic 85 | // ACC_ABSTRACT = 0x00000400, // class, method, ic 86 | // ACC_STRICT = 0x00000800, // method 87 | // ACC_SYNTHETIC = 0x00001000, // field, method, ic 88 | // ACC_ANNOTATION = 0x00002000, // class, ic (1.5) 89 | // ACC_ENUM = 0x00004000, // class, field, ic (1.5) 90 | // ACC_CONSTRUCTOR = 0x00010000, // method (Dalvik only) 91 | // ACC_DECLARED_SYNCHRONIZED = 0x00020000, // method (Dalvik only) 92 | // ACC_CLASS_MASK = 93 | // (ACC_PUBLIC | ACC_FINAL | ACC_INTERFACE | ACC_ABSTRACT 94 | // | ACC_SYNTHETIC | ACC_ANNOTATION | ACC_ENUM), 95 | // ACC_INNER_CLASS_MASK = 96 | // (ACC_CLASS_MASK | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC), 97 | // ACC_FIELD_MASK = 98 | // (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC | ACC_FINAL 99 | // | ACC_VOLATILE | ACC_TRANSIENT | ACC_SYNTHETIC | ACC_ENUM), 100 | // ACC_METHOD_MASK = 101 | // (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC | ACC_FINAL 102 | // | ACC_SYNCHRONIZED | ACC_BRIDGE | ACC_VARARGS | ACC_NATIVE 103 | // | ACC_ABSTRACT | ACC_STRICT | ACC_SYNTHETIC | ACC_CONSTRUCTOR 104 | // | ACC_DECLARED_SYNCHRONIZED); 105 | 106 | 107 | 108 | 109 | public static int getSize(){ 110 | return 4 * 8; 111 | } 112 | 113 | 114 | 115 | // @Override 116 | // public String toString(){ 117 | // return "class_idx:"+class_idx+",access_flags:"+access_flags+",superclass_idx:"+superclass_idx+",iterfaces_off:"+iterfaces_off 118 | // +",source_file_idx:"+source_file_idx+",annotations_off:"+annotations_off+",class_data_off:"+class_data_off 119 | // +",static_value_off:"+static_value_off; 120 | // } 121 | 122 | } 123 | -------------------------------------------------------------------------------- /Any/src/main/java/com/makelove/test/bean/CodeItem.java: -------------------------------------------------------------------------------- 1 | package com.makelove.test.bean; 2 | 3 | 4 | import com.makelove.test.utils.Utils; 5 | 6 | /** 7 | * 8 | */ 9 | public class CodeItem { 10 | 11 | 12 | private int startOff; 13 | 14 | public CodeItem(int startOff){ 15 | this.startOff=startOff; 16 | } 17 | 18 | 19 | 20 | /** 21 | * struct code_item 22 | { 23 | ushort registers_size; 24 | ushort ins_size; 25 | ushort outs_size; 26 | ushort tries_size; 27 | uint debug_info_off; 28 | 29 | uint insns_size; 30 | ushort insns [ insns_size ]; 31 | 32 | 33 | 34 | ushort paddding; // optional 35 | try_item tries [ tyies_size ]; // optional 36 | encoded_catch_handler_list handlers; // optional 37 | } 38 | /** 39 | *将DebugInfoOff 偏移改成 0 40 | * aijiami的 会改偏移地址导致 41 | * jadx解析报错 42 | */ 43 | public byte[] setDebug_info_off_Zero(byte[] src){ 44 | //先拿到 DebugInfoOff 45 | byte[] bytes = Utils.copyByte(src, startOff + 8, 4); 46 | //设置成0 47 | Utils.byteSetZero(bytes); 48 | //替换 49 | return Utils.setByte(src, startOff + 8, bytes); 50 | 51 | } 52 | 53 | 54 | 55 | 56 | /* 57 | 拿到 insns_size的 大小 58 | * @param src 59 | * @param startOff 60 | * @return 61 | */ 62 | public int getInsnsSize(byte[] src){ 63 | // 64 | byte[] bytes = Utils.copyByte(src, startOff + 12, 4); 65 | 66 | int size = Utils.byte2int(bytes); 67 | 68 | return size; 69 | } 70 | 71 | /** 72 | * 将 Insns数据段 设置成指定数据 73 | * 返回最新的 总数据段 74 | * @param src 75 | * @param rep 76 | * @return 77 | */ 78 | public byte[] SetInsns(byte[] src,byte[] rep) { 79 | //return Utils.copyByte(src, startOff + 16, getInsnsSize(src, startOff)); 80 | return Utils.setByte(src,startOff+12,rep); 81 | } 82 | 83 | /** 84 | * 返回Insns数据 85 | * @param src 86 | * @return 87 | */ 88 | public byte[] getInsns(byte[] src) { 89 | return Utils.copyByte(src, startOff + 16, getInsnsSize(src)); 90 | } 91 | 92 | 93 | 94 | 95 | // public byte[] registers_size; 96 | // public byte[] ins_size; 97 | // public byte[] outs_size; 98 | // public byte[] tries_size; 99 | // public byte[] debug_info_off; 100 | // public byte[] insns_size; 101 | // public byte[] insns; 102 | // 103 | // @Override 104 | // public byte[] getData() { 105 | // return Utils.byteMergerAll(registers_size,ins_size, 106 | // outs_size,tries_size,debug_info_off,insns_size,insns); 107 | // } 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | // @Override 121 | // public String toString(){ 122 | // return "regsize:"+registers_size+",ins_size:"+ins_size 123 | // +",outs_size:"+outs_size+",tries_size:"+tries_size+",debug_info_off:"+debug_info_off 124 | // +",insns_size:"+insns_size + "\ninsns:"+getInsnsStr(); 125 | // } 126 | // 127 | // private String getInsnsStr(){ 128 | // StringBuilder sb = new StringBuilder(); 129 | // for(int i=0;i map_item = new ArrayList(); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /Any/src/main/java/com/makelove/test/bean/MethodIdsItem.java: -------------------------------------------------------------------------------- 1 | package com.makelove.test.bean; 2 | 3 | import com.makelove.test.utils.Utils; 4 | 5 | public class MethodIdsItem implements getData{ 6 | 7 | /** 8 | * struct filed_id_item 9 | { 10 | ushort class_idx; 11 | ushort proto_idx; 12 | uint name_idx; 13 | } 14 | */ 15 | 16 | public byte[] class_idx; 17 | //方法原型 =返回类型 +参数列表 18 | public byte[] proto_idx; 19 | public byte[] name_idx; 20 | 21 | public static int getSize(){ 22 | return 2 + 2 + 4; 23 | } 24 | 25 | @Override 26 | public byte[] getData() { 27 | return Utils.byteMergerAll(class_idx,proto_idx, 28 | name_idx); 29 | } 30 | 31 | // @Override 32 | // public String toString(){ 33 | // return "class_idx:"+class_idx+",proto_idx:"+proto_idx+",name_idx:"+name_idx; 34 | // } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Any/src/main/java/com/makelove/test/bean/ProtoIdsItem.java: -------------------------------------------------------------------------------- 1 | package com.makelove.test.bean; 2 | 3 | import com.makelove.test.utils.Utils; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class ProtoIdsItem implements getData{ 9 | 10 | /** 11 | * struct proto_id_item 12 | { 13 | uint shorty_idx; 14 | uint return_type_idx; 15 | uint parameters_off; 16 | } 17 | */ 18 | //StringList 的 idx 19 | public byte[] shorty_idx; 20 | public byte[] return_type_idx; 21 | //储存的是TypeID的地址 TypeID 指向string 的地址 22 | public byte[] parameters_off; 23 | 24 | 25 | //没指针 parameters_off 不等于0 26 | //TypeList 有数值 27 | public TypeList TypeList; 28 | 29 | public static int getSize(){ 30 | return 4 + 4 + 4; 31 | } 32 | 33 | @Override 34 | public byte[] getData() { 35 | return Utils.byteMergerAll(shorty_idx,return_type_idx,parameters_off); 36 | } 37 | 38 | 39 | // @Override 40 | // public String toString(){ 41 | // return "shorty_idx:"+shorty_idx 42 | // +",return_type_idx:"+return_type_idx+ 43 | // ",parameters_off: "+parameters_off+ 44 | // ",parametersList: "+ 45 | // //判断 参数 列表 是否有数据 46 | // (parametersList.size()!=0?parametersList.toString():"") 47 | // //默认 为 0 等于 0打印 "" 48 | // //开始 位置 49 | // +",parameterCount: "+(parameterCount==0?"0":parametersList.size()+""); 50 | // 51 | // } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /Any/src/main/java/com/makelove/test/bean/StringDataItem.java: -------------------------------------------------------------------------------- 1 | package com.makelove.test.bean; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class StringDataItem { 7 | 8 | /** 9 | * struct string_data_item 10 | { 11 | uleb128 utf16_size; 12 | ubyte data; 13 | } 14 | */ 15 | 16 | 17 | 18 | public byte[] size; 19 | public byte[] data; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /Any/src/main/java/com/makelove/test/bean/StringIdsItem.java: -------------------------------------------------------------------------------- 1 | package com.makelove.test.bean; 2 | 3 | 4 | 5 | public class StringIdsItem implements getData{ 6 | 7 | /** 8 | * struct string_ids_item 9 | { 10 | uint string_data_off; 11 | } 12 | */ 13 | //存放的都是 偏移 14 | public byte[] string_data_off; 15 | 16 | public static int getSize(){ 17 | return 4; 18 | } 19 | 20 | @Override 21 | public byte[] getData() { 22 | return this.string_data_off; 23 | } 24 | 25 | 26 | 27 | // @Override 28 | // public String toString(){ 29 | // return Utils.bytesToHexString(Utils.int2Byte(string_data_off)); 30 | // } 31 | 32 | 33 | 34 | 35 | } 36 | -------------------------------------------------------------------------------- /Any/src/main/java/com/makelove/test/bean/TypeIdsItem.java: -------------------------------------------------------------------------------- 1 | package com.makelove.test.bean; 2 | 3 | 4 | 5 | public class TypeIdsItem { 6 | 7 | /** 8 | * struct type_ids_item 9 | { 10 | uint descriptor_idx; 11 | } 12 | */ 13 | //这里的descriptor_idx就是解析之后的字符串中的索引值 14 | public byte[] descriptor_idx; 15 | 16 | public static int getSize(){ 17 | return 4; 18 | } 19 | 20 | // @Override 21 | // public byte[] getData() { 22 | // return this.descriptor_idx; 23 | // } 24 | 25 | 26 | 27 | 28 | // @Override 29 | // public String toString(){ 30 | // return Utils.bytesToHexString(Utils.int2Byte(descriptor_idx)); 31 | // } 32 | 33 | 34 | 35 | } 36 | -------------------------------------------------------------------------------- /Any/src/main/java/com/makelove/test/bean/TypeList.java: -------------------------------------------------------------------------------- 1 | package com.makelove.test.bean; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class TypeList { 7 | public byte[] typeIds; 8 | } 9 | -------------------------------------------------------------------------------- /Any/src/main/java/com/makelove/test/bean/getData.java: -------------------------------------------------------------------------------- 1 | package com.makelove.test.bean; 2 | 3 | /** 4 | * Created by lyh on 2018/9/26. 5 | */ 6 | 7 | public interface getData { 8 | 9 | public byte[] getData(); 10 | } 11 | -------------------------------------------------------------------------------- /Any/src/main/java/com/makelove/test/utils/DexHander.java: -------------------------------------------------------------------------------- 1 | package com.makelove.test.utils; 2 | 3 | import com.makelove.test.bean.ClassDataItem; 4 | import com.makelove.test.bean.ClassDefItem; 5 | import com.makelove.test.bean.CodeItem; 6 | import com.makelove.test.bean.Dex; 7 | import com.makelove.test.bean.EncodedField; 8 | import com.makelove.test.bean.EncodedMethod; 9 | import com.makelove.test.bean.FieldIdsItem; 10 | import com.makelove.test.bean.HeaderType; 11 | import com.makelove.test.bean.MethodIdsItem; 12 | import com.makelove.test.bean.ProtoIdsItem; 13 | import com.makelove.test.bean.StringIdsItem; 14 | import com.makelove.test.bean.TypeIdsItem; 15 | import com.makelove.test.bean.TypeList; 16 | 17 | /** 18 | * Created by lyh on 2018/9/28. 19 | */ 20 | 21 | public class DexHander { 22 | private Dex mDex; 23 | 24 | 25 | 26 | 27 | private static int HeaderOffset = 0; 28 | 29 | private static int StringListCount = 0; 30 | private static int StringListOffset = 0; 31 | 32 | private static int typeListCount = 0; 33 | private static int typeListOffset = 0; 34 | 35 | private static int protoListCount = 0; 36 | private static int protoListOffset = 0; 37 | 38 | private static int fieldListCount = 0; 39 | private static int fieldListOffset = 0; 40 | 41 | private static int methodListCount = 0; 42 | private static int methodListOffset = 0; 43 | 44 | private static int classDefListCount = 0; 45 | private static int classDefListOffset = 0; 46 | 47 | private static int dataListCount = 0; 48 | 49 | //ClassData 解析时候用不上 需要 根据 ClassDef里面的 50 | //data_offset拿到 偏移 和大小 然后 分别赋值 51 | private static int dataListOffset = 0; 52 | //存放data的 偏移 比如 第一个 StringData 数据 53 | private static int mapListOffset = 0; 54 | 55 | 56 | 57 | /** 58 | * 对 Dex进行赋值 59 | * @param src 60 | * @return 61 | */ 62 | public Dex SetDex(byte[] src){ 63 | mDex=new Dex(src); 64 | praseDexHeader(src,mDex); 65 | praseDexStringList(src,mDex); 66 | praseDexTypeList(src,mDex); 67 | praseDexProtoList(src,mDex); 68 | praseDexFieldList(src,mDex); 69 | praseDexMethodList(src,mDex); 70 | praseDexClassDefList(src,mDex); 71 | praseDexData(src,mDex); 72 | return mDex; 73 | } 74 | 75 | /** 76 | * @param src 77 | * @param dex 78 | */ 79 | private void praseDexData(byte[] src, Dex dex) { 80 | 81 | 82 | dex.Data=Utils.copyByte(src,dataListOffset,dataListCount); 83 | 84 | 85 | // byte[] foundation=null; 86 | // //StringList的Data数据 87 | // for(int i=0;iClassData->ClassDataItem 155 | * 对ClassDataItem 进行解析 可以得到 ClassData 具体 156 | * @param srcByte 157 | */ 158 | private static ClassDefItem parseClassDataItem(byte[] srcByte, int offset,ClassDefItem classDefItem){ 159 | //LogUtils.e("size 开始偏移地址: "+offset); 160 | ClassDataItem item = new ClassDataItem(); 161 | 162 | 163 | // 4个 leb128变量 164 | for(int i=0;i<4;i++){ 165 | byte[] byteAry = Utils.readUnsignedLeb128(srcByte, offset); 166 | //LogUtils.e("偏移基地址"+offset); 167 | //LogUtils.e("ByteLength"+byteAry.length); 最前面一个 1 168 | //循环了4次 把四个size赋值以后 169 | // 剩下的 就是 4个 Encoded 的 数据 170 | offset += byteAry.length; 171 | 172 | // int size = 0; 173 | 174 | // if(byteAry.length == 1){ 175 | // size = byteAry[0]; 176 | // }else if(byteAry.length == 2){ 177 | // size = Utils.byte2Short(byteAry); 178 | // }else if(byteAry.length == 4){ 179 | // size = Utils.byte2int(byteAry); 180 | // } 181 | if(i == 0){ 182 | item.static_fields_size = byteAry; 183 | }else if(i == 1){ 184 | item.instance_fields_size = byteAry; 185 | }else if(i == 2){ 186 | item.direct_methods_size = byteAry; 187 | }else if(i == 3){ 188 | item.virtual_methods_size = byteAry; 189 | } 190 | } 191 | 192 | 193 | // static_fields 194 | //每一个 ClassData有多个 EncodedField 和 EncodeMethod 195 | //顺序排列 196 | EncodedField[] staticFieldAry = new EncodedField[item.static_fields_size.length]; 197 | 198 | //LogUtils.e("Encoded 开始偏移地址: "+offset); 199 | for(int i=0;i mPermissionList = new ArrayList<>(); 22 | 23 | 24 | private static String[] PERMISSIONS; 25 | 26 | // Manifest.permission.READ_EXTERNAL_STORAGE, 27 | // Manifest.permission.WRITE_EXTERNAL_STORAGE, 28 | // Manifest.permission.READ_PHONE_STATE, 29 | 30 | 31 | 32 | 33 | 34 | 35 | private static PermissionCallBack call; 36 | 37 | /** 38 | * 初始化权限的方法 39 | */ 40 | public static void initPermission(Activity activity, 41 | String[] PERMISSIONS_STORAGE, 42 | PermissionCallBack callback 43 | ) { 44 | call=callback; 45 | PERMISSIONS=PERMISSIONS_STORAGE; 46 | //先检查权限 47 | if(isGetPermission(activity,PERMISSIONS_STORAGE)){ 48 | call.getPermission(true); 49 | return ; 50 | }else { 51 | ActivityCompat.requestPermissions(activity,mPermissionList. 52 | toArray(new String[mPermissionList.size()]),1); 53 | } 54 | 55 | } 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | /** 检测全选代码 68 | * @param Permission 检测权限的 字符串数组 69 | * 70 | * @return 是否都获取到 71 | */ 72 | private static boolean isGetPermission(Context context, String[] Permission){ 73 | //大于6.0 74 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 75 | //检测权限的 集合 76 | mPermissionList.clear(); 77 | for (int i = 0; i < Permission.length; i++) { 78 | if (ContextCompat.checkSelfPermission(context, Permission[i]) != PackageManager.PERMISSION_GRANTED) { 79 | //将没有获取到的权限 加到集合里 80 | mPermissionList.add(Permission[i]); 81 | } 82 | 83 | } 84 | if(mPermissionList.size()==0){ 85 | return true; 86 | }else { 87 | return false; 88 | } 89 | } 90 | //小于6.0直接true 91 | return true; 92 | } 93 | 94 | 95 | } 96 | -------------------------------------------------------------------------------- /Any/src/main/java/com/makelove/test/utils/Utils.java: -------------------------------------------------------------------------------- 1 | package com.makelove.test.utils; 2 | 3 | import java.nio.ByteBuffer; 4 | import java.nio.CharBuffer; 5 | import java.nio.charset.Charset; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * Created by lyh on 2018/9/26. 11 | */ 12 | 13 | public class Utils { 14 | 15 | 16 | /** 17 | * 合并多个 Byte数组 18 | * @param values 19 | * @return 20 | */ 21 | public static byte[] byteMergerAll(byte[]... values) { 22 | int length_byte = 0; 23 | for (int i = 0; i < values.length; i++) { 24 | if(values[i]!=null) { 25 | length_byte += values[i].length; 26 | } 27 | } 28 | byte[] all_byte = new byte[length_byte]; 29 | int countLength = 0; 30 | for (int i = 0; i < values.length; i++) { 31 | byte[] b = values[i]; 32 | if(b!=null) { 33 | System.arraycopy(b, 0, all_byte, countLength, b.length); 34 | countLength += b.length; 35 | } 36 | } 37 | return all_byte; 38 | } 39 | 40 | 41 | 42 | public static int byte2int(byte[] res) { 43 | int targets = (res[0] & 0xff) | ((res[1] << 8) & 0xff00) 44 | | ((res[2] << 24) >>> 8) | (res[3] << 24); 45 | return targets; 46 | } 47 | 48 | public static byte[] int2Byte(final int integer) { 49 | int byteNum = (40 -Integer.numberOfLeadingZeros (integer < 0 ? ~integer : integer))/ 8; 50 | byte[] byteArray = new byte[4]; 51 | 52 | for (int n = 0; n < byteNum; n++) 53 | byteArray[3 - n] = (byte) (integer>>> (n * 8)); 54 | 55 | return (byteArray); 56 | } 57 | 58 | public static byte[] short2Byte(short number) { 59 | int temp = number; 60 | byte[] b = new byte[2]; 61 | for (int i = 0; i < b.length; i++) { 62 | b[i] = new Integer(temp & 0xff).byteValue();//将最低位保存在最低位 63 | temp = temp >> 8; // 向右移8位 64 | } 65 | return b; 66 | } 67 | 68 | public static short byte2Short(byte[] b) { 69 | short s = 0; 70 | try { 71 | s = 0; 72 | short s0 = (short) (b[0] & 0xff); 73 | short s1 = (short) (b[1] & 0xff); 74 | s1 <<= 8; 75 | s = (short) (s0 | s1); 76 | } catch (Exception e) { 77 | e.printStackTrace(); 78 | return s; 79 | } 80 | return s; 81 | } 82 | 83 | public static String bytesToHexString(byte[] src){ 84 | //byte[] src = reverseBytes(src1); 85 | StringBuilder stringBuilder = new StringBuilder(""); 86 | if (src == null || src.length <= 0) { 87 | return null; 88 | } 89 | for (int i = 0; i < src.length; i++) { 90 | int v = src[i] & 0xFF; 91 | String hv = Integer.toHexString(v); 92 | if (hv.length() < 2) { 93 | stringBuilder.append(0); 94 | } 95 | stringBuilder.append(hv+" "); 96 | } 97 | return stringBuilder.toString(); 98 | } 99 | 100 | public static char[] getChars(byte[] bytes) { 101 | Charset cs = Charset.forName ("UTF-8"); 102 | ByteBuffer bb = ByteBuffer.allocate (bytes.length); 103 | bb.put (bytes); 104 | bb.flip (); 105 | CharBuffer cb = cs.decode (bb); 106 | return cb.array(); 107 | } 108 | 109 | 110 | /** 111 | * 打印 list详情 112 | * @param list 113 | */ 114 | public static void outDetailed(List list){ 115 | for(Object t:list){ 116 | LogUtils.e("lyh296488320",t.toString()); 117 | } 118 | } 119 | 120 | public static byte[] copyByte(byte[] src, int start, int len){ 121 | 122 | if(src == null){ 123 | return null; 124 | } 125 | if(start > src.length){ 126 | return null; 127 | } 128 | if((start+len) > src.length){ 129 | return null; 130 | } 131 | if(start<0){ 132 | return null; 133 | } 134 | if(len<=0){ 135 | return null; 136 | } 137 | byte[] resultByte = new byte[len]; 138 | for(int i=0;i newByte = new ArrayList(); 168 | for(int i=0;i= srcByte.length){ 188 | return ""; 189 | } 190 | byte val = srcByte[start]; 191 | int i = 1; 192 | ArrayList byteList = new ArrayList(); 193 | while(val != 0){ 194 | byteList.add(srcByte[start+i]); 195 | val = srcByte[start+i]; 196 | i++; 197 | } 198 | byte[] valAry = new byte[byteList.size()]; 199 | for(int j=0;j byteAryList = new ArrayList(); 272 | byte bytes = copyByte(srcByte, offset, 1)[0]; 273 | byte highBit = (byte)(bytes & 0x80); 274 | byteAryList.add(bytes); 275 | offset ++; 276 | while(highBit != 0){ 277 | bytes = copyByte(srcByte, offset, 1)[0]; 278 | highBit = (byte)(bytes & 0x80); 279 | offset ++; 280 | byteAryList.add(bytes); 281 | } 282 | byte[] byteAry = new byte[byteAryList.size()]; 283 | for(int j=0;j 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /Any/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 11 | 16 | 21 | 26 | 31 | 36 | 41 | 46 | 51 | 56 | 61 | 66 | 71 | 76 | 81 | 86 | 91 | 96 | 101 | 106 | 111 | 116 | 121 | 126 | 131 | 136 | 141 | 146 | 151 | 156 | 161 | 166 | 171 | 172 | -------------------------------------------------------------------------------- /Any/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Any/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Any/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Any/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w296488320/DexAnalyzeForAndroid/92ec9155089bf6b56f75406a4de6f75640199871/Any/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /Any/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w296488320/DexAnalyzeForAndroid/92ec9155089bf6b56f75406a4de6f75640199871/Any/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Any/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w296488320/DexAnalyzeForAndroid/92ec9155089bf6b56f75406a4de6f75640199871/Any/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /Any/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w296488320/DexAnalyzeForAndroid/92ec9155089bf6b56f75406a4de6f75640199871/Any/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Any/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w296488320/DexAnalyzeForAndroid/92ec9155089bf6b56f75406a4de6f75640199871/Any/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Any/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w296488320/DexAnalyzeForAndroid/92ec9155089bf6b56f75406a4de6f75640199871/Any/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Any/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w296488320/DexAnalyzeForAndroid/92ec9155089bf6b56f75406a4de6f75640199871/Any/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Any/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w296488320/DexAnalyzeForAndroid/92ec9155089bf6b56f75406a4de6f75640199871/Any/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Any/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w296488320/DexAnalyzeForAndroid/92ec9155089bf6b56f75406a4de6f75640199871/Any/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Any/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w296488320/DexAnalyzeForAndroid/92ec9155089bf6b56f75406a4de6f75640199871/Any/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Any/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /Any/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Test 3 | 4 | -------------------------------------------------------------------------------- /Any/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Any/src/test/java/com/makelove/test/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.makelove.test; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /Dex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w296488320/DexAnalyzeForAndroid/92ec9155089bf6b56f75406a4de6f75640199871/Dex.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DexAnalyzeForAndroid 2 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # For more information about using CMake with Android Studio, read the 2 | # documentation: https://d.android.com/studio/projects/add-native-code.html 3 | 4 | # Sets the minimum version of CMake required to build the native library. 5 | 6 | cmake_minimum_required(VERSION 3.4.1) 7 | 8 | # Creates and names a library, sets it as either STATIC 9 | # or SHARED, and provides the relative paths to its source code. 10 | # You can define multiple libraries, and CMake builds them for you. 11 | # Gradle automatically packages shared libraries with your APK. 12 | 13 | add_library( # Sets the name of the library. 14 | native-lib 15 | 16 | # Sets the library as a shared library. 17 | SHARED 18 | 19 | # Provides a relative path to your source file(s). 20 | src/main/cpp/native-lib.cpp ) 21 | 22 | # Searches for a specified prebuilt library and stores the path as a 23 | # variable. Because CMake includes system libraries in the search path by 24 | # default, you only need to specify the name of the public NDK library 25 | # you want to add. CMake verifies that the library exists before 26 | # completing its build. 27 | 28 | find_library( # Sets the name of the path variable. 29 | log-lib 30 | 31 | # Specifies the name of the NDK library that 32 | # you want CMake to locate. 33 | log ) 34 | 35 | # Specifies libraries CMake should link to your target library. You 36 | # can link multiple libraries, such as libraries you define in this 37 | # build script, prebuilt third-party libraries, or system libraries. 38 | 39 | target_link_libraries( # Specifies the target library. 40 | native-lib 41 | 42 | # Links the target library to the log library 43 | # included in the NDK. 44 | ${log-lib} ) -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 26 5 | defaultConfig { 6 | applicationId "com.makelove.dex" 7 | minSdkVersion 21 8 | targetSdkVersion 26 9 | versionCode 1 10 | versionName "1.0" 11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 12 | // externalNativeBuild { 13 | // cmake { 14 | // cppFlags "-frtti -fexceptions" 15 | // } 16 | // } 17 | } 18 | buildTypes { 19 | release { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 22 | } 23 | } 24 | // externalNativeBuild { 25 | // cmake { 26 | // path "CMakeLists.txt" 27 | // } 28 | // } 29 | } 30 | 31 | dependencies { 32 | implementation fileTree(dir: 'libs', include: ['*.jar']) 33 | implementation 'com.android.support:appcompat-v7:27.1.1' 34 | implementation 'com.android.support.constraint:constraint-layout:1.1.3' 35 | testImplementation 'junit:junit:4.12' 36 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 37 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 38 | } 39 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/makelove/dex/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.makelove.dex; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.makelove.dex", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /app/src/main/cpp/native-lib.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | extern "C" 5 | JNIEXPORT jstring 6 | 7 | JNICALL 8 | Java_com_makelove_dex_MainActivity_stringFromJNI( 9 | JNIEnv *env, 10 | jobject /* this */) { 11 | std::string hello = "Hello from C++"; 12 | return env->NewStringUTF(hello.c_str()); 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/makelove/dex/Bean/struct/AnnotationsDirectoryItem.java: -------------------------------------------------------------------------------- 1 | package com.makelove.dex.Bean.struct; 2 | 3 | public class AnnotationsDirectoryItem { 4 | 5 | /** 6 | * u4 classAnnotationsOff; 7 | u4 fieldsSize; 8 | u4 methodsSize; 9 | u4 parametersSize; 10 | */ 11 | 12 | public int classAnnotationsOff; 13 | public int fieldsSize; 14 | public int methodsSize; 15 | public int parametersSize; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/makelove/dex/Bean/struct/ClassDataItem.java: -------------------------------------------------------------------------------- 1 | package com.makelove.dex.Bean.struct; 2 | 3 | public class ClassDataItem { 4 | 5 | /** 6 | * uleb128 unsigned little-endian base 128 7 | struct class_data_item 8 | { 9 | uleb128 static_fields_size; 10 | uleb128 instance_fields_size; 11 | uleb128 direct_methods_size; 12 | uleb128 virtual_methods_size; 13 | encoded_field static_fields [ static_fields_size ]; 14 | encoded_field instance_fields [ instance_fields_size ]; 15 | encoded_method direct_methods [ direct_method_size ]; 16 | encoded_method virtual_methods [ virtual_methods_size ]; 17 | } 18 | */ 19 | 20 | //uleb128只用来编码32位的整型数 21 | public int static_fields_size; 22 | public int instance_fields_size; 23 | public int direct_methods_size; 24 | public int virtual_methods_size; 25 | 26 | public EncodedField[] static_fields; 27 | public EncodedField[] instance_fields; 28 | public EncodedMethod[] direct_methods; 29 | public EncodedMethod[] virtual_methods; 30 | 31 | @Override 32 | public String toString(){ 33 | return "static_fields_size:"+static_fields_size+",instance_fields_size:" 34 | +instance_fields_size+",direct_methods_size:"+direct_methods_size+",virtual_methods_size:"+virtual_methods_size 35 | +"\n"+getFieldsAndMethods(); 36 | } 37 | 38 | private String getFieldsAndMethods(){ 39 | StringBuilder sb = new StringBuilder(); 40 | sb.append("static_fields:\n"); 41 | for(int i=0;i map_item = new ArrayList(); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/com/makelove/dex/Bean/struct/MethodIdsItem.java: -------------------------------------------------------------------------------- 1 | package com.makelove.dex.Bean.struct; 2 | 3 | public class MethodIdsItem { 4 | 5 | /** 6 | * struct filed_id_item 7 | { 8 | ushort class_idx; 9 | ushort proto_idx; 10 | uint name_idx; 11 | } 12 | */ 13 | 14 | public short class_idx; 15 | //方法原型 =返回类型 +参数列表 16 | public short proto_idx; 17 | public int name_idx; 18 | 19 | public static int getSize(){ 20 | return 2 + 2 + 4; 21 | } 22 | 23 | @Override 24 | public String toString(){ 25 | return "class_idx:"+class_idx+",proto_idx:"+proto_idx+",name_idx:"+name_idx; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/makelove/dex/Bean/struct/ProtoIdsItem.java: -------------------------------------------------------------------------------- 1 | package com.makelove.dex.Bean.struct; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class ProtoIdsItem { 7 | 8 | /** 9 | * struct proto_id_item 10 | { 11 | uint shorty_idx; 12 | uint return_type_idx; 13 | uint parameters_off; 14 | } 15 | */ 16 | //StringList 的 idx 17 | public int shorty_idx; 18 | public int return_type_idx; 19 | //储存的是TypeID的地址 TypeID 指向string 的地址 20 | public int parameters_off; 21 | 22 | 23 | public List parametersList = new ArrayList(); 24 | public int parameterCount; 25 | 26 | public static int getSize(){ 27 | return 4 + 4 + 4; 28 | } 29 | 30 | @Override 31 | public String toString(){ 32 | return "shorty_idx:"+shorty_idx 33 | +",return_type_idx:"+return_type_idx+ 34 | ",parameters_off: "+parameters_off+ 35 | ",parametersList: "+ 36 | //判断 参数 列表 是否有数据 37 | (parametersList.size()!=0?parametersList.toString():"") 38 | //默认 为 0 等于 0打印 "" 39 | //开始 位置 40 | +",parameterCount: "+(parameterCount==0?"0":parametersList.size()+""); 41 | 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/makelove/dex/Bean/struct/StringDataItem.java: -------------------------------------------------------------------------------- 1 | package com.makelove.dex.Bean.struct; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class StringDataItem { 7 | 8 | /** 9 | * struct string_data_item 10 | { 11 | uleb128 utf16_size; 12 | ubyte data; 13 | } 14 | */ 15 | 16 | 17 | 18 | public List utf16_size = new ArrayList(); 19 | public byte data; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/makelove/dex/Bean/struct/StringIdsItem.java: -------------------------------------------------------------------------------- 1 | package com.makelove.dex.Bean.struct; 2 | 3 | 4 | import com.makelove.dex.utils.Utils; 5 | 6 | public class StringIdsItem { 7 | 8 | /** 9 | * struct string_ids_item 10 | { 11 | uint string_data_off; 12 | } 13 | */ 14 | //存放的都是 偏移 15 | public int string_data_off; 16 | 17 | public static int getSize(){ 18 | return 4; 19 | } 20 | 21 | @Override 22 | public String toString(){ 23 | return Utils.bytesToHexString(Utils.int2Byte(string_data_off)); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/makelove/dex/Bean/struct/TypeIdsItem.java: -------------------------------------------------------------------------------- 1 | package com.makelove.dex.Bean.struct; 2 | 3 | 4 | import com.makelove.dex.utils.Utils; 5 | 6 | public class TypeIdsItem { 7 | 8 | /** 9 | * struct type_ids_item 10 | { 11 | uint descriptor_idx; 12 | } 13 | */ 14 | //这里的descriptor_idx就是解析之后的字符串中的索引值 15 | public int descriptor_idx; 16 | 17 | public static int getSize(){ 18 | return 4; 19 | } 20 | 21 | @Override 22 | public String toString(){ 23 | return Utils.bytesToHexString(Utils.int2Byte(descriptor_idx)); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/makelove/dex/Bean/struct/TypeList.java: -------------------------------------------------------------------------------- 1 | package com.makelove.dex.Bean.struct; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class TypeList { 7 | 8 | /** 9 | * struct type_list 10 | { 11 | uint size; 12 | ushort type_idx[size]; 13 | } 14 | */ 15 | 16 | public int size;//�����ĸ��� 17 | public List type_idx = new ArrayList();//���������� 18 | 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/com/makelove/dex/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.makelove.dex; 2 | 3 | import android.Manifest; 4 | import android.content.pm.PackageManager; 5 | import android.support.annotation.NonNull; 6 | import android.support.v4.app.ActivityCompat; 7 | import android.support.v7.app.AppCompatActivity; 8 | import android.os.Bundle; 9 | import android.util.Log; 10 | import android.widget.Toast; 11 | 12 | import com.makelove.dex.utils.DexUtilis; 13 | import com.makelove.dex.utils.LogUtils; 14 | import com.makelove.dex.utils.ParseDexUtils; 15 | import com.makelove.dex.utils.PermissionCallBack; 16 | import com.makelove.dex.utils.PermissionUtils; 17 | 18 | public class MainActivity extends AppCompatActivity implements PermissionCallBack{ 19 | 20 | private static String[] PERMISSIONS={ 21 | Manifest.permission.READ_EXTERNAL_STORAGE, 22 | Manifest.permission.WRITE_EXTERNAL_STORAGE, 23 | }; 24 | 25 | @Override 26 | protected void onCreate(Bundle savedInstanceState) { 27 | super.onCreate(savedInstanceState); 28 | setContentView(R.layout.activity_main); 29 | PermissionUtils.initPermission(this,PERMISSIONS,this); 30 | 31 | } 32 | 33 | 34 | 35 | 36 | @Override 37 | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 38 | super.onRequestPermissionsResult(requestCode, permissions, grantResults); 39 | int count=0; 40 | switch (requestCode) { 41 | case 1: 42 | for (int i = 0; i < grantResults.length; i++) { 43 | if (grantResults[i] != PackageManager.PERMISSION_GRANTED) { 44 | //判断是否勾选禁止后不再询问 45 | boolean showRequestPermission = ActivityCompat. 46 | shouldShowRequestPermissionRationale(this, permissions[i]); 47 | if (showRequestPermission) { 48 | return; 49 | } else { 50 | Toast.makeText(getApplicationContext(), "权限",Toast.LENGTH_LONG).show(); 51 | } 52 | }else { 53 | //拿到 权限 54 | count++; 55 | } 56 | 57 | } 58 | if(count==grantResults.length){ 59 | //全部拿到 60 | Test(); 61 | }else { 62 | //没有全部拿到 63 | // ToastUtils.showToast(this,getString(R.string.asdfasd)); 64 | // System.exit(0); 65 | } 66 | //初始化推送 67 | break; 68 | 69 | } 70 | } 71 | 72 | 73 | 74 | 75 | 76 | private void Test() { 77 | String path = DexUtilis.getSDPath() + "/" + "Dex" + "/" + "classes.dex"; 78 | 79 | byte[] srcByte = DexUtilis.Dex(path); 80 | 81 | LogUtils.e("ByteSize",srcByte.length+""); 82 | 83 | 84 | 85 | LogUtils.e("ParseHeader:"); 86 | ParseDexUtils.praseDexHeader(srcByte); 87 | LogUtils.e("ParseHeader","++++++++++++++++++++++++++++++++++++++++"); 88 | 89 | 90 | 91 | 92 | LogUtils.e("Parse StringList:"); 93 | ParseDexUtils.parseStringIds(srcByte); 94 | LogUtils.e("Parse StringIds:","++++++++++++++++++++++++++++++++++++++++"); 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | LogUtils.e("Parse TypeIds:"); 104 | ParseDexUtils.parseTypeIds(srcByte); 105 | LogUtils.e("Parse TypeIds:","++++++++++++++++++++++++++++++++++++++++"); 106 | // 107 | // 108 | // 109 | // 110 | LogUtils.e("Parse ProtoIds:"); 111 | ParseDexUtils.parseProtoIds(srcByte); 112 | LogUtils.e("Parse ProtoIds:","++++++++++++++++++++++++++++++++++++++++"); 113 | // 114 | // 115 | // 116 | // 117 | //// 118 | LogUtils.e("Parse FieldIds:"); 119 | ParseDexUtils.parseFieldIds(srcByte); 120 | LogUtils.e("Parse FieldIds:","++++++++++++++++++++++++++++++++++++++++"); 121 | // 122 | // 123 | //// 124 | LogUtils.e("Parse MethodIds:"); 125 | ParseDexUtils.parseMethodIds(srcByte); 126 | LogUtils.e("Parse MethodIds:","++++++++++++++++++++++++++++++++++++++++"); 127 | 128 | 129 | 130 | 131 | LogUtils.e("Parse ClassDefIds:"); 132 | ParseDexUtils.parseClassDefIds(srcByte); 133 | LogUtils.e("Parse ClassDefIds:","++++++++++++++++++++++++++++++++++++++++"); 134 | // 135 | // 136 | // 137 | // 138 | LogUtils.e("Parse MapList:"); 139 | ParseDexUtils.parseMapItemList(srcByte); 140 | LogUtils.e("Parse MapList:","++++++++++++++++++++++++++++++++++++++++"); 141 | 142 | LogUtils.e("Parse Class Data:"); 143 | ParseDexUtils.parseClassData(srcByte); 144 | LogUtils.e("Parse Class Data:","++++++++++++++++++++++++++++++++++++++++"); 145 | 146 | 147 | 148 | 149 | // LogUtils.e("Parse Code Content:"); 150 | // ParseDexUtils.parseCode(srcByte); 151 | // LogUtils.e("Parse Code Content:","++++++++++++++++++++++++++++++++++++++++"); 152 | 153 | } 154 | 155 | 156 | @Override 157 | public void getPermission(boolean isGet) { 158 | if(isGet){ 159 | Test(); 160 | } 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /app/src/main/java/com/makelove/dex/utils/DexUtilis.java: -------------------------------------------------------------------------------- 1 | package com.makelove.dex.utils; 2 | 3 | import android.os.Environment; 4 | 5 | import java.io.ByteArrayOutputStream; 6 | import java.io.File; 7 | import java.io.FileInputStream; 8 | import java.io.FileOutputStream; 9 | 10 | /** 11 | * Created by lyh on 2018/9/18. 12 | */ 13 | 14 | public class DexUtilis { 15 | 16 | 17 | /** 18 | * Dex2Byte[] 19 | * @param path 20 | * @return 21 | */ 22 | public static byte[] Dex(String path) { 23 | 24 | 25 | // byte[] srcByte = null; 26 | // FileInputStream fis = null; 27 | // ByteArrayOutputStream bos = null; 28 | // try{ 29 | // fis = new FileInputStream(path); 30 | // bos = new ByteArrayOutputStream(); 31 | // byte[] buffer = new byte[1024]; 32 | // int len = 0; 33 | // while((len=fis.read(buffer)) != -1){ 34 | // bos.write(buffer, 0, len); 35 | // } 36 | // srcByte = bos.toByteArray(); 37 | // }catch(Exception e){ 38 | // LogUtils.e("read res file error:"+e.toString()); 39 | // }finally{ 40 | // try{ 41 | // fis.close(); 42 | // bos.close(); 43 | // }catch(Exception e){ 44 | // LogUtils.e("close file error:"+e.toString()); 45 | // } 46 | // } 47 | // 48 | // if(srcByte == null){ 49 | // LogUtils.e("get src error..."); 50 | // return null; 51 | // } 52 | // return srcByte; 53 | 54 | 55 | byte[] srcByte = null; 56 | 57 | 58 | File file = new File(path); 59 | FileInputStream fis = null; 60 | FileOutputStream fos = null; 61 | try { 62 | fis = new FileInputStream(file); 63 | byte[] b = new byte[(int) file.length()]; 64 | fis.read(b); 65 | fos = new FileOutputStream(file); 66 | 67 | fos.write(b); 68 | 69 | srcByte=b; 70 | 71 | } catch (Exception e) { 72 | e.printStackTrace(); 73 | } finally { 74 | try { 75 | fis.close(); 76 | fos.close(); 77 | } catch (Exception e) { 78 | e.printStackTrace(); 79 | } 80 | } 81 | 82 | if(srcByte == null){ 83 | LogUtils.e("get src error"); 84 | return null; 85 | } 86 | 87 | return srcByte; 88 | } 89 | 90 | 91 | /** 92 | *获取sdCard路径 93 | * @return 94 | */ 95 | public static String getSDPath(){ 96 | File sdDir = null; 97 | boolean sdCardExist = Environment.getExternalStorageState() 98 | .equals(android.os.Environment.MEDIA_MOUNTED);//判断sd卡是否存在 99 | if(sdCardExist) 100 | { 101 | sdDir = Environment.getExternalStorageDirectory();//获取跟目录 102 | } 103 | return sdDir.toString(); 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /app/src/main/java/com/makelove/dex/utils/LogUtils.java: -------------------------------------------------------------------------------- 1 | package com.makelove.dex.utils; 2 | 3 | import android.util.Log; 4 | 5 | public class LogUtils { 6 | 7 | private static boolean enableLog = true; 8 | 9 | public static void e(String tag , String msg){ 10 | 11 | if(enableLog){ 12 | Log.e(tag, msg); 13 | } 14 | } 15 | 16 | public static void e(String msg){ 17 | 18 | if(enableLog){ 19 | Log.e("Q296488320", msg); 20 | } 21 | } 22 | 23 | 24 | 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/com/makelove/dex/utils/ParseDexUtils.java: -------------------------------------------------------------------------------- 1 | package com.makelove.dex.utils; 2 | 3 | import android.util.Log; 4 | 5 | import com.makelove.dex.Bean.struct.ClassDataItem; 6 | import com.makelove.dex.Bean.struct.ClassDefItem; 7 | import com.makelove.dex.Bean.struct.CodeItem; 8 | import com.makelove.dex.Bean.struct.EncodedField; 9 | import com.makelove.dex.Bean.struct.EncodedMethod; 10 | import com.makelove.dex.Bean.struct.FieldIdsItem; 11 | import com.makelove.dex.Bean.struct.HeaderType; 12 | import com.makelove.dex.Bean.struct.MapItem; 13 | import com.makelove.dex.Bean.struct.MapList; 14 | import com.makelove.dex.Bean.struct.MethodIdsItem; 15 | import com.makelove.dex.Bean.struct.ProtoIdsItem; 16 | import com.makelove.dex.Bean.struct.StringIdsItem; 17 | import com.makelove.dex.Bean.struct.TypeIdsItem; 18 | 19 | import java.util.ArrayList; 20 | import java.util.HashMap; 21 | import java.util.List; 22 | 23 | 24 | 25 | public class ParseDexUtils { 26 | 27 | 28 | //classDef 偏移 + size = classData 起始偏移 29 | //classData 偏移 + size =Dex总大小 30 | //Map数据 在 Data里面 31 | //用010解析 DataHeader里面的 DataSize是 32 | // Data的总大小 不是 个数 (其余的是个数 ) 33 | //DataSize+DataOff==fileSize 34 | private static int HeaderOffset = 0; 35 | 36 | private static int StringListCount = 0; 37 | private static int StringListOffset = 0; 38 | 39 | private static int typeListCount = 0; 40 | private static int typeListOffset = 0; 41 | 42 | private static int protoListCount = 0; 43 | private static int protoListOffset = 0; 44 | 45 | private static int fieldListCount = 0; 46 | private static int fieldListOffset = 0; 47 | 48 | private static int methodListCount = 0; 49 | private static int methodListOffset = 0; 50 | 51 | private static int classDefListCount = 0; 52 | private static int classDefListOffset = 0; 53 | 54 | private static int dataListCount = 0; 55 | 56 | //ClassData 解析时候用不上 需要 根据 ClassDef里面的 57 | //data_offset拿到 偏移 和大小 然后 分别赋值 58 | private static int dataListOffset = 0; 59 | //存放data的 偏移 比如 第一个 StringData 数据 60 | private static int mapListOffset = 0; 61 | 62 | 63 | 64 | // public toString 时候需要用到 数据 65 | public static List stringIdsList = new ArrayList(); 66 | 67 | 68 | 69 | public static List typeIdsList = new ArrayList(); 70 | public static List protoIdsList = new ArrayList(); 71 | public static List fieldIdsList = new ArrayList(); 72 | public static List methodIdsList = new ArrayList(); 73 | 74 | 75 | public static List classDefIdsList = new ArrayList(); 76 | 77 | 78 | 79 | public static List classDataItemList = new ArrayList(); 80 | 81 | public static List directMethodCodeItemList = new ArrayList(); 82 | public static List virtualMethodCodeItemList = new ArrayList(); 83 | 84 | public static List stringList = new ArrayList(); 85 | 86 | 87 | 88 | 89 | 90 | public static HashMap 91 | classDataMap = new HashMap(); 92 | 93 | /** 94 | * 解析头部 95 | * @param byteSrc 96 | */ 97 | public static void praseDexHeader(byte[] byteSrc){ 98 | HeaderType headerType = new HeaderType(); 99 | //魔教 100 | byte[] magic = Utils.copyByte(byteSrc, 0, 8); 101 | headerType.magic = magic; 102 | 103 | //checksum 效验 dex是否损毁 104 | byte[] checksumByte = Utils.copyByte(byteSrc, 8, 4); 105 | headerType.checksum = Utils.byte2int(checksumByte); 106 | 107 | //siganature SHA-1 20个字节 108 | byte[] siganature = Utils.copyByte(byteSrc, 12, 20); 109 | headerType.siganature = siganature; 110 | 111 | //file_size 文件总大小 112 | byte[] fileSizeByte = Utils.copyByte(byteSrc, 32, 4); 113 | headerType.file_size = Utils.byte2int(fileSizeByte); 114 | 115 | //header_size 头部大小 一般为70和字节 116 | byte[] headerSizeByte = Utils.copyByte(byteSrc, 36, 4); 117 | headerType.header_size = Utils.byte2int(headerSizeByte); 118 | 119 | //endian_tag 判断大小端 120 | byte[] endianTagByte = Utils.copyByte(byteSrc, 40, 4); 121 | headerType.endian_tag = Utils.byte2int(endianTagByte); 122 | 123 | //link_size 124 | byte[] linkSizeByte = Utils.copyByte(byteSrc, 44, 4); 125 | headerType.link_size = Utils.byte2int(linkSizeByte); 126 | 127 | //link_off 128 | byte[] linkOffByte = Utils.copyByte(byteSrc, 48, 4); 129 | headerType.link_off = Utils.byte2int(linkOffByte); 130 | 131 | //map_off 132 | byte[] mapOffByte = Utils.copyByte(byteSrc, 52, 4); 133 | headerType.map_off = Utils.byte2int(mapOffByte); 134 | 135 | //string_ids_size 136 | byte[] stringIdsSizeByte = Utils.copyByte(byteSrc, 56, 4); 137 | headerType.string_ids_size = Utils.byte2int(stringIdsSizeByte); 138 | 139 | //string_ids_off 140 | byte[] stringIdsOffByte = Utils.copyByte(byteSrc, 60, 4); 141 | headerType.string_ids_off = Utils.byte2int(stringIdsOffByte); 142 | 143 | // type_ids_size 144 | byte[] typeIdsSizeByte = Utils.copyByte(byteSrc, 64, 4); 145 | headerType.type_ids_size = Utils.byte2int(typeIdsSizeByte); 146 | 147 | // type_ids_off 148 | byte[] typeIdsOffByte = Utils.copyByte(byteSrc, 68, 4); 149 | headerType.type_ids_off = Utils.byte2int(typeIdsOffByte); 150 | 151 | // proto_ids_size 152 | byte[] protoIdsSizeByte = Utils.copyByte(byteSrc, 72, 4); 153 | headerType.proto_ids_size = Utils.byte2int(protoIdsSizeByte); 154 | 155 | // proto_ids_off 156 | byte[] protoIdsOffByte = Utils.copyByte(byteSrc, 76, 4); 157 | headerType.proto_ids_off = Utils.byte2int(protoIdsOffByte); 158 | 159 | // field_ids_size 160 | byte[] fieldIdsSizeByte = Utils.copyByte(byteSrc, 80, 4); 161 | headerType.field_ids_size = Utils.byte2int(fieldIdsSizeByte); 162 | 163 | // field_ids_off 164 | byte[] fieldIdsOffByte = Utils.copyByte(byteSrc, 84, 4); 165 | headerType.field_ids_off = Utils.byte2int(fieldIdsOffByte); 166 | 167 | // method_ids_size 168 | byte[] methodIdsSizeByte = Utils.copyByte(byteSrc, 88, 4); 169 | headerType.method_ids_size = Utils.byte2int(methodIdsSizeByte); 170 | 171 | // method_ids_off 172 | byte[] methodIdsOffByte = Utils.copyByte(byteSrc, 92, 4); 173 | headerType.method_ids_off = Utils.byte2int(methodIdsOffByte); 174 | 175 | // class_defs_size 176 | byte[] classDefsSizeByte = Utils.copyByte(byteSrc, 96, 4); 177 | headerType.class_defs_size = Utils.byte2int(classDefsSizeByte); 178 | 179 | // class_defs_off 180 | byte[] classDefsOffByte = Utils.copyByte(byteSrc, 100, 4); 181 | headerType.class_defs_off = Utils.byte2int(classDefsOffByte); 182 | 183 | // data_size 184 | byte[] dataSizeByte = Utils.copyByte(byteSrc, 104, 4); 185 | headerType.data_size = Utils.byte2int(dataSizeByte); 186 | 187 | // data_off 188 | byte[] dataOffByte = Utils.copyByte(byteSrc, 108, 4); 189 | headerType.data_off = Utils.byte2int(dataOffByte); 190 | 191 | LogUtils.e(headerType.toString()); 192 | 193 | 194 | HeaderOffset = headerType.header_size; 195 | 196 | StringListCount = headerType.string_ids_size; 197 | StringListOffset = headerType.string_ids_off; 198 | typeListCount = headerType.type_ids_size; 199 | typeListOffset = headerType.type_ids_off; 200 | fieldListCount = headerType.field_ids_size; 201 | fieldListOffset = headerType.field_ids_off; 202 | protoListCount = headerType.proto_ids_size; 203 | protoListOffset = headerType.proto_ids_off; 204 | methodListCount = headerType.method_ids_size; 205 | methodListOffset = headerType.method_ids_off; 206 | classDefListCount = headerType.class_defs_size; 207 | classDefListOffset = headerType.class_defs_off; 208 | 209 | mapListOffset = headerType.map_off; 210 | 211 | } 212 | 213 | /** 214 | *解析字符串的 Item 的偏移地址 215 | * (stringIdsList 存放的是地址 不是数据 ) 216 | * 然后将 地址里面的 内容 转换成 字符串 217 | * @param srcByte 218 | */ 219 | public static void parseStringIds(byte[] srcByte){ 220 | //单个大小 221 | int idSize = StringIdsItem.getSize(); 222 | //个数 223 | int countIds = StringListCount; 224 | 225 | for(int i=0;i TypeIndex-> stringListIdx 288 | (item.return_type_idx).descriptor_idx)); 289 | 290 | if(item.parameters_off != 0){ 291 | //说明有参数 重新赋值打印 292 | ProtoIdsItem itemHasParmeter = parseParameterTypeList(srcByte, item.parameters_off, item); 293 | itemHasParmeter.shorty_idx=item.shorty_idx; 294 | itemHasParmeter.return_type_idx=item.return_type_idx; 295 | } 296 | LogUtils.e("ProtoIdsItem item",item.toString()); 297 | 298 | } 299 | } 300 | 301 | /** 302 | * 303 | * 解析 ProtoIds—>ParameterTypeList 304 | * @param srcByte 305 | * @param startOff 306 | * @param item 307 | * @return 308 | */ 309 | //解析方法的所有参数类型 310 | private static ProtoIdsItem parseParameterTypeList(byte[] srcByte, int startOff, ProtoIdsItem item){ 311 | //ParameterTypeList 是由一个 size 和一个 short 集合表示 312 | 313 | //因为保存的是地址 先拿到地址的byte 转换成 相对应的数值 314 | //指针4字节 315 | byte[] sizeByte = Utils.copyByte(srcByte, startOff, 4); 316 | //size 是 有几个 参数 的 size 317 | int size = Utils.byte2int(sizeByte); 318 | //这个 list是参数列表的 list 每一个 方法 都有自己的参数列表 319 | List parametersList = new ArrayList(); 320 | //存放的也是 index 但是用 short储存的 321 | //储存的也是 Typelist的 位置 322 | // 需要先拿到 Typelist的 位置 然后拿到里面的 323 | // descriptor_idx 在从string 里面找到 324 | // 所以 默认就是 StringList的 位置 325 | List typeList = new ArrayList(size); 326 | for(int i=0;i paramList = protoIdsList.get(item.proto_idx).parametersList; 407 | StringBuilder parameters = new StringBuilder(); 408 | //if (paramList.size() != 0) { 409 | parameters.append(returnTypeStr+"("); 410 | for(String str : paramList){ 411 | parameters.append(str+","); 412 | } 413 | //parameters.append(")"+shortStr); 414 | parameters.append(")"); 415 | //} 416 | LogUtils.e("class:"+stringList.get(classIndex)+",name:"+stringList.get(item.name_idx)+",proto:"+parameters); 417 | } 418 | 419 | } 420 | 421 | 422 | /** 423 | * 解析 ClassDefIds 424 | * @param srcByte 425 | */ 426 | public static void parseClassDefIds(byte[] srcByte){ 427 | LogUtils.e("开始 偏移的16进制 classDefListOffset:"+ 428 | Utils.bytesToHexString(Utils.int2Byte(classDefListOffset))); 429 | LogUtils.e("classDefSize的 个数:"+ classDefListCount); 430 | int idSize = ClassDefItem.getSize(); 431 | int countIds = classDefListCount; 432 | for(int i=0;iClassData 465 | * 一个classDef对应 一个 classData 466 | * @param srcByte 467 | */ 468 | public static void parseClassData(byte[] srcByte){ 469 | for(String key : classDataMap.keySet()){ 470 | int dataOffset = classDataMap.get(key).class_data_off; 471 | //LogUtils.e("data offset:"+Utils.bytesToHexString(Utils.int2Byte(dataOffset))); 472 | ClassDataItem item = parseClassDataItem(srcByte, dataOffset); 473 | 474 | classDataItemList.add(item); 475 | LogUtils.e("class item:"+item); 476 | } 477 | } 478 | 479 | 480 | 481 | /** 482 | * 解析 ClassDefIds->ClassData->ClassDataItem 483 | * 对ClassDataItem 进行解析 可以得到 ClassData 具体 484 | * @param srcByte 485 | */ 486 | private static ClassDataItem parseClassDataItem(byte[] srcByte, int offset){ 487 | //LogUtils.e("size 开始偏移地址: "+offset); 488 | ClassDataItem item = new ClassDataItem(); 489 | // 4个 leb128变量 490 | for(int i=0;i<4;i++){ 491 | byte[] byteAry = Utils.readUnsignedLeb128(srcByte, offset); 492 | //LogUtils.e("偏移基地址"+offset); 493 | //LogUtils.e("ByteLength"+byteAry.length); 最前面一个 1 494 | //循环了4次 把四个size赋值以后 495 | // 剩下的 就是 4个 Encoded 的 数据 496 | offset += byteAry.length; 497 | int size = 0; 498 | 499 | if(byteAry.length == 1){ 500 | size = byteAry[0]; 501 | }else if(byteAry.length == 2){ 502 | size = Utils.byte2Short(byteAry); 503 | }else if(byteAry.length == 4){ 504 | size = Utils.byte2int(byteAry); 505 | } 506 | if(i == 0){ 507 | item.static_fields_size = size; 508 | }else if(i == 1){ 509 | item.instance_fields_size = size; 510 | }else if(i == 2){ 511 | item.direct_methods_size = size; 512 | }else if(i == 3){ 513 | item.virtual_methods_size = size; 514 | } 515 | } 516 | 517 | 518 | // static_fields 519 | //每一个 ClassData有多个 EncodedField 和 EncodeMethod 520 | //顺序排列 521 | EncodedField[] staticFieldAry = new EncodedField[item.static_fields_size]; 522 | 523 | //LogUtils.e("Encoded 开始偏移地址: "+offset); 524 | for(int i=0;i mPermissionList = new ArrayList<>(); 28 | 29 | 30 | private static String[] PERMISSIONS; 31 | 32 | // Manifest.permission.READ_EXTERNAL_STORAGE, 33 | // Manifest.permission.WRITE_EXTERNAL_STORAGE, 34 | // Manifest.permission.READ_PHONE_STATE, 35 | 36 | 37 | 38 | 39 | 40 | 41 | private static PermissionCallBack call; 42 | 43 | /** 44 | * 初始化权限的方法 45 | */ 46 | public static void initPermission(Activity activity, 47 | String[] PERMISSIONS_STORAGE, 48 | PermissionCallBack callback 49 | ) { 50 | call=callback; 51 | PERMISSIONS=PERMISSIONS_STORAGE; 52 | //先检查权限 53 | if(isGetPermission(activity,PERMISSIONS_STORAGE)){ 54 | call.getPermission(true); 55 | return ; 56 | }else { 57 | ActivityCompat.requestPermissions(activity,mPermissionList. 58 | toArray(new String[mPermissionList.size()]),1); 59 | } 60 | 61 | } 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | /** 检测全选代码 74 | * @param Permission 检测权限的 字符串数组 75 | * 76 | * @return 是否都获取到 77 | */ 78 | private static boolean isGetPermission(Context context, String[] Permission){ 79 | //大于6.0 80 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 81 | //检测权限的 集合 82 | mPermissionList.clear(); 83 | for (int i = 0; i < Permission.length; i++) { 84 | if (ContextCompat.checkSelfPermission(context, Permission[i]) != PackageManager.PERMISSION_GRANTED) { 85 | //将没有获取到的权限 加到集合里 86 | mPermissionList.add(Permission[i]); 87 | } 88 | 89 | } 90 | if(mPermissionList.size()==0){ 91 | return true; 92 | }else { 93 | return false; 94 | } 95 | } 96 | //小于6.0直接true 97 | return true; 98 | } 99 | 100 | 101 | } 102 | -------------------------------------------------------------------------------- /app/src/main/java/com/makelove/dex/utils/Utils.java: -------------------------------------------------------------------------------- 1 | package com.makelove.dex.utils; 2 | 3 | import android.util.Log; 4 | 5 | import java.nio.ByteBuffer; 6 | import java.nio.CharBuffer; 7 | import java.nio.charset.Charset; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | public class Utils { 12 | 13 | public static int byte2int(byte[] res) { 14 | int targets = (res[0] & 0xff) | ((res[1] << 8) & 0xff00) 15 | | ((res[2] << 24) >>> 8) | (res[3] << 24); 16 | return targets; 17 | } 18 | 19 | public static byte[] int2Byte(final int integer) { 20 | int byteNum = (40 -Integer.numberOfLeadingZeros (integer < 0 ? ~integer : integer))/ 8; 21 | byte[] byteArray = new byte[4]; 22 | 23 | for (int n = 0; n < byteNum; n++) 24 | byteArray[3 - n] = (byte) (integer>>> (n * 8)); 25 | 26 | return (byteArray); 27 | } 28 | 29 | public static byte[] short2Byte(short number) { 30 | int temp = number; 31 | byte[] b = new byte[2]; 32 | for (int i = 0; i < b.length; i++) { 33 | b[i] = new Integer(temp & 0xff).byteValue();//将最低位保存在最低位 34 | temp = temp >> 8; // 向右移8位 35 | } 36 | return b; 37 | } 38 | 39 | public static short byte2Short(byte[] b) { 40 | short s = 0; 41 | try { 42 | s = 0; 43 | short s0 = (short) (b[0] & 0xff); 44 | short s1 = (short) (b[1] & 0xff); 45 | s1 <<= 8; 46 | s = (short) (s0 | s1); 47 | } catch (Exception e) { 48 | e.printStackTrace(); 49 | return s; 50 | } 51 | return s; 52 | } 53 | 54 | public static String bytesToHexString(byte[] src){ 55 | //byte[] src = reverseBytes(src1); 56 | StringBuilder stringBuilder = new StringBuilder(""); 57 | if (src == null || src.length <= 0) { 58 | return null; 59 | } 60 | for (int i = 0; i < src.length; i++) { 61 | int v = src[i] & 0xFF; 62 | String hv = Integer.toHexString(v); 63 | if (hv.length() < 2) { 64 | stringBuilder.append(0); 65 | } 66 | stringBuilder.append(hv+" "); 67 | } 68 | return stringBuilder.toString(); 69 | } 70 | 71 | public static char[] getChars(byte[] bytes) { 72 | Charset cs = Charset.forName ("UTF-8"); 73 | ByteBuffer bb = ByteBuffer.allocate (bytes.length); 74 | bb.put (bytes); 75 | bb.flip (); 76 | CharBuffer cb = cs.decode (bb); 77 | return cb.array(); 78 | } 79 | 80 | 81 | /** 82 | * 打印 list详情 83 | * @param list 84 | */ 85 | public static void outDetailed(List list){ 86 | for(Object t:list){ 87 | LogUtils.e("lyh296488320",t.toString()); 88 | } 89 | } 90 | 91 | public static byte[] copyByte(byte[] src, int start, int len){ 92 | 93 | if(src == null){ 94 | return null; 95 | } 96 | if(start > src.length){ 97 | return null; 98 | } 99 | if((start+len) > src.length){ 100 | return null; 101 | } 102 | if(start<0){ 103 | return null; 104 | } 105 | if(len<=0){ 106 | return null; 107 | } 108 | byte[] resultByte = new byte[len]; 109 | for(int i=0;i newByte = new ArrayList(); 139 | for(int i=0;i= srcByte.length){ 159 | return ""; 160 | } 161 | byte val = srcByte[start]; 162 | int i = 1; 163 | ArrayList byteList = new ArrayList(); 164 | while(val != 0){ 165 | byteList.add(srcByte[start+i]); 166 | val = srcByte[start+i]; 167 | i++; 168 | } 169 | byte[] valAry = new byte[byteList.size()]; 170 | for(int j=0;j byteAryList = new ArrayList(); 203 | byte bytes = Utils.copyByte(srcByte, offset, 1)[0]; 204 | byte highBit = (byte)(bytes & 0x80); 205 | byteAryList.add(bytes); 206 | offset ++; 207 | while(highBit != 0){ 208 | bytes = Utils.copyByte(srcByte, offset, 1)[0]; 209 | highBit = (byte)(bytes & 0x80); 210 | offset ++; 211 | byteAryList.add(bytes); 212 | } 213 | byte[] byteAry = new byte[byteAryList.size()]; 214 | for(int j=0;j 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 11 | 16 | 21 | 26 | 31 | 36 | 41 | 46 | 51 | 56 | 61 | 66 | 71 | 76 | 81 | 86 | 91 | 96 | 101 | 106 | 111 | 116 | 121 | 126 | 131 | 136 | 141 | 146 | 151 | 156 | 161 | 166 | 171 | 172 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w296488320/DexAnalyzeForAndroid/92ec9155089bf6b56f75406a4de6f75640199871/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w296488320/DexAnalyzeForAndroid/92ec9155089bf6b56f75406a4de6f75640199871/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w296488320/DexAnalyzeForAndroid/92ec9155089bf6b56f75406a4de6f75640199871/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w296488320/DexAnalyzeForAndroid/92ec9155089bf6b56f75406a4de6f75640199871/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w296488320/DexAnalyzeForAndroid/92ec9155089bf6b56f75406a4de6f75640199871/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w296488320/DexAnalyzeForAndroid/92ec9155089bf6b56f75406a4de6f75640199871/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w296488320/DexAnalyzeForAndroid/92ec9155089bf6b56f75406a4de6f75640199871/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w296488320/DexAnalyzeForAndroid/92ec9155089bf6b56f75406a4de6f75640199871/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w296488320/DexAnalyzeForAndroid/92ec9155089bf6b56f75406a4de6f75640199871/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w296488320/DexAnalyzeForAndroid/92ec9155089bf6b56f75406a4de6f75640199871/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Dex 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/test/java/com/makelove/dex/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.makelove.dex; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | 5 | repositories { 6 | google() 7 | jcenter() 8 | } 9 | dependencies { 10 | classpath 'com.android.tools.build:gradle:3.0.0' 11 | 12 | 13 | // NOTE: Do not place your application dependencies here; they belong 14 | // in the individual module build.gradle files 15 | } 16 | } 17 | 18 | allprojects { 19 | repositories { 20 | google() 21 | jcenter() 22 | } 23 | } 24 | 25 | task clean(type: Delete) { 26 | delete rootProject.buildDir 27 | } 28 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w296488320/DexAnalyzeForAndroid/92ec9155089bf6b56f75406a4de6f75640199871/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Sep 18 13:34:40 CST 2018 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':Any' 2 | --------------------------------------------------------------------------------