├── .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 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | Android
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | 1.8
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
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 |
5 |
6 |
7 |
8 |
9 |
10 |
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 |
--------------------------------------------------------------------------------