├── .gitignore ├── .idea ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── libs │ └── XposedBridgeApi-54.jar ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── example │ │ └── greywolf │ │ └── qq750hook │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ └── xposed_init │ ├── java │ │ └── com │ │ │ ├── example │ │ │ └── greywolf │ │ │ │ └── qq750hook │ │ │ │ └── MainActivity.java │ │ │ └── wolf │ │ │ └── q750hook │ │ │ └── Main.java │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── example │ └── greywolf │ └── qq750hook │ ├── ExampleUnitTest.java │ └── Test.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── script ├── pullLogFile.bat └── viewlog.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | .idea 5 | # Files for the ART/Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Android Studio Navigation editor temp files 30 | .navigation/ 31 | 32 | # Android Studio captures folder 33 | captures/ 34 | 35 | # Intellij 36 | *.iml 37 | .idea/workspace.xml 38 | .idea/tasks.xml 39 | .idea/gradle.xml 40 | .idea/dictionaries 41 | .idea/libraries 42 | 43 | # Keystore files 44 | *.jks 45 | 46 | # External native build folder generated in Android Studio 2.2 and later 47 | .externalNativeBuild 48 | 49 | # Google Services (e.g. APIs or Firebase) 50 | google-services.json 51 | 52 | # Freeline 53 | freeline.py 54 | freeline/ 55 | freeline_project_description.json 56 | *.iml 57 | .gradle 58 | /local.properties 59 | /.idea/workspace.xml 60 | /.idea/libraries 61 | .DS_Store 62 | /build 63 | /captures 64 | .externalNativeBuild 65 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 20 | 21 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 26 | 45 | 46 | 47 | 48 | 49 | 50 | 52 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MobileQQHook 2 | support MobileQQV8.8.68 3 | 4 | #If it helps you,give me a star please. -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /release 3 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 30 5 | defaultConfig { 6 | applicationId "com.example.greywolf.qq750hook" 7 | minSdkVersion 15 8 | targetSdkVersion 30 9 | versionCode 2 10 | versionName "1.2" 11 | testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | implementation 'androidx.appcompat:appcompat:1.3.0' 23 | implementation 'androidx.constraintlayout:constraintlayout:2.0.4' 24 | compileOnly files('libs/XposedBridgeApi-54.jar') 25 | } 26 | -------------------------------------------------------------------------------- /app/libs/XposedBridgeApi-54.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GreyWolf007/AndroidQQHook/bb192a76c8cca95ddedaf0c9d1ec672341492740/app/libs/XposedBridgeApi-54.jar -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/example/greywolf/qq750hook/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.example.greywolf.qq750hook; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.example.greywolf.qq750hook", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 23 | 26 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/assets/xposed_init: -------------------------------------------------------------------------------- 1 | com.wolf.q750hook.Main -------------------------------------------------------------------------------- /app/src/main/java/com/example/greywolf/qq750hook/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.greywolf.qq750hook; 2 | ; 3 | import android.os.Bundle; 4 | 5 | import androidx.appcompat.app.AppCompatActivity; 6 | 7 | public class MainActivity extends AppCompatActivity { 8 | 9 | @Override 10 | protected void onCreate(Bundle savedInstanceState) { 11 | super.onCreate(savedInstanceState); 12 | setContentView(R.layout.activity_main); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/wolf/q750hook/Main.java: -------------------------------------------------------------------------------- 1 | package com.wolf.q750hook; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | import android.os.Bundle; 6 | import android.util.Log; 7 | 8 | import java.io.PrintWriter; 9 | import java.io.StringWriter; 10 | import java.lang.reflect.Field; 11 | import java.text.SimpleDateFormat; 12 | import java.util.HashMap; 13 | import java.util.UUID; 14 | 15 | import de.robv.android.xposed.IXposedHookLoadPackage; 16 | import de.robv.android.xposed.XC_MethodHook; 17 | import de.robv.android.xposed.XposedBridge; 18 | import de.robv.android.xposed.XposedHelpers; 19 | import de.robv.android.xposed.callbacks.XC_LoadPackage; 20 | 21 | /** 22 | * for mobile qq V8.0.0 23 | * Created by GreyWolf on 2018/2/21. 24 | */ 25 | 26 | public class Main implements IXposedHookLoadPackage { 27 | static final String MobileQQPN = "com.tencent.mobileqq"; 28 | static final String LOGTAG = "qqhook"; 29 | 30 | static final String LOGTAG_PACKET = "qqhook-packet"; 31 | 32 | @Override 33 | public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable { 34 | if (!loadPackageParam.packageName.equals(MobileQQPN)) { 35 | return; 36 | } 37 | log("Hook MobileQQ Successful!"); 38 | 39 | XposedHelpers.findAndHookMethod(Application.class, "attach", Context.class, new XC_MethodHook() { 40 | @Override 41 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 42 | // this will be called before the clock was updated by the original method 43 | } 44 | 45 | @Override 46 | protected void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable { 47 | /* ClassLoader cl = ((Context) param.args[0]).getClassLoader(); 48 | Class hookclass = null; 49 | final String class_name = "com.tencent.mobileqq.transfile.GroupPicUploadProcessor"; 50 | try { 51 | hookclass = cl.loadClass(class_name); 52 | } catch (Exception e) { 53 | log("[Failed!]Can not find " + class_name); 54 | return; 55 | } 56 | log("[success!]Find class " + class_name); 57 | 58 | XposedHelpers.findAndHookMethod(hookclass, 59 | "b", StringBuilder.class, new XC_MethodHook() { 60 | @Override 61 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 62 | // this will be called before the clock was updated by the original method 63 | } 64 | 65 | @Override 66 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 67 | // this will be called after the clock was updated by the original method 68 | log("after hook:" + class_name + "---" + getStack()); 69 | } 70 | });*/ 71 | } 72 | }); // end of findAndHookMethod 73 | // log("hook attach successful!"); 74 | 75 | XposedHelpers.findAndHookMethod("oicq.wlogin_sdk.tools.EcdhCrypt", loadPackageParam.classLoader, "GenECDHKeyEx", 76 | String.class, String.class, String.class, 77 | new XC_MethodHook() { 78 | @Override 79 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 80 | String p1 = (String) param.args[0]; 81 | String p2 = (String) param.args[1]; 82 | String p3 = (String) param.args[2]; 83 | 84 | log("GenECDHKeyEx Papam 1 len=" + p1.length() / 2 + ":" + (p1)); 85 | log("GenECDHKeyEx Papam 2 len=" + p2.length() / 2 + ":" + (p2)); 86 | log("GenECDHKeyEx Papam 3 len=" + p3.length() / 2 + ":" + (p3)); 87 | } 88 | }); 89 | 90 | XposedHelpers.findAndHookMethod("oicq.wlogin_sdk.tools.EcdhCrypt", loadPackageParam.classLoader, "set_c_pri_key", 91 | byte[].class, 92 | new XC_MethodHook() { 93 | @Override 94 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 95 | byte[] p1 = (byte[]) param.args[0]; 96 | log("set_c_pri_key Papam 1 len=" + p1.length + ":" + bytesToHex(p1)); 97 | 98 | } 99 | }); 100 | XposedHelpers.findAndHookMethod("oicq.wlogin_sdk.tools.EcdhCrypt", loadPackageParam.classLoader, "set_c_pub_key", 101 | byte[].class, 102 | new XC_MethodHook() { 103 | @Override 104 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 105 | byte[] p1 = (byte[]) param.args[0]; 106 | log("set_c_pub_key Papam 1 len=" + p1.length + ":" + bytesToHex(p1)); 107 | 108 | } 109 | }); 110 | XposedHelpers.findAndHookMethod("oicq.wlogin_sdk.tools.EcdhCrypt", loadPackageParam.classLoader, "set_g_share_key", 111 | byte[].class, 112 | new XC_MethodHook() { 113 | @Override 114 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 115 | byte[] p1 = (byte[]) param.args[0]; 116 | log("set_g_share_key Papam 1 len=" + p1.length + ":" + bytesToHex(p1)); 117 | 118 | } 119 | }); 120 | 121 | 122 | //Hook Session key 123 | XposedHelpers.findAndHookMethod("oicq.wlogin_sdk.request.WloginAllSigInfo", loadPackageParam.classLoader, "put_siginfo", 124 | long.class, long.class, long.class, long.class, long.class, byte[].class, 125 | byte[].class, byte[].class, byte[].class, byte[].class, byte[].class, byte[].class, byte 126 | [].class, byte[].class, byte[].class, byte[].class, byte[].class, byte[][].class, long[] 127 | .class, int.class, 128 | new XC_MethodHook() { 129 | @Override 130 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 131 | byte[][] data = (byte[][]) param.args[17]; 132 | byte[] sessionkey = data[3]; 133 | byte[] wtsessionticket = data[13]; 134 | byte[] wtsessionticketkey = data[13]; 135 | log("SessionKey len=" + sessionkey.length + ":" + bytesToHex(sessionkey)); 136 | log("wt session ticket:" + bytesToHex(wtsessionticket) + "|" + "wtsessionticket key:" + bytesToHex(wtsessionticketkey)); 137 | 138 | long curr = (long) param.args[2];// System.currentTimeMillis() / 1000; 139 | long[] validTime = (long[]) param.args[18]; 140 | 141 | long _D2_expire_time = validTime[5]; 142 | long _sid_expire_time = validTime[6]; 143 | long _vKey_expire_time = validTime[2]; 144 | long _sKey_expire_time = validTime[1]; 145 | long _userStWebSig_expire_time = validTime[4]; 146 | long _userA8_expire_time = validTime[3]; 147 | long _lsKey_expire_time = validTime[0]; 148 | 149 | log( 150 | "Original" + 151 | "_D2_expire_time:" + formatTimeUnix10(_D2_expire_time + curr) + " Valid:" + _D2_expire_time + " s|" + 152 | "_sid_expire_time:" + formatTimeUnix10(_sid_expire_time + curr) + " Valid:" + _sid_expire_time + " s|" + 153 | "_vKey_expire_time:" + formatTimeUnix10(_vKey_expire_time + curr) + " Valid:" + _vKey_expire_time + " s|" + 154 | "_sKey_expire_time:" + formatTimeUnix10(_sKey_expire_time + curr) + " Valid:" + _sKey_expire_time + " s|" + 155 | "_userStWebSig_expire_time:" + formatTimeUnix10(_userStWebSig_expire_time + curr) + " Valid:" + _userStWebSig_expire_time + " s|" + 156 | "_userA8_expire_time:" + formatTimeUnix10(_userA8_expire_time + curr) + " Valid:" + _userA8_expire_time + " s|" + 157 | "_lsKey_expire_time:" + formatTimeUnix10(_lsKey_expire_time + curr) + " Valid:" + _lsKey_expire_time + " s|" 158 | 159 | ); 160 | /** 161 | * log 162 | * 02-24 08:50:15.343 I/qqhook ( 2942): _D2_expire_time:2018/03/17 08:50:15 Valid:1814400 s|_sid_expire_time:2018/03/17 08:50:15 Valid:1814400 s|_vKey_expire_time:2018/03/17 08:50:15 Valid:1814400 s|_sKey_expire_time:2018/02/25 08:50:15 Valid:86400 s|_userStWebSig_expire_time:2018/02/24 10:50:15 Valid:7200 s|_userA8_expire_time:2018/02/25 08:50:15 Valid:86400 s|_lsKey_expire_time:2018/03/16 08:50:15 Valid:1728000 s| 163 | */ 164 | //Get wtlogin.exchange_emp 165 | // for (int i = 0; i < validTime.length; i++) 166 | // validTime[i] = 10; 167 | // validTime[5]=10; 168 | // validTime[6] = 10; 169 | 170 | } 171 | } 172 | ); 173 | 174 | //Fix Tea Rand 175 | XposedHelpers.findAndHookMethod("oicq.wlogin_sdk.tools.b", loadPackageParam.classLoader, "b", 176 | new XC_MethodHook() { 177 | @Override 178 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 179 | param.setResult(50); 180 | } 181 | }); 182 | 183 | //Hook SessionKey Valid Time 单位/s 184 | XposedHelpers.findAndHookMethod("oicq.wlogin_sdk.tlv_type.tlv_t138", loadPackageParam.classLoader, "get_d2_chg_time", 185 | new XC_MethodHook() { 186 | @Override 187 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 188 | int validtimeSecond = (int) param.getResult(); 189 | log("SessionKey Valid " + validtimeSecond + " s"); 190 | } 191 | } 192 | ); 193 | 194 | 195 | //Test 196 | //region 开启Native层调试 tag libboot 197 | XposedHelpers.findAndHookMethod("com.tencent.qphone.base.util.CodecWarpper", loadPackageParam.classLoader, "init", 198 | Context.class, boolean.class, boolean.class, 199 | new XC_MethodHook() { 200 | @Override 201 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 202 | param.args[1] = true; 203 | log("Open libcodecwrapperV2.so Debug Logcat Successful!"); 204 | } 205 | }); 206 | 207 | XposedHelpers.findAndHookMethod("com.tencent.qphone.base.util.CodecWarpper", loadPackageParam.classLoader, "getAppid", 208 | new XC_MethodHook() { 209 | @Override 210 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 211 | log("APPID==" + param.getResult()); 212 | 213 | } 214 | }); 215 | //endregion 216 | 217 | //region 开启oicq.wloginsdk 日志 TAG wlogin_sdk 218 | final String OICQCLASS = "oicq.wlogin_sdk.tools.util"; 219 | final String wlogin_sdk_tag = "wlogin_sdk"; 220 | XposedHelpers.findAndHookMethod(OICQCLASS, loadPackageParam.classLoader, "LOGD", 221 | String.class, 222 | new XC_MethodHook() { 223 | @Override 224 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 225 | String p1 = (String) param.args[0]; 226 | 227 | Log.d(wlogin_sdk_tag + getLineInfo(2), p1); 228 | } 229 | } 230 | ); 231 | XposedHelpers.findAndHookMethod(OICQCLASS, loadPackageParam.classLoader, "LOGD", 232 | String.class, String.class, 233 | new XC_MethodHook() { 234 | @Override 235 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 236 | String p1 = (String) param.args[0]; 237 | String p2 = (String) param.args[1]; 238 | 239 | Log.d(wlogin_sdk_tag + getLineInfo(2), p1 + ":" + p2); 240 | } 241 | } 242 | ); 243 | 244 | XposedHelpers.findAndHookMethod(OICQCLASS, loadPackageParam.classLoader, "LOGI", 245 | String.class, String.class, 246 | new XC_MethodHook() { 247 | @Override 248 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 249 | String p1 = (String) param.args[0]; 250 | String p2 = (String) param.args[1]; 251 | 252 | Log.i(wlogin_sdk_tag + getLineInfo(2), p1 + ":" + p2); 253 | } 254 | } 255 | ); 256 | XposedHelpers.findAndHookMethod(OICQCLASS, loadPackageParam.classLoader, "LOGI", 257 | String.class, 258 | new XC_MethodHook() { 259 | @Override 260 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 261 | String p1 = (String) param.args[0]; 262 | 263 | Log.i(wlogin_sdk_tag + getLineInfo(2), p1); 264 | } 265 | } 266 | ); 267 | XposedHelpers.findAndHookMethod(OICQCLASS, loadPackageParam.classLoader, "LOGW", 268 | String.class, String.class, 269 | new XC_MethodHook() { 270 | @Override 271 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 272 | String p1 = (String) param.args[0]; 273 | String p2 = (String) param.args[1]; 274 | 275 | Log.w(wlogin_sdk_tag + getLineInfo(2), p1 + ":" + p2); 276 | } 277 | } 278 | ); 279 | XposedHelpers.findAndHookMethod(OICQCLASS, loadPackageParam.classLoader, "LOGW", 280 | String.class, String.class, String.class, 281 | new XC_MethodHook() { 282 | @Override 283 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 284 | String p1 = (String) param.args[0]; 285 | String p2 = (String) param.args[1]; 286 | String p3 = (String) param.args[2]; 287 | 288 | Log.w(wlogin_sdk_tag + getLineInfo(2), p1 + ":" + p2 + ":" + p3); 289 | } 290 | } 291 | ); 292 | //endregion 293 | 294 | //region 开启QLog 基本是QQ全局log 295 | /** 296 | * CodeWrapper tag MSF.C.CodecWarpper 297 | */ 298 | final String QLogClass = "com.tencent.qphone.base.util.QLog"; 299 | XposedHelpers.findAndHookMethod(QLogClass, loadPackageParam.classLoader, "d", 300 | String.class, int.class, String.class, Throwable.class, 301 | new XC_MethodHook() { 302 | @Override 303 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 304 | String arg1 = (String) param.args[0]; 305 | int arg2 = (int) param.args[1]; 306 | String arg3 = (String) param.args[2]; 307 | Throwable arg4 = (Throwable) param.args[3]; 308 | if (arg3 == null) { 309 | arg3 = ""; 310 | } 311 | if (arg4 == null) { 312 | Log.d(arg1, arg3); 313 | } else { 314 | Log.d(arg1, arg3, arg4); 315 | } 316 | } 317 | }); 318 | 319 | 320 | XposedHelpers.findAndHookMethod(QLogClass, loadPackageParam.classLoader, "e", 321 | String.class, int.class, String.class, Throwable.class, 322 | new XC_MethodHook() { 323 | @Override 324 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 325 | String arg1 = (String) param.args[0]; 326 | int arg2 = (int) param.args[1]; 327 | String arg3 = (String) param.args[2]; 328 | Throwable arg4 = (Throwable) param.args[3]; 329 | if (arg3 == null) { 330 | arg3 = ""; 331 | } 332 | if (arg4 == null) { 333 | Log.e(arg1, arg3); 334 | } else { 335 | Log.e(arg1, arg3, arg4); 336 | } 337 | } 338 | }); 339 | 340 | XposedHelpers.findAndHookMethod(QLogClass, loadPackageParam.classLoader, "i", 341 | String.class, int.class, String.class, Throwable.class, 342 | new XC_MethodHook() { 343 | @Override 344 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 345 | String arg1 = (String) param.args[0]; 346 | int arg2 = (int) param.args[1]; 347 | String arg3 = (String) param.args[2]; 348 | Throwable arg4 = (Throwable) param.args[3]; 349 | if (arg3 == null) { 350 | arg3 = ""; 351 | } 352 | if (arg4 == null) { 353 | Log.i(arg1, arg3); 354 | } else { 355 | Log.i(arg1, arg3, arg4); 356 | } 357 | } 358 | }); 359 | //endregion 360 | //Test 361 | 362 | 363 | //Hook数据包 364 | final String CodecWarpperClass = "com.tencent.qphone.base.util.CodecWarpper"; 365 | /** 366 | * 发送包 V3 367 | */ 368 | // int i, String str, String str2, String str3, 369 | // String str4, String str5, 370 | // byte[] bArr, int i2, 371 | // int i3, String str6, byte b, byte b2, 372 | // byte[] bArr2, boolean z 373 | XposedHelpers.findAndHookMethod(CodecWarpperClass, loadPackageParam.classLoader, "nativeEncodeRequest", 374 | int.class, 375 | String.class, 376 | String.class, 377 | String.class, 378 | String.class, 379 | String.class, 380 | 381 | byte[].class, 382 | int.class, 383 | int.class, 384 | String.class, 385 | byte.class, 386 | byte.class, 387 | byte[].class, 388 | boolean.class, 389 | new XC_MethodHook() { 390 | @Override 391 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 392 | log("nativeEncodeRequest V3"); 393 | } 394 | 395 | @Override 396 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 397 | int requestSsoSeq = (int) param.args[0]; 398 | String imei = (String) param.args[1]; 399 | String subscriberId = (String) param.args[2]; 400 | String revision = (String) param.args[3]; 401 | String serviceCmd = (String) param.args[5]; 402 | String msgCookie = bytesToHex((byte[]) param.args[6]); 403 | int appid = (int) param.args[7]; 404 | int msfappid = (int) param.args[8]; 405 | String uin = (String) param.args[9]; 406 | /*byte b = (byte) 0; 407 | if (NetConnInfoCenter.isWifiConn()) { 408 | b = (byte) 1; 409 | } else if (NetConnInfoCenter.isMobileConn()) { 410 | indexOf = NetConnInfoCenter.getMobileNetworkType() + 100; 411 | if (indexOf > 254) { 412 | indexOf = 254; 413 | if (QLog.isColorLevel()) { 414 | QLog.d("MSF.C.NetConnTag", 2, "error,netWorkType is " + 254); 415 | } 416 | } 417 | b = (byte) indexOf; 418 | }*/ 419 | byte netWorkType = (byte) param.args[11]; 420 | byte[] wupBuffer = (byte[]) param.args[12]; 421 | 422 | byte[] sendData = (byte[]) param.getResult(); 423 | 424 | if (serviceCmd.startsWith("wtlogin.")) { 425 | log(LOGTAG_PACKET, "SEND DATA->" + 426 | "serviceCmd:" + serviceCmd + "|" + 427 | "requestSsoSeq:" + requestSsoSeq + "|" + 428 | "sendData Length:" + (sendData.length) + "|" + 429 | "wupBuffer Length:" + (wupBuffer.length) + "|" + 430 | "imei:" + imei + "|" + 431 | "subscriberId:" + subscriberId + "|" + 432 | "revision:" + revision + "|" + 433 | "msgCookie:" + msgCookie + "|" + 434 | "appid:" + appid + "|" + 435 | "msfappid:" + msfappid + "|" + 436 | "uin:" + uin + "|" + 437 | "netWorkType:" + netWorkType + "|" + 438 | "wupBuffer:" + bytesToHex(wupBuffer) + "|" 439 | // + "sendData:" + bytesToHex(sendData) + "|" 440 | ); 441 | } else { 442 | log(LOGTAG_PACKET, "SEND DATA->" + 443 | "serviceCmd:" + serviceCmd + "|" + 444 | "requestSsoSeq:" + requestSsoSeq + "|" + 445 | "sendData Length:" + (sendData.length) + "|" + 446 | "wupBuffer Length:" + (wupBuffer.length) + "|" + 447 | "msgCookie:" + msgCookie + "|" + 448 | "uin:" + uin + "|" + 449 | "wupBuffer:" + bytesToHex(wupBuffer) + "|" 450 | // + "sendData:" + bytesToHex(sendData) + "|" 451 | ); 452 | } 453 | 454 | } 455 | }); 456 | 457 | 458 | /** 459 | * 发送包V2 460 | */ 461 | //int i, String str, String str2, String str3, String str4, String str5, 462 | // byte[] bArr, int i2, int i3, String str6, 463 | // byte b, byte b2, byte[] bArr2, byte[] bArr3, byte[] bArr4, boolean z 464 | XposedHelpers.findAndHookMethod(CodecWarpperClass, loadPackageParam.classLoader, "nativeEncodeRequest", 465 | int.class, String.class, String.class, String.class, String 466 | .class, String.class, 467 | byte[].class, int.class, int.class, String.class, 468 | byte.class, byte.class, 469 | byte[].class, 470 | byte[].class, byte[].class, boolean.class, 471 | new XC_MethodHook() { 472 | @Override 473 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 474 | log("nativeEncodeRequest V2"); 475 | } 476 | 477 | @Override 478 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 479 | int requestSsoSeq = (int) param.args[0]; 480 | String imei = (String) param.args[1]; 481 | String subscriberId = (String) param.args[2]; 482 | String revision = (String) param.args[3]; 483 | String serviceCmd = (String) param.args[5]; 484 | String msgCookie = bytesToHex((byte[]) param.args[6]); 485 | int appid = (int) param.args[7]; 486 | int msfappid = (int) param.args[8]; 487 | String uin = (String) param.args[9]; 488 | byte netWorkType = (byte) param.args[11]; 489 | byte[] pbtimestamp = (byte[]) param.args[12]; 490 | byte[] wupBuffer = (byte[]) param.args[14]; 491 | 492 | byte[] sendData = (byte[]) param.getResult(); 493 | 494 | if (serviceCmd.startsWith("wtlogin.")) { 495 | log(LOGTAG_PACKET, "SEND DATA->" + 496 | "serviceCmd:" + serviceCmd + "|" + 497 | "requestSsoSeq:" + requestSsoSeq + "|" + 498 | "sendData Length:" + (sendData.length) + "|" + 499 | "wupBuffer Length:" + (wupBuffer.length) + "|" + 500 | "imei:" + imei + "|" + 501 | "subscriberId:" + subscriberId + "|" + 502 | "revision:" + revision + "|" + 503 | "msgCookie:" + msgCookie + "|" + 504 | "appid:" + appid + "|" + 505 | "msfappid:" + msfappid + "|" + 506 | "uin:" + uin + "|" + 507 | "netWorkType:" + netWorkType + "|" + 508 | "pbtimestamp:" + bytesToHex(pbtimestamp) + "|" + 509 | "wupBuffer:" + bytesToHex(wupBuffer) + "|" 510 | // + "sendData:" + bytesToHex(sendData) + "|" 511 | ); 512 | } else { 513 | log(LOGTAG_PACKET, "SEND DATA->" + 514 | "serviceCmd:" + serviceCmd + "|" + 515 | "requestSsoSeq:" + requestSsoSeq + "|" + 516 | "sendData Length:" + (sendData.length) + "|" + 517 | "wupBuffer Length:" + (wupBuffer.length) + "|" + 518 | "msgCookie:" + msgCookie + "|" + 519 | "uin:" + uin + "|" + 520 | "pbtimestamp:" + bytesToHex(pbtimestamp) + "|" + 521 | "wupBuffer:" + bytesToHex(wupBuffer) + "|" 522 | // + "sendData:" + bytesToHex(sendData) + "|" 523 | ); 524 | } 525 | 526 | } 527 | }); 528 | 529 | /** 530 | * 发送包V1 531 | */ 532 | //int i, String str, String str2, String str3, String str4, String str5, 533 | // byte[] bArr, int i2, int i3, String str6, 534 | // byte b, byte b2, byte b3, byte[] bArr2, byte[] bArr3, byte[] bArr4, boolean z 535 | XposedHelpers.findAndHookMethod(CodecWarpperClass, loadPackageParam.classLoader, "nativeEncodeRequest", 536 | int.class, String.class, String.class, String.class, String.class, String.class, 537 | byte[].class, 538 | int.class, int.class, String.class, 539 | byte.class, byte.class, byte.class, byte[].class, 540 | byte[].class, byte[].class, boolean.class, 541 | new XC_MethodHook() { 542 | @Override 543 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 544 | log("nativeEncodeRequest V1"); 545 | } 546 | 547 | @Override 548 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 549 | int requestSsoSeq = (int) param.args[0]; 550 | String imei = (String) param.args[1]; 551 | String subscriberId = (String) param.args[2]; 552 | String revision = (String) param.args[3]; 553 | String serviceCmd = (String) param.args[5]; 554 | String msgCookie = bytesToHex((byte[]) param.args[6]); 555 | int appid = (int) param.args[7]; 556 | int msfappid = (int) param.args[8]; 557 | String uin = (String) param.args[9]; 558 | byte netWorkType = (byte) param.args[11]; 559 | byte activeNetworkIpType = (byte) param.args[12]; 560 | byte[] reserveFields = (byte[]) param.args[13]; 561 | byte[] wupBuffer = (byte[]) param.args[15]; 562 | 563 | byte[] sendData = (byte[]) param.getResult(); 564 | 565 | if (serviceCmd.startsWith("wtlogin.")) { 566 | log(LOGTAG_PACKET, "SEND DATA->" + 567 | "serviceCmd:" + serviceCmd + "|" + 568 | "requestSsoSeq:" + requestSsoSeq + "|" + 569 | "sendData Length:" + (sendData.length) + "|" + 570 | "wupBuffer Length:" + (wupBuffer.length) + "|" + 571 | "imei:" + imei + "|" + 572 | "subscriberId:" + subscriberId + "|" + 573 | "revision:" + revision + "|" + 574 | "msgCookie:" + msgCookie + "|" + 575 | "appid:" + appid + "|" + 576 | "msfappid:" + msfappid + "|" + 577 | "uin:" + uin + "|" + 578 | "netWorkType:" + netWorkType + "|" + 579 | "activeNetworkIpType:" + activeNetworkIpType + "|" + 580 | "reserveFields:" + bytesToHex(reserveFields) + "|" + 581 | "wupBuffer:" + bytesToHex(wupBuffer) + "|" 582 | // + "sendData:" + bytesToHex(sendData) + "|" 583 | ); 584 | } else { 585 | log(LOGTAG_PACKET, "SEND DATA->" + 586 | "serviceCmd:" + serviceCmd + "|" + 587 | "requestSsoSeq:" + requestSsoSeq + "|" + 588 | "sendData Length:" + (sendData.length) + "|" + 589 | "wupBuffer Length:" + (wupBuffer.length) + "|" + 590 | "msgCookie:" + msgCookie + "|" + 591 | "uin:" + uin + "|" + 592 | "netWorkType:" + netWorkType + "|" + 593 | "activeNetworkIpType:" + activeNetworkIpType + "|" + 594 | "reserveFields:" + bytesToHex(reserveFields) + "|" + 595 | "wupBuffer:" + bytesToHex(wupBuffer) + "|" 596 | // + "sendData:" + bytesToHex(sendData) + "|" 597 | ); 598 | } 599 | } 600 | }); 601 | //Hook 接收包 602 | XposedHelpers.findAndHookMethod(CodecWarpperClass, loadPackageParam.classLoader, "nativeOnReceData", 603 | byte[].class, int.class, 604 | new XC_MethodHook() { 605 | @Override 606 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 607 | byte[] data = (byte[]) param.args[0]; 608 | log(LOGTAG_PACKET, "RECEIVE DATA ->" + 609 | "Buf Length:" + (data.length) + "|" + 610 | "Buf:" + bytesToHex(data) + "|i=" + param.args[1] 611 | ); 612 | } 613 | }); 614 | 615 | final Class FromServiceMsg = XposedHelpers.findClass("com.tencent.qphone.base.remote.FromServiceMsg", loadPackageParam.classLoader); 616 | XposedHelpers.findAndHookMethod("com.tencent.mobileqq.msf.core.ae$a", loadPackageParam.classLoader, "onResponse", 617 | int.class, Object.class, int.class, byte[].class, 618 | new XC_MethodHook() { 619 | @Override 620 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 621 | int p1 = (int) param.args[0]; 622 | Object fromServiceMsg = (Object) param.args[1]; 623 | int p3 = (int) param.args[2]; 624 | byte[] p4 = (byte[]) param.args[3]; 625 | 626 | 627 | int appId = 0; 628 | int appSeq = 0; 629 | HashMap attributes; 630 | String errorMsg = null; 631 | Bundle extraData; 632 | int flag = 0; 633 | byte fromVersion = 0; 634 | Object msfCommand = null; 635 | byte[] msgCookie = null; 636 | int resultCode = 0; 637 | String serviceCmd = null; 638 | int ssoSeq = 0; 639 | String uin = null; 640 | byte[] wupBuffer = null; 641 | 642 | //获取数据 643 | for (Field f : FromServiceMsg.getDeclaredFields()) { 644 | f.setAccessible(true); 645 | switch (f.getName()) { 646 | case "appId": 647 | appId = (int) f.get(fromServiceMsg); 648 | break; 649 | case "appSeq": 650 | appSeq = (int) f.get(fromServiceMsg); 651 | break; 652 | case "attributes": 653 | attributes = (HashMap) f.get(fromServiceMsg); 654 | break; 655 | case "errorMsg": 656 | errorMsg = (String) f.get(fromServiceMsg); 657 | break; 658 | case "extraData": 659 | extraData = (Bundle) f.get(fromServiceMsg); 660 | break; 661 | case "flag": 662 | flag = (int) f.get(fromServiceMsg); 663 | break; 664 | case "fromVersion": 665 | fromVersion = (byte) f.get(fromServiceMsg); 666 | break; 667 | case "msgCookie": 668 | msgCookie = (byte[]) f.get(fromServiceMsg); 669 | break; 670 | case "resultCode": 671 | resultCode = (int) f.get(fromServiceMsg); 672 | break; 673 | case "serviceCmd": 674 | serviceCmd = (String) f.get(fromServiceMsg); 675 | break; 676 | case "ssoSeq": 677 | ssoSeq = (int) f.get(fromServiceMsg); 678 | break; 679 | case "uin": 680 | uin = (String) f.get(fromServiceMsg); 681 | break; 682 | case "wupBuffer": 683 | wupBuffer = (byte[]) f.get(fromServiceMsg); 684 | break; 685 | case "msfCommand": 686 | msfCommand = f.get(fromServiceMsg).toString(); 687 | break; 688 | 689 | } 690 | } 691 | 692 | 693 | log(LOGTAG_PACKET, "RECEIVE -> onResponse ->" + 694 | "serviceCmd:" + serviceCmd + "|" + 695 | "appSeq:" + appSeq + "|" + 696 | "ssoSeq:" + ssoSeq + "|" + 697 | "wupBuffer Length:" + (wupBuffer.length) + "|" + 698 | "uin:" + uin + "|" + 699 | "resultCode:" + resultCode + "|" + 700 | // "" + p1 + "|" + 701 | // "" + fromServiceMsg + "|" + 702 | "len:" + p3 + "|" + 703 | // "" + bytesToHex(p4) + "|" + 704 | "msName:" + msfCommand + "|" + 705 | "errorMsg:" + errorMsg + "|" + 706 | "appId:" + appId + "|" + 707 | "flag:" + flag + "|" + 708 | "fromVersion:" + fromVersion + "|" + 709 | "msgCookie:" + bytesToHex(msgCookie) + "|" + 710 | "wupBuffer:" + bytesToHex(wupBuffer) + "|" 711 | ); 712 | } 713 | }); 714 | 715 | 716 | // log("Fix Tea Rand value:50"); 717 | 718 | 719 | log("Add All Hooks to MobileQQ Successful"); 720 | 721 | } 722 | 723 | public static String getLineInfo(int arg3) { 724 | String v0; 725 | if (arg3 < 0) { 726 | v0 = ""; 727 | return v0; 728 | } 729 | 730 | try { 731 | StackTraceElement v0_2 = new Throwable().getStackTrace()[arg3]; 732 | v0 = "[" + v0_2.getFileName() + ":" + v0_2.getLineNumber() + "]"; 733 | } catch (Throwable v0_1) { 734 | v0 = ""; 735 | } 736 | 737 | return v0; 738 | } 739 | 740 | public static String getStack() { 741 | try { 742 | StringBuffer sb = new StringBuffer(); 743 | StackTraceElement[] v0_2 = new Throwable().getStackTrace(); 744 | for (StackTraceElement ele : v0_2) { 745 | sb.append(ele.toString()) 746 | .append("#"); 747 | } 748 | return sb.toString(); 749 | } catch (Exception e) { 750 | 751 | } 752 | return "get stack error"; 753 | } 754 | 755 | final static int limit = 1023 * 3; 756 | 757 | public static void log(String msg) { 758 | log(LOGTAG, msg); 759 | } 760 | 761 | public static void log(String tag, String msg) { 762 | String uuid = UUID.randomUUID().toString(); 763 | 764 | if (msg.length() > limit) { 765 | while (msg.length() > limit) { 766 | Log.i(tag, "uuid:" + uuid + ":" + msg.substring(0, limit)); 767 | msg = msg.substring(limit); 768 | } 769 | Log.i(tag, "uuid:" + uuid + ":" + msg); 770 | } else { 771 | Log.i(tag, msg); 772 | } 773 | } 774 | 775 | private final static char[] hexArray = "0123456789ABCDEF".toCharArray(); 776 | 777 | public static String bytesToHex(byte[] bytes) { 778 | if (bytes == null) return "null"; 779 | char[] hexChars = new char[bytes.length * 2]; 780 | for (int j = 0; j < bytes.length; j++) { 781 | int v = bytes[j] & 0xFF; 782 | hexChars[j * 2] = hexArray[v >>> 4]; 783 | hexChars[j * 2 + 1] = hexArray[v & 0x0F]; 784 | } 785 | return new String(hexChars); 786 | } 787 | 788 | public static String formatTimeUnix10(long timeunix) { 789 | SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); 790 | return simpleDateFormat.format(timeunix * 1000); 791 | } 792 | } 793 | -------------------------------------------------------------------------------- /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 | 8 | 9 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GreyWolf007/AndroidQQHook/bb192a76c8cca95ddedaf0c9d1ec672341492740/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GreyWolf007/AndroidQQHook/bb192a76c8cca95ddedaf0c9d1ec672341492740/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GreyWolf007/AndroidQQHook/bb192a76c8cca95ddedaf0c9d1ec672341492740/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GreyWolf007/AndroidQQHook/bb192a76c8cca95ddedaf0c9d1ec672341492740/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GreyWolf007/AndroidQQHook/bb192a76c8cca95ddedaf0c9d1ec672341492740/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GreyWolf007/AndroidQQHook/bb192a76c8cca95ddedaf0c9d1ec672341492740/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GreyWolf007/AndroidQQHook/bb192a76c8cca95ddedaf0c9d1ec672341492740/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GreyWolf007/AndroidQQHook/bb192a76c8cca95ddedaf0c9d1ec672341492740/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GreyWolf007/AndroidQQHook/bb192a76c8cca95ddedaf0c9d1ec672341492740/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GreyWolf007/AndroidQQHook/bb192a76c8cca95ddedaf0c9d1ec672341492740/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | AndroidQQHook 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/test/java/com/example/greywolf/qq750hook/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.example.greywolf.qq750hook; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | 18 | 19 | } -------------------------------------------------------------------------------- /app/src/test/java/com/example/greywolf/qq750hook/Test.java: -------------------------------------------------------------------------------- 1 | package com.example.greywolf.qq750hook; 2 | 3 | /** 4 | * Created by GreyWolf on 2018/2/21. 5 | */ 6 | 7 | public class Test { 8 | public static void main(String[] args) { 9 | System.out.println(getLineInfo(2)); 10 | } 11 | 12 | public static String getLineInfo(int arg3) { 13 | String v0; 14 | if (arg3 < 0) { 15 | v0 = ""; 16 | return v0; 17 | } 18 | 19 | try { 20 | StackTraceElement v0_2 = new Throwable().getStackTrace()[arg3]; 21 | v0 = "[" + v0_2.getFileName() + ":" + v0_2.getLineNumber() + "]"; 22 | } catch (Throwable v0_1) { 23 | v0 = ""; 24 | } 25 | 26 | return v0; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | maven { 7 | url 'https://maven.google.com/' 8 | name 'Google' 9 | } 10 | maven { 11 | url "https://plugins.gradle.org/m2/" 12 | } 13 | mavenCentral() 14 | google() 15 | } 16 | dependencies { 17 | classpath 'com.android.tools.build:gradle:4.1.3' 18 | // NOTE: Do not place your application dependencies here; they belong 19 | // in the individual module build.gradle files 20 | } 21 | } 22 | 23 | allprojects { 24 | repositories { 25 | jcenter() 26 | maven { 27 | url 'https://maven.google.com/' 28 | name 'Google' 29 | } 30 | mavenCentral() 31 | google() 32 | } 33 | } 34 | 35 | task clean(type: Delete) { 36 | delete rootProject.buildDir 37 | } 38 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | ## For more details on how to configure your build environment visit 2 | # http://www.gradle.org/docs/current/userguide/build_environment.html 3 | # 4 | # Specifies the JVM arguments used for the daemon process. 5 | # The setting is particularly useful for tweaking memory settings. 6 | # Default value: -Xmx1024m -XX:MaxPermSize=256m 7 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 8 | # 9 | # When configured, Gradle will run in incubating parallel mode. 10 | # This option should only be used with decoupled projects. More details, visit 11 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 12 | # org.gradle.parallel=true 13 | #Wed Feb 16 09:37:52 CST 2022 14 | org.gradle.jvmargs=-Xmx1536m 15 | android.useAndroidX=true 16 | android.enableJetifier=true 17 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GreyWolf007/AndroidQQHook/bb192a76c8cca95ddedaf0c9d1ec672341492740/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /script/pullLogFile.bat: -------------------------------------------------------------------------------- 1 | echo pull logcat file 2 | adb pull /sdcard/qq.log -------------------------------------------------------------------------------- /script/viewlog.bat: -------------------------------------------------------------------------------- 1 | echo View Logcat 2 | start cmd /c "echo startlog&&adb shell rm -f /sdcard/qq.log&&adb logcat -v time -f /sdcard/qq.log -s qqhook" 3 | sleep 1 4 | start cmd /c "adb shell tail -f /sdcard/qq.log" 5 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | --------------------------------------------------------------------------------