-
Notifications
You must be signed in to change notification settings - Fork 161
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
adj: new dexkit cache and browser use this for debugging
- Loading branch information
Showing
7 changed files
with
378 additions
and
117 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
137 changes: 137 additions & 0 deletions
137
app/src/main/java/com/sevtinge/hyperceiler/module/base/dexkit/DexKitCacheFile.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
package com.sevtinge.hyperceiler.module.base.dexkit; | ||
|
||
import static com.sevtinge.hyperceiler.utils.log.XposedLogUtils.logD; | ||
import static com.sevtinge.hyperceiler.utils.log.XposedLogUtils.logE; | ||
import static com.sevtinge.hyperceiler.utils.log.XposedLogUtils.logI; | ||
|
||
import org.json.JSONArray; | ||
import org.json.JSONException; | ||
|
||
import java.io.BufferedReader; | ||
import java.io.BufferedWriter; | ||
import java.io.File; | ||
import java.io.FileReader; | ||
import java.io.FileWriter; | ||
import java.io.IOException; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.Paths; | ||
import java.nio.file.attribute.PosixFilePermission; | ||
import java.util.Set; | ||
|
||
import de.robv.android.xposed.callbacks.XC_LoadPackage; | ||
|
||
public class DexKitCacheFile { | ||
|
||
static String TAG = "DexKitCacheFile"; | ||
|
||
public static String getFilePath(XC_LoadPackage.LoadPackageParam loadPackageParam, String callingClassName, String tag) { | ||
return "/data/user/0/" + loadPackageParam.packageName + "/cache/HyperCeiler_" + callingClassName + "_" + tag + "_DexKit_Cache.dat"; | ||
} | ||
|
||
public static void checkFile(XC_LoadPackage.LoadPackageParam loadPackageParam, String callingClassName, String tag) { | ||
String path = getFilePath(loadPackageParam, callingClassName, tag); | ||
File file = new File(path); | ||
File parentDir = file.getParentFile(); | ||
if (parentDir == null) { | ||
logE(TAG, "parentDir is null: " + path); | ||
} | ||
if (parentDir != null && !parentDir.exists()) { | ||
if (parentDir.mkdirs()) { | ||
logI(TAG, "mkdirs: " + parentDir); | ||
} else { | ||
logE(TAG, "mkdirs: " + parentDir); | ||
} | ||
} | ||
if (!file.exists()) { | ||
try { | ||
if (file.createNewFile()) { | ||
writeFile(loadPackageParam, new JSONArray(), callingClassName, tag); | ||
setPermission(path); | ||
logI(TAG, "createNewFile: " + file); | ||
} else { | ||
logE(TAG, "createNewFile: " + file); | ||
} | ||
} catch (IOException e) { | ||
logE(TAG, "createNewFile: " + e); | ||
} | ||
} else { | ||
setPermission(path); | ||
} | ||
} | ||
|
||
public static void writeFile(XC_LoadPackage.LoadPackageParam loadPackageParam, JSONArray jsonArray, String callingClassName, String tag) { | ||
String path = getFilePath(loadPackageParam, callingClassName, tag); | ||
if (jsonArray == null) { | ||
logE(TAG, "write json is null"); | ||
return; | ||
} | ||
try (BufferedWriter writer = new BufferedWriter(new | ||
FileWriter(path, false))) { | ||
writer.write(jsonArray.toString()); | ||
} catch (IOException e) { | ||
logE(TAG, "writeFile: " + e); | ||
} | ||
} | ||
|
||
public static boolean isEmptyFile(XC_LoadPackage.LoadPackageParam loadPackageParam, String callingClassName, String tag) { | ||
if(!isFileExists(loadPackageParam, callingClassName, tag)){ | ||
JSONArray jsonArray = readFile(loadPackageParam, callingClassName, tag); | ||
return jsonArray.length() == 0; | ||
} | ||
return false; | ||
} | ||
|
||
public static boolean isFileExists(XC_LoadPackage.LoadPackageParam loadPackageParam, String callingClassName, String tag) { | ||
File file = new File(getFilePath(loadPackageParam, callingClassName, tag)); | ||
return file.exists(); | ||
} | ||
|
||
public static JSONArray readFile(XC_LoadPackage.LoadPackageParam loadPackageParam, String callingClassName, String tag) { | ||
String path = getFilePath(loadPackageParam, callingClassName, tag); | ||
try (BufferedReader reader = new BufferedReader(new | ||
FileReader(path))) { | ||
StringBuilder builder = new StringBuilder(); | ||
String line; | ||
while ((line = reader.readLine()) != null) { | ||
builder.append(line); | ||
} | ||
String jsonString = builder.toString(); | ||
if (jsonString.isEmpty()) { | ||
jsonString = "[]"; | ||
} | ||
return new JSONArray(jsonString); | ||
} catch (IOException | JSONException e) { | ||
logE(TAG, "readFile: " + e); | ||
} | ||
return new JSONArray(); | ||
} | ||
|
||
public static boolean resetFile(XC_LoadPackage.LoadPackageParam loadPackageParam, String callingClassName, String tag) { | ||
// 清空文件内容 | ||
writeFile(loadPackageParam, new JSONArray(), callingClassName, tag); | ||
return isEmptyFile(loadPackageParam, callingClassName, tag); | ||
} | ||
|
||
public static void setPermission(String paths) { | ||
// 指定文件的路径 | ||
Path filePath = Paths.get(paths); | ||
|
||
try { | ||
// 获取当前文件的权限 | ||
Set<PosixFilePermission> permissions = Files.getPosixFilePermissions(filePath); | ||
|
||
// 添加世界可读写权限 | ||
permissions.add(PosixFilePermission.OTHERS_READ); | ||
permissions.add(PosixFilePermission.OTHERS_WRITE); | ||
permissions.add(PosixFilePermission.GROUP_READ); | ||
permissions.add(PosixFilePermission.GROUP_WRITE); | ||
|
||
// 设置新的权限 | ||
Files.setPosixFilePermissions(filePath, permissions); | ||
} catch (IOException e) { | ||
logE(TAG, "setPermission: " + e); | ||
} | ||
} | ||
|
||
} |
150 changes: 150 additions & 0 deletions
150
app/src/main/java/com/sevtinge/hyperceiler/module/base/dexkit/DexKitData.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
package com.sevtinge.hyperceiler.module.base.dexkit; | ||
|
||
import static com.sevtinge.hyperceiler.module.base.dexkit.DexKitCacheFile.readFile; | ||
import static com.sevtinge.hyperceiler.module.base.tool.OtherTool.getPackageVersionCode; | ||
import static com.sevtinge.hyperceiler.utils.log.XposedLogUtils.logD; | ||
import static com.sevtinge.hyperceiler.utils.log.XposedLogUtils.logE; | ||
|
||
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; | ||
import static de.robv.android.xposed.XposedHelpers.findClassIfExists; | ||
|
||
import com.sevtinge.hyperceiler.module.base.dexkit.DexKitCacheFile; | ||
|
||
import org.json.JSONArray; | ||
import org.json.JSONException; | ||
import org.json.JSONObject; | ||
import org.luckypray.dexkit.query.FindMethod; | ||
import org.luckypray.dexkit.query.matchers.MethodMatcher; | ||
import org.luckypray.dexkit.result.MethodData; | ||
|
||
import java.lang.reflect.Method; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
import java.util.Objects; | ||
|
||
import de.robv.android.xposed.XC_MethodHook; | ||
import de.robv.android.xposed.callbacks.XC_LoadPackage; | ||
|
||
public class DexKitData { | ||
|
||
public static void hookMethodWithDexKit(String tag, XC_LoadPackage.LoadPackageParam loadPackageParam, MethodMatcher methodMatcher, Object... callback) { | ||
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); | ||
String callingClassName = stackTrace[3].getClassName(); | ||
int lastDotIndex = callingClassName.lastIndexOf('.'); | ||
callingClassName = callingClassName.substring(lastDotIndex + 1); | ||
try { | ||
String className; | ||
String methodName; | ||
List<String> paramList; | ||
if (!DexKitCacheFile.isEmptyFile(loadPackageParam, callingClassName, tag)) { | ||
try { | ||
className = getClassName(loadPackageParam, callingClassName, tag); | ||
methodName = getMethodName(loadPackageParam, callingClassName, tag); | ||
paramList = getParamList(loadPackageParam, callingClassName, tag); | ||
} catch (JSONException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} else { | ||
MethodData methodData = DexKit.getDexKitBridge().findMethod(FindMethod.create() | ||
.matcher(methodMatcher) | ||
).singleOrThrow(() -> new IllegalStateException("No Such Method Found.")); | ||
className = methodData.getClassName(); | ||
methodName = methodData.getMethodName(); | ||
paramList = methodData.getParamNames(); | ||
putDexKitCache(loadPackageParam, callingClassName, tag, className, methodName, paramList); | ||
} | ||
if (paramList == null) { | ||
findAndHookMethod(findClassIfExists(className, loadPackageParam.classLoader), methodName, callback); | ||
} else { | ||
findAndHookMethod(findClassIfExists(className, loadPackageParam.classLoader), methodName, paramList.toArray(), callback); | ||
} | ||
} catch (Exception e){ | ||
logE(callingClassName, loadPackageParam.packageName, "Having trouble finding "+tag+": "+e); | ||
} | ||
} | ||
|
||
public static void putDexKitCache(XC_LoadPackage.LoadPackageParam loadPackageParam, String callingClassName, String tag, String className, String methodName, List<String> paramList) { | ||
JSONObject jsonObject = new JSONObject(); | ||
try { | ||
jsonObject.put("ClassName", className); | ||
jsonObject.put("MethodName", methodName); | ||
jsonObject.put("ParamList", paramList); | ||
} catch (JSONException e) { | ||
throw new RuntimeException(e); | ||
} | ||
JSONArray jsonArray = new JSONArray(); | ||
jsonArray.put(jsonObject); | ||
DexKitCacheFile.writeFile(loadPackageParam, jsonArray, callingClassName, tag); | ||
} | ||
|
||
public static String getClassName(XC_LoadPackage.LoadPackageParam loadPackageParam, String callingClassName, String tag) throws JSONException { | ||
return readFile(loadPackageParam, callingClassName, tag).getJSONObject(0).getString("ClassName"); | ||
} | ||
|
||
public static String getMethodName(XC_LoadPackage.LoadPackageParam loadPackageParam, String callingClassName, String tag) throws JSONException { | ||
return readFile(loadPackageParam, callingClassName, tag).getJSONObject(0).getString("MethodName"); | ||
} | ||
|
||
public static List<String> getParamList(XC_LoadPackage.LoadPackageParam loadPackageParam, String callingClassName, String tag) throws JSONException { | ||
JSONObject jsonObject = readFile(loadPackageParam, callingClassName, tag).getJSONObject(0); | ||
if (jsonObject.has("ParamList")) { | ||
List<String> list = Arrays.asList(jsonObject.getString("ParamList").split(",")); | ||
if (!list.isEmpty()) { | ||
return list; | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
public static class MethodHookWithDexKit extends XC_MethodHook { | ||
|
||
protected void before(MethodHookParam param) throws Throwable { | ||
} | ||
|
||
protected void after(MethodHookParam param) throws Throwable { | ||
} | ||
|
||
public MethodHookWithDexKit() { | ||
super(); | ||
} | ||
|
||
public MethodHookWithDexKit(int priority) { | ||
super(priority); | ||
} | ||
|
||
public static MethodHookWithDexKit returnConstant(final Object result) { | ||
return new MethodHookWithDexKit(PRIORITY_DEFAULT) { | ||
@Override | ||
protected void before(MethodHookParam param) { | ||
param.setResult(result); | ||
} | ||
}; | ||
} | ||
|
||
public static final MethodHookWithDexKit DO_NOTHING = new MethodHookWithDexKit(PRIORITY_HIGHEST * 2) { | ||
@Override | ||
protected void before(MethodHookParam param) { | ||
param.setResult(null); | ||
} | ||
}; | ||
|
||
@Override | ||
public void beforeHookedMethod(MethodHookParam param) throws Throwable { | ||
try { | ||
this.before(param); | ||
} catch (Throwable t) { | ||
// logE("BeforeHook", t); | ||
} | ||
} | ||
|
||
@Override | ||
public void afterHookedMethod(MethodHookParam param) throws Throwable { | ||
try { | ||
this.after(param); | ||
} catch (Throwable t) { | ||
// logE("AfterHook", t); | ||
} | ||
} | ||
} | ||
|
||
} |
53 changes: 53 additions & 0 deletions
53
app/src/main/java/com/sevtinge/hyperceiler/module/hook/browser/DebugMode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package com.sevtinge.hyperceiler.module.hook.browser; | ||
|
||
import static com.sevtinge.hyperceiler.module.base.tool.OtherTool.getPackageVersionCode; | ||
|
||
import com.sevtinge.hyperceiler.module.base.BaseHook; | ||
import com.sevtinge.hyperceiler.module.base.dexkit.DexKitData; | ||
|
||
import org.luckypray.dexkit.query.matchers.MethodMatcher; | ||
|
||
public class DebugMode extends BaseHook { | ||
@Override | ||
public void init() throws NoSuchMethodException { | ||
DexKitData.hookMethodWithDexKit("EnvironmentFlag", lpparam, | ||
MethodMatcher.create() | ||
.usingStrings("environment_flag") | ||
.returnType(String.class), | ||
new DexKitData.MethodHookWithDexKit() { | ||
@Override | ||
protected void before(MethodHookParam param) throws Throwable { | ||
param.setResult(1); | ||
} | ||
}); | ||
DexKitData.hookMethodWithDexKit("DebugMode0", lpparam, | ||
MethodMatcher.create() | ||
.usingStrings("pref_key_debug_mode_new") | ||
.returnType(boolean.class), | ||
new DexKitData.MethodHookWithDexKit() { | ||
@Override | ||
protected void before(MethodHookParam param) throws Throwable { | ||
param.setResult(true); | ||
} | ||
}); | ||
DexKitData.hookMethodWithDexKit("DebugMode1", lpparam, | ||
MethodMatcher.create() | ||
.usingStrings("pref_key_debug_mode") | ||
.returnType(boolean.class), | ||
new DexKitData.MethodHookWithDexKit() { | ||
@Override | ||
protected void before(MethodHookParam param) throws Throwable { | ||
param.setResult(true); | ||
} | ||
}); | ||
DexKitData.hookMethodWithDexKit("Key", lpparam, | ||
MethodMatcher.create() | ||
.usingStrings("pref_key_debug_mode_" + getPackageVersionCode(lpparam)) | ||
.returnType(boolean.class), new DexKitData.MethodHookWithDexKit() { | ||
@Override | ||
protected void before(MethodHookParam param) throws Throwable { | ||
param.setResult(true); | ||
} | ||
}); | ||
} | ||
} |
Oops, something went wrong.