├── .gitignore
├── .idea
├── codeStyles
│ └── Project.xml
├── gradle.xml
├── markdown-navigator-enh.xml
├── markdown-navigator.xml
├── misc.xml
└── runConfigurations.xml
├── app-release.apk
├── app
├── .gitignore
├── build.gradle
├── libs
│ ├── armeabi-v7a
│ │ ├── libcms.so
│ │ ├── libjsc.so
│ │ ├── libttEncrypt.so
│ │ └── libuserinfo.so
│ ├── armeabi
│ │ ├── libcms.so
│ │ ├── libjsc.so
│ │ ├── libttEncrypt.so
│ │ └── libuserinfo.so
│ └── x86
│ │ ├── libcms.so
│ │ ├── libjsc.so
│ │ ├── libttEncrypt.so
│ │ └── libuserinfo.so
├── proguard-rules.pro
├── release
│ ├── app-release.apk
│ └── output.json
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ ├── bytedance
│ │ └── frameworks
│ │ │ └── core
│ │ │ └── encrypt
│ │ │ └── TTEncryptUtils.java
│ │ ├── ss
│ │ ├── android
│ │ │ └── common
│ │ │ │ └── applog
│ │ │ │ ├── GlobalContext.java
│ │ │ │ └── UserInfo.java
│ │ └── sys
│ │ │ ├── ces
│ │ │ └── a.java
│ │ │ └── secuni
│ │ │ └── b
│ │ │ └── c.java
│ │ └── yf
│ │ └── douyintool
│ │ ├── App.java
│ │ ├── DeviceUtil.java
│ │ ├── LibUtil.java
│ │ ├── MainActivity.java
│ │ ├── MyApp.java
│ │ ├── MyController.java
│ │ ├── NetUtils.java
│ │ ├── PmsHookBinderInvocationHandler.java
│ │ ├── SecurityUntil.java
│ │ ├── ServerManager.java
│ │ ├── Service
│ │ └── MyService.java
│ │ ├── ServiceManagerWraper.java
│ │ ├── b.java
│ │ ├── bean
│ │ └── DeviceBean.java
│ │ └── controller
│ │ └── RequestController.java
│ ├── jni
│ ├── Android.mk
│ ├── CydiaNativeHook.cpp
│ ├── armeabi
│ │ ├── libsubstrate-dvm.so
│ │ └── libsubstrate.so
│ ├── libsubstrate-dvm.so
│ ├── libsubstrate.so
│ ├── substrate.h
│ └── x86
│ │ ├── libsubstrate-dvm.so
│ │ └── libsubstrate.so
│ └── 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
├── 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/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 |
15 | # Project exclude paths
16 | /app/.cxx/
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | xmlns:android
14 |
15 | ^$
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | xmlns:.*
25 |
26 | ^$
27 |
28 |
29 | BY_NAME
30 |
31 |
32 |
33 |
34 |
35 |
36 | .*:id
37 |
38 | http://schemas.android.com/apk/res/android
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | .*:name
48 |
49 | http://schemas.android.com/apk/res/android
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | name
59 |
60 | ^$
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | style
70 |
71 | ^$
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | .*
81 |
82 | ^$
83 |
84 |
85 | BY_NAME
86 |
87 |
88 |
89 |
90 |
91 |
92 | .*
93 |
94 | http://schemas.android.com/apk/res/android
95 |
96 |
97 | ANDROID_ATTRIBUTE_ORDER
98 |
99 |
100 |
101 |
102 |
103 |
104 | .*
105 |
106 | .*
107 |
108 |
109 | BY_NAME
110 |
111 |
112 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
19 |
20 |
--------------------------------------------------------------------------------
/.idea/markdown-navigator-enh.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 |
--------------------------------------------------------------------------------
/.idea/markdown-navigator.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 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/.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 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app-release.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app-release.apk
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 28
5 | defaultConfig {
6 | applicationId "com.yf.douyintool"
7 | minSdkVersion 19
8 | targetSdkVersion 28
9 | versionCode 1
10 | versionName "1"
11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
12 |
13 | externalNativeBuild{
14 | ndkBuild{
15 | abiFilters "x86"
16 | // abiFilters "armeabi-v7a"
17 | }
18 | }
19 |
20 |
21 | }
22 | // splits {
23 | // abi {
24 | // enable true
25 | // reset()
26 | // include 'x86', 'armeabi-v7a','x86_64'
27 | // universalApk true
28 | // }
29 | // }
30 |
31 | buildTypes {
32 | release {
33 | minifyEnabled false
34 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
35 | ndk{
36 | abiFilters "armeabi-v7a","x86",'x86_64'
37 | }
38 | }
39 | debug{
40 | ndk{
41 | abiFilters "armeabi-v7a","x86",'x86_64'
42 | }
43 | }
44 | }
45 |
46 | externalNativeBuild{
47 | ndkBuild{
48 | path "src/main/jni/Android.mk"
49 | }
50 | }
51 |
52 | sourceSets {
53 | main {
54 | // 1. 配置在根目录libs下可以加载第三方so库, (最好不要创建jniLibs, 在众多的开源库中可能会引起冲突,还没发现)
55 | // 2. 运行时会自动将libs目录下的so库拷贝到指定目录
56 | // 3. 如果自己创建的so不需要重新编译,可以将(app/build/intermediates/transforms)生成的so拷贝到这个目录
57 | jniLibs.srcDirs=['Libs']
58 | // 如果是单个文件夹 可以直接这样如下配置
59 | // jniLibs.srcDir 'libs'
60 | } }
61 | }
62 |
63 | dependencies {
64 | implementation fileTree(dir: 'libs', include: ['*.jar'])
65 | implementation 'com.android.support:appcompat-v7:28.0.0'
66 | implementation 'com.android.support.constraint:constraint-layout:1.1.3'
67 | testImplementation 'junit:junit:4.12'
68 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
69 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
70 | compileOnly 'de.robv.android.xposed:api:82'
71 | implementation 'com.squareup.okhttp3:okhttp:3.10.0'
72 | implementation 'com.squareup.okio:okio:2.2.2'
73 | implementation 'com.google.code.gson:gson:2.8.4'
74 | implementation 'com.yanzhenjie.andserver:api:2.1.1'
75 | annotationProcessor 'com.yanzhenjie.andserver:processor:2.1.1'
76 | implementation("com.google.guava:guava:28.1-android")
77 | implementation 'com.alibaba:fastjson:1.2.51'
78 | }
79 |
--------------------------------------------------------------------------------
/app/libs/armeabi-v7a/libcms.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/libs/armeabi-v7a/libcms.so
--------------------------------------------------------------------------------
/app/libs/armeabi-v7a/libjsc.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/libs/armeabi-v7a/libjsc.so
--------------------------------------------------------------------------------
/app/libs/armeabi-v7a/libttEncrypt.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/libs/armeabi-v7a/libttEncrypt.so
--------------------------------------------------------------------------------
/app/libs/armeabi-v7a/libuserinfo.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/libs/armeabi-v7a/libuserinfo.so
--------------------------------------------------------------------------------
/app/libs/armeabi/libcms.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/libs/armeabi/libcms.so
--------------------------------------------------------------------------------
/app/libs/armeabi/libjsc.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/libs/armeabi/libjsc.so
--------------------------------------------------------------------------------
/app/libs/armeabi/libttEncrypt.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/libs/armeabi/libttEncrypt.so
--------------------------------------------------------------------------------
/app/libs/armeabi/libuserinfo.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/libs/armeabi/libuserinfo.so
--------------------------------------------------------------------------------
/app/libs/x86/libcms.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/libs/x86/libcms.so
--------------------------------------------------------------------------------
/app/libs/x86/libjsc.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/libs/x86/libjsc.so
--------------------------------------------------------------------------------
/app/libs/x86/libttEncrypt.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/libs/x86/libttEncrypt.so
--------------------------------------------------------------------------------
/app/libs/x86/libuserinfo.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/libs/x86/libuserinfo.so
--------------------------------------------------------------------------------
/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/release/app-release.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/release/app-release.apk
--------------------------------------------------------------------------------
/app/release/output.json:
--------------------------------------------------------------------------------
1 | [{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":1},"path":"app-release.apk","properties":{"packageId":"com.yf.douyintool","split":"","minSdkVersion":"19"}}]
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/java/com/bytedance/frameworks/core/encrypt/TTEncryptUtils.java:
--------------------------------------------------------------------------------
1 | package com.bytedance.frameworks.core.encrypt;
2 |
3 | public class TTEncryptUtils {
4 | private static native byte[] handleData(byte[] bArr, int i);
5 |
6 | static {
7 | System.loadLibrary("ttEncrypt");
8 | }
9 |
10 | public static byte[] a(byte[] bArr, int i) {
11 | if (bArr != null && i > 0) {
12 | try {
13 | if (bArr.length == i) {
14 | return handleData(bArr, i);
15 | }
16 | } catch (Throwable unused) {
17 | return null;
18 | }
19 | }
20 | return null;
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/com/ss/android/common/applog/GlobalContext.java:
--------------------------------------------------------------------------------
1 | package com.ss.android.common.applog;
2 |
3 | import android.content.Context;
4 |
5 | public class GlobalContext {
6 | // public static ChangeQuickRedirect changeQuickRedirect;
7 | private static Context mContext;
8 |
9 | public static Context getContext() {
10 | return mContext;
11 | }
12 |
13 | public static void setContext(Context context) {
14 | mContext = context;
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/com/ss/android/common/applog/UserInfo.java:
--------------------------------------------------------------------------------
1 | package com.ss.android.common.applog;
2 |
3 | import com.yf.douyintool.LibUtil;
4 |
5 | public class UserInfo {
6 | static {
7 | LibUtil.a(GlobalContext.getContext(),"cms");
8 | // LibUtil.a(GlobalContext.getContext(),"userinfo");
9 | }
10 | public static native String a();
11 |
12 | public static native String getDescription();
13 |
14 | public static native String getFile();
15 |
16 | public static native String getFingerprint();
17 |
18 | public static native void getPackage(String str);
19 |
20 | public static native String getS();
21 |
22 | public static native byte[] getT();
23 |
24 | public static native int getTemperature();
25 |
26 | public static native int getType();
27 |
28 | public static native String getUserInfo(int i, String str, String[] strArr);
29 |
30 | public static native String getUserInfo(int i, String str, String[] strArr, String str2);
31 |
32 | public static native String getUserInfo(int i, String[] strArr, String[] strArr2, String str);
33 |
34 | public static native String getUserInfoSkipGet(int i, String str, String[] strArr);
35 |
36 | public static native int initUser(String str);
37 |
38 | public static native int isR();
39 |
40 | public static native void setAppId(int i);
41 |
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/app/src/main/java/com/ss/sys/ces/a.java:
--------------------------------------------------------------------------------
1 | package com.ss.sys.ces;
2 |
3 | import android.content.Context;
4 |
5 | public class a {
6 | static {
7 | try {
8 | System.loadLibrary("cms");
9 | } catch (UnsatisfiedLinkError unused) {
10 | }
11 | }
12 |
13 | public static native byte[] d(byte[] bArr);
14 |
15 | public static native byte[] e(byte[] bArr); //mas
16 |
17 | public static native void jni(int i, int i2);
18 |
19 | public static native void jns(int i, String str);
20 |
21 | public static native byte[] leviathan(int i, byte[] bArr); //X-Gorgen
22 |
23 | public static native byte[] rb(Context context, String str, String str2);
24 |
25 | public static native void ws(int i);
26 |
27 | public static native Object meta(int i, Context context, Object obj);
28 |
29 |
30 |
31 |
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/ss/sys/secuni/b/c.java:
--------------------------------------------------------------------------------
1 | package com.ss.sys.secuni.b;
2 |
3 | import android.content.Context;
4 |
5 | public class c {
6 | static {
7 | try {
8 | System.loadLibrary("cms");
9 | } catch (Throwable unused) {
10 | }
11 | }
12 |
13 | public static native byte[] n0(Context context);
14 |
15 | public static native int n1(Context context, String str);
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yf/douyintool/App.java:
--------------------------------------------------------------------------------
1 | package com.yf.douyintool;
2 |
3 | import android.app.Application;
4 |
5 | public class App extends Application {
6 | @Override
7 | public void onCreate() {
8 | super.onCreate();
9 | ServiceManagerWraper.hookPMS(getApplicationContext());
10 |
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yf/douyintool/DeviceUtil.java:
--------------------------------------------------------------------------------
1 | package com.yf.douyintool;
2 |
3 | import java.util.Random;
4 |
5 | public class DeviceUtil {
6 | public static String getMac(){
7 | StringBuilder sb=new StringBuilder();
8 | for (int i = 0; i <6; i++) {
9 | String s1=Integer.toHexString(new Random().nextInt(16));
10 | String s2=Integer.toHexString(new Random().nextInt(16));
11 | sb.append(s1+s2);
12 | if (i!=5){
13 | sb.append(":");
14 | }
15 | }
16 | return sb.toString();
17 | }
18 |
19 |
20 | public static String getRanHex(int i){
21 | StringBuilder sb=new StringBuilder();
22 | for (int j = 0; j a = new ArrayList();
18 |
19 | public static synchronized boolean a(Context context, String str) {
20 | String mapLibraryName;
21 | File file;
22 | File file2;
23 | synchronized (LibUtil.class) {
24 | if (a.contains(str)) {
25 | return true;
26 | }
27 | try {
28 | System.loadLibrary(str);
29 | a.add(str);
30 | } catch (UnsatisfiedLinkError error) {
31 | mapLibraryName = System.mapLibraryName(str);
32 | file = null;
33 | if (context != null) {
34 | }
35 | file2 = null;
36 | if (file2 != null) {
37 | }
38 | if (file == null) {
39 | }
40 | } catch (Throwable unused) {
41 | return false;
42 | }
43 | mapLibraryName = System.mapLibraryName(str);
44 | file = null;
45 | if (context != null) {
46 | if (context.getFilesDir() != null) {
47 | file2 = new File(context.getFilesDir(), "libso");
48 | if (!file2.exists()) {
49 | new File(file2.getAbsolutePath()).mkdirs();
50 | }
51 | if (file2 != null) {
52 | file = new File(file2, mapLibraryName);
53 | }
54 | if (file == null) {
55 | return false;
56 | }
57 | if (file.exists()) {
58 | file.delete();
59 | }
60 | if (a(context, str, file) != null) {
61 | return false;
62 | }
63 | try {
64 | System.load(file.getAbsolutePath());
65 | a.add(str);
66 | } catch (Throwable unused2) {
67 | return false;
68 | }
69 | }
70 | }
71 | file2 = null;
72 | if (file2 != null) {
73 | }
74 | if (file == null) {
75 | }
76 | }
77 | return true;
78 | }
79 |
80 | private static String a(Context context, String str, File file) {
81 | InputStream inputStream;
82 | Throwable th;
83 | Closeable closeable = null;
84 | ZipFile zipFile;
85 | String stringBuilder;
86 | try {
87 | zipFile = new ZipFile(new File(context.getApplicationInfo().sourceDir), 1);
88 | try {
89 | OutputStream fileOutputStream;
90 | StringBuilder stringBuilder2 = new StringBuilder("lib/");
91 | stringBuilder2.append(Build.CPU_ABI);
92 | stringBuilder2.append("/");
93 | stringBuilder2.append(System.mapLibraryName(str));
94 | ZipEntry entry = zipFile.getEntry(stringBuilder2.toString());
95 | if (entry == null) {
96 | int indexOf = Build.CPU_ABI.indexOf(45);
97 | StringBuilder stringBuilder3 = new StringBuilder("lib/");
98 | String str2 = Build.CPU_ABI;
99 | if (indexOf <= 0) {
100 | indexOf = Build.CPU_ABI.length();
101 | }
102 | stringBuilder3.append(str2.substring(0, indexOf));
103 | stringBuilder3.append("/");
104 | stringBuilder3.append(System.mapLibraryName(str));
105 | str = stringBuilder3.toString();
106 | entry = zipFile.getEntry(str);
107 | if (entry == null) {
108 | StringBuilder stringBuilder4 = new StringBuilder("Library entry not found:");
109 | stringBuilder4.append(str);
110 | stringBuilder = stringBuilder4.toString();
111 | b.a(null);
112 | b.a(null);
113 | b.a(zipFile);
114 | return stringBuilder;
115 | }
116 | }
117 | file.createNewFile();
118 | inputStream = zipFile.getInputStream(entry);
119 | try {
120 | fileOutputStream = new FileOutputStream(file);
121 | } catch (Throwable th2) {
122 | th = th2;
123 | try {
124 | stringBuilder = th.getMessage();
125 | b.a(closeable);
126 | b.a(inputStream);
127 | b.a(zipFile);
128 | return stringBuilder;
129 | } catch (Throwable th3) {
130 | th = th3;
131 | b.a(closeable);
132 | b.a(inputStream);
133 | b.a(zipFile);
134 | throw th;
135 | }
136 | }
137 | try {
138 | byte[] bArr = new byte[16384];
139 | while (true) {
140 | int read = inputStream.read(bArr);
141 | if (read > 0) {
142 | fileOutputStream.write(bArr, 0, read);
143 | } else {
144 | // c.a("android.os.FileUtils", file.getAbsolutePath(), Integer.valueOf(493), Integer.valueOf(-1), Integer.valueOf(-1));
145 | b.a(fileOutputStream);
146 | b.a(inputStream);
147 | b.a(zipFile);
148 | return null;
149 | }
150 | }
151 | } catch (Throwable th4) {
152 | th = th4;
153 | closeable = fileOutputStream;
154 | b.a(closeable);
155 | b.a(inputStream);
156 | b.a(zipFile);
157 | throw th;
158 | }
159 | } catch (Throwable th5) {
160 | th = th5;
161 | inputStream = null;
162 | b.a(closeable);
163 | b.a(inputStream);
164 | b.a(zipFile);
165 | throw th;
166 | }
167 | } catch (Throwable th6) {
168 | th = th6;
169 | inputStream = null;
170 | // zipFile = inputStream;
171 | b.a(closeable);
172 | b.a(inputStream);
173 | // b.a(zipFile);
174 | // throw th;
175 | }
176 | return null;
177 | }
178 |
179 |
180 |
181 | }
182 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yf/douyintool/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.yf.douyintool;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.os.Build;
7 | import android.provider.Settings;
8 | import android.support.v7.app.AppCompatActivity;
9 | import android.os.Bundle;
10 | import android.telecom.Call;
11 | import android.telephony.TelephonyManager;
12 | import android.text.TextUtils;
13 | import android.util.Log;
14 | import android.view.View;
15 | import android.widget.Button;
16 | import android.widget.TextView;
17 |
18 | import com.ss.android.common.applog.UserInfo;
19 | import com.ss.sys.ces.a;
20 | import com.yf.douyintool.Service.MyService;
21 |
22 | /***
23 | * 来源:
24 | * https://github.com/coder-fly/douyin_sign
25 | */
26 | public class MainActivity extends AppCompatActivity {
27 | public static final String TAG="yf";
28 | private static final String NULL_MD5_STRING = "00000000000000000000000000000000";
29 | // public String ck="install_id=94761796773; ttreq=1$9cf124c9495dc5a1da9e9a611eee577738dc8fc1; odin_tt=9ac4660ee23266248ee5edb5afe9a293118bbaa210b20316f36845e27e6bd44517b8a69241c8a4e09d91f53b0642fe61e70cf88eadfa6d9d59bc401369d06c40; qh[360]=1";
30 | public String ck="install_id=94761796773; qh[360]=1";
31 | public String sessionid="";
32 | public String xtttoken="004cd1df7bd4fddd6674a80e6da09c27304b0a39de5343f08f1adb0f196433c3cc48286ee0aa915761b71e0201000f8ccf37";
33 |
34 | @Override
35 | protected void onCreate(Bundle savedInstanceState) {
36 | super.onCreate(savedInstanceState);
37 | setContentView(R.layout.activity_main);
38 |
39 | }
40 |
41 |
42 | public void OpenServer(View view){
43 | switch (view.getId()){
44 | case R.id.id_bt_index:
45 | //启动服务:创建-->启动-->销毁
46 | //如果服务已经创建了,后续重复启动,操作的都是同一个服务,不会再重新创建了,除非你先销毁它
47 | UserInfo.setAppId(1128);
48 | UserInfo.initUser("a3668f0afac72ca3f6c1697d29e0e1bb1fef4ab0285319b95ac39fa42c38d05f");
49 | Intent intent = new Intent(this, MyService.class);
50 | Log.d(TAG, "operate: button");
51 | startService(intent);
52 | ((Button) view).setText("服务已开启");
53 | }
54 | }
55 |
56 |
57 |
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yf/douyintool/MyApp.java:
--------------------------------------------------------------------------------
1 | package com.yf.douyintool;
2 |
3 | import android.app.Application;
4 |
5 | public class MyApp extends Application {
6 | private static MyApp myApp;
7 | public static MyApp getInstance() {
8 | return myApp;
9 | }
10 | @Override
11 | public void onCreate() {
12 | super.onCreate();
13 | myApp = this;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yf/douyintool/MyController.java:
--------------------------------------------------------------------------------
1 | package com.yf.douyintool;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Context;
5 | import android.provider.Settings;
6 | import android.telephony.TelephonyManager;
7 | import android.text.TextUtils;
8 | import android.util.Base64;
9 | import android.util.Log;
10 | import android.view.View;;
11 |
12 | import com.bytedance.frameworks.core.encrypt.TTEncryptUtils;
13 | import com.google.common.base.Splitter;
14 | import com.google.gson.Gson;
15 | import com.ss.android.common.applog.UserInfo;
16 | import com.ss.sys.ces.a;
17 | import com.yanzhenjie.andserver.annotation.Controller;
18 | import com.yanzhenjie.andserver.annotation.GetMapping;
19 | import com.yanzhenjie.andserver.annotation.PostMapping;
20 | import com.yanzhenjie.andserver.framework.body.JsonBody;
21 | import com.yanzhenjie.andserver.framework.body.FileBody;
22 | import com.yanzhenjie.andserver.framework.body.StringBody;
23 | import com.yanzhenjie.andserver.http.HttpRequest;
24 | import com.yanzhenjie.andserver.http.HttpResponse;
25 | import org.json.JSONException;
26 | import org.json.JSONObject;
27 |
28 | import com.yf.douyintool.bean.DeviceBean;
29 |
30 | import org.json.JSONObject;
31 | import java.io.ByteArrayOutputStream;
32 | import java.io.File;
33 | import java.io.FileNotFoundException;
34 | import java.io.FileOutputStream;
35 | import java.io.IOException;
36 | import java.security.MessageDigest;
37 | import java.security.NoSuchAlgorithmException;
38 | import java.util.ArrayList;
39 | import java.util.Arrays;
40 | import java.util.Calendar;
41 | import java.util.HashMap;
42 | import java.util.List;
43 | import java.util.Map;
44 | import java.util.TimeZone;
45 | import java.util.UUID;
46 | import java.util.zip.GZIPOutputStream;
47 |
48 | import okhttp3.Callback;
49 | import okhttp3.FormBody;
50 | import okhttp3.MediaType;
51 | import okhttp3.OkHttpClient;
52 | import okhttp3.Request;
53 | import okhttp3.RequestBody;
54 | import okhttp3.Response;
55 |
56 | /***
57 | * 结合AndServer,实现抖音X-Gorgon算法,设备id生成接口
58 | * http://www.louislivi.com/archives/147
59 | */
60 | @Controller
61 | public class MyController {
62 | public static final String TAG = "MyController";
63 | private static final String NULL_MD5_STRING = "00000000000000000000000000000000";
64 | public String sessionid = "";
65 | public String ck="odin_tt=1";
66 | public String xtttoken = "004cd1df7bd4fddd6674a80e6da09c27304b0a39de5343f08f1adb0f196433c3cc48286ee0aa915761b71e0201000f8ccf37";
67 | public String comman_params = "&retry_type=no_retry&ac=wifi&&gps_access=1&js_sdk_version=&app_type=normal&manifest_version_code=570&address_book_access=2&mcc_mnc=46011&os_version=8.1.0&channel=wandoujia_aweme1&version_code=570&device_type=vivo%20X20A&language=zh&resolution=1080*2160&openudid=a8b382e730db8c41&update_version_code=5702&app_name=aweme&version_name=5.7.0&os_api=27&device_brand=vivo&ssmix=a&device_platform=android&dpi=480&aid=1128";
68 |
69 | public MyController(){
70 | UserInfo.setAppId(1128);
71 | UserInfo.initUser("a3668f0afac72ca3f6c1697d29e0e1bb1fef4ab0285319b95ac39fa42c38d05f");
72 | }
73 |
74 | @GetMapping("/device_id")
75 | public void device_register(HttpRequest request, HttpResponse response) {
76 | try {
77 | JSONObject device_message = new JSONObject(getDevice());
78 | response.setBody(new JsonBody(device_message));
79 | } catch (JSONException e) {
80 | e.printStackTrace();
81 | }
82 | }
83 |
84 |
85 | @PostMapping("/user_info")
86 | public void user_info(HttpRequest request, HttpResponse response) {
87 | String user_id = request.getParameter("user_id");
88 | String device_id = request.getParameter("device_id");
89 | String iid = request.getParameter("iid");
90 | int ts= (int) (System.currentTimeMillis()/1000);
91 | String _ricket=System.currentTimeMillis()+"";
92 | String url="https://aweme.snssdk.com/aweme/v1/user/?user_id="+user_id+"&ts="+ts+"&iid="+iid+"&device_id="+device_id+"&_rticket="+_ricket+comman_params;
93 | JSONObject device_message = signs_(device_id,iid,ts,url);
94 | response.setBody(new JsonBody(device_message));
95 | }
96 |
97 | @PostMapping("/get_comments")
98 | public void get_comments(HttpRequest request, HttpResponse response) {
99 | String aweme_id = request.getParameter("aweme_id");
100 | String cursor = request.getParameter("cursor");
101 | String device_id = request.getParameter("device_id");
102 | String iid = request.getParameter("iid");
103 | int ts= (int) (System.currentTimeMillis()/1000);
104 | String _ricket=System.currentTimeMillis()+"";
105 | String url = "https://api.amemv.com/aweme/v2/comment/list/?aweme_id="+aweme_id+"&cursor="+cursor+"&count=20&ts="+ts+"&_rticket="+_ricket+"&device_id="+device_id+"&iid="+iid + comman_params;
106 | JSONObject device_message = signs_(device_id,iid,ts,url);
107 | response.setBody(new JsonBody(device_message));
108 | }
109 |
110 | @PostMapping("/sign")
111 | public void sign(HttpRequest request, HttpResponse response) {
112 | String url = request.getParameter("url");
113 | String device_id = request.getParameter("device_id");
114 | String iid = request.getParameter("iid");
115 | int ts= (int) (System.currentTimeMillis()/1000);
116 | String _ricket=System.currentTimeMillis()+"";
117 | if(device_id==null| iid==null){
118 | response.setBody(new StringBody("params error,please check."));
119 | }
120 | url = url+"&ts="+ts+"&_rticket="+_ricket+"&device_id="+device_id+"&iid="+iid;
121 | JSONObject message = signs_(device_id,iid,ts,url);
122 | response.setBody(new JsonBody(message));
123 | }
124 |
125 | @PostMapping("/comments")
126 | public void comments(HttpRequest request, HttpResponse response) {
127 | String aweme_id = request.getParameter("aweme_id");
128 |
129 | int ts= (int) (System.currentTimeMillis()/1000);
130 | String _ricket=System.currentTimeMillis()+"";
131 | String url = " https://aweme.snssdk.com/aweme/v2/comment/list/?aweme_id="+aweme_id+"&cursor=0&count=20&address_book_access=1&gps_access=1&ts="+ts+"&js_sdk_version=&app_type=normal&os_api=22&device_type=PRO%206%20Plus&device_platform=android&ssmix=a&manifest_version_code=570&dpi=191&uuid=864757481134476&version_code=570&app_name=aweme&version_name=5.7.0&openudid=27c5a40b187e24c1&resolution=576*1024&os_version=5.1.1&language=zh&device_brand=Meizu&ac=wifi&update_version_code=5702&aid=1128&channel=wandoujia_aweme1&_rticket="+_ricket+"&mcc_mnc=46000";
132 | JSONObject device_message = signs_("","",ts,url);
133 | response.setBody(new JsonBody(device_message));
134 | }
135 |
136 | @PostMapping("/user_post")
137 | public void user_post(HttpRequest request, HttpResponse response) {
138 | String user_id = request.getParameter("user_id");
139 | String max_cursor = request.getParameter("max_cursor");
140 | String device_id = request.getParameter("device_id");
141 | String iid = request.getParameter("iid");
142 | int ts= (int) (System.currentTimeMillis()/1000);
143 | String _ricket=System.currentTimeMillis()+"";
144 | String url = "https://aweme.snssdk.com/aweme/v1/aweme/post/?max_cursor="+max_cursor+"&user_id="+user_id+"&count=20&ts="+ts+"&_rticket="+_ricket+"&device_id="+device_id+"&iid="+iid + "&retry_type=no_retry" +comman_params;
145 | JSONObject device_message = signs_(device_id,iid,ts,url);
146 | response.setBody(new JsonBody(device_message));
147 | }
148 |
149 | @PostMapping("/user_favorite")
150 | public void user_favorite(HttpRequest request, HttpResponse response) {
151 | String user_id = request.getParameter("user_id");
152 | String max_cursor = request.getParameter("max_cursor");
153 | String device_id = request.getParameter("device_id");
154 | String iid = request.getParameter("iid");
155 | int ts= (int) (System.currentTimeMillis()/1000);
156 | String _ricket=System.currentTimeMillis()+"";
157 | String url = "https://aweme.snssdk.com/aweme/v1/aweme/favorite/?max_cursor="+max_cursor+"&user_id="+user_id+"&count=20&ts="+ts+"&_rticket="+_ricket+"&device_id="+device_id+"&iid="+iid +comman_params;
158 | JSONObject device_message = signs_(device_id,iid,ts,url);
159 | response.setBody(new JsonBody(device_message));
160 | }
161 |
162 | @PostMapping("/user_following")
163 | public void user_following(HttpRequest request, HttpResponse response) {
164 | String user_id = request.getParameter("user_id");
165 | String max_time = request.getParameter("max_time");
166 | String device_id = request.getParameter("device_id");
167 | String iid = request.getParameter("iid");
168 | int ts= (int) (System.currentTimeMillis()/1000);
169 | String _ricket=System.currentTimeMillis()+"";
170 | String url = "https://aweme.snssdk.com/aweme/v1/user/following/list/?user_id="+user_id+"&max_time="+max_time+"&count=20&ts="+ts+"&_rticket="+_ricket+"&device_id="+device_id+"&iid="+iid +comman_params;
171 | JSONObject device_message = signs_(device_id,iid,ts,url);
172 | response.setBody(new JsonBody(device_message));
173 | }
174 |
175 | @PostMapping("/get_gon")
176 | public void get_gon(HttpRequest request, HttpResponse response){
177 | String url = request.getParameter("url");
178 | String iid = request.getParameter("iid");
179 | long time = 1579572797;
180 | String p=url.substring(url.indexOf("?")+1,url.length());
181 | String cookie = "install_id="+ iid +"; qh[360]=1";
182 | String s=getXGon(p,"",cookie,sessionid);
183 | Log.i(TAG,s+time);
184 | String XGon= ByteToStr(a.leviathan((int)time,StrToByte(s)));
185 | JSONObject device_message = new JSONObject();
186 | try{
187 | device_message.put("x-gorgon",XGon);
188 | device_message.put("time",time);
189 | device_message.put("url",url);
190 | } catch (JSONException e) {
191 | e.printStackTrace();
192 | }
193 | response.setBody(new JsonBody(device_message));
194 |
195 | }
196 |
197 |
198 | @PostMapping("/user_followers")
199 | public void user_followers(HttpRequest request, HttpResponse response) {
200 | String user_id = request.getParameter("user_id");
201 | String max_time = request.getParameter("max_time");
202 | String device_id = request.getParameter("device_id");
203 | String iid = request.getParameter("iid");
204 | int ts= (int) (System.currentTimeMillis()/1000);
205 | String _ricket=System.currentTimeMillis()+"";
206 | String url = "https://aweme.snssdk.com/aweme/v1/user/follower/list/?user_id="+user_id+"&max_time="+max_time+"&count=20&ts="+ts+"&_rticket="+_ricket+"&device_id="+device_id+"&iid="+iid +comman_params;
207 | JSONObject device_message = signs_(device_id,iid,ts,url);
208 | response.setBody(new JsonBody(device_message));
209 | }
210 |
211 | @PostMapping("/hot_videos")
212 | public void hot_videos(HttpRequest request, HttpResponse response) {
213 | String device_id = request.getParameter("device_id");
214 | String iid = request.getParameter("iid");
215 | int ts= (int) (System.currentTimeMillis()/1000);
216 | String _ricket=System.currentTimeMillis()+"";
217 | String url = "https://aweme.snssdk.com/aweme/v1/hotsearch/aweme/billboard/?&ts="+ts+"&_rticket="+_ricket+"&device_id="+device_id+"&iid="+iid +comman_params;
218 | JSONObject device_message = signs_(device_id,iid,ts,url);
219 | response.setBody(new JsonBody(device_message));
220 | }
221 |
222 | @PostMapping("/positive_video")
223 | public void positive_video(HttpRequest request, HttpResponse response) {
224 | String device_id = request.getParameter("device_id");
225 | String iid = request.getParameter("iid");
226 | int ts= (int) (System.currentTimeMillis()/1000);
227 | String _ricket=System.currentTimeMillis()+"";
228 | String url = "https://aweme.snssdk.com/aweme/v1/hotsearch/positive_energy/billboard/?&ts="+ts+"&_rticket="+_ricket+"&device_id="+device_id+"&iid="+iid +comman_params;
229 | JSONObject device_message = signs_(device_id,iid,ts,url);
230 | response.setBody(new JsonBody(device_message));
231 | }
232 |
233 | @PostMapping("/video_search")
234 | public void video_search(HttpRequest request, HttpResponse response) {
235 | String device_id = request.getParameter("device_id");
236 | String iid = request.getParameter("iid");
237 | String keyword = request.getParameter("keyword");
238 | String offset = request.getParameter("offset");
239 | String search_id = request.getParameter("search_id");
240 | if(search_id==null){
241 | search_id="";
242 | }
243 | System.out.print("ssss"+search_id);
244 | int ts= (int) (System.currentTimeMillis()/1000);
245 | String _ricket=System.currentTimeMillis()+"";
246 | String url = "https://aweme.snssdk.com/aweme/v1/search/item/?ts="+ts+"&js_sdk_version=&app_type=normal&os_api=23&device_type=MI%205s&device_platform=android&ssmix=a&iid="+iid+"&manifest_version_code=570&dpi=192&uuid=910000000127703&version_code=570&app_name=aweme&version_name=5.7.0&openudid=a631422c6936684a&device_id="+device_id+"&resolution=576*1024&os_version=6.0.1&language=zh&device_brand=Xiaomi&ac=wifi&update_version_code=5702&aid=1128&channel=wandoujia_aweme1&_rticket=" + _ricket;
247 | String url3 = "https://aweme.snssdk.com/aweme/v1/search/item/?cursor=0&keyword=xianggang&count=10&ts="+ts+"&js_sdk_version=&app_type=normal&os_api=23&device_type=MI%205s&device_platform=android&ssmix=a&iid="+iid+"&manifest_version_code=570&dpi=192&uuid=910000000127703&version_code=570&app_name=aweme&version_name=5.7.0&openudid=a631422c6936684a&device_id="+device_id+"&resolution=576*1024&os_version=6.0.1&language=zh&device_brand=Xiaomi&ac=wifi&update_version_code=5702&aid=1128&channel=wandoujia_aweme1&_rticket=" + _ricket;
248 | // String url2 = "https://aweme.snssdk.com/aweme/v1/search/item/?ts="+ts+"&js_sdk_version=&app_type=normal&os_api=23&device_type=MI%205s&device_platform=android&ssmix=a&iid="+iid+"&manifest_version_code=570&dpi=192&uuid=910000000127703&version_code=570&app_name=aweme&version_name=5.7.0&openudid=a631422c6936684a&device_id="+device_id+"&resolution=576*1024&os_version=6.0.1&language=zh&device_brand=Xiaomi&ac=wifi&update_version_code=5702&aid=1128&channel=wandoujia_aweme1&_rticket=" + _ricket;
249 | // url2 += "&keyword="+keyword+"&offset="+offset+"&count=10&source=video_search&is_pull_refresh=1&hot_search=0&search_id="+search_id+"&query_correct_type=1";
250 | String ss=url3.substring(url3.indexOf("?")+1,url.length()).replace("&","|").replace("=","|");
251 | String [] km=ss.split("\\|");
252 | System.out.println(Arrays.toString(km));
253 | String ascp=UserInfo.getUserInfo(ts,url,km,device_id);
254 | String as=ascp.substring(0,22);
255 | String cp=ascp.substring(22,ascp.length());
256 | String mas=ByteToStr(a.e(as.getBytes()));
257 | url=url+"&as="+as+"&cp="+cp+"&mas="+mas;
258 | long time=System.currentTimeMillis()/1000;
259 | String p=url.substring(url.indexOf("?")+1,url.length());
260 | String cookie = "install_id="+ iid +"; qh[360]=1";
261 | String s=getXGon(p,"",cookie,sessionid);
262 | String XGon= ByteToStr(a.leviathan((int)time,StrToByte(s)));
263 | JSONObject device_message = new JSONObject();
264 | try{
265 | device_message.put("as",as);
266 | device_message.put("cp",cp);
267 | device_message.put("mas",mas);
268 | device_message.put("x-gorgon",XGon);
269 | device_message.put("time",time);
270 | device_message.put("url",url);
271 | } catch (JSONException e) {
272 | e.printStackTrace();
273 | }
274 | response.setBody(new JsonBody(device_message));
275 | }
276 |
277 |
278 |
279 | public static String getParam(String url, String name) {
280 | String params = url.substring(url.indexOf("?") + 1, url.length());
281 | Map split = Splitter.on("&").withKeyValueSeparator("=").split(params);
282 | return split.get(name);
283 | }
284 |
285 | public JSONObject signs_(String device_id,String iid,int ts,String url){
286 | String ss=url.substring(url.indexOf("?")+1,url.length()).replace("&","|").replace("=","|");
287 | String [] km=ss.split("\\|");
288 | Log.i(TAG,"ts="+ts);
289 | Log.i(TAG,"url="+url);
290 | Log.i(TAG,"km="+Arrays.toString(km));
291 | Log.i(TAG,"device_id="+device_id);
292 | String ascp=UserInfo.getUserInfo(ts,url,km,device_id);
293 | String as=ascp.substring(0,22);
294 | String cp=ascp.substring(22,ascp.length());
295 | String mas=ByteToStr(a.e(as.getBytes()));
296 | url=url+"&as="+as+"&cp="+cp+"&mas="+mas;
297 | long time=System.currentTimeMillis()/1000;
298 | String p=url.substring(url.indexOf("?")+1,url.length());
299 | // String cookie = "install_id="+ iid +"; qh[360]=1";
300 | String cookie = "";
301 | String s=getXGon(p,"",cookie,sessionid);
302 | String XGon= ByteToStr(a.leviathan((int)time,StrToByte(s)));
303 | JSONObject device_message = new JSONObject();
304 | try{
305 | device_message.put("as",as);
306 | device_message.put("cp",cp);
307 | device_message.put("mas",mas);
308 | device_message.put("x-gorgon",XGon);
309 | device_message.put("time",time);
310 | device_message.put("url",url);
311 | } catch (JSONException e) {
312 | e.printStackTrace();
313 | }
314 | // doGetNet(url,time,XGon);
315 | return device_message;
316 | }
317 |
318 | public static String getAndroidId(Context context) {
319 | String ANDROID_ID = Settings.System.getString(context.getContentResolver(), Settings.System.ANDROID_ID);
320 | return ANDROID_ID;
321 | }
322 |
323 | public static String ByteToStr(byte[] bArr) {
324 |
325 | int i = 0;
326 |
327 | char[] toCharArray = "0123456789abcdef".toCharArray();
328 | char[] cArr = new char[(bArr.length * 2)];
329 | while (i < bArr.length) {
330 | int i2 = bArr[i] & 255;
331 | int i3 = i * 2;
332 | cArr[i3] = toCharArray[i2 >>> 4];
333 | cArr[i3 + 1] = toCharArray[i2 & 15];
334 | i++;
335 | }
336 | return new String(cArr);
337 |
338 | }
339 |
340 | public static byte[] StrToByte(String str) {
341 | String str2 = str;
342 | Object[] objArr = new Object[1];
343 | int i = 0;
344 | objArr[0] = str2;
345 |
346 | int length = str.length();
347 | byte[] bArr = new byte[(length / 2)];
348 | while (i < length) {
349 | bArr[i / 2] = (byte) ((Character.digit(str2.charAt(i), 16) << 4) + Character.digit(str2.charAt(i + 1), 16));
350 | i += 2;
351 | }
352 | return bArr;
353 | }
354 |
355 | public String getXGon(String url, String stub, String ck, String sessionid) {
356 | StringBuilder sb = new StringBuilder();
357 | if (TextUtils.isEmpty(url)) {
358 | sb.append(NULL_MD5_STRING);
359 | } else {
360 | sb.append(encryption(url).toLowerCase());
361 | }
362 |
363 | if (TextUtils.isEmpty(stub)) {
364 | sb.append(NULL_MD5_STRING);
365 | } else {
366 | sb.append(stub);
367 | }
368 |
369 | if (TextUtils.isEmpty(ck)) {
370 | sb.append(NULL_MD5_STRING);
371 | } else {
372 | sb.append(encryption(ck).toLowerCase());
373 | }
374 |
375 | if (TextUtils.isEmpty(sessionid)) {
376 | sb.append(NULL_MD5_STRING);
377 | } else {
378 | sb.append(encryption(sessionid).toLowerCase());
379 | }
380 | return sb.toString();
381 | }
382 |
383 | public String encryption(String str) {
384 | String re_md5 = null;
385 | try {
386 | MessageDigest md = MessageDigest.getInstance("MD5");
387 | md.update(str.getBytes());
388 | byte b[] = md.digest();
389 |
390 | int i;
391 |
392 | StringBuffer buf = new StringBuffer("");
393 | for (int offset = 0; offset < b.length; offset++) {
394 | i = b[offset];
395 | if (i < 0)
396 | i += 256;
397 | if (i < 16)
398 | buf.append("0");
399 | buf.append(Integer.toHexString(i));
400 | }
401 |
402 | re_md5 = buf.toString();
403 |
404 | } catch (NoSuchAlgorithmException e) {
405 | e.printStackTrace();
406 | }
407 | return re_md5.toUpperCase();
408 | }
409 |
410 | public String[] MapTo(Map map) {
411 | List list = new ArrayList<>();
412 | for (String key : map.keySet()) {
413 | // System.out.println("key= "+ key + " and value= " + map.get(key));
414 | list.add(key);
415 | list.add(map.get(key));
416 | }
417 | String[] str = (String[]) list.toArray(new String[0]);
418 | return str;
419 | }
420 |
421 | public static String format_url(String str) {
422 | int indexOf = str.indexOf("?");
423 | int indexOf2 = str.indexOf("#");
424 | return indexOf == -1 ? null : indexOf2 == -1 ? str.substring(indexOf + 1) : indexOf2 < indexOf ? null : str.substring(indexOf + 1, indexOf2);
425 | }
426 |
427 | public String result;
428 |
429 |
430 | public String getDevice() {
431 | String uuid = DeviceUtil.getRanInt(15);; //设备id
432 | String openudid = DeviceUtil.getRanInt(16);; //android_id
433 | String _rticket = System.currentTimeMillis() + ""; //获取当前时间
434 | String url = "https://log.snssdk.com/service/2/device_register/?mcc_mnc=46000&ac=wifi&channel=wandoujia_aweme1&aid=1128&app_name=aweme&version_code=570&version_name=5.7.0&device_platform=android&ssmix=a&device_type=DUK-AL20&device_brand=HUAWEI&language=zh&os_api=22&os_version=5.1.1&uuid=" + uuid + "&openudid=" + openudid + "&manifest_version_code=570&resolution=1024x576&dpi=191&update_version_code=5702&_rticket=" + _rticket + "&tt_data=a&config_retry=b";
435 | String stb = url.substring(url.indexOf("?") + 1, url.length());
436 | String STUB = encryption(stb).toUpperCase();
437 | String ck = "qh[360]=1";
438 | int time = (int) (System.currentTimeMillis() / 1000);
439 |
440 | String s = getXGon(url, STUB, ck, null);
441 | String XGon = ByteToStr(a.leviathan(time, StrToByte(s)));
442 |
443 | final RequestBody formBody = RequestBody.create(MediaType.parse("application/octet-stream;tt-data=a"), getDevice(openudid, uuid));
444 | Request request = new Request.Builder()
445 | .url(url)
446 | .post(formBody)
447 | .addHeader("X-SS-STUB",stb) //post md5
448 | .addHeader("X-SS-REQ-TICKET", System.currentTimeMillis() + "")
449 | // .addHeader("X-Khronos", time + "")
450 | // .addHeader("X-Gorgon",XGon)
451 | .addHeader("sdk-version", "1")
452 | .addHeader("Content-Type", "application/octet-stream;tt-data=a")
453 | .addHeader("Cookie", ck)
454 | .addHeader("X-Pods", "")
455 | .addHeader("Connection", "Keep-Alive")
456 | .addHeader("User-Agent", "okhttp/3.10.0.1")
457 | .build();
458 | OkHttpClient okHttpClient = new OkHttpClient();
459 | okhttp3.Call call = okHttpClient.newCall(request);
460 | call.enqueue(new Callback() {
461 | @Override
462 | public void onFailure(okhttp3.Call call, IOException e) {
463 | Log.d(TAG, "onFailure: " + e.getMessage());
464 | }
465 |
466 | @Override
467 | public void onResponse(okhttp3.Call call, Response response) throws IOException {
468 | Log.d(TAG, response.protocol() + " " + response.code() + " " + response.message());
469 | result = response.body().string();
470 | }
471 | });
472 |
473 | try{
474 | JSONObject device_message = new JSONObject(result);
475 | device_message.put("uuid",uuid);
476 | device_message.put("openudid",openudid);
477 | return device_message.toString();
478 |
479 | } catch (JSONException e) {
480 | e.printStackTrace();
481 | }
482 | return result;
483 | }
484 |
485 | public static byte[] compressWithgzip(byte[] bArr) throws Exception {
486 | Throwable th;
487 | GZIPOutputStream gZIPOutputStream = null;
488 | try {
489 | ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(8192);
490 | GZIPOutputStream gZIPOutputStream2 = new GZIPOutputStream(byteArrayOutputStream);
491 | try {
492 | gZIPOutputStream2.write(bArr);
493 | gZIPOutputStream2.close();
494 | return byteArrayOutputStream.toByteArray();
495 | } catch (Throwable th2) {
496 | th = th2;
497 | gZIPOutputStream = gZIPOutputStream2;
498 | if (gZIPOutputStream != null) {
499 | gZIPOutputStream.close();
500 | }
501 | throw th;
502 | }
503 | } catch (Throwable th3) {
504 | th = th3;
505 | if (gZIPOutputStream != null) {
506 | }
507 | // throw th;
508 | }
509 | return null;
510 | }
511 |
512 |
513 | public byte[] getDevice(String openudid, String udid) {
514 | //DeviceBean
515 | String Serial_number = DeviceUtil.getRanInt(8);
516 | DeviceBean deviceBean = new DeviceBean();
517 | deviceBean.set_gen_time(System.currentTimeMillis() + "");
518 | deviceBean.setMagic_tag("ss_app_log");
519 | //HeaderBean
520 | DeviceBean.HeaderBean headerBean = new DeviceBean.HeaderBean();
521 | headerBean.setDisplay_name("抖音短视频");
522 | headerBean.setUpdate_version_code(5702);
523 | headerBean.setManifest_version_code(570);
524 | headerBean.setAid(1128);
525 | headerBean.setChannel("wandoujia_aweme1");
526 | headerBean.setAppkey("57bfa27c67e58e7d920028d3"); //appkey
527 | headerBean.setPackageX("com.ss.android.ugc.aweme");
528 | headerBean.setApp_version("5.7.0");
529 | headerBean.setVersion_code(570);
530 | headerBean.setSdk_version("2.5.5.8");
531 | headerBean.setOs("Android");
532 | headerBean.setOs_version("5.1.1");
533 | headerBean.setOs_api(22);
534 | headerBean.setDevice_model("DUK-AL20");
535 | headerBean.setDevice_brand("HUAWEI");
536 | headerBean.setDevice_manufacturer("HUAWEI");
537 | headerBean.setCpu_abi("armeabi-v7a");
538 | headerBean.setBuild_serial(Serial_number); ////android.os.Build.SERIAL
539 | headerBean.setRelease_build("c4e7178_20190401"); // release版本
540 | headerBean.setDensity_dpi(191);
541 | headerBean.setDisplay_density("mdpi");
542 | headerBean.setResolution("1024x576");
543 | headerBean.setLanguage("zh");
544 | // headerBean.setMc("dc:87:9d:2d:cb:dc"); //mac 地址
545 | headerBean.setMc(DeviceUtil.getMac()); //mac 地址
546 | headerBean.setTimezone(8);
547 | headerBean.setAccess("wifi");
548 | headerBean.setNot_request_sender(0);
549 | headerBean.setCarrier("China Mobile GSM");
550 | headerBean.setMcc_mnc("46000");
551 | headerBean.setRom("EMUI-eng.se.infra.20191230.112159"); //Build.VERSION.INCREMENTAL
552 | headerBean.setRom_version("HUAWEI-user 5.1.1 20171130.276299 release-keys"); //Build.DISPLAY
553 | headerBean.setSig_hash("aea615ab910015038f73c47e45d21466"); //app md5加密 固定
554 | headerBean.setDevice_id(""); //获取之后的设备id
555 | headerBean.setOpenudid(openudid); //openudid #############
556 | headerBean.setUdid(udid); //真机的imei ############
557 | headerBean.setClientudid(UUID.randomUUID().toString()); //uuid
558 | // headerBean.setClientudid("3fa25ffa-1203-407d-9187-426e2d745156"); //uuid
559 | headerBean.setSerial_number(Serial_number); //android.os.Build.SERIAL
560 | headerBean.setRegion("CN");
561 | headerBean.setTz_name("Asia\\/Shanghai"); //timeZone.getID();
562 | headerBean.setTz_offset(28800); //String.valueOf(timeZone.getOffset(System.currentTimeMillis()) / 1000)
563 | headerBean.setSim_region("cn");
564 | List sim_serial_number = new ArrayList<>();
565 | DeviceBean.HeaderBean.SimSerialNumberBean bean = new DeviceBean.HeaderBean.SimSerialNumberBean();
566 | // bean.setSim_serial_number(DeviceUtil.getRanInt(20));
567 | bean.setSim_serial_number("89014103211118510720");
568 | sim_serial_number.add(bean);
569 | headerBean.setSim_serial_number(sim_serial_number);
570 | deviceBean.setHeader(headerBean);
571 | TimeZone timeZone = Calendar.getInstance().getTimeZone();
572 | timeZone.getID();
573 | //r
574 | Gson gson = new Gson();
575 |
576 | String r = gson.toJson(deviceBean);
577 |
578 | Log.i(TAG, r);
579 | try {
580 | byte[] bArr2 = r.getBytes("UTF-8");
581 |
582 | ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(8192);
583 | GZIPOutputStream gZIPOutputStream = new GZIPOutputStream(byteArrayOutputStream);
584 | gZIPOutputStream.write(bArr2);
585 | gZIPOutputStream.close();
586 | bArr2 = byteArrayOutputStream.toByteArray();
587 | bArr2 = TTEncryptUtils.a(bArr2, bArr2.length);
588 | return bArr2;
589 | } catch (Exception e) {
590 | e.printStackTrace();
591 | }
592 | return null;
593 | }
594 |
595 |
596 | public void doPostNet(String url, RequestBody requestBody, long time, String XGon, String stub) {
597 | Request request = new Request.Builder()
598 | .url(url)
599 | .post(requestBody)
600 | .addHeader("X-SS-STUB", stub)
601 | .addHeader("X-SS-REQ-TICKET", System.currentTimeMillis() + "")
602 | .addHeader("X-Khronos", time + "")
603 | .addHeader("X-Gorgon", XGon)
604 | .addHeader("sdk-version", "1")
605 | .addHeader("Cookie", ck)
606 | .addHeader("X-Pods", "")
607 | .addHeader("Connection", "Keep-Alive")
608 | .addHeader("User-Agent", "okhttp/3.10.0.1")
609 | .addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
610 | .addHeader("x-tt-token", xtttoken) //登录成功头部返回的数据
611 | // .addHeader("Host","aweme.snssdk.com")
612 | .build();
613 | OkHttpClient okHttpClient = new OkHttpClient();
614 | okHttpClient.newCall(request).enqueue(new Callback() {
615 | @Override
616 | public void onFailure(okhttp3.Call call, IOException e) {
617 | Log.d(TAG, "onFailure: " + e.getMessage());
618 |
619 | }
620 |
621 | @Override
622 | public void onResponse(okhttp3.Call call, Response response) throws IOException {
623 | Log.d(TAG, response.protocol() + " " + response.code() + " " + response.message());
624 | Log.i(TAG, response.body().string());
625 | }
626 |
627 | });
628 | }
629 |
630 | public void doGetNet(String url, long time, String XGon) {
631 | Request request = new Request.Builder()
632 | .url(url)
633 | .get()
634 | .addHeader("X-SS-REQ-TICKET", System.currentTimeMillis() + "")
635 | .addHeader("X-Khronos", time + "")
636 | .addHeader("X-Gorgon", XGon)
637 | .addHeader("sdk-version", "1")
638 | .addHeader("Cookie", ck)
639 | .addHeader("X-Pods", "")
640 | .addHeader("Connection", "Keep-Alive")
641 | .addHeader("User-Agent", "okhttp/3.10.0.1")
642 | // .addHeader("x-tt-token", xtttoken)
643 | .addHeader("Host","aweme.snssdk.com")
644 | .build();
645 | OkHttpClient okHttpClient = new OkHttpClient();
646 | okHttpClient.newCall(request).enqueue(new Callback() {
647 | @Override
648 | public void onFailure(okhttp3.Call call, IOException e) {
649 | Log.d(TAG, "onFailure: " + e.getMessage());
650 | }
651 |
652 | @Override
653 | public void onResponse(okhttp3.Call call, Response response) throws IOException {
654 | Log.d(TAG, response.protocol() + " " + response.code() + " " + response.message());
655 | Log.e(TAG, response.body().string());
656 | }
657 | });
658 | }
659 |
660 | }
661 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yf/douyintool/NetUtils.java:
--------------------------------------------------------------------------------
1 | package com.yf.douyintool;
2 |
3 | import java.net.InetAddress;
4 | import java.net.NetworkInterface;
5 | import java.net.SocketException;
6 | import java.util.Enumeration;
7 | import java.util.regex.Pattern;
8 |
9 | public class NetUtils {
10 |
11 | private static final Pattern IPV4_PATTERN = Pattern.compile("^(" +
12 |
13 | "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}" +
14 |
15 | "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$");
16 |
17 |
18 | private static boolean isIPv4Address(String input) {
19 |
20 | return IPV4_PATTERN.matcher(input).matches();
21 |
22 | }
23 |
24 | //获取本机IP地址
25 |
26 | public static InetAddress getLocalIPAddress() {
27 |
28 | Enumeration enumeration = null;
29 |
30 | try {
31 |
32 | enumeration = NetworkInterface.getNetworkInterfaces();
33 |
34 | } catch (SocketException e) {
35 |
36 | e.printStackTrace();
37 |
38 | }
39 |
40 | if (enumeration != null) {
41 |
42 | while (enumeration.hasMoreElements()) {
43 |
44 | NetworkInterface nif = enumeration.nextElement();
45 |
46 | Enumeration inetAddresses = nif.getInetAddresses();
47 |
48 | if (inetAddresses != null)
49 |
50 | while (inetAddresses.hasMoreElements()) {
51 |
52 | InetAddress inetAddress = inetAddresses.nextElement();
53 |
54 | if (!inetAddress.isLoopbackAddress() && isIPv4Address(inetAddress.getHostAddress())) {
55 |
56 | return inetAddress;
57 |
58 | }
59 |
60 | }
61 | }
62 |
63 | }
64 |
65 | return null;
66 |
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yf/douyintool/PmsHookBinderInvocationHandler.java:
--------------------------------------------------------------------------------
1 | package com.yf.douyintool;
2 |
3 | import android.content.pm.PackageInfo;
4 | import android.content.pm.PackageManager;
5 | import android.content.pm.Signature;
6 | import android.util.Log;
7 |
8 | import java.lang.reflect.InvocationHandler;
9 | import java.lang.reflect.Method;
10 |
11 | public class PmsHookBinderInvocationHandler implements InvocationHandler {
12 |
13 | private Object base;
14 |
15 | //应用正确的签名信息
16 | private String SIGN;
17 | private String appPkgName = "";
18 |
19 | public PmsHookBinderInvocationHandler(Object base, String sign, String appPkgName, int hashCode) {
20 | try {
21 | this.base = base;
22 | this.SIGN = sign;
23 | this.appPkgName = appPkgName;
24 | } catch (Exception e) {
25 | Log.d("jw", "error:"+Log.getStackTraceString(e));
26 | }
27 | }
28 |
29 | @Override
30 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
31 | Log.i("jw", method.getName());
32 | if("getPackageInfo".equals(method.getName())){
33 | String pkgName = (String)args[0];
34 | Integer flag = (Integer)args[1];
35 | if(flag == PackageManager.GET_SIGNATURES && appPkgName.equals(pkgName)){
36 | Signature sign = new Signature(SIGN);
37 | PackageInfo info = (PackageInfo) method.invoke(base, args);
38 | info.signatures[0] = sign;
39 | return info;
40 | }
41 | }
42 | return method.invoke(base, args);
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yf/douyintool/SecurityUntil.java:
--------------------------------------------------------------------------------
1 | package com.yf.douyintool;
2 |
3 | import android.text.TextUtils;
4 |
5 | public class SecurityUntil {
6 | static final char[] a;
7 |
8 | static {
9 | a = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
10 | }
11 |
12 | public static String d(String arg3) {
13 | int v0 = 0;
14 | try {
15 | if(TextUtils.isEmpty(((String)arg3))) {
16 | return null;
17 | }
18 |
19 | byte[] v1 = arg3.getBytes("UTF-8");
20 | while(v0 < v1.length) {
21 | v1[v0] = ((byte)(v1[v0] ^ 5));
22 | ++v0;
23 | }
24 |
25 | return a(v1, 0, v1.length);
26 | }
27 | catch(Exception v0_1) {
28 | return arg3;
29 | }
30 | }
31 |
32 | public static String a(byte[] arg8, int arg9, int arg10) {
33 | if(arg8 == null) {
34 | throw new NullPointerException("bytes is null");
35 | }
36 |
37 | if(arg9 >= 0 && arg9 + arg10 <= arg8.length) {
38 | char[] v3 = new char[arg10 * 2];
39 | int v0 = 0;
40 | int v2 = 0;
41 | while(v0 < arg10) {
42 | int v4 = arg8[v0 + arg9] & 255;
43 | int v5 = v2 + 1;
44 | v3[v2] = a[v4 >> 4];
45 | v2 = v5 + 1;
46 | v3[v5] = a[v4 & 15];
47 | ++v0;
48 | }
49 |
50 | return new String(v3, 0, arg10 * 2);
51 | }
52 |
53 | throw new IndexOutOfBoundsException();
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yf/douyintool/ServerManager.java:
--------------------------------------------------------------------------------
1 | package com.yf.douyintool;
2 |
3 | import android.content.Context;
4 | import android.util.Log;
5 |
6 | import com.yanzhenjie.andserver.AndServer;
7 | import com.yanzhenjie.andserver.Server;
8 |
9 | import java.net.InetAddress;
10 | import java.util.concurrent.TimeUnit;
11 |
12 | public class ServerManager {
13 | private static final String TAG = "ServerManager";
14 |
15 | private Server mServer;
16 |
17 | /**
18 | * Create server.
19 | */
20 | public ServerManager(Context context, InetAddress inetAddress, int port) {
21 |
22 | mServer = AndServer.serverBuilder(context)
23 | .inetAddress(inetAddress)
24 | .port(port)
25 | .timeout(10, TimeUnit.SECONDS)
26 | .listener(new Server.ServerListener() {
27 | @Override
28 | public void onStarted() {
29 | // TODO The server started successfully.
30 | Log.d(TAG, "onStarted: ");
31 | }
32 |
33 | @Override
34 | public void onStopped() {
35 | // TODO The server has stopped.
36 | Log.d(TAG, "onStopped: ");
37 | }
38 |
39 | @Override
40 | public void onException(Exception e) {
41 | // TODO An exception occurred while the server was starting.
42 | Log.e(TAG, "onException: ", e);
43 | }
44 | })
45 | .build();
46 | }
47 |
48 | /**
49 | * Start server.
50 | */
51 | public void startServer() {
52 | if (mServer.isRunning()) {
53 | // TODO The server is already up.
54 | } else {
55 | mServer.startup();
56 | }
57 | }
58 |
59 | /**
60 | * Stop server.
61 | */
62 | public void stopServer() {
63 | if (mServer.isRunning()) {
64 | mServer.shutdown();
65 | } else {
66 | Log.w("AndServer", "The server has not started yet.");
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yf/douyintool/Service/MyService.java:
--------------------------------------------------------------------------------
1 | package com.yf.douyintool.Service;
2 |
3 | import android.app.Service;
4 | import android.content.Intent;
5 | import android.os.IBinder;
6 | import android.util.Log;
7 |
8 | import com.yf.douyintool.NetUtils;
9 | import com.yf.douyintool.ServerManager;
10 |
11 | import java.net.InetAddress;
12 | import java.net.UnknownHostException;
13 |
14 | import javax.security.auth.login.LoginException;
15 |
16 | public class MyService extends Service {
17 | private static final String TAG = "NigthTeam";
18 |
19 | @Override
20 | public void onCreate() {
21 | super.onCreate();
22 | Log.d(TAG, "onCreate: MyService");
23 | new Thread() {
24 | @Override
25 | public void run() {
26 | super.run();
27 | InetAddress inetAddress = null;
28 | String ip = "0.0.0.0";
29 | int port = 8005;
30 | try {
31 | inetAddress = InetAddress.getByName(ip);
32 | Log.d(TAG, "onCreate: " + inetAddress.getHostAddress());
33 | ServerManager serverManager = new ServerManager(getApplicationContext(), inetAddress, port);
34 | serverManager.startServer();
35 | Log.d(TAG, "run: address = " + NetUtils.getLocalIPAddress()+ ":" + port);
36 | Thread.setDefaultUncaughtExceptionHandler(handler);
37 | } catch (UnknownHostException e) {
38 | e.printStackTrace();
39 | }
40 |
41 | }
42 | }.start();
43 | }
44 |
45 | private Thread.UncaughtExceptionHandler handler = new Thread.UncaughtExceptionHandler() {
46 | @Override
47 | public void uncaughtException(Thread t, Throwable e) {
48 | //restartApp(); //发生崩溃异常时,重启应用
49 | Log.e(TAG,"发生崩溃异常, 需要重启应用...");
50 | }
51 | };
52 |
53 | @Override
54 | public IBinder onBind(Intent intent) {
55 | return null;
56 | }
57 |
58 | @Override
59 | public void onDestroy() {
60 | super.onDestroy();
61 | }
62 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yf/douyintool/ServiceManagerWraper.java:
--------------------------------------------------------------------------------
1 | package com.yf.douyintool;
2 |
3 | import android.content.Context;
4 | import android.content.pm.PackageManager;
5 | import android.util.Log;
6 |
7 | import java.lang.reflect.Field;
8 | import java.lang.reflect.Method;
9 | import java.lang.reflect.Proxy;
10 |
11 | public class ServiceManagerWraper {
12 | public static void hookPMS(Context context, String signed, String appPkgName, int hashCode){
13 | try{
14 | // 获取全局的ActivityThread对象
15 | Class> activityThreadClass = Class.forName("android.app.ActivityThread");
16 | Method currentActivityThreadMethod =
17 | activityThreadClass.getDeclaredMethod("currentActivityThread");
18 | Object currentActivityThread = currentActivityThreadMethod.invoke(null);
19 | // 获取ActivityThread里面原始的sPackageManager
20 | Field sPackageManagerField = activityThreadClass.getDeclaredField("sPackageManager");
21 | sPackageManagerField.setAccessible(true);
22 | Object sPackageManager = sPackageManagerField.get(currentActivityThread);
23 | // 准备好代理对象, 用来替换原始的对象
24 | Class> iPackageManagerInterface = Class.forName("android.content.pm.IPackageManager");
25 | Object proxy = Proxy.newProxyInstance(
26 | iPackageManagerInterface.getClassLoader(),
27 | new Class>[] { iPackageManagerInterface },
28 | new PmsHookBinderInvocationHandler(sPackageManager, signed, appPkgName, 0));
29 | // 1. 替换掉ActivityThread里面的 sPackageManager 字段
30 | sPackageManagerField.set(currentActivityThread, proxy);
31 | // 2. 替换 ApplicationPackageManager里面的 mPM对象
32 | PackageManager pm = context.getPackageManager();
33 | Field mPmField = pm.getClass().getDeclaredField("mPM");
34 | mPmField.setAccessible(true);
35 | mPmField.set(pm, proxy);
36 | }catch (Exception e){
37 | Log.d("jw", "hook pms error:"+Log.getStackTraceString(e));
38 | }
39 | }
40 |
41 | public static void hookPMS(Context context){
42 | String qqSign = "308203563082023ea00302010202044efec96a300d06092a864886f70d0101050500306d310b300906035504061302434e3110300e060355040813074265696a696e673110300e060355040713074265696a696e6731123010060355040a13094279746544616e636531123010060355040b13094279746544616e636531123010060355040313094d6963726f2043616f301e170d3131313233313038333535345a170d3339303531383038333535345a306d310b300906035504061302434e3110300e060355040813074265696a696e673110300e060355040713074265696a696e6731123010060355040a13094279746544616e636531123010060355040b13094279746544616e636531123010060355040313094d6963726f2043616f30820122300d06092a864886f70d01010105000382010f003082010a0282010100a46d108be827bff2c1ac7ad986c463b8cda9f0e7ddc21295af55bd16f7bfabb36fa33b72a8e76f5a59b48b29cb6e34c38d065589636dd120f39346c37b3753830422cc0c84243fdf0e28d3e5970dcd641c70c9e2e3ec66ac14afd351abb59d6885370e16b64bbfb28fbb234dffe25f5cfb6680c84121770cf3a177bc8a28b78b7c86d30a61eb67b9fbfd92e0c8fc5eb8346a238ddfe08522f091c622789932d9debe6910b4b903d02e5f6ded69f5c13a5d1742dac21050dfbb5f4ea615028d7a8642e4a93e075cf8f0e33a4a654af11f4f9a4905d917f0bbb84e63a1a2e90b8997f936e5bf5a75ea6d19d1d93d2677886e59e95c0bb33505363c05e10a389d0b0203010001300d06092a864886f70d010105050003820101008704e53758907db6785bec65c5f51af050873c4b0a5e08f90191b901c59969ce537942dbc9307f8fcc23b1c281a66fe46136890564f89fb16839ac69f836a9ea074eb03da8578330ab50b185bd6916f195a67036060a0bbf2aed06990e72bc4dede895ae5e695371aa4ad26efcd44b65891bda9ce02d9e71548592c2951e2cb62ed4408eec7e828ce573ffba0458341aef25957b2a76403da091322eb845b6a9903fe6aed1434012d483f1c668e2468ce129815e18283baa5e1c4209691b36ffa86506ff6a4b83f24faa744383b75968046c69703d2c5df38bad6920d9122cb1f7c78e8bfe283870359c053115e2ba0a7a03c9656a2f5a2d81f6a6fad5db2cd7";
43 | hookPMS(context, qqSign, "com.ss.android.ugc.aweme", 0);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yf/douyintool/b.java:
--------------------------------------------------------------------------------
1 | package com.yf.douyintool;
2 |
3 | import java.io.Closeable;
4 | import java.io.IOException;
5 | import java.util.zip.ZipFile;
6 |
7 | public class b {
8 | public static void a(Closeable closeable) {
9 | if (closeable != null) {
10 | try {
11 | closeable.close();
12 | } catch (IOException unused) {
13 | }
14 | }
15 | }
16 |
17 | public static void a(ZipFile zipFile) {
18 | if (zipFile != null) {
19 | try {
20 | zipFile.close();
21 | } catch (IOException unused) {
22 | }
23 | }
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yf/douyintool/bean/DeviceBean.java:
--------------------------------------------------------------------------------
1 | package com.yf.douyintool.bean;
2 |
3 |
4 |
5 | import java.util.List;
6 |
7 | public class DeviceBean {
8 |
9 | /**
10 | * magic_tag : ss_app_log
11 | * header : {"display_name":"抖音短视频","update_version_code":5502,"manifest_version_code":550,"aid":1128,"channel":"aweGW","appkey":"57bfa27c67e58e7d920028d3","package":"com.ss.android.ugc.aweme","app_version":"5.5.0","version_code":550,"sdk_version":"2.5.5.8","os":"Android","os_version":"5.1.1","os_api":22,"device_model":"SM-G925F","device_brand":"samsung","device_manufacturer":"samsung","cpu_abi":"armeabi-v7a","build_serial":"95294183","release_build":"2132ca7_20190320","density_dpi":192,"display_density":"mdpi","resolution":"1280x720","language":"zh","mc":"c8:de:47:39:c9:f6","timezone":8,"access":"wifi","not_request_sender":0,"carrier":"China Mobile GSM","mcc_mnc":"46000","rom":"eng.se.infra.20181117.120021","rom_version":"samsung-user 5.1.1 20171130.276299 release-keys","sig_hash":"aea615ab910015038f73c47e45d21466","device_id":"66868373655","openudid":"2021049774027898","udid":"864434952979918","clientudid":"8578d20c-8229-4b81-a031-4fc7747b00ad","serial_number":"95294183","sim_serial_number":[{"sim_serial_number":"89014103211118510720"}],"region":"CN","tz_name":"Asia/Shanghai","tz_offset":28800,"sim_region":"cn"}
12 | * _gen_time : 1553499369782
13 | */
14 |
15 | private String magic_tag;
16 | private HeaderBean header;
17 | private String _gen_time;
18 |
19 | public String getMagic_tag() {
20 | return magic_tag;
21 | }
22 |
23 | public void setMagic_tag(String magic_tag) {
24 | this.magic_tag = magic_tag;
25 | }
26 |
27 | public HeaderBean getHeader() {
28 | return header;
29 | }
30 |
31 | public void setHeader(HeaderBean header) {
32 | this.header = header;
33 | }
34 |
35 | public String get_gen_time() {
36 | return _gen_time;
37 | }
38 |
39 | public void set_gen_time(String _gen_time) {
40 | this._gen_time = _gen_time;
41 | }
42 |
43 | public static class HeaderBean {
44 | /**
45 | * display_name : 抖音短视频
46 | * update_version_code : 5502
47 | * manifest_version_code : 550
48 | * aid : 1128
49 | * channel : aweGW
50 | * appkey : 57bfa27c67e58e7d920028d3
51 | * package : com.ss.android.ugc.aweme
52 | * app_version : 5.5.0
53 | * version_code : 550
54 | * sdk_version : 2.5.5.8
55 | * os : Android
56 | * os_version : 5.1.1
57 | * os_api : 22
58 | * device_model : SM-G925F
59 | * device_brand : samsung
60 | * device_manufacturer : samsung
61 | * cpu_abi : armeabi-v7a
62 | * build_serial : 95294183
63 | * release_build : 2132ca7_20190320
64 | * density_dpi : 192
65 | * display_density : mdpi
66 | * resolution : 1280x720
67 | * language : zh
68 | * mc : c8:de:47:39:c9:f6
69 | * timezone : 8
70 | * access : wifi
71 | * not_request_sender : 0
72 | * carrier : China Mobile GSM
73 | * mcc_mnc : 46000
74 | * rom : eng.se.infra.20181117.120021
75 | * rom_version : samsung-user 5.1.1 20171130.276299 release-keys
76 | * sig_hash : aea615ab910015038f73c47e45d21466
77 | * device_id : 66868373655
78 | * openudid : 2021049774027898
79 | * udid : 864434952979918
80 | * clientudid : 8578d20c-8229-4b81-a031-4fc7747b00ad
81 | * serial_number : 95294183
82 | * sim_serial_number : [{"sim_serial_number":"89014103211118510720"}]
83 | * region : CN
84 | * tz_name : Asia/Shanghai
85 | * tz_offset : 28800
86 | * sim_region : cn
87 | */
88 |
89 | private String display_name;
90 | private int update_version_code;
91 | private int manifest_version_code;
92 | private int aid;
93 | private String channel;
94 | private String appkey;
95 | // @com.google.gson.annotations.SerializedName("package")
96 | // @SerializedName("package")
97 | // private String package;
98 | private String packageX;
99 | private String app_version;
100 | private int version_code;
101 | private String sdk_version;
102 | private String os;
103 | private String os_version;
104 | private int os_api;
105 | private String device_model;
106 | private String device_brand;
107 | private String device_manufacturer;
108 | private String cpu_abi;
109 | private String build_serial;
110 | private String release_build;
111 | private int density_dpi;
112 | private String display_density;
113 | private String resolution;
114 | private String language;
115 | private String mc;
116 | private int timezone;
117 | private String access;
118 | private int not_request_sender;
119 | private String carrier;
120 | private String mcc_mnc;
121 | private String rom;
122 | private String rom_version;
123 | private String sig_hash;
124 | private String device_id;
125 | private String openudid;
126 | private String udid;
127 | private String clientudid;
128 | private String serial_number;
129 | private String region;
130 | private String tz_name;
131 | private int tz_offset;
132 | private String sim_region;
133 | private List sim_serial_number;
134 |
135 | public String getDisplay_name() {
136 | return display_name;
137 | }
138 |
139 | public void setDisplay_name(String display_name) {
140 | this.display_name = display_name;
141 | }
142 |
143 | public int getUpdate_version_code() {
144 | return update_version_code;
145 | }
146 |
147 | public void setUpdate_version_code(int update_version_code) {
148 | this.update_version_code = update_version_code;
149 | }
150 |
151 | public int getManifest_version_code() {
152 | return manifest_version_code;
153 | }
154 |
155 | public void setManifest_version_code(int manifest_version_code) {
156 | this.manifest_version_code = manifest_version_code;
157 | }
158 |
159 | public int getAid() {
160 | return aid;
161 | }
162 |
163 | public void setAid(int aid) {
164 | this.aid = aid;
165 | }
166 |
167 | public String getChannel() {
168 | return channel;
169 | }
170 |
171 | public void setChannel(String channel) {
172 | this.channel = channel;
173 | }
174 |
175 | public String getAppkey() {
176 | return appkey;
177 | }
178 |
179 | public void setAppkey(String appkey) {
180 | this.appkey = appkey;
181 | }
182 |
183 | public String getPackageX() {
184 | return packageX;
185 | }
186 |
187 | public void setPackageX(String packageX) {
188 | this.packageX = packageX;
189 | }
190 |
191 | public String getApp_version() {
192 | return app_version;
193 | }
194 |
195 | public void setApp_version(String app_version) {
196 | this.app_version = app_version;
197 | }
198 |
199 | public int getVersion_code() {
200 | return version_code;
201 | }
202 |
203 | public void setVersion_code(int version_code) {
204 | this.version_code = version_code;
205 | }
206 |
207 | public String getSdk_version() {
208 | return sdk_version;
209 | }
210 |
211 | public void setSdk_version(String sdk_version) {
212 | this.sdk_version = sdk_version;
213 | }
214 |
215 | public String getOs() {
216 | return os;
217 | }
218 |
219 | public void setOs(String os) {
220 | this.os = os;
221 | }
222 |
223 | public String getOs_version() {
224 | return os_version;
225 | }
226 |
227 | public void setOs_version(String os_version) {
228 | this.os_version = os_version;
229 | }
230 |
231 | public int getOs_api() {
232 | return os_api;
233 | }
234 |
235 | public void setOs_api(int os_api) {
236 | this.os_api = os_api;
237 | }
238 |
239 | public String getDevice_model() {
240 | return device_model;
241 | }
242 |
243 | public void setDevice_model(String device_model) {
244 | this.device_model = device_model;
245 | }
246 |
247 | public String getDevice_brand() {
248 | return device_brand;
249 | }
250 |
251 | public void setDevice_brand(String device_brand) {
252 | this.device_brand = device_brand;
253 | }
254 |
255 | public String getDevice_manufacturer() {
256 | return device_manufacturer;
257 | }
258 |
259 | public void setDevice_manufacturer(String device_manufacturer) {
260 | this.device_manufacturer = device_manufacturer;
261 | }
262 |
263 | public String getCpu_abi() {
264 | return cpu_abi;
265 | }
266 |
267 | public void setCpu_abi(String cpu_abi) {
268 | this.cpu_abi = cpu_abi;
269 | }
270 |
271 | public String getBuild_serial() {
272 | return build_serial;
273 | }
274 |
275 | public void setBuild_serial(String build_serial) {
276 | this.build_serial = build_serial;
277 | }
278 |
279 | public String getRelease_build() {
280 | return release_build;
281 | }
282 |
283 | public void setRelease_build(String release_build) {
284 | this.release_build = release_build;
285 | }
286 |
287 | public int getDensity_dpi() {
288 | return density_dpi;
289 | }
290 |
291 | public void setDensity_dpi(int density_dpi) {
292 | this.density_dpi = density_dpi;
293 | }
294 |
295 | public String getDisplay_density() {
296 | return display_density;
297 | }
298 |
299 | public void setDisplay_density(String display_density) {
300 | this.display_density = display_density;
301 | }
302 |
303 | public String getResolution() {
304 | return resolution;
305 | }
306 |
307 | public void setResolution(String resolution) {
308 | this.resolution = resolution;
309 | }
310 |
311 | public String getLanguage() {
312 | return language;
313 | }
314 |
315 | public void setLanguage(String language) {
316 | this.language = language;
317 | }
318 |
319 | public String getMc() {
320 | return mc;
321 | }
322 |
323 | public void setMc(String mc) {
324 | this.mc = mc;
325 | }
326 |
327 | public int getTimezone() {
328 | return timezone;
329 | }
330 |
331 | public void setTimezone(int timezone) {
332 | this.timezone = timezone;
333 | }
334 |
335 | public String getAccess() {
336 | return access;
337 | }
338 |
339 | public void setAccess(String access) {
340 | this.access = access;
341 | }
342 |
343 | public int getNot_request_sender() {
344 | return not_request_sender;
345 | }
346 |
347 | public void setNot_request_sender(int not_request_sender) {
348 | this.not_request_sender = not_request_sender;
349 | }
350 |
351 | public String getCarrier() {
352 | return carrier;
353 | }
354 |
355 | public void setCarrier(String carrier) {
356 | this.carrier = carrier;
357 | }
358 |
359 | public String getMcc_mnc() {
360 | return mcc_mnc;
361 | }
362 |
363 | public void setMcc_mnc(String mcc_mnc) {
364 | this.mcc_mnc = mcc_mnc;
365 | }
366 |
367 | public String getRom() {
368 | return rom;
369 | }
370 |
371 | public void setRom(String rom) {
372 | this.rom = rom;
373 | }
374 |
375 | public String getRom_version() {
376 | return rom_version;
377 | }
378 |
379 | public void setRom_version(String rom_version) {
380 | this.rom_version = rom_version;
381 | }
382 |
383 | public String getSig_hash() {
384 | return sig_hash;
385 | }
386 |
387 | public void setSig_hash(String sig_hash) {
388 | this.sig_hash = sig_hash;
389 | }
390 |
391 | public String getDevice_id() {
392 | return device_id;
393 | }
394 |
395 | public void setDevice_id(String device_id) {
396 | this.device_id = device_id;
397 | }
398 |
399 | public String getOpenudid() {
400 | return openudid;
401 | }
402 |
403 | public void setOpenudid(String openudid) {
404 | this.openudid = openudid;
405 | }
406 |
407 | public String getUdid() {
408 | return udid;
409 | }
410 |
411 | public void setUdid(String udid) {
412 | this.udid = udid;
413 | }
414 |
415 | public String getClientudid() {
416 | return clientudid;
417 | }
418 |
419 | public void setClientudid(String clientudid) {
420 | this.clientudid = clientudid;
421 | }
422 |
423 | public String getSerial_number() {
424 | return serial_number;
425 | }
426 |
427 | public void setSerial_number(String serial_number) {
428 | this.serial_number = serial_number;
429 | }
430 |
431 | public String getRegion() {
432 | return region;
433 | }
434 |
435 | public void setRegion(String region) {
436 | this.region = region;
437 | }
438 |
439 | public String getTz_name() {
440 | return tz_name;
441 | }
442 |
443 | public void setTz_name(String tz_name) {
444 | this.tz_name = tz_name;
445 | }
446 |
447 | public int getTz_offset() {
448 | return tz_offset;
449 | }
450 |
451 | public void setTz_offset(int tz_offset) {
452 | this.tz_offset = tz_offset;
453 | }
454 |
455 | public String getSim_region() {
456 | return sim_region;
457 | }
458 |
459 | public void setSim_region(String sim_region) {
460 | this.sim_region = sim_region;
461 | }
462 |
463 | public List getSim_serial_number() {
464 | return sim_serial_number;
465 | }
466 |
467 | public void setSim_serial_number(List sim_serial_number) {
468 | this.sim_serial_number = sim_serial_number;
469 | }
470 |
471 | public static class SimSerialNumberBean {
472 | /**
473 | * sim_serial_number : 89014103211118510720
474 | */
475 |
476 | private String sim_serial_number;
477 |
478 | public String getSim_serial_number() {
479 | return sim_serial_number;
480 | }
481 |
482 | public void setSim_serial_number(String sim_serial_number) {
483 | this.sim_serial_number = sim_serial_number;
484 | }
485 | }
486 | }
487 | }
488 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yf/douyintool/controller/RequestController.java:
--------------------------------------------------------------------------------
1 | package com.yf.douyintool.controller;
2 |
3 | import android.text.TextUtils;
4 | import android.util.Log;
5 |
6 | import com.alibaba.fastjson.JSONObject;
7 | import com.bytedance.frameworks.core.encrypt.TTEncryptUtils;
8 | import com.google.gson.Gson;
9 | import com.ss.sys.ces.a;
10 | import com.yanzhenjie.andserver.annotation.GetMapping;
11 | import com.yanzhenjie.andserver.annotation.PostMapping;
12 | import com.yanzhenjie.andserver.annotation.RequestBody;
13 | import com.yanzhenjie.andserver.annotation.RestController;
14 | import com.yanzhenjie.andserver.util.MediaType;
15 | import com.yf.douyintool.DeviceUtil;
16 | import com.yf.douyintool.bean.DeviceBean;
17 |
18 | import java.io.ByteArrayOutputStream;
19 | import java.io.IOException;
20 | import java.security.MessageDigest;
21 | import java.security.NoSuchAlgorithmException;
22 | import java.util.ArrayList;
23 | import java.util.Calendar;
24 | import java.util.HashMap;
25 | import java.util.List;
26 | import java.util.Map;
27 | import java.util.TimeZone;
28 | import java.util.UUID;
29 | import java.util.concurrent.TimeUnit;
30 | import java.util.zip.GZIPOutputStream;
31 |
32 | import okhttp3.ConnectionPool;
33 | import okhttp3.FormBody;
34 | import okhttp3.Interceptor;
35 | import okhttp3.OkHttpClient;
36 | import okhttp3.Protocol;
37 | import okhttp3.Request;
38 | import okhttp3.Response;
39 |
40 | /***
41 | * http://www.louislivi.com/archives/147
42 | * 结合AndServer,实现抖音X-Gorgon算法,设备id生成接口
43 | */
44 | @RestController
45 | public class RequestController {
46 | private static final String NULL_MD5_STRING = "00000000000000000000000000000000";
47 | public String sessionid = "";
48 | public String xtttoken = "";
49 |
50 | @PostMapping(value = "/request", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
51 | public String test(@RequestBody String requestBodyString) {
52 | JSONObject jsonObject = new JSONObject();
53 | JSONObject requestBody = JSONObject.parseObject(requestBodyString);
54 | String ck = requestBody.getString("cookie");
55 | String url = requestBody.getString("url");
56 | String postData = requestBody.getString("postData");
57 | if (ck == null || url == null) {
58 | jsonObject.put("status_code", 0);
59 | jsonObject.put("status_msg", "缺少参数!");
60 | return jsonObject.toJSONString();
61 | }
62 | if (url.contains("douplus/order/create")) {
63 | // 如果是投放订单每次生产不同的DeviceData
64 | JSONObject deviceData = getNewDeviceData();
65 | url = replaceUrlParam(url, "device_id", deviceData.getString("device_id"));
66 | url = replaceUrlParam(url, "iid", deviceData.getString("install_id"));
67 | // Log.i("orderCreate", "替换device_id成功!");
68 | }
69 | // String _ricket = System.currentTimeMillis() + "";
70 | long time = System.currentTimeMillis() / 1000;
71 | String p = url.substring(url.indexOf("?") + 1, url.length());
72 | boolean isPost = postData != null && !postData.equals("");
73 | String result;
74 | if (isPost) {
75 | FormBody.Builder formBody = new FormBody.Builder();
76 | String STUB = encryption(postData);
77 | Map map = new HashMap<>();
78 | String[] ks = postData.split("&");
79 | for (int i = 0; i < ks.length; i++) {
80 | String[] ur = ks[i].split("=");
81 | if (ur.length == 1) {
82 | map.put(ur[0], "");
83 | } else {
84 | map.put(ur[0], ur[1]);
85 |
86 | }
87 | }
88 | for (Map.Entry m : map.entrySet()) {
89 | formBody.add(m.getKey(), m.getValue());
90 | }
91 | String s = getXGon(p, STUB, ck, sessionid);
92 | String XGon = ByteToStr(a.leviathan((int) time, StrToByte(s)));
93 | result = doPostNet(url, formBody.build(), time, XGon, STUB, ck);
94 | } else {
95 | String s = getXGon(p, "", ck, sessionid);
96 | String XGon = ByteToStr(a.leviathan((int) time, StrToByte(s)));
97 | result = doGetNet(url, time, XGon, ck);
98 | }
99 | jsonObject = JSONObject.parseObject(result);
100 | if (jsonObject == null) {
101 | jsonObject = new JSONObject();
102 | jsonObject.put("status_code", -2);
103 | jsonObject.put("status_msg", "未知错误!");
104 | }
105 | return jsonObject.toJSONString();
106 | }
107 |
108 |
109 | @GetMapping(value = "/getDeviceData", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
110 | public String getDeviceData() {
111 | return getNewDeviceData().toJSONString();
112 | }
113 |
114 | @GetMapping(value = "/getQuery", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
115 | public String getQuery() {
116 | String uuid = DeviceUtil.getRanInt(15); //设备id
117 | String openudid = DeviceUtil.getRanInt(16); //android_id
118 | String _rticket = System.currentTimeMillis() + ""; //获取当前时间
119 | String url = "https://log.snssdk.com/service/2/device_register/?mcc_mnc=46000&ac=wifi&channel=aweGW&aid=1128&app_name=aweme&version_code=550&version_name=5.5.0&device_platform=android&ssmix=a&device_type=SM-G925F&device_brand=samsung&language=zh&os_api=22&os_version=5.1.1&uuid=" + uuid + "&openudid=" + openudid + "&manifest_version_code=550&resolution=720*1280&dpi=192&update_version_code=5502&_rticket=" + _rticket + "&tt_data=a&config_retry=b";
120 | String stb = url.substring(url.indexOf("?") + 1, url.length());
121 | String STUB = encryption(stb).toUpperCase();
122 | String ck = "odin_tt=9c1e0ebae55f3c2d9f71ab2aadce63126022e8960819bace07d441d977ad60eff6312161f546ebfe747528d03d53a161728250938c4287a588d86aa599c284b3; qh[360]=1; install_id=66715314288; ttreq=1$0b4589453328800ed93e002538883aa52da3e1d5";
123 | int time = (int) (System.currentTimeMillis() / 1000);
124 | String s = getXGon(url, STUB, ck, null);
125 | String XGon = ByteToStr(a.leviathan(time, StrToByte(s)));
126 | String device = getDevice(openudid, uuid);
127 | JSONObject deviceJson = JSONObject.parseObject(device);
128 | final okhttp3.RequestBody formBody = okhttp3.RequestBody.create(okhttp3.MediaType.parse("application/octet-stream;tt-data=a"), this.toGzip(device));
129 | String result = doPostNet(url, formBody, time, XGon, "", ck);
130 | JSONObject deviceResult = JSONObject.parseObject(result);
131 | JSONObject jsonObject = new JSONObject();
132 | jsonObject.put("status_code", 0);
133 | JSONObject headerJson = deviceJson.getJSONObject("header");
134 | String data = String.format("os_api=22&device_type=SM-G925F&ssmix=a&manifest_version_code=911&dpi=320&uuid=%s&app_name=aweme&version_name=9.1.1&ts=%d&app_type=normal&ac=wifi&update_version_code=9104&channel=huawei_1&_rticket=%s&device_platform=android&iid=%s&version_code=911&cdid=%s&openudid=%s&device_id=%s&resolution=720*1280&os_version=5.1.1&language=zh&device_brand=OPPO&aid=1128&mcc_mnc=46007",
135 | uuid, time, _rticket, deviceResult.getString("install_id_str"), headerJson.getString("clientudid"), openudid, deviceResult.getString("device_id_str"));
136 | jsonObject.put("data", data);
137 | Log.i("data", data);
138 | return jsonObject.toJSONString();
139 | }
140 |
141 | public JSONObject getNewDeviceData() {
142 | String uuid = DeviceUtil.getRanInt(15); //设备id
143 | String openudid = DeviceUtil.getRanInt(16); //android_id
144 | String _rticket = System.currentTimeMillis() + ""; //获取当前时间
145 | String url = "https://log.snssdk.com/service/2/device_register/?mcc_mnc=46000&ac=wifi&channel=aweGW&aid=1128&app_name=aweme&version_code=550&version_name=5.5.0&device_platform=android&ssmix=a&device_type=SM-G925F&device_brand=samsung&language=zh&os_api=22&os_version=5.1.1&uuid=" + uuid + "&openudid=" + openudid + "&manifest_version_code=550&resolution=720*1280&dpi=192&update_version_code=5502&_rticket=" + _rticket + "&tt_data=a&config_retry=b";
146 | String stb = url.substring(url.indexOf("?") + 1, url.length());
147 | String STUB = encryption(stb).toUpperCase();
148 | String ck = "odin_tt=9c1e0ebae55f3c2d9f71ab2a12ce63c46022e8912819bace07d441d977ad60eff6301161f546ebfe747528d03d53a161728250938c4287a588d86aa599c284b3; qh[360]=1; install_id=66715314288; ttreq=1$0b4589453328800ed93e002538883aa52da3e1d5";
149 | int time = (int) (System.currentTimeMillis() / 1000);
150 | String s = getXGon(url, STUB, ck, null);
151 | String XGon = ByteToStr(a.leviathan(time, StrToByte(s)));
152 | final okhttp3.RequestBody formBody = okhttp3.RequestBody.create(okhttp3.MediaType.parse("application/octet-stream;tt-data=a"), this.toGzip(this.getDevice(openudid, uuid)));
153 | String result = doPostNet(url, formBody, time, XGon, "", ck);
154 | JSONObject jsonObject = JSONObject.parseObject(result);
155 | if (jsonObject == null) {
156 | jsonObject = new JSONObject();
157 | jsonObject.put("status_code", -2);
158 | jsonObject.put("status_msg", "未知错误!");
159 | }
160 | return jsonObject;
161 | }
162 |
163 | public String getDevice(String openudid, String udid) {
164 | //DeviceBean
165 | String Serial_number = DeviceUtil.getRanInt(8);
166 | DeviceBean deviceBean = new DeviceBean();
167 | deviceBean.set_gen_time(System.currentTimeMillis() + "");
168 | deviceBean.setMagic_tag("ss_app_log");
169 | //HeaderBean
170 | DeviceBean.HeaderBean headerBean = new DeviceBean.HeaderBean();
171 | headerBean.setDisplay_name("抖音短视频");
172 | headerBean.setUpdate_version_code(5502);
173 | headerBean.setManifest_version_code(550);
174 | headerBean.setAid(1128);
175 | headerBean.setChannel("aweGW");
176 | headerBean.setAppkey("59bfa27c67e59e7d920028d9"); //appkey
177 | headerBean.setPackageX("com.ss.android.ugc.aweme");
178 | headerBean.setApp_version("5.5.0");
179 | headerBean.setVersion_code(550);
180 | headerBean.setSdk_version("2.5.5.8");
181 | headerBean.setOs("Android");
182 | headerBean.setOs_version("5.1.1");
183 | headerBean.setOs_api(22);
184 | headerBean.setDevice_model("SM-G925F");
185 | headerBean.setDevice_brand("samsung");
186 | headerBean.setDevice_manufacturer("samsung");
187 | headerBean.setCpu_abi("armeabi-v7a");
188 | headerBean.setBuild_serial(Serial_number); ////android.os.Build.SERIAL
189 | headerBean.setRelease_build("2132ca7_20190321"); // release版本
190 | headerBean.setDensity_dpi(192);
191 | headerBean.setDisplay_density("mdpi");
192 | headerBean.setResolution("1280x720");
193 | headerBean.setLanguage("zh");
194 | headerBean.setMc(DeviceUtil.getMac()); //mac 地址
195 | headerBean.setTimezone(8);
196 | headerBean.setAccess("wifi");
197 | headerBean.setNot_request_sender(0);
198 | headerBean.setCarrier("China Mobile GSM");
199 | headerBean.setMcc_mnc("46000");
200 | headerBean.setRom("eng.se.infra.20181117.120021"); //Build.VERSION.INCREMENTAL
201 | headerBean.setRom_version("samsung-user 5.1.1 20171130.276299 release-keys"); //Build.DISPLAY
202 | headerBean.setSig_hash("aea615ab910015038f73c47e45d21466"); //app md5加密 固定
203 | headerBean.setDevice_id(""); //获取之后的设备id
204 | headerBean.setOpenudid(openudid); //openudid
205 | headerBean.setUdid(udid); //真机的imei
206 | headerBean.setClientudid(UUID.randomUUID().toString()); //uuid
207 | headerBean.setSerial_number(Serial_number); //android.os.Build.SERIAL
208 | headerBean.setRegion("CN");
209 | headerBean.setTz_name("Asia\\/Shanghai"); //timeZone.getID();
210 | headerBean.setTimezone(28800); //String.valueOf(timeZone.getOffset(System.currentTimeMillis()) / 1000)
211 | headerBean.setSim_region("cn");
212 | List sim_serial_number = new ArrayList<>();
213 | DeviceBean.HeaderBean.SimSerialNumberBean bean = new DeviceBean.HeaderBean.SimSerialNumberBean();
214 | bean.setSim_serial_number(DeviceUtil.getRanInt(20));
215 | sim_serial_number.add(bean);
216 | headerBean.setSim_serial_number(sim_serial_number);
217 | // Log.i("deviceHeader", headerBean.toString());
218 | deviceBean.setHeader(headerBean);
219 | TimeZone timeZone = Calendar.getInstance().getTimeZone();
220 | timeZone.getID();
221 | //r
222 | Gson gson = new Gson();
223 | return gson.toJson(deviceBean);
224 | }
225 |
226 | public byte[] toGzip(String r) {
227 | try {
228 | byte[] bArr2 = r.getBytes("UTF-8");
229 |
230 | ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(8192);
231 | GZIPOutputStream gZIPOutputStream = new GZIPOutputStream(byteArrayOutputStream);
232 | gZIPOutputStream.write(bArr2);
233 | gZIPOutputStream.close();
234 | bArr2 = byteArrayOutputStream.toByteArray();
235 | bArr2 = TTEncryptUtils.a(bArr2, bArr2.length);
236 | return bArr2;
237 | } catch (Exception e) {
238 | e.printStackTrace();
239 | }
240 | return null;
241 | }
242 |
243 |
244 | public class RetryIntercepter implements Interceptor {
245 |
246 | public int maxRetry;//最大重试次数
247 | private int retryNum = 0;//假如设置为3次重试的话,则最大可能请求4次(默认1次+3次重试)
248 |
249 | public RetryIntercepter(int maxRetry) {
250 | this.maxRetry = maxRetry;
251 | }
252 |
253 | @Override
254 | public Response intercept(Chain chain) throws IOException {
255 | Request request = chain.request();
256 | // System.out.println("retryNum=" + retryNum);
257 | boolean isSuccessful;
258 | Response response = null;
259 | try {
260 | response = chain.proceed(request);
261 | isSuccessful = response.isSuccessful();
262 | } catch (Exception e) {
263 | isSuccessful = false;
264 | }
265 | while (!isSuccessful && retryNum < maxRetry) {
266 | retryNum++;
267 | System.out.println("retryNum=" + retryNum);
268 | response = chain.proceed(request);
269 | }
270 |
271 | return response;
272 | }
273 | }
274 |
275 | public String doGetNet(String url, long time, String XGon, String ck) {
276 | // Log.i("XGon", XGon);
277 | // Log.i("time", String.valueOf(time));
278 | Request request = new Request.Builder()
279 | .url(url)
280 | .get()
281 | .addHeader("X-SS-REQ-TICKET", System.currentTimeMillis() + "")
282 | .addHeader("X-Khronos", time + "")
283 | .addHeader("X-Gorgon", XGon)
284 | .addHeader("sdk-version", "1")
285 | .addHeader("Cookie", ck)
286 | .addHeader("X-Pods", "")
287 | .addHeader("Connection", "Keep-Alive")
288 | .addHeader("User-Agent", "okhttp/3.10.0.1")
289 | .addHeader("x-tt-token", xtttoken)
290 | .addHeader("Accept-Encoding", "identity")
291 | .addHeader("Connection", "Upgrade, HTTP2-Settings")
292 | .addHeader("Upgrade", "h2c")
293 | .build();
294 | List protocols = new ArrayList<>();
295 | // protocols.add(Protocol.H2_PRIOR_KNOWLEDGE);
296 | protocols.add(Protocol.HTTP_2);
297 | protocols.add(Protocol.HTTP_1_1);
298 | OkHttpClient okHttpClient = new OkHttpClient.Builder()
299 | .retryOnConnectionFailure(true)
300 | .protocols(protocols)
301 | .connectionPool(new ConnectionPool(10, 30, TimeUnit.SECONDS))
302 | .addInterceptor(new RetryIntercepter(3))
303 | .build();
304 | Response response = null;
305 | try {
306 | response = okHttpClient.newCall(request).execute();
307 | } catch (IOException e) {
308 | e.printStackTrace();
309 | }
310 | //响应成功
311 | if (response.isSuccessful()) {
312 | try {
313 | return response.body().string();
314 | } catch (IOException e) {
315 | e.printStackTrace();
316 | }
317 | }
318 | JSONObject jsonObject = new JSONObject();
319 | jsonObject.put("status_code", -2);
320 | jsonObject.put("status_msg", "未知错误!");
321 | return jsonObject.toJSONString();
322 | }
323 |
324 | public String doPostNet(String url, okhttp3.RequestBody requestBody, long time, String XGon, String stub, String ck) {
325 | Request request = new Request.Builder()
326 | .url(url)
327 | .post(requestBody)
328 | .addHeader("X-SS-STUB", stub)
329 | .addHeader("X-SS-REQ-TICKET", System.currentTimeMillis() + "")
330 | .addHeader("X-Khronos", time + "")
331 | .addHeader("X-Gorgon", XGon)
332 | .addHeader("sdk-version", "1")
333 | .addHeader("Cookie", ck)
334 | .addHeader("X-Pods", "")
335 | .addHeader("Connection", "Keep-Alive")
336 | .addHeader("User-Agent", "okhttp/3.10.0.1")
337 | .addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
338 | .addHeader("x-tt-token", xtttoken) //登录成功头部返回的数据
339 | .build();
340 | List protocols = new ArrayList<>();
341 | // protocols.add(Protocol.H2_PRIOR_KNOWLEDGE);
342 | protocols.add(Protocol.HTTP_2);
343 | protocols.add(Protocol.HTTP_1_1);
344 | OkHttpClient okHttpClient = new OkHttpClient.Builder()
345 | .retryOnConnectionFailure(true)
346 | .protocols(protocols)
347 | .connectionPool(new ConnectionPool(10, 30, TimeUnit.SECONDS))
348 | .addInterceptor(new RetryIntercepter(3))
349 | .build();
350 | Response response = null;
351 | try {
352 | response = okHttpClient.newCall(request).execute();
353 | } catch (IOException e) {
354 | e.printStackTrace();
355 | }
356 | //响应成功
357 | if (response.isSuccessful()) {
358 | try {
359 | return response.body().string();
360 | } catch (IOException e) {
361 | e.printStackTrace();
362 | }
363 | }
364 | JSONObject jsonObject = new JSONObject();
365 | jsonObject.put("status_code", -2);
366 | jsonObject.put("status_msg", "未知错误!");
367 | return jsonObject.toJSONString();
368 | }
369 |
370 | public static byte[] StrToByte(String str) {
371 | String str2 = str;
372 | Object[] objArr = new Object[1];
373 | int i = 0;
374 | objArr[0] = str2;
375 |
376 | int length = str.length();
377 | byte[] bArr = new byte[(length / 2)];
378 | while (i < length) {
379 | bArr[i / 2] = (byte) ((Character.digit(str2.charAt(i), 16) << 4) + Character.digit(str2.charAt(i + 1), 16));
380 | i += 2;
381 | }
382 | return bArr;
383 | }
384 |
385 | public static String ByteToStr(byte[] bArr) {
386 |
387 | int i = 0;
388 |
389 | char[] toCharArray = "0123456789abcdef".toCharArray();
390 | char[] cArr = new char[(bArr.length * 2)];
391 | while (i < bArr.length) {
392 | int i2 = bArr[i] & 255;
393 | int i3 = i * 2;
394 | cArr[i3] = toCharArray[i2 >>> 4];
395 | cArr[i3 + 1] = toCharArray[i2 & 15];
396 | i++;
397 | }
398 | return new String(cArr);
399 |
400 | }
401 |
402 | public String encryption(String str) {
403 | String re_md5 = null;
404 | try {
405 | MessageDigest md = MessageDigest.getInstance("MD5");
406 | md.update(str.getBytes());
407 | byte b[] = md.digest();
408 |
409 | int i;
410 |
411 | StringBuffer buf = new StringBuffer("");
412 | for (int offset = 0; offset < b.length; offset++) {
413 | i = b[offset];
414 | if (i < 0)
415 | i += 256;
416 | if (i < 16)
417 | buf.append("0");
418 | buf.append(Integer.toHexString(i));
419 | }
420 |
421 | re_md5 = buf.toString();
422 |
423 | } catch (NoSuchAlgorithmException e) {
424 | e.printStackTrace();
425 | }
426 | return re_md5.toUpperCase();
427 | }
428 |
429 | public String getXGon(String url, String stub, String ck, String sessionid) {
430 | StringBuilder sb = new StringBuilder();
431 | if (TextUtils.isEmpty(url)) {
432 | sb.append(NULL_MD5_STRING);
433 | } else {
434 | sb.append(encryption(url).toLowerCase());
435 | }
436 |
437 | if (TextUtils.isEmpty(stub)) {
438 | sb.append(NULL_MD5_STRING);
439 | } else {
440 | sb.append(stub);
441 | }
442 |
443 | if (TextUtils.isEmpty(ck)) {
444 | sb.append(NULL_MD5_STRING);
445 | } else {
446 | sb.append(encryption(ck).toLowerCase());
447 | }
448 |
449 | if (TextUtils.isEmpty(sessionid)) {
450 | sb.append(NULL_MD5_STRING);
451 | } else {
452 | sb.append(encryption(sessionid).toLowerCase());
453 | // sb.append(sessionid);
454 | }
455 | return sb.toString();
456 | }
457 |
458 | /**
459 | * 替换url中的参数
460 | *
461 | * @param url
462 | * @param name
463 | * @param value
464 | * @return
465 | */
466 | public static String replaceUrlParam(String url, String name, String value) {
467 | int index = url.indexOf(name + "=");
468 | if (index != -1) {
469 | StringBuilder sb = new StringBuilder();
470 | sb.append(url.substring(0, index)).append(name).append("=").append(value);
471 | int idx = url.indexOf("&", index);
472 | if (idx != -1) {
473 | sb.append(url.substring(idx));
474 | }
475 | url = sb.toString();
476 | }
477 | return url;
478 | }
479 | }
480 |
--------------------------------------------------------------------------------
/app/src/main/jni/Android.mk:
--------------------------------------------------------------------------------
1 | LOCAL_PATH := $(call my-dir)
2 |
3 | include $(CLEAR_VARS)
4 | LOCAL_MODULE := substrate
5 | LOCAL_SRC_FILES := libsubstrate.so
6 | include $(PREBUILT_SHARED_LIBRARY)
7 |
8 | include $(CLEAR_VARS)
9 | LOCAL_MODULE := substrate-dvm
10 | LOCAL_SRC_FILES := libsubstrate-dvm.so
11 | include $(PREBUILT_SHARED_LIBRARY)
12 |
13 | include $(CLEAR_VARS)
14 | LOCAL_MODULE := CydiaHook.cy
15 | LOCAL_SRC_FILES := CydiaNativeHook.cpp
16 | LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog
17 | LOCAL_LDLIBS += -L$(LOCAL_PATH) -lsubstrate-dvm -lsubstrate
18 | include $(BUILD_SHARED_LIBRARY)
--------------------------------------------------------------------------------
/app/src/main/jni/CydiaNativeHook.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Administrator on 2019/4/2.
3 | //
4 | #include
5 | #include "substrate.h"
6 | #include
7 | #include
8 | #include
9 |
10 | #define TAG "CydiaHook"
11 |
12 | #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
13 |
14 | MSConfig(MSFilterLibrary, "/system/lib/arm/libdvm.so");
15 |
16 | void * get_base_of_lib_from_maps(const char *SoName)
17 | {
18 | void * imagehandle = dlopen(SoName, RTLD_LOCAL | RTLD_LAZY);
19 | if (SoName == NULL)
20 | return NULL;
21 | if (imagehandle == NULL){
22 | return NULL;
23 | }
24 | uintptr_t * irc = NULL;
25 | FILE *f = NULL;
26 | char line[200] = {0};
27 | char *state = NULL;
28 | char *tok = NULL;
29 | char * baseAddr = NULL;
30 | if ((f = fopen("/proc/self/maps", "r")) == NULL)
31 | return NULL;
32 | while (fgets(line, 199, f) != NULL)
33 | {
34 | tok = strtok_r(line, "-", &state);
35 | baseAddr = tok;
36 | tok = strtok_r(NULL, "\t ", &state);
37 | tok = strtok_r(NULL, "\t ", &state); // "r-xp" field
38 | tok = strtok_r(NULL, "\t ", &state); // "0000000" field
39 | tok = strtok_r(NULL, "\t ", &state); // "01:02" field
40 | tok = strtok_r(NULL, "\t ", &state); // "133224" field
41 | tok = strtok_r(NULL, "\t ", &state); // path field
42 |
43 | if (tok != NULL) {
44 | int i;
45 | for (i = (int)strlen(tok)-1; i >= 0; --i) {
46 | if (!(tok[i] == ' ' || tok[i] == '\r' || tok[i] == '\n' || tok[i] == '\t'))
47 | break;
48 | tok[i] = 0;
49 | }
50 | {
51 | size_t toklen = strlen(tok);
52 | size_t solen = strlen(SoName);
53 | if (toklen > 0) {
54 | if (toklen >= solen && strcmp(tok + (toklen - solen), SoName) == 0) {
55 | fclose(f);
56 | return (uintptr_t*)strtoll(baseAddr,NULL,16);
57 | }
58 | }
59 | }
60 | }
61 | }
62 | fclose(f);
63 | return NULL;
64 | }
65 |
66 | jint (*old_RegiserNatives)(JNIEnv *env, jclass clazz, const JNINativeMethod* methods,jint nMethods) = NULL;
67 | jint new_RegiserNatives(JNIEnv *env, jclass clazz, const JNINativeMethod* methods,jint nMethods){
68 | //传入你想Hookd的So文件的绝对地址
69 | void * Soaddress = get_base_of_lib_from_maps("/data/data-lib/com.yf.douyintool/libcms.so");
70 | if (Soaddress != (void *) env){
71 | //去掉你不想要的,如果有多个就自己修改把 LOGD("exclude So address %p",Soaddress);
72 | return old_RegiserNatives(env,clazz,methods,nMethods);
73 | }
74 | LOGD("------------------------------------------------");
75 | LOGD("env:%p,class:%p,methods:%p,methods_num:%d",env,clazz,methods,nMethods);
76 | LOGD("------------------------------------------------");
77 | for (int i = 0;i < nMethods;i++){
78 | LOGD("name:%s,sign:%s,address:%p",methods[i].name,methods[i].signature,methods[i].fnPtr);
79 | }
80 | LOGD("------------------------------------------------");
81 | return old_RegiserNatives(env,clazz,methods,nMethods);
82 | }
83 |
84 | void * Hook_Symbol(const char * LibraryName, const char * SymbolName){
85 | void * handle = dlopen(LibraryName,RTLD_GLOBAL | RTLD_NOW);
86 | if (handle != NULL){
87 | LOGD("Hook so %s success",LibraryName);
88 | void * symbol = dlsym(handle,SymbolName);
89 | if (symbol != NULL){
90 | LOGD("Hook function %s success",SymbolName);
91 | return symbol;
92 | } else{
93 | LOGD("error find functicon:%s",SymbolName);
94 | LOGD("dl error:%s",dlerror());
95 | return NULL;
96 | }
97 | } else{
98 | LOGD("error find so : %s",LibraryName);
99 | return NULL;
100 | }
101 | }
102 |
103 | MSInitialize{
104 | LOGD("CydiaHook MSinitialize.");
105 | MSImageRef image = MSGetImageByName("/system/lib/arm/libdvm.so");
106 | if (image != NULL){
107 | LOGD("Hook so libdvm.so success");
108 | void * function_address = MSFindSymbol(image,"_Z12dexFileParsePKhji");
109 | if (function_address != NULL){
110 | LOGD("get _Z12dexFileParsePKhji address success");
111 | LOGD("begin hook funvtion sub_668c4");
112 | void * RegiserNatives = (void *)((uint32_t)function_address - 0x43f0); //function_address:lib_base+0xc4990 差值:43f0
113 | LOGD("RegiserNatives address:%p",RegiserNatives);
114 | MSHookFunction(RegiserNatives,(void*)&new_RegiserNatives, (void **)&old_RegiserNatives);
115 | } else{
116 | LOGD("error find functicon _Z12dexFileParsePKhji");
117 | }
118 | } else{
119 | LOGD("error find so : libdvm.so");
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/app/src/main/jni/armeabi/libsubstrate-dvm.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/src/main/jni/armeabi/libsubstrate-dvm.so
--------------------------------------------------------------------------------
/app/src/main/jni/armeabi/libsubstrate.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/src/main/jni/armeabi/libsubstrate.so
--------------------------------------------------------------------------------
/app/src/main/jni/libsubstrate-dvm.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/src/main/jni/libsubstrate-dvm.so
--------------------------------------------------------------------------------
/app/src/main/jni/libsubstrate.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/src/main/jni/libsubstrate.so
--------------------------------------------------------------------------------
/app/src/main/jni/substrate.h:
--------------------------------------------------------------------------------
1 | /* Cydia Substrate - Powerful Code Insertion Platform
2 | * Copyright (C) 2008-2013 Jay Freeman (saurik)
3 | */
4 |
5 | /* GNU Lesser General Public License, Version 3 {{{ */
6 | /*
7 | * Substrate is free software: you can redistribute it and/or modify it under
8 | * the terms of the GNU Lesser General Public License as published by the
9 | * Free Software Foundation, either version 3 of the License, or (at your
10 | * option) any later version.
11 | *
12 | * Substrate is distributed in the hope that it will be useful, but WITHOUT
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 | * License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with Substrate. If not, see .
19 | **/
20 | /* }}} */
21 |
22 | #ifndef SUBSTRATE_H_
23 | #define SUBSTRATE_H_
24 |
25 | #ifdef __APPLE__
26 | #ifdef __cplusplus
27 | extern "C" {
28 | #endif
29 | #include
30 | #ifdef __cplusplus
31 | }
32 | #endif
33 |
34 | #include
35 | #include
36 | #endif
37 |
38 | #include
39 | #include
40 |
41 | #define _finline \
42 | inline __attribute__((__always_inline__))
43 | #define _disused \
44 | __attribute__((__unused__))
45 |
46 | #ifdef __cplusplus
47 | #define _default(value) = value
48 | #else
49 | #define _default(value)
50 | #endif
51 |
52 | #ifdef __cplusplus
53 | extern "C" {
54 | #endif
55 |
56 | bool MSHookProcess(pid_t pid, const char *library);
57 |
58 | typedef const void *MSImageRef;
59 |
60 | MSImageRef MSGetImageByName(const char *file);
61 | void *MSFindSymbol(MSImageRef image, const char *name);
62 |
63 | void MSHookFunction(void *symbol, void *replace, void **result);
64 |
65 | #ifdef __APPLE__
66 | #ifdef __arm__
67 | __attribute__((__deprecated__))
68 | IMP MSHookMessage(Class _class, SEL sel, IMP imp, const char *prefix _default(NULL));
69 | #endif
70 | void MSHookMessageEx(Class _class, SEL sel, IMP imp, IMP *result);
71 | #endif
72 |
73 | #ifdef __ANDROID__
74 | #include
75 | void MSJavaHookClassLoad(JNIEnv *jni, const char *name, void (*callback)(JNIEnv *, jclass, void *), void *data _default(NULL));
76 | void MSJavaHookMethod(JNIEnv *jni, jclass _class, jmethodID methodID, void *function, void **result);
77 | void MSJavaBlessClassLoader(JNIEnv *jni, jobject loader);
78 |
79 | typedef struct MSJavaObjectKey_ *MSJavaObjectKey;
80 | MSJavaObjectKey MSJavaCreateObjectKey();
81 | void MSJavaReleaseObjectKey(MSJavaObjectKey key);
82 | void *MSJavaGetObjectKey(JNIEnv *jni, jobject object, MSJavaObjectKey key);
83 | void MSJavaSetObjectKey(JNIEnv *jni, jobject object, MSJavaObjectKey key, void *value, void (*clean)(void *, JNIEnv *, void *) _default(NULL), void *data _default(NULL));
84 | #endif
85 |
86 | #ifdef __cplusplus
87 | }
88 | #endif
89 |
90 | #ifdef __cplusplus
91 |
92 | #ifdef __APPLE__
93 |
94 | namespace etl {
95 |
96 | template
97 | struct Case {
98 | static char value[Case_ + 1];
99 | };
100 |
101 | typedef Case Yes;
102 | typedef Case No;
103 |
104 | namespace be {
105 | template
106 | static Yes CheckClass_(void (Checked_::*)());
107 |
108 | template
109 | static No CheckClass_(...);
110 | }
111 |
112 | template
113 | struct IsClass {
114 | void gcc32();
115 |
116 | static const bool value = (sizeof(be::CheckClass_(0).value) == sizeof(Yes::value));
117 | };
118 |
119 | }
120 |
121 | #ifdef __arm__
122 | template
123 | __attribute__((__deprecated__))
124 | static inline Type_ *MSHookMessage(Class _class, SEL sel, Type_ *imp, const char *prefix = NULL) {
125 | return reinterpret_cast(MSHookMessage(_class, sel, reinterpret_cast(imp), prefix));
126 | }
127 | #endif
128 |
129 | template
130 | static inline void MSHookMessage(Class _class, SEL sel, Type_ *imp, Type_ **result) {
131 | return MSHookMessageEx(_class, sel, reinterpret_cast(imp), reinterpret_cast(result));
132 | }
133 |
134 | template
135 | static inline Type_ &MSHookIvar(id self, const char *name) {
136 | Ivar ivar(class_getInstanceVariable(object_getClass(self), name));
137 | void *pointer(ivar == NULL ? NULL : reinterpret_cast(self) + ivar_getOffset(ivar));
138 | return *reinterpret_cast(pointer);
139 | }
140 |
141 | #define MSAddMessage0(_class, type, arg0) \
142 | class_addMethod($ ## _class, @selector(arg0), (IMP) &$ ## _class ## $ ## arg0, type);
143 | #define MSAddMessage1(_class, type, arg0) \
144 | class_addMethod($ ## _class, @selector(arg0:), (IMP) &$ ## _class ## $ ## arg0 ## $, type);
145 | #define MSAddMessage2(_class, type, arg0, arg1) \
146 | class_addMethod($ ## _class, @selector(arg0:arg1:), (IMP) &$ ## _class ## $ ## arg0 ## $ ## arg1 ## $, type);
147 | #define MSAddMessage3(_class, type, arg0, arg1, arg2) \
148 | class_addMethod($ ## _class, @selector(arg0:arg1:arg2:), (IMP) &$ ## _class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $, type);
149 | #define MSAddMessage4(_class, type, arg0, arg1, arg2, arg3) \
150 | class_addMethod($ ## _class, @selector(arg0:arg1:arg2:arg3:), (IMP) &$ ## _class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $, type);
151 | #define MSAddMessage5(_class, type, arg0, arg1, arg2, arg3, arg4) \
152 | class_addMethod($ ## _class, @selector(arg0:arg1:arg2:arg3:arg4:), (IMP) &$ ## _class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $ ## arg4 ## $, type);
153 | #define MSAddMessage6(_class, type, arg0, arg1, arg2, arg3, arg4, arg5) \
154 | class_addMethod($ ## _class, @selector(arg0:arg1:arg2:arg3:arg4:arg5:), (IMP) &$ ## _class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $ ## arg4 ## $ ## arg5 ## $, type);
155 | #define MSAddMessage7(_class, type, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
156 | class_addMethod($ ## _class, @selector(arg0:arg1:arg2:arg3:arg4:arg5:arg6:), (IMP) &$ ## _class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $ ## arg4 ## $ ## arg5 ## $ $$ arg6 ## $, type);
157 | #define MSAddMessage8(_class, type, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
158 | class_addMethod($ ## _class, @selector(arg0:arg1:arg2:arg3:arg4:arg5:arg6:arg7:), (IMP) &$ ## _class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $ ## arg4 ## $ ## arg5 ## $ $$ arg6 ## $ ## arg7 ## $, type);
159 |
160 | #define MSHookMessage0(_class, arg0) \
161 | MSHookMessage($ ## _class, @selector(arg0), MSHake(_class ## $ ## arg0))
162 | #define MSHookMessage1(_class, arg0) \
163 | MSHookMessage($ ## _class, @selector(arg0:), MSHake(_class ## $ ## arg0 ## $))
164 | #define MSHookMessage2(_class, arg0, arg1) \
165 | MSHookMessage($ ## _class, @selector(arg0:arg1:), MSHake(_class ## $ ## arg0 ## $ ## arg1 ## $))
166 | #define MSHookMessage3(_class, arg0, arg1, arg2) \
167 | MSHookMessage($ ## _class, @selector(arg0:arg1:arg2:), MSHake(_class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $))
168 | #define MSHookMessage4(_class, arg0, arg1, arg2, arg3) \
169 | MSHookMessage($ ## _class, @selector(arg0:arg1:arg2:arg3:), MSHake(_class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $))
170 | #define MSHookMessage5(_class, arg0, arg1, arg2, arg3, arg4) \
171 | MSHookMessage($ ## _class, @selector(arg0:arg1:arg2:arg3:arg4:), MSHake(_class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $ ## arg4 ## $))
172 | #define MSHookMessage6(_class, arg0, arg1, arg2, arg3, arg4, arg5) \
173 | MSHookMessage($ ## _class, @selector(arg0:arg1:arg2:arg3:arg4:arg5:), MSHake(_class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $ ## arg4 ## $ ## arg5 ## $))
174 | #define MSHookMessage7(_class, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
175 | MSHookMessage($ ## _class, @selector(arg0:arg1:arg2:arg3:arg4:arg5:arg6:), MSHake(_class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $ ## arg4 ## $ ## arg5 ## $ ## arg6 ## $))
176 | #define MSHookMessage8(_class, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
177 | MSHookMessage($ ## _class, @selector(arg0:arg1:arg2:arg3:arg4:arg5:arg6:arg7:), MSHake(_class ## $ ## arg0 ## $ ## arg1 ## $ ## arg2 ## $ ## arg3 ## $ ## arg4 ## $ ## arg5 ## $ ## arg6 ## $ ## arg7 ## $))
178 |
179 | #define MSRegister_(name, dollar, colon) \
180 | namespace { static class C_$ ## name ## $ ## dollar { public: _finline C_$ ## name ## $ ##dollar() { \
181 | MSHookMessage($ ## name, @selector(colon), MSHake(name ## $ ## dollar)); \
182 | } } V_$ ## name ## $ ## dollar; } \
183 |
184 | #define MSIgnore_(name, dollar, colon)
185 |
186 | #define MSMessage_(extra, type, _class, name, dollar, colon, call, args...) \
187 | static type _$ ## name ## $ ## dollar(Class _cls, type (*_old)(_class, SEL, ## args, ...), type (*_spr)(struct objc_super *, SEL, ## args, ...), _class self, SEL _cmd, ## args); \
188 | MSHook(type, name ## $ ## dollar, _class self, SEL _cmd, ## args) { \
189 | Class const _cls($ ## name); \
190 | type (* const _old)(_class, SEL, ## args, ...) = reinterpret_cast(_ ## name ## $ ## dollar); \
191 | typedef type (*msgSendSuper_t)(struct objc_super *, SEL, ## args, ...); \
192 | msgSendSuper_t const _spr(::etl::IsClass::value ? reinterpret_cast(&objc_msgSendSuper_stret) : reinterpret_cast(&objc_msgSendSuper)); \
193 | return _$ ## name ## $ ## dollar call; \
194 | } \
195 | extra(name, dollar, colon) \
196 | static _finline type _$ ## name ## $ ## dollar(Class _cls, type (*_old)(_class, SEL, ## args, ...), type (*_spr)(struct objc_super *, SEL, ## args, ...), _class self, SEL _cmd, ## args)
197 |
198 | /* for((x=1;x!=7;++x)){ echo -n "#define MSMessage${x}_(extra, type, _class, name";for((y=0;y!=x;++y));do echo -n ", sel$y";done;for((y=0;y!=x;++y));do echo -n ", type$y, arg$y";done;echo ") \\";echo -n " MSMessage_(extra, type, _class, name,";for((y=0;y!=x;++y));do if [[ $y -ne 0 ]];then echo -n " ##";fi;echo -n " sel$y ## $";done;echo -n ", ";for((y=0;y!=x;++y));do echo -n "sel$y:";done;echo -n ", (_cls, _old, _spr, self, _cmd";for((y=0;y!=x;++y));do echo -n ", arg$y";done;echo -n ")";for((y=0;y!=x;++y));do echo -n ", type$y arg$y";done;echo ")";} */
199 |
200 | #define MSMessage0_(extra, type, _class, name, sel0) \
201 | MSMessage_(extra, type, _class, name, sel0, sel0, (_cls, _old, _spr, self, _cmd))
202 | #define MSMessage1_(extra, type, _class, name, sel0, type0, arg0) \
203 | MSMessage_(extra, type, _class, name, sel0 ## $, sel0:, (_cls, _old, _spr, self, _cmd, arg0), type0 arg0)
204 | #define MSMessage2_(extra, type, _class, name, sel0, sel1, type0, arg0, type1, arg1) \
205 | MSMessage_(extra, type, _class, name, sel0 ## $ ## sel1 ## $, sel0:sel1:, (_cls, _old, _spr, self, _cmd, arg0, arg1), type0 arg0, type1 arg1)
206 | #define MSMessage3_(extra, type, _class, name, sel0, sel1, sel2, type0, arg0, type1, arg1, type2, arg2) \
207 | MSMessage_(extra, type, _class, name, sel0 ## $ ## sel1 ## $ ## sel2 ## $, sel0:sel1:sel2:, (_cls, _old, _spr, self, _cmd, arg0, arg1, arg2), type0 arg0, type1 arg1, type2 arg2)
208 | #define MSMessage4_(extra, type, _class, name, sel0, sel1, sel2, sel3, type0, arg0, type1, arg1, type2, arg2, type3, arg3) \
209 | MSMessage_(extra, type, _class, name, sel0 ## $ ## sel1 ## $ ## sel2 ## $ ## sel3 ## $, sel0:sel1:sel2:sel3:, (_cls, _old, _spr, self, _cmd, arg0, arg1, arg2, arg3), type0 arg0, type1 arg1, type2 arg2, type3 arg3)
210 | #define MSMessage5_(extra, type, _class, name, sel0, sel1, sel2, sel3, sel4, type0, arg0, type1, arg1, type2, arg2, type3, arg3, type4, arg4) \
211 | MSMessage_(extra, type, _class, name, sel0 ## $ ## sel1 ## $ ## sel2 ## $ ## sel3 ## $ ## sel4 ## $, sel0:sel1:sel2:sel3:sel4:, (_cls, _old, _spr, self, _cmd, arg0, arg1, arg2, arg3, arg4), type0 arg0, type1 arg1, type2 arg2, type3 arg3, type4 arg4)
212 | #define MSMessage6_(extra, type, _class, name, sel0, sel1, sel2, sel3, sel4, sel5, type0, arg0, type1, arg1, type2, arg2, type3, arg3, type4, arg4, type5, arg5) \
213 | MSMessage_(extra, type, _class, name, sel0 ## $ ## sel1 ## $ ## sel2 ## $ ## sel3 ## $ ## sel4 ## $ ## sel5 ## $, sel0:sel1:sel2:sel3:sel4:sel5:, (_cls, _old, _spr, self, _cmd, arg0, arg1, arg2, arg3, arg4, arg5), type0 arg0, type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)
214 | #define MSMessage7_(extra, type, _class, name, sel0, sel1, sel2, sel3, sel4, sel5, sel6, type0, arg0, type1, arg1, type2, arg2, type3, arg3, type4, arg4, type5, arg5, type6, arg6) \
215 | MSMessage_(extra, type, _class, name, sel0 ## $ ## sel1 ## $ ## sel2 ## $ ## sel3 ## $ ## sel4 ## $ ## sel5 ## $ ## sel6 ## $, sel0:sel1:sel2:sel3:sel4:sel5:sel6:, (_cls, _old, _spr, self, _cmd, arg0, arg1, arg2, arg3, arg4, arg5, arg6), type0 arg0, type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6)
216 | #define MSMessage8_(extra, type, _class, name, sel0, sel1, sel2, sel3, sel4, sel5, sel6, sel7, type0, arg0, type1, arg1, type2, arg2, type3, arg3, type4, arg4, type5, arg5, type6, arg6, type7, arg7) \
217 | MSMessage_(extra, type, _class, name, sel0 ## $ ## sel1 ## $ ## sel2 ## $ ## sel3 ## $ ## sel4 ## $ ## sel5 ## $ ## sel6 ## $ ## sel7 ## $, sel0:sel1:sel2:sel3:sel4:sel5:sel6:sel7:, (_cls, _old, _spr, self, _cmd, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7), type0 arg0, type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6, type7 arg7)
218 |
219 | #define MSInstanceMessage0(type, _class, args...) MSMessage0_(MSIgnore_, type, _class *, _class, ## args)
220 | #define MSInstanceMessage1(type, _class, args...) MSMessage1_(MSIgnore_, type, _class *, _class, ## args)
221 | #define MSInstanceMessage2(type, _class, args...) MSMessage2_(MSIgnore_, type, _class *, _class, ## args)
222 | #define MSInstanceMessage3(type, _class, args...) MSMessage3_(MSIgnore_, type, _class *, _class, ## args)
223 | #define MSInstanceMessage4(type, _class, args...) MSMessage4_(MSIgnore_, type, _class *, _class, ## args)
224 | #define MSInstanceMessage5(type, _class, args...) MSMessage5_(MSIgnore_, type, _class *, _class, ## args)
225 | #define MSInstanceMessage6(type, _class, args...) MSMessage6_(MSIgnore_, type, _class *, _class, ## args)
226 | #define MSInstanceMessage7(type, _class, args...) MSMessage7_(MSIgnore_, type, _class *, _class, ## args)
227 | #define MSInstanceMessage8(type, _class, args...) MSMessage8_(MSIgnore_, type, _class *, _class, ## args)
228 |
229 | #define MSClassMessage0(type, _class, args...) MSMessage0_(MSIgnore_, type, Class, $ ## _class, ## args)
230 | #define MSClassMessage1(type, _class, args...) MSMessage1_(MSIgnore_, type, Class, $ ## _class, ## args)
231 | #define MSClassMessage2(type, _class, args...) MSMessage2_(MSIgnore_, type, Class, $ ## _class, ## args)
232 | #define MSClassMessage3(type, _class, args...) MSMessage3_(MSIgnore_, type, Class, $ ## _class, ## args)
233 | #define MSClassMessage4(type, _class, args...) MSMessage4_(MSIgnore_, type, Class, $ ## _class, ## args)
234 | #define MSClassMessage5(type, _class, args...) MSMessage5_(MSIgnore_, type, Class, $ ## _class, ## args)
235 | #define MSClassMessage6(type, _class, args...) MSMessage6_(MSIgnore_, type, Class, $ ## _class, ## args)
236 | #define MSClassMessage7(type, _class, args...) MSMessage7_(MSIgnore_, type, Class, $ ## _class, ## args)
237 | #define MSClassMessage8(type, _class, args...) MSMessage8_(MSIgnore_, type, Class, $ ## _class, ## args)
238 |
239 | #define MSInstanceMessageHook0(type, _class, args...) MSMessage0_(MSRegister_, type, _class *, _class, ## args)
240 | #define MSInstanceMessageHook1(type, _class, args...) MSMessage1_(MSRegister_, type, _class *, _class, ## args)
241 | #define MSInstanceMessageHook2(type, _class, args...) MSMessage2_(MSRegister_, type, _class *, _class, ## args)
242 | #define MSInstanceMessageHook3(type, _class, args...) MSMessage3_(MSRegister_, type, _class *, _class, ## args)
243 | #define MSInstanceMessageHook4(type, _class, args...) MSMessage4_(MSRegister_, type, _class *, _class, ## args)
244 | #define MSInstanceMessageHook5(type, _class, args...) MSMessage5_(MSRegister_, type, _class *, _class, ## args)
245 | #define MSInstanceMessageHook6(type, _class, args...) MSMessage6_(MSRegister_, type, _class *, _class, ## args)
246 | #define MSInstanceMessageHook7(type, _class, args...) MSMessage7_(MSRegister_, type, _class *, _class, ## args)
247 | #define MSInstanceMessageHook8(type, _class, args...) MSMessage8_(MSRegister_, type, _class *, _class, ## args)
248 |
249 | #define MSClassMessageHook0(type, _class, args...) MSMessage0_(MSRegister_, type, Class, $ ## _class, ## args)
250 | #define MSClassMessageHook1(type, _class, args...) MSMessage1_(MSRegister_, type, Class, $ ## _class, ## args)
251 | #define MSClassMessageHook2(type, _class, args...) MSMessage2_(MSRegister_, type, Class, $ ## _class, ## args)
252 | #define MSClassMessageHook3(type, _class, args...) MSMessage3_(MSRegister_, type, Class, $ ## _class, ## args)
253 | #define MSClassMessageHook4(type, _class, args...) MSMessage4_(MSRegister_, type, Class, $ ## _class, ## args)
254 | #define MSClassMessageHook5(type, _class, args...) MSMessage5_(MSRegister_, type, Class, $ ## _class, ## args)
255 | #define MSClassMessageHook6(type, _class, args...) MSMessage6_(MSRegister_, type, Class, $ ## _class, ## args)
256 | #define MSClassMessageHook7(type, _class, args...) MSMessage7_(MSRegister_, type, Class, $ ## _class, ## args)
257 | #define MSClassMessageHook8(type, _class, args...) MSMessage8_(MSRegister_, type, Class, $ ## _class, ## args)
258 |
259 | #define MSOldCall(args...) \
260 | _old(self, _cmd, ## args)
261 | #define MSSuperCall(args...) \
262 | _spr(& (struct objc_super) {self, class_getSuperclass(_cls)}, _cmd, ## args)
263 |
264 | #define MSIvarHook(type, name) \
265 | type &name(MSHookIvar(self, #name))
266 |
267 | #define MSClassHook(name) \
268 | @class name; \
269 | static Class $ ## name = objc_getClass(#name);
270 | #define MSMetaClassHook(name) \
271 | @class name; \
272 | static Class $$ ## name = object_getClass($ ## name);
273 |
274 | #endif/*__APPLE__*/
275 |
276 | template
277 | static inline void MSHookFunction(Type_ *symbol, Type_ *replace, Type_ **result) {
278 | return MSHookFunction(
279 | reinterpret_cast(symbol),
280 | reinterpret_cast(replace),
281 | reinterpret_cast(result)
282 | );
283 | }
284 |
285 | template
286 | static inline void MSHookFunction(Type_ *symbol, Type_ *replace) {
287 | return MSHookFunction(symbol, replace, reinterpret_cast(NULL));
288 | }
289 |
290 | template
291 | static inline void MSHookSymbol(Type_ *&value, const char *name, MSImageRef image = NULL) {
292 | value = reinterpret_cast(MSFindSymbol(image, name));
293 | }
294 |
295 | template
296 | static inline void MSHookFunction(const char *name, Type_ *replace, Type_ **result = NULL) {
297 | Type_ *symbol;
298 | MSHookSymbol(symbol, name);
299 | return MSHookFunction(symbol, replace, result);
300 | }
301 |
302 | template
303 | static inline void MSHookFunction(MSImageRef image, const char *name, Type_ *replace, Type_ **result = NULL) {
304 | Type_ *symbol;
305 | MSHookSymbol(symbol, name, image);
306 | return MSHookFunction(symbol, replace, result);
307 | }
308 |
309 | #endif
310 |
311 | #ifdef __ANDROID__
312 |
313 | #ifdef __cplusplus
314 |
315 | template
316 | static inline void MSJavaHookMethod(JNIEnv *jni, jclass _class, jmethodID method, Type_ (*replace)(JNIEnv *, Kind_, Args_...), Type_ (**result)(JNIEnv *, Kind_, ...)) {
317 | return MSJavaHookMethod(
318 | jni, _class, method,
319 | reinterpret_cast(replace),
320 | reinterpret_cast(result)
321 | );
322 | }
323 |
324 | #endif
325 |
326 | static inline void MSAndroidGetPackage(JNIEnv *jni, jobject global, const char *name, jobject &local, jobject &loader) {
327 | jclass Context(jni->FindClass("android/content/Context"));
328 | jmethodID Context$createPackageContext(jni->GetMethodID(Context, "createPackageContext", "(Ljava/lang/String;I)Landroid/content/Context;"));
329 | jmethodID Context$getClassLoader(jni->GetMethodID(Context, "getClassLoader", "()Ljava/lang/ClassLoader;"));
330 |
331 | jstring string(jni->NewStringUTF(name));
332 | local = jni->CallObjectMethod(global, Context$createPackageContext, string, 3);
333 | loader = jni->CallObjectMethod(local, Context$getClassLoader);
334 | }
335 |
336 | static inline jclass MSJavaFindClass(JNIEnv *jni, jobject loader, const char *name) {
337 | jclass Class(jni->FindClass("java/lang/Class"));
338 | jmethodID Class$forName(jni->GetStaticMethodID(Class, "forName", "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;"));
339 |
340 | jstring string(jni->NewStringUTF(name));
341 | jobject _class(jni->CallStaticObjectMethod(Class, Class$forName, string, JNI_TRUE, loader));
342 | if (jni->ExceptionCheck())
343 | return NULL;
344 |
345 | return reinterpret_cast(_class);
346 | }
347 |
348 | _disused static void MSJavaCleanWeak(void *data, JNIEnv *jni, void *value) {
349 | jni->DeleteWeakGlobalRef(reinterpret_cast(value));
350 | }
351 |
352 | #endif
353 |
354 | #define MSHook(type, name, args...) \
355 | _disused static type (*_ ## name)(args); \
356 | static type $ ## name(args)
357 |
358 | #define MSJavaHook(type, name, arg0, args...) \
359 | _disused static type (*_ ## name)(JNIEnv *jni, arg0, ...); \
360 | static type $ ## name(JNIEnv *jni, arg0, ## args)
361 |
362 | #ifdef __cplusplus
363 | #define MSHake(name) \
364 | &$ ## name, &_ ## name
365 | #else
366 | #define MSHake(name) \
367 | &$ ## name, (void **) &_ ## name
368 | #endif
369 |
370 | #define SubstrateConcat_(lhs, rhs) \
371 | lhs ## rhs
372 | #define SubstrateConcat(lhs, rhs) \
373 | SubstrateConcat_(lhs, rhs)
374 |
375 | #ifdef __APPLE__
376 | #define SubstrateSection \
377 | __attribute__((__section__("__TEXT, __substrate")))
378 | #else
379 | #define SubstrateSection \
380 | __attribute__((__section__(".substrate")))
381 | #endif
382 |
383 | #ifdef __APPLE__
384 | #define MSFilterCFBundleID "Filter:CFBundleID"
385 | #define MSFilterObjC_Class "Filter:ObjC.Class"
386 | #endif
387 |
388 | #define MSFilterLibrary "Filter:Library"
389 | #define MSFilterExecutable "Filter:Executable"
390 |
391 | #define MSConfig(name, value) \
392 | extern const char SubstrateConcat(_substrate_, __LINE__)[] SubstrateSection = name "=" value;
393 |
394 | #ifdef __cplusplus
395 | #define MSInitialize \
396 | static void _MSInitialize(void); \
397 | namespace { static class $MSInitialize { public: _finline $MSInitialize() { \
398 | _MSInitialize(); \
399 | } } $MSInitialize; } \
400 | static void _MSInitialize()
401 | #else
402 | #define MSInitialize \
403 | __attribute__((__constructor__)) static void _MSInitialize(void)
404 | #endif
405 |
406 | #define Foundation_f "/System/Library/Frameworks/Foundation.framework/Foundation"
407 | #define UIKit_f "/System/Library/Frameworks/UIKit.framework/UIKit"
408 | #define JavaScriptCore_f "/System/Library/PrivateFrameworks/JavaScriptCore.framework/JavaScriptCore"
409 | #define IOKit_f "/System/Library/Frameworks/IOKit.framework/IOKit"
410 |
411 | #endif//SUBSTRATE_H_
412 |
--------------------------------------------------------------------------------
/app/src/main/jni/x86/libsubstrate-dvm.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/src/main/jni/x86/libsubstrate-dvm.so
--------------------------------------------------------------------------------
/app/src/main/jni/x86/libsubstrate.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/src/main/jni/x86/libsubstrate.so
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/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/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #D81B60
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | DouYinTool
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | maven{ url 'http://maven.aliyun.com/nexus/content/groups/public'}
6 | google()
7 | jcenter()
8 |
9 | }
10 | dependencies {
11 | // classpath 'com.android.tools.build:gradle:3.3.1'
12 | classpath 'com.android.tools.build:gradle:3.6.3'
13 |
14 | // NOTE: Do not place your application dependencies here; they belong
15 | // in the individual module build.gradle files
16 | }
17 | }
18 |
19 | allprojects {
20 | repositories {
21 | maven{ url 'http://maven.aliyun.com/nexus/content/groups/public'}
22 | maven { url 'https://jitpack.io' }
23 | google()
24 | jcenter()
25 |
26 | }
27 | }
28 |
29 | task clean(type: Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 |
15 |
16 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aihacker/DouYinTool/740ddc930b9d33611999bf4b1961d79e1edb2cd3/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri May 22 15:40:23 CST 2020
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-5.6.4-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/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 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
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 Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------