Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SandHook: convert all inner hookers to sandhook #175

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 61 additions & 10 deletions dexmaker/src/main/java/external/com/android/dx/DexMaker.java
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ TypeDeclaration getTypeDeclaration(TypeId<?> type) {
* Modifier#FINAL} and {@link Modifier#ABSTRACT}.
*/
public void declare(TypeId<?> type, String sourceFile, int flags,
TypeId<?> supertype, TypeId<?>... interfaces) {
TypeId<?> supertype, TypeId<?>... interfaces) {
TypeDeclaration declaration = getTypeDeclaration(type);
int supportedFlags = Modifier.PUBLIC | Modifier.FINAL | Modifier.ABSTRACT
| AccessFlags.ACC_SYNTHETIC;
Expand Down Expand Up @@ -471,8 +471,23 @@ private ClassLoader generateClassLoader(File result, File dexCache, ClassLoader
}
}

public ClassLoader loadClassDirect(ClassLoader parent, File dexCache, String dexFileName) {
File result = new File(dexCache, dexFileName);
// Check that the file exists. If it does, return a DexClassLoader and skip all
// the dex bytecode generation.
if (result.exists()) {
return generateClassLoader(result, dexCache, parent);
} else {
return null;
}
}

public ClassLoader generateAndLoad(ClassLoader parent, File dexCache) throws IOException {
return generateAndLoad(parent, dexCache, null);
return generateAndLoad(parent, dexCache, generateFileName(), false);
}

public ClassLoader generateAndLoad(ClassLoader parent, File dexCache, String dexFileName) throws IOException {
return generateAndLoad(parent, dexCache, dexFileName, false);
}

/**
Expand Down Expand Up @@ -500,9 +515,8 @@ public ClassLoader generateAndLoad(ClassLoader parent, File dexCache) throws IOE
* @param dexCache the destination directory where generated and optimized
* dex files will be written. If null, this class will try to guess the
* application's private data dir.
* @param fileName the name of dex file
*/
public ClassLoader generateAndLoad(ClassLoader parent, File dexCache, String fileName) throws IOException {
public ClassLoader generateAndLoad(ClassLoader parent, File dexCache, String dexFileName, boolean deleteOld) throws IOException {
if (dexCache == null) {
String property = System.getProperty("dexmaker.dexcache");
if (property != null) {
Expand All @@ -516,13 +530,17 @@ public ClassLoader generateAndLoad(ClassLoader parent, File dexCache, String fil
}
}

if (fileName == null || fileName.isEmpty())
fileName = generateFileName();
File result = new File(dexCache, fileName);
// Check that the file exists. If it does, return a DexClassLoader and skip all
// the dex bytecode generation.
File result = new File(dexCache, dexFileName);

if (result.exists()) {
return generateClassLoader(result, dexCache, parent);
if (deleteOld) {
try {
deleteOldDex(result);
} catch (Throwable throwable) {
}
} else {
return generateClassLoader(result, dexCache, parent);
}
}

/*
Expand All @@ -532,7 +550,14 @@ public ClassLoader generateAndLoad(ClassLoader parent, File dexCache, String fil
*
* TODO: load the dex from memory where supported.
*/

File parentDir = result.getParentFile();
if (!parentDir.exists()) {
parentDir.mkdirs();
}

result.createNewFile();

JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(result));
JarEntry entry = new JarEntry(DexFormat.DEX_IN_JAR_NAME);
byte[] dex = generate();
Expand All @@ -544,6 +569,32 @@ public ClassLoader generateAndLoad(ClassLoader parent, File dexCache, String fil
return generateClassLoader(result, dexCache, parent);
}

public void deleteOldDex(File dexFile) {
dexFile.delete();
String dexDir = dexFile.getParent();
File oatDir = new File(dexDir, "/oat/");
File oatDirArm = new File(oatDir, "/arm/");
File oatDirArm64 = new File(oatDir, "/arm64/");
if (!oatDir.exists())
return;
String nameStart = dexFile.getName().replaceAll(".jar", "");
doDeleteOatFiles(oatDir, nameStart);
doDeleteOatFiles(oatDirArm, nameStart);
doDeleteOatFiles(oatDirArm64, nameStart);
}

private void doDeleteOatFiles(File dir, String nameStart) {
if (!dir.exists())
return;
File[] oats = dir.listFiles();
if (oats == null)
return;
for (File oatFile:oats) {
if (oatFile.isFile() && oatFile.getName().startsWith(nameStart))
oatFile.delete();
}
}

DexFile getDexFile() {
if (outputDex == null) {
DexOptions options = new DexOptions();
Expand Down
2 changes: 1 addition & 1 deletion edxp-sandhook/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ dependencies {
compileOnly files("libs/framework-stub.jar")
implementation project(':edxp-common')
implementation project(':xposed-bridge')
implementation 'com.swift.sandhook:hooklib:3.2.2'
implementation 'com.swift.sandhook:hooklib:3.2.8'
compileOnly project(':dexmaker')
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import android.text.TextUtils;

import com.elderdrivers.riru.edxp.config.EdXpConfigGlobal;
import com.elderdrivers.riru.edxp.util.Utils;
import com.elderdrivers.riru.edxp.sandhook.config.SandHookEdxpConfig;
import com.elderdrivers.riru.edxp.sandhook.config.SandHookProvider;
import com.elderdrivers.riru.edxp.sandhook.core.HookMain;
Expand All @@ -14,9 +13,9 @@
import com.elderdrivers.riru.edxp.sandhook.entry.bootstrap.SysInnerHookInfo;
import com.elderdrivers.riru.edxp.sandhook.entry.bootstrap.WorkAroundHookInfo;
import com.elderdrivers.riru.edxp.sandhook.entry.hooker.SystemMainHooker;
import com.elderdrivers.riru.edxp.util.Utils;
import com.swift.sandhook.SandHookConfig;
import com.swift.sandhook.xposedcompat.XposedCompat;
import com.swift.sandhook.xposedcompat.methodgen.SandHookXposedBridge;

import java.util.concurrent.atomic.AtomicBoolean;

Expand All @@ -31,6 +30,12 @@ public class Router {

private static volatile AtomicBoolean bootstrapHooked = new AtomicBoolean(false);

static boolean useSandHook;

static {
useSandHook = EdXpConfigGlobal.getHookProvider() instanceof SandHookProvider;
}


public static void prepare(boolean isSystem) {
// this flag is needed when loadModules
Expand Down Expand Up @@ -81,33 +86,46 @@ public static void startBootstrapHook(boolean isSystem) {
Utils.logD("startBootstrapHook starts: isSystem = " + isSystem);
ClassLoader classLoader = XposedBridge.BOOTCLASSLOADER;
if (isSystem) {
HookMain.doHookDefault(
if (useSandHook) {
XposedCompat.addHookers(classLoader, SysBootstrapHookInfo.hookItems);
} else {
HookMain.doHookDefault(
Router.class.getClassLoader(),
classLoader,
SysBootstrapHookInfo.class.getName());
XposedCompat.addHookers(classLoader, SysBootstrapHookInfo.hookItems);
}
} else {
HookMain.doHookDefault(
Router.class.getClassLoader(),
classLoader,
AppBootstrapHookInfo.class.getName());
XposedCompat.addHookers(classLoader, AppBootstrapHookInfo.hookItems);
if (useSandHook) {
XposedCompat.addHookers(classLoader, AppBootstrapHookInfo.hookItems);
} else {
HookMain.doHookDefault(
Router.class.getClassLoader(),
classLoader,
AppBootstrapHookInfo.class.getName());
}
}
}

public static void startSystemServerHook() {
// HookMain.doHookDefault(
// Router.class.getClassLoader(),
// SystemMainHooker.systemServerCL,
// SysInnerHookInfo.class.getName());
XposedCompat.addHookers(SystemMainHooker.systemServerCL, SysInnerHookInfo.hookItems);
if (useSandHook) {
XposedCompat.addHookers(SystemMainHooker.systemServerCL, SysInnerHookInfo.hookItems);
} else {
HookMain.doHookDefault(
Router.class.getClassLoader(),
SystemMainHooker.systemServerCL,
SysInnerHookInfo.class.getName());
}
}

public static void startWorkAroundHook() {
HookMain.doHookDefault(
Router.class.getClassLoader(),
XposedBridge.BOOTCLASSLOADER,
WorkAroundHookInfo.class.getName());
if (useSandHook) {
XposedCompat.addHookers(XposedBridge.BOOTCLASSLOADER, WorkAroundHookInfo.hookItems);
} else {
HookMain.doHookDefault(
Router.class.getClassLoader(),
XposedBridge.BOOTCLASSLOADER,
WorkAroundHookInfo.class.getName());
}
}

public static void onEnterChildProcess() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@

public class AppBootstrapHookInfo implements KeepMembers {
public static String[] hookItemNames = {
OnePlusWorkAroundHooker.class.getName()
OnePlusWorkAroundHooker.class.getName(),
HandleBindAppHooker.class.getName(),
LoadedApkConstructorHooker.class.getName(),
};

public static Class[] hookItems = {
HandleBindAppHooker.class,
LoadedApkConstructorHooker.class
LoadedApkConstructorHooker.class,
OnePlusWorkAroundHooker.class
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@

public class SysBootstrapHookInfo implements KeepMembers {
public static String[] hookItemNames = {
OnePlusWorkAroundHooker.class.getName()
OnePlusWorkAroundHooker.class.getName(),
HandleBindAppHooker.class.getName(),
SystemMainHooker.class.getName(),
LoadedApkConstructorHooker.class.getName()
};

public static Class[] hookItems = {
HandleBindAppHooker.class,
SystemMainHooker.class,
LoadedApkConstructorHooker.class
LoadedApkConstructorHooker.class,
OnePlusWorkAroundHooker.class
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ public class WorkAroundHookInfo implements KeepMembers {
};

public static Class[] hookItems = {
OnePlusWorkAroundHooker.class
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@
import android.content.res.CompatibilityInfo;

import com.elderdrivers.riru.common.KeepMembers;
import com.elderdrivers.riru.edxp.util.Utils;
import com.elderdrivers.riru.edxp.Main;
import com.elderdrivers.riru.edxp.sandhook.entry.Router;
import com.elderdrivers.riru.edxp.util.Utils;
import com.swift.sandhook.SandHook;
import com.swift.sandhook.annotation.HookClass;
import com.swift.sandhook.annotation.HookMethod;
import com.swift.sandhook.annotation.HookMethodBackup;
import com.swift.sandhook.annotation.HookMode;
import com.swift.sandhook.annotation.Param;
import com.swift.sandhook.annotation.SkipParamCheck;
import com.swift.sandhook.annotation.ThisObject;
Expand All @@ -27,8 +26,8 @@
import de.robv.android.xposed.callbacks.XC_LoadPackage;

import static com.elderdrivers.riru.edxp.config.InstallerChooser.INSTALLER_PACKAGE_NAME;
import static com.elderdrivers.riru.edxp.util.ClassLoaderUtils.replaceParentClassLoader;
import static com.elderdrivers.riru.edxp.sandhook.entry.hooker.XposedBlackListHooker.BLACK_LIST_PACKAGE_NAME;
import static com.elderdrivers.riru.edxp.util.ClassLoaderUtils.replaceParentClassLoader;

// normal process initialization (for new Activity, Service, BroadcastReceiver etc.)
@HookClass(ActivityThread.class)
Expand All @@ -45,7 +44,7 @@ public class HandleBindAppHooker implements KeepMembers {
@HookMethod("handleBindApplication")
public static void hook(@ThisObject ActivityThread thiz, @Param("android.app.ActivityThread$AppBindData") Object bindData) throws Throwable {
if (XposedBlackListHooker.shouldDisableHooks("")) {
SandHook.callOriginByBackup(backup, thiz, bindData);
backup(thiz, bindData);
return;
}
try {
Expand Down Expand Up @@ -96,10 +95,11 @@ public static void hook(@ThisObject ActivityThread thiz, @Param("android.app.Act
} catch (Throwable t) {
Router.logE("error when hooking bindApp", t);
} finally {
SandHook.callOriginByBackup(backup, thiz, bindData);
backup(thiz, bindData);
}
}

public static void backup(Object thiz, Object bindData) {
public static void backup(Object thiz, Object bindData) throws Throwable {
SandHook.callOriginByBackup(backup, thiz, bindData);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,12 @@ public static void hook(@ThisObject Object thiz, ActivityThread activityThread,
boolean includeCode, boolean registerPackage) throws Throwable {

if (XposedBlackListHooker.shouldDisableHooks("")) {
SandHook.callOriginByBackup(backup, thiz, activityThread, aInfo, compatInfo, baseLoader, securityViolation, includeCode, registerPackage);

backup(thiz, activityThread, aInfo, compatInfo, baseLoader, securityViolation, includeCode, registerPackage);
return;
}

Router.logD("LoadedApk#<init> starts");
SandHook.callOriginByBackup(backup, thiz, activityThread, aInfo, compatInfo, baseLoader, securityViolation, includeCode, registerPackage);
backup(thiz, activityThread, aInfo, compatInfo, baseLoader, securityViolation, includeCode, registerPackage);

try {
LoadedApk loadedApk = (LoadedApk) thiz;
Expand Down Expand Up @@ -105,7 +104,7 @@ public static void hook(@ThisObject Object thiz, ActivityThread activityThread,
public static void backup(Object thiz, ActivityThread activityThread,
ApplicationInfo aInfo, CompatibilityInfo compatInfo,
ClassLoader baseLoader, boolean securityViolation,
boolean includeCode, boolean registerPackage) {

boolean includeCode, boolean registerPackage) throws Throwable {
SandHook.callOriginByBackup(backup, thiz, activityThread, aInfo, compatInfo, baseLoader, securityViolation, includeCode, registerPackage);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.elderdrivers.riru.common.KeepMembers;
import com.elderdrivers.riru.edxp.Main;
import com.elderdrivers.riru.edxp.sandhook.entry.Router;
import com.swift.sandhook.SandHook;
import com.swift.sandhook.annotation.HookClass;
import com.swift.sandhook.annotation.HookMethod;
import com.swift.sandhook.annotation.HookMethodBackup;
Expand Down Expand Up @@ -40,15 +41,15 @@ public class OnePlusWorkAroundHooker implements KeepMembers {
static Method backup;

@HookMethod("inCompatConfigList")
public static boolean hook(int type, String packageName) {
public static boolean hook(int type, String packageName) throws Throwable {
if (XposedBridge.disableHooks || Router.forkCompleted) {
return backup(type, packageName);
}
Router.logD("BaseDexClassLoader#inCompatConfigList() starts");
return false;
}

public static boolean backup(int type, String packageName) {
return false;
public static boolean backup(int type, String packageName) throws Throwable {
return (boolean) SandHook.callOriginByBackup(backup, null, type, packageName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public class StartBootstrapServicesHooker implements KeepMembers {
public static void hook(@ThisObject Object systemServer) throws Throwable {

if (XposedBridge.disableHooks) {
SandHook.callOriginByBackup(backup, systemServer);
backup(systemServer);
return;
}

Expand Down Expand Up @@ -71,11 +71,11 @@ public static void hook(@ThisObject Object systemServer) throws Throwable {
} catch (Throwable t) {
Router.logE("error when hooking startBootstrapServices", t);
} finally {
SandHook.callOriginByBackup(backup, systemServer);
backup(systemServer);
}
}

public static void backup(Object systemServer) {

public static void backup(Object systemServer) throws Throwable {
SandHook.callOriginByBackup(backup, systemServer);
}
}
Loading