epic
Dynamic java method AOP hook for Android(continution of Dexposed on ART), Supporting 5.0~11
Top Related Projects
LSPosed Framework
The Magic Mask for Android
Using system APIs directly with adb/root privileges from normal apps through a Java process started with app_process.
The Java part of the Xposed framework.
The native part of the Xposed framework (mainly the modified app_process binary).
Quick Overview
Epic is an open-source Android dynamic instrumentation tool that allows developers to modify the behavior of Android apps at runtime without modifying their source code. It provides a powerful framework for hooking Java methods, native functions, and system calls on both rooted and non-rooted devices.
Pros
- Works on both rooted and non-rooted devices
- Supports a wide range of Android versions (5.0 to 13)
- Provides a high-level API for easy method hooking
- Offers good performance with minimal overhead
Cons
- Limited documentation and examples
- Requires some knowledge of Android internals
- May not work with all apps due to security measures
- Potential for misuse in malicious applications
Code Examples
- Hooking a Java method:
Epic.hookMethod(MainActivity.class.getDeclaredMethod("onCreate", Bundle.class), new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
Log.d("Epic", "MainActivity.onCreate() is about to be called");
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
Log.d("Epic", "MainActivity.onCreate() has been called");
}
});
- Hooking a native function:
Epic.hookNative(Process.findModuleByName("libc.so"), "open", new NativeHook() {
@Override
public Object invoke(Object[] args) throws Throwable {
String path = (String) args[0];
Log.d("Epic", "open() called with path: " + path);
return super.invoke(args);
}
});
- Replacing a method implementation:
Epic.replaceMethod(TextView.class.getDeclaredMethod("setText", CharSequence.class), new XC_MethodReplacement() {
@Override
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
CharSequence text = (CharSequence) param.args[0];
Log.d("Epic", "setText() called with: " + text);
return null;
}
});
Getting Started
- Add Epic to your project's dependencies:
dependencies {
implementation 'me.weishu:epic:0.11.0'
}
- Initialize Epic in your application's
onCreate()
method:
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Epic.init(this);
}
}
- Start hooking methods:
try {
Epic.hookMethod(TargetClass.class.getDeclaredMethod("targetMethod"), new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
// Your code here
}
});
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
Competitor Comparisons
LSPosed Framework
Pros of LSPosed
- More active development with frequent updates and bug fixes
- Broader compatibility across different Android versions and devices
- Larger community support and user base
Cons of LSPosed
- More complex setup process for users
- Potentially higher resource usage due to broader feature set
Code Comparison
LSPosed:
public class XposedBridge {
private static final String TAG = "LSPosed";
private static final CopyOnWriteSortedSet<XC_LoadPackage> sLoadedPackageCallbacks = new CopyOnWriteSortedSet<>();
// ...
}
Epic:
public final class Epic {
private static final String TAG = "Epic";
private static volatile boolean isInitialized = false;
// ...
}
Key Differences
- LSPosed is specifically designed for Xposed module development, while Epic is a more general-purpose Android Java method hook framework
- LSPosed offers a more comprehensive set of features for system-wide modifications
- Epic focuses on simplicity and ease of use, with a lighter footprint
Use Cases
LSPosed is better suited for:
- System-wide modifications
- Complex module development
- Users familiar with Xposed ecosystem
Epic is preferable for:
- Simple method hooking tasks
- Projects requiring minimal setup
- Developers new to method hooking
Both projects aim to provide powerful tools for Android app modification, but cater to different levels of complexity and use cases.
The Magic Mask for Android
Pros of Magisk
- More comprehensive root solution with system-level modifications
- Larger community and ecosystem of modules
- Actively maintained with frequent updates
Cons of Magisk
- Requires unlocked bootloader and custom recovery
- Higher risk of bricking device if not used carefully
- More complex setup process for beginners
Code Comparison
Magisk (Java):
public class SuImpl extends SuMasterImpl {
@Override
public void start() {
// Initialize root access
}
}
Epic (Java):
public class Epic {
public static void install(String packageName) {
// Hook system calls
}
}
Key Differences
- Magisk focuses on system-wide root access and modifications
- Epic specializes in runtime hooking and method interception
- Magisk requires device-specific setup, while Epic works on app level
- Magisk offers more customization options for advanced users
- Epic provides easier integration for developers in existing apps
Use Cases
Magisk:
- Full system root access
- Custom ROM features without flashing
- System-wide ad-blocking
Epic:
- App behavior modification
- Runtime debugging and analysis
- Security research and penetration testing
Both projects serve different purposes in the Android ecosystem, with Magisk targeting system-level modifications and Epic focusing on app-level runtime manipulation.
Using system APIs directly with adb/root privileges from normal apps through a Java process started with app_process.
Pros of Shizuku
- Provides a more user-friendly approach to obtaining elevated permissions
- Offers better compatibility with newer Android versions
- Supports a wider range of devices and custom ROMs
Cons of Shizuku
- Requires additional setup steps for users
- May have limitations in certain system-level operations compared to Epic
- Potentially less flexible for advanced developers
Code Comparison
Epic:
public class Epic {
public static boolean isRoot() {
return Process.myUid() == 0;
}
}
Shizuku:
public class Shizuku {
public static boolean checkSelfPermission() {
return ContextCompat.checkSelfPermission(context, "moe.shizuku.manager.permission.API_V23") == PackageManager.PERMISSION_GRANTED;
}
}
Both projects aim to provide elevated permissions on Android, but they approach the problem differently. Epic focuses on modifying the app process directly, while Shizuku uses a separate privileged process to handle operations. Epic may offer more direct control over system functions, but Shizuku provides a safer and more user-friendly approach, especially for non-rooted devices. The code comparison shows how Epic checks for root access, while Shizuku verifies its own permission status.
The Java part of the Xposed framework.
Pros of XposedBridge
- More established and widely adopted in the Android modding community
- Extensive documentation and community support
- Offers deeper system-level modifications and hooks
Cons of XposedBridge
- Requires rooted devices, limiting its user base
- More complex setup process for both developers and users
- Potential security risks due to system-level access
Code Comparison
XposedBridge:
public class XC_MethodHook {
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {}
protected void afterHookedMethod(MethodHookParam param) throws Throwable {}
}
Epic:
public class XC_MethodHook {
public void beforeHookedMethod(MethodHookParam param) throws Throwable {}
public void afterHookedMethod(MethodHookParam param) throws Throwable {}
}
Both projects use similar method hooking structures, but Epic aims to provide a more accessible alternative to XposedBridge without requiring root access. Epic focuses on app-level modifications, making it easier to use but potentially less powerful for system-wide changes. XposedBridge offers more extensive capabilities but comes with higher complexity and security considerations. The choice between the two depends on the specific requirements of the project and the target audience.
The native part of the Xposed framework (mainly the modified app_process binary).
Pros of Xposed
- More established and widely used in the Android modding community
- Supports a broader range of Android versions and devices
- Has a larger ecosystem of modules and extensions
Cons of Xposed
- Requires root access, which can void device warranties
- Can potentially cause system instability if not used carefully
- Development has slowed down in recent years
Code Comparison
Xposed:
public class MyModule implements IXposedHookLoadPackage {
public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable {
XposedHelpers.findAndHookMethod("com.example.Class", lpparam.classLoader,
"methodName", String.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
// Modification logic here
}
});
}
}
Epic:
public class MyHook implements XC_MethodHook {
public void beforeHookedMethod(MethodHookParam param) throws Throwable {
// Modification logic here
}
}
DexposedBridge.hookMethod(Method.class.getDeclaredMethod("invoke", Object.class, Object[].class),
new MyHook());
Both frameworks allow for method hooking and modification, but Xposed uses a more declarative approach with its API, while Epic provides a lower-level interface for hooking methods.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
What is it?
Epic is the continuation of Dexposed on ART (Supports 5.0 ~ 11).
Dexposed is a powerful yet non-invasive runtime AOP (Aspect-oriented Programming) framework for Android app development, based on the work of open-source Xposed framework project.
The AOP of Dexposed is implemented purely non-invasive, without any annotation processor, weaver or bytecode rewriter. The integration is as simple as loading a small JNI library in just one line of code at the initialization phase of your app.
Not only the code of your app, but also the code of Android framework that running in your app process can be hooked.
Epic keeps the same API and all capability of Dexposed, you can do anything which is supported by Dexposed.
Typical use-cases
- Classic AOP programming
- Instrumentation (for testing, performance monitoring and etc.)
- Security audit (sensitive api check,Smash shell)
- Just for fun :)
Integration
Directly add epic aar to your project as compile libraries, Gradle dependency like following(jitpack):
dependencies {
compile 'com.github.tiann:epic:0.11.2'
}
Everything is ready.
Basic usage
There are three injection points for a given method: before, after, origin.
Example 1: monitor the creation and destroy of java thread
class ThreadMethodHook extends XC_MethodHook{
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Thread t = (Thread) param.thisObject;
Log.i(TAG, "thread:" + t + ", started..");
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Thread t = (Thread) param.thisObject;
Log.i(TAG, "thread:" + t + ", exit..");
}
}
DexposedBridge.hookAllConstructors(Thread.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Thread thread = (Thread) param.thisObject;
Class<?> clazz = thread.getClass();
if (clazz != Thread.class) {
Log.d(TAG, "found class extend Thread:" + clazz);
DexposedBridge.findAndHookMethod(clazz, "run", new ThreadMethodHook());
}
Log.d(TAG, "Thread: " + thread.getName() + " class:" + thread.getClass() + " is created.");
}
});
DexposedBridge.findAndHookMethod(Thread.class, "run", new ThreadMethodHook());
Example 2: Intercept the dex loading behavior
DexposedBridge.findAndHookMethod(DexFile.class, "loadDex", String.class, String.class, int.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
String dex = (String) param.args[0];
String odex = (String) param.args[1];
Log.i(TAG, "load dex, input:" + dex + ", output:" + odex);
}
});
Checkout the sample
project to find out more.
Support
Epic supports ART thumb2 and arm64 architecture from Android 5.0 ~ 11. arm32, x86, x86_64 and mips are not supported now (Thus it cannot work on android emulator).
Known Issues
- Short method (instruction less 8 bytes on thumb2 or less 16bytes in ARM64) are not supported.
- Fully inline methods are not supported.
Contribute
We are open to constructive contributions from the community, especially pull request and quality bug report. Currently, the implementation for ART is not proved in large scale, we value your help to test or improve the implementation.
You can clone this project, build and install the sample app, just make some click in your device, if some bugs/crash occurs, please file an issue or a pull request, I would appreciate it :)
Thanks
Contact me
Top Related Projects
LSPosed Framework
The Magic Mask for Android
Using system APIs directly with adb/root privileges from normal apps through a Java process started with app_process.
The Java part of the Xposed framework.
The native part of the Xposed framework (mainly the modified app_process binary).
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot