You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
1. Added debugging information for hook/intercept operations.
A "trace" data item has been added to the existing "operation records." This is a compact plain-text string recording debug info related to the current operation: such as the original and replacement instructions for inline hooks, as well as the addresses and instructions of various trampolines.
Added the tools/record_parser.py script to parse "operation records" (including the new trace data); it supports parsing one or multiple records at a time.
Bug Fixes
1. Fixed an intermittent ANR bug.
This bug was introduced in version 2.0.0.
An ANR could occur if one thread was executing dlclose() while another was executing shadowhook_hook_sym_name() within the same process.
2. Fixed a bug where threads could not enter the shared-mode proxy function after executing pthread_key_clean_all().
In the bionic pthread implementation, pthread_exit() is called during thread termination; this invokes pthread_key_clean_all(), which performs four rounds of TLS cleanup. After pthread_key_clean_all() returns, pthread_exit() proceeds to call functions like munmap().
Shared-mode proxy functions rely on TLS to store context information, but Shadowhook's own TLS data was being cleared during the first round of pthread_key_clean_all(). If the proxy function was entered after this point, the original shared-mode logic could no longer function correctly. To minimize potential side effects, the previous approach was to skip the "proxy function" and call the "original function" directly. - Scope of impact: In addition to the munmap() call within pthread_exit(), this also covers functions called by any TLS destructor functions executed during the final three rounds of TLS cleanup.
3. Fixed a bug where the target ELF might not be found on Android 6.0.
On Android 6.0, if an APK has android:extractNativeLibs=false set, the ELF pathname returned by dl_iterate_phdr() does not include the !/lib/<ABI>/<lib_name> suffix. This caused the target ELF to be missed when using dl_iterate_phdr(). We fixed this issue by dynamically parsing the ELF .dynamic section in memory.
4. Fixed a bug in shared mode where proxy functions could not be entered after the stack exceeded 16 frames.
This bug was introduced in version 2.0.0.
In shared mode, to prevent recursive calls, each thread uses a stack structure to track proxy functions that have been entered but have not yet returned. In version 2.0.0, the stack size constant SH_HUB_STACK_FRAME_MAX was reduced from 127 to 16 for memory optimization; this violated an implicit API contract, preventing entry into proxy functions in certain scenarios. In the current version, SH_HUB_STACK_FRAME_MAX has been reverted to 127.
5. Fixed an intermittent memory corruption bug.
This bug was introduced in version 2.0.0.
When the gap size of the final memory page of an arm64 ELF executable segment fell within the range of [4, 16) bytes, the hooking process would overwrite the subsequent memory area, leading to subtle issues or crashes.
Improvements
1. Improved the execution speed of shadowhook_dlopen().
We have implemented caching for frequently accessed system libraries such as libart.so. Subsequent calls to shadowhook_dlopen() for these libraries now retrieve information from the cache, eliminating the need to acquire the linker's global mutex lock.
As a result of this optimization, APIs involving symbol lookup, such as shadowhook_hook_sym_name() also execute faster.
2. Improved concurrency for hook/intercept APIs.
In previous versions, all hook or intercept API calls were executed serially. Starting with this version, calls targeting different addresses are executed concurrently (though calls targeting the same address remain serial). This significantly alleviates thread blocking and waiting when multiple threads perform hook or intercept operations during app startup.
3. Optimized specific atomic operations and memory ordering.
In previous versions, the implementation of certain atomic operations and memory ordering was imprecise; in isolated cases, this could theoretically lead to issues on the arm64 architecture.
4. Optimized global virtual memory usage.
The total virtual memory usage of the stack in the hub module has been reduced from 4M bytes to 3M bytes.