├── .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 | 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 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 29 | 30 | 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 | 29 | 46 | 47 | 48 | 49 | 50 | 51 | 53 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 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 |