Tip: Version Notice: Version 1.0.0 introduces significant changes, making the tool more static, better suited to its purpose, and offering improved performance and usability.
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
dependencies {
// Choose one of these options; jitpack is recommended as maven might not update as frequently.
// Tip: Replace v.*.*.* with the latest release version.
implementation 'com.github.HChenX:HookTool:v.1.1.0' // jitpack
implementation 'io.github.hchenx:hooktool:v.1.1.0'
// maven Tip: Almost abandoned, please do not use!
}
- HCInit Example.
public void init() {
HCInit.initBasicData(); // Initialize basic module information
HCInit.initStartupParam(); // Initialize the tool during the zygote phase
HCInit.initLoadPackageParam(); // Initialize the tool during the loadPackage phase
}
- Initialize the tool in the Xposed entry point.
@Override
public void initZygote(IXposedHookZygoteInit.StartupParam startupParam) {
HCInit.initBasicData(new BasicData()
.setModulePackageName("com.hchen.demo") // Module package name
.setTag("HChenDemo") // Log tag
.setLogLevel(LOG_D) // Log level
.setPrefsName("hchen_prefs") // Prefs storage file name (optional)
.xPrefsAutoReload(true) // Automatically reload shared preferences, enabled by default (optional)
.useLogExpand(new String[]{
"com.hchen.demo.hook"
}) // Enable logging enhancement features, see method comments for details
); // Tip: Recommended to configure here if using initZygote, as it is initialized early on.
HCInit.initStartupParam(startupParam); // Initialize the tool during the zygote phase
}
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) {
HCInit.initLoadPackageParam(lpparam); // Initialize the tool during the loadPackage phase
}
- If you need to use the prefs tool or the log class in the module, initialize them in the main module screen.
public static class MainActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
HCInit.initBasicData(new BasicData()
.setModulePackageName("com.hchen.demo") // Module package name
.setTag("HChenDemo") // Log tag
.setLogLevel(LOG_D) // Log level
.setPrefsName("hchen_prefs") // Prefs storage file name. (Optional) Tip: Ensure it matches the file name in Xposed.
);
}
}
- Usage Examples
public class MainTest {
public void test() {
CoreTool.hookMethod(/* content */); // Hook method
CoreTool.findClass().get(); // Find class
CoreTool.callMethod(); // Call method
ChainTool.chain("com.hchen.demo", new ChainTool()
.method("method")
.hook()
.method("method")
.hook()
); // Chain calls
PrefsTool.prefs().getString(); // Access shared preferences
// ......
}
}
- Alternatively, you can inherit classes packaged within this tool.
- Strongly recommended to inherit BaseHC for use!
// Hook implementation
public class MainTest extends BaseHC {
@Override
public void init() {
// BaseHC inherits CoreTool tool, so you can call methods directly.
}
// Optional.
// Executed in the zygote phase.
// Be sure to initialize HCInit.initStartupParam(startupParam) at the hook entry point.
@Override
public void initZygote(IXposedHookZygoteInit.StartupParam startupParam) {
Class<?> c = findClass("com.hchen.demo.Main").get();
hookMethod(c, "test", new IHook() {
/* content */
});
}
}
// Executor
public class RunHook implements IXposedHookLoadPackage, IXposedHookZygoteInit {
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) {
new MainTest().onLoadPackage(); // Hook at the loadPackage stage.
}
@Override
public void initZygote(StartupParam startupParam) {
new MainTest().onZygote(); // Hook at the initZygote stage.
}
}
- ProGuard configuration:
// If you do not require log enhancement, add only the following rule (for classes inheriting BaseHC):
-keep class * extends com.hchen.hooktool.BaseHC
// If using log enhancement, add the following rules:
// Suppose hook files are in the directory com.hchen.demo.hook
// If stored in multiple directories, add each directory accordingly.
-keep class com.hchen.demo.hook.**
-keep class com.hchen.demo.hook.**$*
- Done! Enjoy using the tool!
- The tool supports chained calls using the chain() method.
- This is a newly structured chaining solution introduced in the refactored version, making it more efficient and concise.
- Example Code:
// Chain call example
public class MainTest extends BaseHC {
public void test() {
// Look! Isn't it clear and easy to understand?
chain("com.hchen.demo", method("test")
.hook(new IHook() {
@Override
public void before() {
super.before();
}
})
.anyMethod("test")
.hook(new IHook() {
@Override
public void after() {
super.after();
}
})
.constructor()
.returnResult(false)
);
}
}
- This tool is designed with a comprehensive error handling logic, aiming to prevent interruptions in the hook process.
- Example:
public class MainTest extends BaseHC {
public void init() {
Class<?> c = findClass("com.hchen.demo.Demo").get(); // If the class cannot be retrieved, an error log is recorded and null is returned.
hookMethod(c, "test", new IHook() { // If c is null, an error log is recorded and the hook is skipped, allowing the rest of the code to continue.
@Override
public void before() {
((Object) null).getClass(); // Even if an error occurs, it will be logged without being passed to the host app or disrupting the hook process.
}
});
setStaticField("com.hchen.demo.Demo", "demo", true);
callStaticMethod("com.hchen.demo.Demo", "isDemo", false);
((Object) null).getClass(); // If an error is thrown here, it will terminate the hook process, but a log will indicate the error. Please manually avoid such cases!
}
}
- Ideal for scenarios with multiple hook points where process continuity is essential without being disrupted!
- The tool provides a rich set of methods available for use, including:
- ContextTool Class:
- Facilitates easier context retrieval.
public class MainTest {
public void test() {
// Simple way to obtain context.
Context context = ContextTool.getContext(ContextUtils.FLAG_ALL);
}
}
- InvokeTool Class:
- Provides more convenient and robust reflection utilities.
public class MainTest {
public void test() {
// Reflectively calls a method; other reflection operations are similar.
InvokeTool.callMethod(InvokeTool.findClass("com.hchen.demo.Main",
getClass().getClassLoader()), "test", new Class[]{});
}
}
- SystemPropTool Class:
- Provides an easy-to-use tool for reading and modifying properties.
public class MainTest {
public void test() {
// Can set properties only in system frameworks
SystemPropTool.setProp("ro.test.prop", "1");
// Reading is unrestricted
String result = SystemPropTool.getProp("ro.test.prop");
}
}
- PrefsTool Class:
- Enables reading and modifying preferences.
// In the host app
public class MainTest extends BaseHC {
@Override
public void init() {
// xprefs mode:
// Note: in xprefs mode, the host app can only read but not modify configurations.
String s = prefs().getString("test", "1"); // Read preferences
s = prefs("myPrefs").getString("test", "1"); // Specify file name to read
// sprefs mode:
// Configurations are saved to the host app's private directory, and reads are from the same.
prefs(context).editor().putString("test", "1").commit();
// If not inheriting BaseHC, call this way.
PrefsTool.prefs(context).editor().putString("test", "2").commit();
// Note: sprefs and xprefs modes operate independently and can coexist.
// If obtaining context is difficult, this method provides async host app context retrieval.
asyncPrefs(new PrefsTool.IAsyncPrefs() {
@Override
public void async(Context context) {
prefs(context).editor().putString("test", "1").commit();
}
});
}
}
// In the module
public static class MainActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
// IMPORTANT: If using xprefs mode, initialize with PrefsTool.prefs(context) on the main module screen, or it may not function!
PrefsTool.prefs(this); // Or
PrefsTool.prefs(this, /* your prefs name */);
// Usage
prefs(this).editor().putString("test", "1").commit();
prefs(this, "myPrefs").editor().putString("test", "1").commit();
}
}
- CoreTool class:
- Provides complete Hook methods!
- Fully meets your needs!
- DeviceTool class:
- Facilitates access to basic system information.
- Refer to source code and comments for more details.
- ResInjectTool Class:
- Injects module resources into the target scope.
- See source code and comments for details.
- PackagesTool Class:
- Quickly retrieves package information!
- More great tools coming soon …
- The following projects use this tool:
Project Name | Project Link |
---|---|
ForegroundPin | ForegroundPin |
AutoSEffSwitch | AutoSEffSwitch |
- If your project uses this tool, let me know, and I’ll add it to this list.
- For more details on using this tool, check out the projects above—hope they’re helpful!
-
This tool is based on:
-
Please acknowledge this tool if you use it.
- Thank you for using this tool! Enjoy your day!
♥️