Skip to content

shadowhook v1.0.5

Choose a tag to compare

@caikelun caikelun released this 05 Dec 10:00
· 60 commits to main since this release
v1.0.5
3273a7c

Bugs fixed

1. Fix the bug that some function addresses cannot use ELF gap for relative jump when hooking.

This bug will cause the hook stability of some functions to decrease. The bug occurs when the absolute address of a function is in the following ranges:

arch address ranges
thumb [0, 0x1000000)
thumb (0xFF000001, 0xFFFFFFFF]
arm [0, 0x2000000)
arm (0xFE000003, 0xFFFFFFFF]
arm64 [0, 0x8000000)
arm64 (0xFFFFFFFFF8000003, 0xFFFFFFFFFFFFFFFF]

2. Fix the bug that part of ELF cannot be hooked in Android 4.x.

The first LOAD segment of ELF may be read-only (use the linker option --rosegment), and the /proc/self/maps at this time may look like this:

75b8d000-75b9f000 r--p 00000000 b3:1c 89884 /data/app-lib/io.hexhacking.xdl.sample-2/libquick.so
75b9f000-75bde000 r-xp 00012000 b3:1c 89884 /data/app-lib/io.hexhacking.xdl.sample-2/libquick.so
75bde000-75be1000 r--p 00051000 b3:1c 89884 /data/app-lib/io.hexhacking.xdl.sample-2/libquick.so
75be1000-75be2000 rw-p 00054000 b3:1c 89884 /data/app-lib/io.hexhacking.xdl.sample-2/libquick.so

In previous ShadowHook versions, this type of ELF could not be hooked in Android 4.x.

3. Fix the bug that the wrong initialization state may be returned when ShadowHook#init() is called concurrently.

It may actually be still being initialized, but it returns a state that has been initialized.

Improve

1. Avoid additional acquisition of the linker's global mutex lock during initialization.

ShadowHook needs to obtain several symbol addresses in libc.so through dlopen and dlsym during initialization. These operations need to hold the linker's global mutex lock. We moved the above operations to .init_array of libshadowhook.so.

Bugs 修复

1. 修复部分函数地址在 hook 时无法利用 ELF gap 作相对跳转的bug。

这个 bug 会导致部分函数的 hook 稳定性下降。当函数的绝对地址在以下范围内时,会出现这个 bug:

架构 地址范围
thumb [0, 0x1000000)
thumb (0xFF000001, 0xFFFFFFFF]
arm [0, 0x2000000)
arm (0xFE000003, 0xFFFFFFFF]
arm64 [0, 0x8000000)
arm64 (0xFFFFFFFFF8000003, 0xFFFFFFFFFFFFFFFF]

2. 修复 Android 4.x 中无法 hook 部分 ELF 的 bug。

ELF 的第一个 LOAD segment 可能是只读的(用链接器选项 --rosegment),此时的 /proc/self/maps 大概是这样的:

75b8d000-75b9f000 r--p 00000000 b3:1c 89884 /data/app-lib/io.hexhacking.xdl.sample-2/libquick.so
75b9f000-75bde000 r-xp 00012000 b3:1c 89884 /data/app-lib/io.hexhacking.xdl.sample-2/libquick.so
75bde000-75be1000 r--p 00051000 b3:1c 89884 /data/app-lib/io.hexhacking.xdl.sample-2/libquick.so
75be1000-75be2000 rw-p 00054000 b3:1c 89884 /data/app-lib/io.hexhacking.xdl.sample-2/libquick.so

在之前的 ShadowHook 版本中,在 Android 4.x 中这种类型 ELF 无法被 hook。

  • 相关的 xDL 版本:v1.2.1

3. 修复了并发调用 ShadowHook#init() 时可能返回错误的初始化状态的 bug。

可能实际还处在初始化中,但是却返回了已经初始化完成的状态。

改进

1. 避免在初始化期间额外获取 linker 的全局 mutex 锁。

ShadowHook 需要在初始化时通过 dlopendlsym 获取 libc.so 中的几个符号地址,这些操作需要持有 linker 的全局 mutex 锁,我们将上述操作移动到了 libshadowhook.so.init_array 中。