Thor Container Framework: Unified Java and Native Hook for Mobile Apps
Thor is a unified Android container framework that combines Java and native hooking into a lightweight, dynamically loadable module, ensuring backward compatibility, hot‑plug plugin deployment, fault‑tolerant operation, and cloud‑controlled toggling, while real‑world plugins for threads, I/O, privacy, and memory deliver measurable performance and stability gains.
This article introduces the Thor container framework, a unified solution for Java and Native Hook on Android, designed to address performance, stability, and compatibility challenges in large‑scale mobile applications.
Background : Traditional Hook techniques (PLT Hook, Inline Hook, Replace Entrypoint Hook) are fragmented across multiple open‑source frameworks (xHook, bHook, Epic, Dexposed, etc.). Each framework has limitations in compatibility, stability, and dynamic deployment, making it difficult to maintain a consistent Hook capability across the app.
Thor Framework Goals :
Provide complete Hook capabilities (both Java and Native) in a lightweight, dynamically loadable container.
Ensure backward compatibility so that replacing underlying Hook implementations does not affect business code.
Support hot‑plugging of plugins via cloud control, reducing package size and enabling on‑demand installation.
Offer fault‑tolerance mechanisms to prevent Hook‑related crashes from impacting users.
Architecture Overview :
Thor consists of an abstract layer exposing standard Hook interfaces, a plugin layer (application‑level plugins, sandbox plugins, verification modules), and an implementation layer that adapts existing Hook frameworks (Epic, xHook, Android‑Inline‑Hook, etc.). The abstract layer defines function pointers such as int (*thor_plt_hook)(const char *lib_name, const char *symbol, void *hook_func, void **backup_func); and int (*thor_inline_hook)(void *target_func, void *hook_func, void **backup_func); . Implementation modules assign these pointers to concrete Hook functions (e.g., xhook_impl_plt_hook , impl_inline_hook ).
Key Interfaces :
public interface IHookEntity {
void hookMethod(Member hookedMethod, IHookCallback hookCallback);
// ... other methods
} struct thor_abstract {
int (*thor_plt_hook)(const char *lib_name, const char *symbol, void *hook_func, void **backup_func);
int (*thor_inline_hook)(void *target_func, void *hook_func, void **backup_func);
struct thor_plt_ext *plt_ext;
};Plugin Lifecycle :
Signature verification of the plugin (v2 signing).
Parsing the plugin manifest to obtain package name, entry class, ABI list, version, etc.
Extracting native libraries and loading them via a custom ThorClassLoader that prefers plugin classes before host classes.
Instantiating the plugin entry class and injecting Java or Native Hook implementations into the Thor abstract layer.
Managing plugin lifecycle (load, unload, update) through a management UI.
Resilience Features :
Sandbox installation for low‑priority plugins to avoid affecting the main process.
Automatic shutdown after a configurable number of consecutive crashes.
Cloud‑controlled toggling of the framework based on monitoring data.
Practical Use Cases :
1. Thread Plugin – Hooks pthread_create in libart.so via PLT Hook to log Java stack traces for every thread creation, revealing >100 stray threads during app startup. Optimizing thread usage reduced TTI by over 1 second.
static void *(*origin_pthread_create)(pthread_t *, const pthread_attr_t *, void *(*)(void *), void *) = NULL;
void *proxy_pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) {
// custom logic (e.g., log stack)
void *ret = origin_pthread_create(thread, attr, start_routine, arg);
printJavaStackTrace();
return ret;
}
void doHook(long nativePtr) {
thor_abstract *impl = reinterpret_cast
(nativePtr);
impl->thor_plt_hook("libart.so", "pthread_create", (void *)proxy_pthread_create, (void **)&origin_pthread_create);
}2. IO Plugin – PLT Hooks open , read , write , and close to collect IOInfo (file path, buffer size, duration, read/write count). Analysis of close events identifies long‑running or small‑buffer IO on the main thread, leading to a 400 ms reduction in startup time.
class IOInfo {
public:
const std::string file_path_;
int64_t start_time_us_;
long buffer_size_ = 0;
long max_continual_rw_cnt_ = 0;
long file_size_ = 0;
long total_cost_us_ = 0;
};3. Privacy Compliance Plugin – Uses Java Hook to intercept privacy‑sensitive APIs (e.g., TelephonyManager.getDeviceId ) before the user consent dialog, automatically generating issue tickets for developers.
ThorHook.findAndHookMethod(TelephonyManager.class, "getDeviceId", new IHookCallbackImpl(), String.class);4. Memory Plugin – Monitors native malloc / free via PLT Hook to detect memory leaks and large allocations, supporting both offline CI pipelines (automatic hprof dumping) and online cloud‑controlled monitoring for OOM troubleshooting.
Conclusion : Thor demonstrates that a well‑designed container framework can unify disparate Hook technologies, provide dynamic, lightweight, and resilient instrumentation for large Android apps, and enable a thriving plugin ecosystem that drives performance and stability improvements.
Baidu Geek Talk
Follow us to discover more Baidu tech insights.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.