什么是KernelPatch Module (KPM)
KPM是一个ELF文件,可以通过KernelPatch在内核空间中加载和运行
官方文档与代码案例
官方提供了3个案例:
1.hello world
2.inline-hook
3.syscallhook
Hello
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
<span class="token comment">//代码比较简单</span> <span class="token comment">//这里声明了模块名称, 版本, 作者协议, 描述等</span> <span class="token constant">KPM_NAME</span><span class="token punctuation">(</span><span class="token string">"kpm-hello-demo"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token constant">KPM_VERSION</span><span class="token punctuation">(</span><span class="token string">"1.0.0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token constant">KPM_LICENSE</span><span class="token punctuation">(</span><span class="token string">"GPL v2"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token constant">KPM_AUTHOR</span><span class="token punctuation">(</span><span class="token string">"bmax121"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token constant">KPM_DESCRIPTION</span><span class="token punctuation">(</span><span class="token string">"KernelPatch Module Example"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">static</span> long <span class="token function">hello_init</span><span class="token punctuation">(</span><span class="token parameter"><span class="token keyword">const</span> char <span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token keyword">const</span> char <span class="token operator">*</span>event<span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span>__user reserved</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">pr_info</span><span class="token punctuation">(</span><span class="token string">"kpm hello init, event: %s, args: %s\n"</span><span class="token punctuation">,</span> event<span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">pr_info</span><span class="token punctuation">(</span><span class="token string">"kernelpatch version: %x\n"</span><span class="token punctuation">,</span> kpver<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">static</span> long <span class="token function">hello_control0</span><span class="token punctuation">(</span><span class="token parameter"><span class="token keyword">const</span> char <span class="token operator">*</span>args<span class="token punctuation">,</span> char <span class="token operator">*</span>__user out_msg<span class="token punctuation">,</span> int outlen</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">pr_info</span><span class="token punctuation">(</span><span class="token string">"kpm hello control0, args: %s\n"</span><span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">;</span> char echo<span class="token punctuation">[</span><span class="token number">64</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"echo: "</span><span class="token punctuation">;</span> <span class="token function">strncat</span><span class="token punctuation">(</span>echo<span class="token punctuation">,</span> args<span class="token punctuation">,</span> <span class="token number">48</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">compat_copy_to_user</span><span class="token punctuation">(</span>out_msg<span class="token punctuation">,</span> echo<span class="token punctuation">,</span> <span class="token function">sizeof</span><span class="token punctuation">(</span>echo<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">static</span> long <span class="token function">hello_control1</span><span class="token punctuation">(</span><span class="token parameter"><span class="token keyword">void</span> <span class="token operator">*</span>a1<span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span>a2<span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span>a3</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">pr_info</span><span class="token punctuation">(</span><span class="token string">"kpm hello control1, a1: %llx, a2: %llx, a3: %llx\n"</span><span class="token punctuation">,</span> a1<span class="token punctuation">,</span> a2<span class="token punctuation">,</span> a3<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">static</span> long <span class="token function">hello_exit</span><span class="token punctuation">(</span><span class="token parameter"><span class="token keyword">void</span> <span class="token operator">*</span>__user reserved</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">pr_info</span><span class="token punctuation">(</span><span class="token string">"kpm hello exit\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">//这里注册了几个函数: </span> <span class="token constant">KPM_INIT</span><span class="token punctuation">(</span>hello_init<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//初始化</span> <span class="token constant">KPM_CTL0</span><span class="token punctuation">(</span>hello_control0<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//ctl0</span> <span class="token constant">KPM_CTL1</span><span class="token punctuation">(</span>hello_control1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//ctl1</span> <span class="token constant">KPM_EXIT</span><span class="token punctuation">(</span>hello_exit<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//退出</span> |
JavaScript
inline hook
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
<span class="token comment">//同上</span> <span class="token constant">KPM_NAME</span><span class="token punctuation">(</span><span class="token string">"kpm-inline-hook-demo"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token constant">KPM_VERSION</span><span class="token punctuation">(</span><span class="token string">"1.0.0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token constant">KPM_LICENSE</span><span class="token punctuation">(</span><span class="token string">"GPL v2"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token constant">KPM_AUTHOR</span><span class="token punctuation">(</span><span class="token string">"bmax121"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token constant">KPM_DESCRIPTION</span><span class="token punctuation">(</span><span class="token string">"KernelPatch Module Inline Hook Example"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> int __noinline <span class="token function">add</span><span class="token punctuation">(</span><span class="token parameter">int a<span class="token punctuation">,</span> int b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">logkd</span><span class="token punctuation">(</span><span class="token string">"origin add called\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> int ret <span class="token operator">=</span> a <span class="token operator">+</span> b<span class="token punctuation">;</span> <span class="token keyword control-flow">return</span> ret<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">void</span> <span class="token function">before_add</span><span class="token punctuation">(</span><span class="token parameter">hook_fargs2_t <span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span>udata</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">logkd</span><span class="token punctuation">(</span><span class="token string">"before add arg0: %d, arg1: %d\n"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>int<span class="token punctuation">)</span>args<span class="token operator">-</span><span class="token operator">></span>arg0<span class="token punctuation">,</span> <span class="token punctuation">(</span>int<span class="token punctuation">)</span>args<span class="token operator">-</span><span class="token operator">></span>arg1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">void</span> <span class="token function">after_add</span><span class="token punctuation">(</span><span class="token parameter">hook_fargs2_t <span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span>udata</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">logkd</span><span class="token punctuation">(</span><span class="token string">"after add arg0: %d, arg1: %d, ret: %d\n"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>int<span class="token punctuation">)</span>args<span class="token operator">-</span><span class="token operator">></span>arg0<span class="token punctuation">,</span> <span class="token punctuation">(</span>int<span class="token punctuation">)</span>args<span class="token operator">-</span><span class="token operator">></span>arg1<span class="token punctuation">,</span> <span class="token punctuation">(</span>int<span class="token punctuation">)</span>args<span class="token operator">-</span><span class="token operator">></span>ret<span class="token punctuation">)</span><span class="token punctuation">;</span> args<span class="token operator">-</span><span class="token operator">></span>ret <span class="token operator">=</span> <span class="token number">100</span><span class="token punctuation">;</span> <span class="token comment">//修改返回值</span> <span class="token punctuation">}</span> <span class="token keyword">static</span> long <span class="token function">inline_hook_demo_init</span><span class="token punctuation">(</span><span class="token parameter"><span class="token keyword">const</span> char <span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token keyword">const</span> char <span class="token operator">*</span>event<span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span>__user reserved</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">logkd</span><span class="token punctuation">(</span><span class="token string">"kpm inline-hook-demo init\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> int a <span class="token operator">=</span> <span class="token number">20</span><span class="token punctuation">;</span> int b <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> int ret <span class="token operator">=</span> <span class="token function">add</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">logkd</span><span class="token punctuation">(</span><span class="token string">"%d + %d = %d\n"</span><span class="token punctuation">,</span> a<span class="token punctuation">,</span> b<span class="token punctuation">,</span> ret<span class="token punctuation">)</span><span class="token punctuation">;</span> hook_err_t err <span class="token operator">=</span> <span class="token function">hook_wrap2</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span><span class="token punctuation">)</span>add<span class="token punctuation">,</span> before_add<span class="token punctuation">,</span> after_add<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">logkd</span><span class="token punctuation">(</span><span class="token string">"hook err: %d\n"</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span><span class="token punctuation">;</span> ret <span class="token operator">=</span> <span class="token function">add</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">logkd</span><span class="token punctuation">(</span><span class="token string">"%d + %d = %d\n"</span><span class="token punctuation">,</span> a<span class="token punctuation">,</span> b<span class="token punctuation">,</span> ret<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">static</span> long <span class="token function">inline_hook_control0</span><span class="token punctuation">(</span><span class="token parameter"><span class="token keyword">const</span> char <span class="token operator">*</span>args<span class="token punctuation">,</span> char <span class="token operator">*</span>__user out_msg<span class="token punctuation">,</span> int outlen</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">pr_info</span><span class="token punctuation">(</span><span class="token string">"kpm control, args: %s\n"</span><span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">static</span> long <span class="token function">inline_hook_demo_exit</span><span class="token punctuation">(</span><span class="token parameter"><span class="token keyword">void</span> <span class="token operator">*</span>__user reserved</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">unhook</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span><span class="token punctuation">)</span>add<span class="token punctuation">)</span><span class="token punctuation">;</span> int a <span class="token operator">=</span> <span class="token number">20</span><span class="token punctuation">;</span> int b <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> int ret <span class="token operator">=</span> <span class="token function">add</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">logkd</span><span class="token punctuation">(</span><span class="token string">"%d + %d = %d\n"</span><span class="token punctuation">,</span> a<span class="token punctuation">,</span> b<span class="token punctuation">,</span> ret<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">logkd</span><span class="token punctuation">(</span><span class="token string">"kpm inline-hook-demo exit\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token constant">KPM_INIT</span><span class="token punctuation">(</span>inline_hook_demo_init<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token constant">KPM_CTL0</span><span class="token punctuation">(</span>inline_hook_control0<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token constant">KPM_EXIT</span><span class="token punctuation">(</span>inline_hook_demo_exit<span class="token punctuation">)</span><span class="token punctuation">;</span> |
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<span class="token keyword">static</span> long <span class="token function">inline_hook_demo_init</span><span class="token punctuation">(</span><span class="token parameter"><span class="token keyword">const</span> char <span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token keyword">const</span> char <span class="token operator">*</span>event<span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span>__user reserved</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">logkd</span><span class="token punctuation">(</span><span class="token string">"kpm inline-hook-demo init\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> int a <span class="token operator">=</span> <span class="token number">20</span><span class="token punctuation">;</span> int b <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> int ret <span class="token operator">=</span> <span class="token function">add</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">logkd</span><span class="token punctuation">(</span><span class="token string">"%d + %d = %d\n"</span><span class="token punctuation">,</span> a<span class="token punctuation">,</span> b<span class="token punctuation">,</span> ret<span class="token punctuation">)</span><span class="token punctuation">;</span> hook_err_t err <span class="token operator">=</span> <span class="token function">hook_wrap2</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span><span class="token punctuation">)</span>add<span class="token punctuation">,</span> before_add<span class="token punctuation">,</span> after_add<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">logkd</span><span class="token punctuation">(</span><span class="token string">"hook err: %d\n"</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span><span class="token punctuation">;</span> ret <span class="token operator">=</span> <span class="token function">add</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">logkd</span><span class="token punctuation">(</span><span class="token string">"%d + %d = %d\n"</span><span class="token punctuation">,</span> a<span class="token punctuation">,</span> b<span class="token punctuation">,</span> ret<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
JavaScript
定义一个测试函数:__noinline add
__noinline 避免被内联优化, 方便hook
执行hook
1 2 3 4 |
hook_err_t err <span class="token operator">=</span> <span class="token function">hook_wrap2</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span><span class="token punctuation">)</span>add<span class="token punctuation">,</span> before_add<span class="token punctuation">,</span> after_add<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//参数很好理解</span> 第一个是被hook的函数<span class="token punctuation">,</span> 第二个是before hook<span class="token punctuation">,</span> 第三个是after hook<span class="token punctuation">,</span> 第四个是用户数据指针 |
JavaScript
syscall hook
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
<span class="token keyword">const</span> char <span class="token operator">*</span>margs <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">enum</span> hook_type hook_type <span class="token operator">=</span> <span class="token constant">NONE</span><span class="token punctuation">;</span> <span class="token keyword">enum</span> pid_type <span class="token punctuation">{</span> <span class="token constant">PIDTYPE_PID</span><span class="token punctuation">,</span> <span class="token constant">PIDTYPE_TGID</span><span class="token punctuation">,</span> <span class="token constant">PIDTYPE_PGID</span><span class="token punctuation">,</span> <span class="token constant">PIDTYPE_SID</span><span class="token punctuation">,</span> <span class="token constant">PIDTYPE_MAX</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> struct pid_namespace<span class="token punctuation">;</span> <span class="token comment">//函数指针</span> <span class="token function">pid_t</span> <span class="token punctuation">(</span><span class="token operator">*</span>__task_pid_nr_ns<span class="token punctuation">)</span><span class="token punctuation">(</span>struct task_struct <span class="token operator">*</span>task<span class="token punctuation">,</span> <span class="token keyword">enum</span> pid_type type<span class="token punctuation">,</span> struct pid_namespace <span class="token operator">*</span>ns<span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">void</span> <span class="token function">before_openat_0</span><span class="token punctuation">(</span><span class="token parameter">hook_fargs4_t <span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span>udata</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> int dfd <span class="token operator">=</span> <span class="token punctuation">(</span>int<span class="token punctuation">)</span><span class="token function">syscall_argn</span><span class="token punctuation">(</span>args<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> char __user <span class="token operator">*</span>filename <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span><span class="token punctuation">(</span>filename<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token function">syscall_argn</span><span class="token punctuation">(</span>args<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> int flag <span class="token operator">=</span> <span class="token punctuation">(</span>int<span class="token punctuation">)</span><span class="token function">syscall_argn</span><span class="token punctuation">(</span>args<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> umode_t mode <span class="token operator">=</span> <span class="token punctuation">(</span>int<span class="token punctuation">)</span><span class="token function">syscall_argn</span><span class="token punctuation">(</span>args<span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> char buf<span class="token punctuation">[</span><span class="token number">1024</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token function">compat_strncpy_from_user</span><span class="token punctuation">(</span>buf<span class="token punctuation">,</span> filename<span class="token punctuation">,</span> <span class="token function">sizeof</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> struct task_struct <span class="token operator">*</span>task <span class="token operator">=</span> current<span class="token punctuation">;</span> pid_t pid <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">,</span> tgid <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span>__task_pid_nr_ns<span class="token punctuation">)</span> <span class="token punctuation">{</span> pid <span class="token operator">=</span> <span class="token function">__task_pid_nr_ns</span><span class="token punctuation">(</span>task<span class="token punctuation">,</span> <span class="token constant">PIDTYPE_PID</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> tgid <span class="token operator">=</span> <span class="token function">__task_pid_nr_ns</span><span class="token punctuation">(</span>task<span class="token punctuation">,</span> <span class="token constant">PIDTYPE_TGID</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> args<span class="token operator">-</span><span class="token operator">></span>local<span class="token punctuation">.</span><span class="token property-access">data0</span> <span class="token operator">=</span> <span class="token punctuation">(</span>uint64_t<span class="token punctuation">)</span>task<span class="token punctuation">;</span> <span class="token function">pr_info</span><span class="token punctuation">(</span><span class="token string">"hook_chain_0 task: %llx, pid: %d, tgid: %d, openat dfd: %d, filename: %s, flag: %x, mode: %d\n"</span><span class="token punctuation">,</span> task<span class="token punctuation">,</span> pid<span class="token punctuation">,</span> tgid<span class="token punctuation">,</span> dfd<span class="token punctuation">,</span> buf<span class="token punctuation">,</span> flag<span class="token punctuation">,</span> mode<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> uint64_t open_counts <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">void</span> <span class="token function">before_openat_1</span><span class="token punctuation">(</span><span class="token parameter">hook_fargs4_t <span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span>udata</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> uint64_t <span class="token operator">*</span>pcount <span class="token operator">=</span> <span class="token punctuation">(</span>uint64_t <span class="token operator">*</span><span class="token punctuation">)</span>udata<span class="token punctuation">;</span> <span class="token punctuation">(</span><span class="token operator">*</span>pcount<span class="token punctuation">)</span><span class="token operator">++</span><span class="token punctuation">;</span> <span class="token function">pr_info</span><span class="token punctuation">(</span><span class="token string">"hook_chain_1 before openat task: %llx, count: %llx\n"</span><span class="token punctuation">,</span> args<span class="token operator">-</span><span class="token operator">></span>local<span class="token punctuation">.</span><span class="token property-access">data0</span><span class="token punctuation">,</span> <span class="token operator">*</span>pcount<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">void</span> <span class="token function">after_openat_1</span><span class="token punctuation">(</span><span class="token parameter">hook_fargs4_t <span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span>udata</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">pr_info</span><span class="token punctuation">(</span><span class="token string">"hook_chain_1 after openat task: %llx\n"</span><span class="token punctuation">,</span> args<span class="token operator">-</span><span class="token operator">></span>local<span class="token punctuation">.</span><span class="token property-access">data0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">static</span> long <span class="token function">syscall_hook_demo_init</span><span class="token punctuation">(</span><span class="token parameter"><span class="token keyword">const</span> char <span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token keyword">const</span> char <span class="token operator">*</span>event<span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span>__user reserved</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> margs <span class="token operator">=</span> args<span class="token punctuation">;</span> <span class="token function">pr_info</span><span class="token punctuation">(</span><span class="token string">"kpm-syscall-hook-demo init ..., args: %s\n"</span><span class="token punctuation">,</span> margs<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//赋值给函数指针</span> __task_pid_nr_ns <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span><span class="token punctuation">(</span>__task_pid_nr_ns<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token function">kallsyms_lookup_name</span><span class="token punctuation">(</span><span class="token string">"__task_pid_nr_ns"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">pr_info</span><span class="token punctuation">(</span><span class="token string">"kernel function __task_pid_nr_ns addr: %llx\n"</span><span class="token punctuation">,</span> __task_pid_nr_ns<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>margs<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">pr_warn</span><span class="token punctuation">(</span><span class="token string">"no args specified, skip hook\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> hook_err_t err <span class="token operator">=</span> <span class="token constant">HOOK_NO_ERR</span><span class="token punctuation">;</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">strcmp</span><span class="token punctuation">(</span><span class="token string">"function_pointer_hook"</span><span class="token punctuation">,</span> margs<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">pr_info</span><span class="token punctuation">(</span><span class="token string">"function pointer hook ..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span> hook_type <span class="token operator">=</span> <span class="token constant">FUNCTION_POINTER_CHAIN</span><span class="token punctuation">;</span> err <span class="token operator">=</span> <span class="token function">fp_hook_syscalln</span><span class="token punctuation">(</span>__NR_openat<span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> before_openat_0<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> goto out<span class="token punctuation">;</span> err <span class="token operator">=</span> <span class="token function">fp_hook_syscalln</span><span class="token punctuation">(</span>__NR_openat<span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> before_openat_1<span class="token punctuation">,</span> after_openat_1<span class="token punctuation">,</span> <span class="token operator">&</span>open_counts<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword control-flow">else</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">strcmp</span><span class="token punctuation">(</span><span class="token string">"inline_hook"</span><span class="token punctuation">,</span> margs<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">pr_info</span><span class="token punctuation">(</span><span class="token string">"inline hook ..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span> hook_type <span class="token operator">=</span> <span class="token constant">INLINE_CHAIN</span><span class="token punctuation">;</span> err <span class="token operator">=</span> <span class="token function">inline_hook_syscalln</span><span class="token punctuation">(</span>__NR_openat<span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> before_openat_0<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword control-flow">else</span> <span class="token punctuation">{</span> <span class="token function">pr_warn</span><span class="token punctuation">(</span><span class="token string">"unknown args: %s\n"</span><span class="token punctuation">,</span> margs<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token literal-property property">out</span><span class="token operator">:</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">pr_err</span><span class="token punctuation">(</span><span class="token string">"hook openat error: %d\n"</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword control-flow">else</span> <span class="token punctuation">{</span> <span class="token function">pr_info</span><span class="token punctuation">(</span><span class="token string">"hook openat success\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword control-flow">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">static</span> long <span class="token function">syscall_hook_control0</span><span class="token punctuation">(</span><span class="token parameter"><span class="token keyword">const</span> char <span class="token operator">*</span>args<span class="token punctuation">,</span> char <span class="token operator">*</span>__user out_msg<span class="token punctuation">,</span> int outlen</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">pr_info</span><span class="token punctuation">(</span><span class="token string">"syscall_hook control, args: %s\n"</span><span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">static</span> long <span class="token function">syscall_hook_demo_exit</span><span class="token punctuation">(</span><span class="token parameter"><span class="token keyword">void</span> <span class="token operator">*</span>__user reserved</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">pr_info</span><span class="token punctuation">(</span><span class="token string">"kpm-syscall-hook-demo exit ...\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span>hook_type <span class="token operator">==</span> <span class="token constant">INLINE_CHAIN</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">inline_unhook_syscall</span><span class="token punctuation">(</span>__NR_openat<span class="token punctuation">,</span> before_openat_0<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword control-flow">else</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span>hook_type <span class="token operator">==</span> <span class="token constant">FUNCTION_POINTER_CHAIN</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">fp_unhook_syscall</span><span class="token punctuation">(</span>__NR_openat<span class="token punctuation">,</span> before_openat_0<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">fp_unhook_syscall</span><span class="token punctuation">(</span>__NR_openat<span class="token punctuation">,</span> before_openat_1<span class="token punctuation">,</span> after_openat_1<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword control-flow">else</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token keyword control-flow">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token constant">KPM_INIT</span><span class="token punctuation">(</span>syscall_hook_demo_init<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token constant">KPM_CTL0</span><span class="token punctuation">(</span>syscall_hook_control0<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token constant">KPM_EXIT</span><span class="token punctuation">(</span>syscall_hook_demo_exit<span class="token punctuation">)</span><span class="token punctuation">;</span> |
JavaScript
初始化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<span class="token keyword">static</span> long <span class="token function">syscall_hook_demo_init</span><span class="token punctuation">(</span><span class="token parameter"><span class="token keyword">const</span> char <span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token keyword">const</span> char <span class="token operator">*</span>event<span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span>__user reserved</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> margs <span class="token operator">=</span> args<span class="token punctuation">;</span> <span class="token comment">// 获取内核函数地址复制给函数指针, 方便后面调用</span> __task_pid_nr_ns <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span><span class="token punctuation">(</span>__task_pid_nr_ns<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token function">kallsyms_lookup_name</span><span class="token punctuation">(</span><span class="token string">"__task_pid_nr_ns"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>margs<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">pr_warn</span><span class="token punctuation">(</span><span class="token string">"no args specified, skip hook\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> hook_err_t err <span class="token operator">=</span> <span class="token constant">HOOK_NO_ERR</span><span class="token punctuation">;</span> <span class="token comment">// 根据参数选择hook类型</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">strcmp</span><span class="token punctuation">(</span><span class="token string">"function_pointer_hook"</span><span class="token punctuation">,</span> margs<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 函数指针方式hook</span> hook_type <span class="token operator">=</span> <span class="token constant">FUNCTION_POINTER_CHAIN</span><span class="token punctuation">;</span> <span class="token comment">// 安装两个钩子形成链</span> err <span class="token operator">=</span> <span class="token function">fp_hook_syscalln</span><span class="token punctuation">(</span>__NR_openat<span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> before_openat_0<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> goto out<span class="token punctuation">;</span> err <span class="token operator">=</span> <span class="token function">fp_hook_syscalln</span><span class="token punctuation">(</span>__NR_openat<span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> before_openat_1<span class="token punctuation">,</span> after_openat_1<span class="token punctuation">,</span> <span class="token operator">&</span>open_counts<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword control-flow">else</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">strcmp</span><span class="token punctuation">(</span><span class="token string">"inline_hook"</span><span class="token punctuation">,</span> margs<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 内联方式hook</span> hook_type <span class="token operator">=</span> <span class="token constant">INLINE_CHAIN</span><span class="token punctuation">;</span> err <span class="token operator">=</span> <span class="token function">inline_hook_syscalln</span><span class="token punctuation">(</span>__NR_openat<span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> before_openat_0<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token literal-property property">out</span><span class="token operator">:</span> <span class="token keyword control-flow">return</span> err <span class="token operator">?</span> <span class="token operator">-</span><span class="token number">1</span> <span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
JavaScript
如果参数是function_pointer_hook, 使用fp_hook_syscalln来hook系统函数, hook了openat
如果是inline_hook, 则使用inline_hook_syscalln来hook系统函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<span class="token keyword">void</span> <span class="token function">before_openat_0</span><span class="token punctuation">(</span><span class="token parameter">hook_fargs4_t <span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span>udata</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//获取openat四个参数</span> int dfd <span class="token operator">=</span> <span class="token punctuation">(</span>int<span class="token punctuation">)</span><span class="token function">syscall_argn</span><span class="token punctuation">(</span>args<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//fd</span> <span class="token keyword">const</span> char __user <span class="token operator">*</span>filename <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span><span class="token punctuation">(</span>filename<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token function">syscall_argn</span><span class="token punctuation">(</span>args<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//filename</span> int flag <span class="token operator">=</span> <span class="token punctuation">(</span>int<span class="token punctuation">)</span><span class="token function">syscall_argn</span><span class="token punctuation">(</span>args<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//打开标志</span> umode_t mode <span class="token operator">=</span> <span class="token punctuation">(</span>int<span class="token punctuation">)</span><span class="token function">syscall_argn</span><span class="token punctuation">(</span>args<span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//模式</span> <span class="token comment">//从用户空间复制文件名</span> char buf<span class="token punctuation">[</span><span class="token number">1024</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token function">compat_strncpy_from_user</span><span class="token punctuation">(</span>buf<span class="token punctuation">,</span> filename<span class="token punctuation">,</span> <span class="token function">sizeof</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//获取当前进程</span> struct task_struct <span class="token operator">*</span>task <span class="token operator">=</span> current<span class="token punctuation">;</span> pid_t pid <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">,</span> tgid <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span> <span class="token comment">//调用__task_pid_nr_ns函数指针获取pid和tgid(线程组id)</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span>__task_pid_nr_ns<span class="token punctuation">)</span> <span class="token punctuation">{</span> pid <span class="token operator">=</span> <span class="token function">__task_pid_nr_ns</span><span class="token punctuation">(</span>task<span class="token punctuation">,</span> <span class="token constant">PIDTYPE_PID</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> tgid <span class="token operator">=</span> <span class="token function">__task_pid_nr_ns</span><span class="token punctuation">(</span>task<span class="token punctuation">,</span> <span class="token constant">PIDTYPE_TGID</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">//保存到local data中</span> args<span class="token operator">-</span><span class="token operator">></span>local<span class="token punctuation">.</span><span class="token property-access">data0</span> <span class="token operator">=</span> <span class="token punctuation">(</span>uint64_t<span class="token punctuation">)</span>task<span class="token punctuation">;</span> <span class="token function">pr_info</span><span class="token punctuation">(</span><span class="token string">"hook_chain_0 task: %llx, pid: %d, tgid: %d, openat dfd: %d, filename: %s, flag: %x, mode: %d\n"</span><span class="token punctuation">,</span> task<span class="token punctuation">,</span> pid<span class="token punctuation">,</span> tgid<span class="token punctuation">,</span> dfd<span class="token punctuation">,</span> buf<span class="token punctuation">,</span> flag<span class="token punctuation">,</span> mode<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
JavaScript
通过syscall_argn来获取参数值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
uint64_t open_counts <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">void</span> <span class="token function">before_openat_1</span><span class="token punctuation">(</span><span class="token parameter">hook_fargs4_t <span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span>udata</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//获取参数复制给pcount</span> uint64_t <span class="token operator">*</span>pcount <span class="token operator">=</span> <span class="token punctuation">(</span>uint64_t <span class="token operator">*</span><span class="token punctuation">)</span>udata<span class="token punctuation">;</span> <span class="token punctuation">(</span><span class="token operator">*</span>pcount<span class="token punctuation">)</span><span class="token operator">++</span><span class="token punctuation">;</span> <span class="token comment">//累加</span> <span class="token function">pr_info</span><span class="token punctuation">(</span><span class="token string">"hook_chain_1 before openat task: %llx, count: %llx\n"</span><span class="token punctuation">,</span> args<span class="token operator">-</span><span class="token operator">></span>local<span class="token punctuation">.</span><span class="token property-access">data0</span><span class="token punctuation">,</span> <span class="token operator">*</span>pcount<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">void</span> <span class="token function">after_openat_1</span><span class="token punctuation">(</span><span class="token parameter">hook_fargs4_t <span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span>udata</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">pr_info</span><span class="token punctuation">(</span><span class="token string">"hook_chain_1 after openat task: %llx\n"</span><span class="token punctuation">,</span> args<span class="token operator">-</span><span class="token operator">></span>local<span class="token punctuation">.</span><span class="token property-access">data0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//这里打印出累加后的值</span> <span class="token punctuation">}</span> |
JavaScript
实际案例分析
模块作用:redirect /system/etc/hosts to /data/adb/hosts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
<span class="token constant">KPM_NAME</span><span class="token punctuation">(</span><span class="token string">"hosts_redirect"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token constant">KPM_VERSION</span><span class="token punctuation">(</span><span class="token constant">MYKPM_VERSION</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token constant">KPM_LICENSE</span><span class="token punctuation">(</span><span class="token string">"GPL v2"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token constant">KPM_AUTHOR</span><span class="token punctuation">(</span><span class="token string">"lzghzr"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token constant">KPM_DESCRIPTION</span><span class="token punctuation">(</span><span class="token string">"redirect /system/etc/hosts to /data/adb/hosts/{n}"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> #define <span class="token constant">IZERO</span> <span class="token punctuation">(</span>1UL <span class="token operator"><<</span> <span class="token number">0x10</span><span class="token punctuation">)</span> #define <span class="token constant">UZERO</span> <span class="token punctuation">(</span>1UL <span class="token operator"><<</span> <span class="token number">0x20</span><span class="token punctuation">)</span> struct open_flags<span class="token punctuation">;</span> struct file<span class="token operator">*</span> <span class="token punctuation">(</span><span class="token operator">*</span>do_filp_open<span class="token punctuation">)</span><span class="token punctuation">(</span>int dfd<span class="token punctuation">,</span> struct filename<span class="token operator">*</span> pathname<span class="token punctuation">,</span> <span class="token keyword">const</span> struct open_flags<span class="token operator">*</span> op<span class="token punctuation">)</span><span class="token punctuation">;</span> char<span class="token operator">*</span> <span class="token function">kfunc_def</span><span class="token punctuation">(</span>d_path<span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token keyword">const</span> struct path<span class="token operator">*</span> path<span class="token punctuation">,</span> char<span class="token operator">*</span> buf<span class="token punctuation">,</span> int buflen<span class="token punctuation">)</span><span class="token punctuation">;</span> int <span class="token function">kfunc_def</span><span class="token punctuation">(</span>kern_path<span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token keyword">const</span> char<span class="token operator">*</span> name<span class="token punctuation">,</span> unsigned int flags<span class="token punctuation">,</span> struct path<span class="token operator">*</span> path<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">void</span> <span class="token function">kfunc_def</span><span class="token punctuation">(</span>_raw_spin_lock<span class="token punctuation">)</span><span class="token punctuation">(</span>raw_spinlock_t<span class="token operator">*</span> lock<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">void</span> <span class="token function">kfunc_def</span><span class="token punctuation">(</span>_raw_spin_unlock<span class="token punctuation">)</span><span class="token punctuation">(</span>raw_spinlock_t<span class="token operator">*</span> lock<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">static</span> uint64_t task_struct_fs_offset <span class="token operator">=</span> <span class="token constant">UZERO</span><span class="token punctuation">,</span> task_struct_alloc_lock_offset <span class="token operator">=</span> <span class="token constant">UZERO</span><span class="token punctuation">,</span> fs_struct_pwd_offset <span class="token operator">=</span> <span class="token constant">UZERO</span><span class="token punctuation">,</span> fs_struct_lock_offset <span class="token operator">=</span> <span class="token constant">UZERO</span><span class="token punctuation">;</span> char hosts_source<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"/system/etc/hosts"</span><span class="token punctuation">;</span> char hosts_target<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"/data/adb/hosts/0"</span><span class="token punctuation">;</span> <span class="token keyword">static</span> uid_t <span class="token function">current_uid</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> struct cred<span class="token operator">*</span> cred <span class="token operator">=</span> <span class="token operator">*</span><span class="token punctuation">(</span>struct cred<span class="token operator">**</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">(</span>uintptr_t<span class="token punctuation">)</span>current <span class="token operator">+</span> task_struct_offset<span class="token punctuation">.</span><span class="token property-access">cred_offset</span><span class="token punctuation">)</span><span class="token punctuation">;</span> uid_t uid <span class="token operator">=</span> <span class="token operator">*</span><span class="token punctuation">(</span>uid_t<span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">(</span>uintptr_t<span class="token punctuation">)</span>cred <span class="token operator">+</span> cred_offset<span class="token punctuation">.</span><span class="token property-access">uid_offset</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">return</span> uid<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">static</span> inline <span class="token keyword">void</span> <span class="token function">set_priv_selinx_allow</span><span class="token punctuation">(</span><span class="token parameter">struct task_struct<span class="token operator">*</span> task<span class="token punctuation">,</span> int val</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> struct task_ext<span class="token operator">*</span> ext <span class="token operator">=</span> <span class="token function">get_task_ext</span><span class="token punctuation">(</span>task<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token function">likely</span><span class="token punctuation">(</span><span class="token function">task_ext_valid</span><span class="token punctuation">(</span>ext<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> ext<span class="token operator">-</span><span class="token operator">></span>priv_selinux_allow <span class="token operator">=</span> val<span class="token punctuation">;</span> <span class="token function">dsb</span><span class="token punctuation">(</span>ish<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">static</span> bool <span class="token function">endWith</span><span class="token punctuation">(</span><span class="token parameter"><span class="token keyword">const</span> char<span class="token operator">*</span> str<span class="token punctuation">,</span> <span class="token keyword">const</span> char<span class="token operator">*</span> suffix</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>str <span class="token operator">||</span> <span class="token operator">!</span>suffix<span class="token punctuation">)</span> <span class="token keyword control-flow">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> size_t lenstr <span class="token operator">=</span> <span class="token function">strlen</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span> size_t lensuffix <span class="token operator">=</span> <span class="token function">strlen</span><span class="token punctuation">(</span>suffix<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span>lensuffix <span class="token operator">></span> lenstr<span class="token punctuation">)</span> <span class="token keyword control-flow">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token keyword control-flow">return</span> <span class="token function">strncmp</span><span class="token punctuation">(</span>str <span class="token operator">+</span> lenstr <span class="token operator">-</span> lensuffix<span class="token punctuation">,</span> suffix<span class="token punctuation">,</span> lensuffix<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">do_filp_open_before</span><span class="token punctuation">(</span><span class="token parameter">hook_fargs3_t<span class="token operator">*</span> args<span class="token punctuation">,</span> <span class="token keyword">void</span><span class="token operator">*</span> udata</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> args<span class="token operator">-</span><span class="token operator">></span>local<span class="token punctuation">.</span><span class="token property-access">data0</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token function">unlikely</span><span class="token punctuation">(</span>hosts_target<span class="token punctuation">[</span><span class="token number">16</span><span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token string">'0'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword control-flow">return</span><span class="token punctuation">;</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token function">current_uid</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword control-flow">return</span><span class="token punctuation">;</span> struct filename<span class="token operator">*</span> pathname <span class="token operator">=</span> <span class="token punctuation">(</span>struct filename<span class="token operator">*</span><span class="token punctuation">)</span>args<span class="token operator">-</span><span class="token operator">></span>arg1<span class="token punctuation">;</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token function">unlikely</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">strcmp</span><span class="token punctuation">(</span>pathname<span class="token operator">-</span><span class="token operator">></span>name<span class="token punctuation">,</span> hosts_source<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> args<span class="token operator">-</span><span class="token operator">></span>local<span class="token punctuation">.</span><span class="token property-access">data0</span> <span class="token operator">=</span> <span class="token punctuation">(</span>uint64_t<span class="token punctuation">)</span>pathname<span class="token operator">-</span><span class="token operator">></span>name<span class="token punctuation">;</span> pathname<span class="token operator">-</span><span class="token operator">></span>name <span class="token operator">=</span> hosts_target<span class="token punctuation">;</span> <span class="token function">set_priv_selinx_allow</span><span class="token punctuation">(</span>current<span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword control-flow">else</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token function">unlikely</span><span class="token punctuation">(</span><span class="token function">endWith</span><span class="token punctuation">(</span>pathname<span class="token operator">-</span><span class="token operator">></span>name<span class="token punctuation">,</span> <span class="token string">"hosts"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> struct task_struct<span class="token operator">*</span> task <span class="token operator">=</span> current<span class="token punctuation">;</span> spinlock_t task_lock <span class="token operator">=</span> <span class="token operator">*</span><span class="token punctuation">(</span>spinlock_t<span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">(</span>uintptr_t<span class="token punctuation">)</span>task <span class="token operator">+</span> task_struct_alloc_lock_offset<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">spin_lock</span><span class="token punctuation">(</span><span class="token operator">&</span>task_lock<span class="token punctuation">)</span><span class="token punctuation">;</span> struct fs_struct<span class="token operator">*</span> fs <span class="token operator">=</span> <span class="token operator">*</span><span class="token punctuation">(</span>struct fs_struct<span class="token operator">**</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">(</span>uintptr_t<span class="token punctuation">)</span>task <span class="token operator">+</span> task_struct_fs_offset<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token function">likely</span><span class="token punctuation">(</span>fs<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// spinlock_t fs_lock = *(spinlock_t*)((uintptr_t)fs + fs_struct_lock_offset);</span> <span class="token comment">// spin_lock(&fs_lock);</span> <span class="token function">spin_lock</span><span class="token punctuation">(</span><span class="token operator">&</span>fs<span class="token operator">-</span><span class="token operator">></span>lock<span class="token punctuation">)</span><span class="token punctuation">;</span> struct path<span class="token operator">*</span> pwd <span class="token operator">=</span> <span class="token punctuation">(</span>struct path<span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">(</span>uintptr_t<span class="token punctuation">)</span>fs <span class="token operator">+</span> fs_struct_pwd_offset<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token function">likely</span><span class="token punctuation">(</span>pwd<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> char buf<span class="token punctuation">[</span><span class="token constant">PATH_MAX</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&</span>buf<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token constant">PATH_MAX</span><span class="token punctuation">)</span><span class="token punctuation">;</span> char<span class="token operator">*</span> pwd_path <span class="token operator">=</span> <span class="token function">d_path</span><span class="token punctuation">(</span>pwd<span class="token punctuation">,</span> buf<span class="token punctuation">,</span> <span class="token constant">PATH_MAX</span><span class="token punctuation">)</span><span class="token punctuation">;</span> #ifdef <span class="token constant">DEBUG</span> <span class="token function">logkm</span><span class="token punctuation">(</span><span class="token string">"pwd_path=%s\n"</span><span class="token punctuation">,</span> pwd_path<span class="token punctuation">)</span><span class="token punctuation">;</span> #endif <span class="token comment">/* DEBUG */</span> <span class="token operator">*</span> buf <span class="token operator">=</span> <span class="token string">'\0'</span><span class="token punctuation">;</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span>pathname<span class="token operator">-</span><span class="token operator">></span>name<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">!=</span> <span class="token string">'/'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">strncat</span><span class="token punctuation">(</span>buf<span class="token punctuation">,</span> pwd_path<span class="token punctuation">,</span> <span class="token function">strlen</span><span class="token punctuation">(</span>pwd_path<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">strncat</span><span class="token punctuation">(</span>buf<span class="token punctuation">,</span> <span class="token string">"/"</span><span class="token punctuation">,</span> <span class="token function">strlen</span><span class="token punctuation">(</span><span class="token string">"/"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">strncat</span><span class="token punctuation">(</span>buf<span class="token punctuation">,</span> pathname<span class="token operator">-</span><span class="token operator">></span>name<span class="token punctuation">,</span> <span class="token function">strlen</span><span class="token punctuation">(</span>pathname<span class="token operator">-</span><span class="token operator">></span>name<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> #ifdef <span class="token constant">DEBUG</span> <span class="token function">logkm</span><span class="token punctuation">(</span><span class="token string">"full_path=%s\n"</span><span class="token punctuation">,</span> buf<span class="token punctuation">)</span><span class="token punctuation">;</span> #endif <span class="token comment">/* DEBUG */</span> struct path path<span class="token punctuation">;</span> int err <span class="token operator">=</span> <span class="token function">kern_path</span><span class="token punctuation">(</span>buf<span class="token punctuation">,</span> <span class="token constant">LOOKUP_FOLLOW</span><span class="token punctuation">,</span> <span class="token operator">&</span>path<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token function">likely</span><span class="token punctuation">(</span><span class="token operator">!</span>err<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&</span>buf<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token constant">PATH_MAX</span><span class="token punctuation">)</span><span class="token punctuation">;</span> char<span class="token operator">*</span> hosts_name <span class="token operator">=</span> <span class="token function">d_path</span><span class="token punctuation">(</span><span class="token operator">&</span>path<span class="token punctuation">,</span> buf<span class="token punctuation">,</span> <span class="token constant">PATH_MAX</span><span class="token punctuation">)</span><span class="token punctuation">;</span> #ifdef <span class="token constant">DEBUG</span> <span class="token function">logkm</span><span class="token punctuation">(</span><span class="token string">"hosts_name=%s\n"</span><span class="token punctuation">,</span> hosts_name<span class="token punctuation">)</span><span class="token punctuation">;</span> #endif <span class="token comment">/* DEBUG */</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token function">likely</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token constant">IS_ERR</span><span class="token punctuation">(</span>hosts_name<span class="token punctuation">)</span> <span class="token operator">&&</span> <span class="token operator">!</span><span class="token function">strcmp</span><span class="token punctuation">(</span>hosts_name<span class="token punctuation">,</span> hosts_source<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> args<span class="token operator">-</span><span class="token operator">></span>local<span class="token punctuation">.</span><span class="token property-access">data0</span> <span class="token operator">=</span> <span class="token punctuation">(</span>uint64_t<span class="token punctuation">)</span>pathname<span class="token operator">-</span><span class="token operator">></span>name<span class="token punctuation">;</span> pathname<span class="token operator">-</span><span class="token operator">></span>name <span class="token operator">=</span> hosts_target<span class="token punctuation">;</span> <span class="token function">set_priv_selinx_allow</span><span class="token punctuation">(</span>task<span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">spin_unlock</span><span class="token punctuation">(</span><span class="token operator">&</span>fs<span class="token operator">-</span><span class="token operator">></span>lock<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">spin_unlock</span><span class="token punctuation">(</span><span class="token operator">&</span>task_lock<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">do_filp_open_after</span><span class="token punctuation">(</span><span class="token parameter">hook_fargs3_t<span class="token operator">*</span> args<span class="token punctuation">,</span> <span class="token keyword">void</span><span class="token operator">*</span> udata</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token function">unlikely</span><span class="token punctuation">(</span>args<span class="token operator">-</span><span class="token operator">></span>local<span class="token punctuation">.</span><span class="token property-access">data0</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">set_priv_selinx_allow</span><span class="token punctuation">(</span>current<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> struct filename<span class="token operator">*</span> pathname <span class="token operator">=</span> <span class="token punctuation">(</span>struct filename<span class="token operator">*</span><span class="token punctuation">)</span>args<span class="token operator">-</span><span class="token operator">></span>arg1<span class="token punctuation">;</span> pathname<span class="token operator">-</span><span class="token operator">></span>name <span class="token operator">=</span> <span class="token punctuation">(</span>char<span class="token operator">*</span><span class="token punctuation">)</span>args<span class="token operator">-</span><span class="token operator">></span>local<span class="token punctuation">.</span><span class="token property-access">data0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">static</span> long <span class="token function">inline_hook_control0</span><span class="token punctuation">(</span><span class="token parameter"><span class="token keyword">const</span> char<span class="token operator">*</span> ctl_args<span class="token punctuation">,</span> char<span class="token operator">*</span> __user out_msg<span class="token punctuation">,</span> int outlen</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> char num <span class="token operator">=</span> ctl_args <span class="token operator">?</span> <span class="token operator">*</span>ctl_args <span class="token operator">:</span> <span class="token string">'1'</span><span class="token punctuation">;</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token function">unlikely</span><span class="token punctuation">(</span>num <span class="token operator"><</span> <span class="token string">'0'</span> <span class="token operator">||</span> num <span class="token operator">></span> <span class="token string">'9'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword control-flow">return</span> <span class="token operator">-</span><span class="token number">11</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> hosts_target<span class="token punctuation">[</span><span class="token number">16</span><span class="token punctuation">]</span> <span class="token operator">=</span> num<span class="token punctuation">;</span> char msg<span class="token punctuation">[</span><span class="token number">64</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token function">snprintf</span><span class="token punctuation">(</span>msg<span class="token punctuation">,</span> <span class="token function">sizeof</span><span class="token punctuation">(</span>msg<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"_(._.)_"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">compat_copy_to_user</span><span class="token punctuation">(</span>out_msg<span class="token punctuation">,</span> msg<span class="token punctuation">,</span> <span class="token function">sizeof</span><span class="token punctuation">(</span>msg<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">static</span> long <span class="token function">calculate_offsets</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 获取 pwd 相关偏移</span> <span class="token comment">// task->fs</span> <span class="token comment">// fs->pwd</span> <span class="token function">int</span> <span class="token punctuation">(</span><span class="token operator">*</span>proc_cwd_link<span class="token punctuation">)</span><span class="token punctuation">(</span>struct dentry<span class="token operator">*</span> dentry<span class="token punctuation">,</span> struct path<span class="token operator">*</span> path<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">lookup_name</span><span class="token punctuation">(</span>proc_cwd_link<span class="token punctuation">)</span><span class="token punctuation">;</span> uint32_t<span class="token operator">*</span> proc_cwd_link_src <span class="token operator">=</span> <span class="token punctuation">(</span>uint32_t<span class="token operator">*</span><span class="token punctuation">)</span>proc_cwd_link<span class="token punctuation">;</span> <span class="token keyword control-flow">for</span> <span class="token punctuation">(</span>u32 i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> <span class="token number">0x30</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> #ifdef <span class="token constant">CONFIG_DEBUG</span> <span class="token function">logkm</span><span class="token punctuation">(</span><span class="token string">"proc_cwd_link %x %llx\n"</span><span class="token punctuation">,</span> i<span class="token punctuation">,</span> proc_cwd_link<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> #endif <span class="token comment">/* CONFIG_DEBUG */</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span>proc_cwd_link_src<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token constant">ARM64_RET</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword control-flow">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword control-flow">else</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>proc_cwd_link_src<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">&</span> <span class="token constant">MASK_LDP_64_</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token constant">INST_LDP_64_</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> uint64_t imm7 <span class="token operator">=</span> <span class="token function">bits32</span><span class="token punctuation">(</span>proc_cwd_link_src<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">21</span><span class="token punctuation">,</span> <span class="token number">15</span><span class="token punctuation">)</span><span class="token punctuation">;</span> fs_struct_pwd_offset <span class="token operator">=</span> <span class="token function">sign64_extend</span><span class="token punctuation">(</span><span class="token punctuation">(</span>imm7 <span class="token operator"><<</span> 0b11u<span class="token punctuation">)</span><span class="token punctuation">,</span> 16u<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword control-flow">else</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span>task_struct_alloc_lock_offset <span class="token operator">!=</span> <span class="token constant">UZERO</span> <span class="token operator">&&</span> <span class="token punctuation">(</span>proc_cwd_link_src<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">&</span> <span class="token constant">MASK_ADD_64</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token constant">INST_ADD_64</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> uint32_t sh <span class="token operator">=</span> <span class="token function">bit</span><span class="token punctuation">(</span>proc_cwd_link_src<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">22</span><span class="token punctuation">)</span><span class="token punctuation">;</span> uint64_t imm12 <span class="token operator">=</span> imm12 <span class="token operator">=</span> <span class="token function">bits32</span><span class="token punctuation">(</span>proc_cwd_link_src<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">21</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span>sh<span class="token punctuation">)</span> <span class="token punctuation">{</span> fs_struct_lock_offset <span class="token operator">=</span> <span class="token function">sign64_extend</span><span class="token punctuation">(</span><span class="token punctuation">(</span>imm12 <span class="token operator"><<</span> 12u<span class="token punctuation">)</span><span class="token punctuation">,</span> 16u<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword control-flow">else</span> <span class="token punctuation">{</span> fs_struct_lock_offset <span class="token operator">=</span> <span class="token function">sign64_extend</span><span class="token punctuation">(</span><span class="token punctuation">(</span>imm12<span class="token punctuation">)</span><span class="token punctuation">,</span> 16u<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword control-flow">else</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span>task_struct_alloc_lock_offset <span class="token operator">!=</span> <span class="token constant">UZERO</span> <span class="token operator">&&</span> <span class="token punctuation">(</span>proc_cwd_link_src<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">&</span> <span class="token constant">MASK_LDR_64_</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token constant">INST_LDR_64_</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> uint64_t imm12 <span class="token operator">=</span> <span class="token function">bits32</span><span class="token punctuation">(</span>proc_cwd_link_src<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">21</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span> task_struct_fs_offset <span class="token operator">=</span> <span class="token function">sign64_extend</span><span class="token punctuation">(</span><span class="token punctuation">(</span>imm12 <span class="token operator"><<</span> 0b11u<span class="token punctuation">)</span><span class="token punctuation">,</span> 16u<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword control-flow">else</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span>task_struct_alloc_lock_offset <span class="token operator">==</span> <span class="token constant">UZERO</span> <span class="token operator">&&</span> <span class="token punctuation">(</span>proc_cwd_link_src<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">&</span> <span class="token constant">MASK_ADD_64</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token constant">INST_ADD_64</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> uint32_t sh <span class="token operator">=</span> <span class="token function">bit</span><span class="token punctuation">(</span>proc_cwd_link_src<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">22</span><span class="token punctuation">)</span><span class="token punctuation">;</span> uint64_t imm12 <span class="token operator">=</span> imm12 <span class="token operator">=</span> <span class="token function">bits32</span><span class="token punctuation">(</span>proc_cwd_link_src<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">21</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span>sh<span class="token punctuation">)</span> <span class="token punctuation">{</span> task_struct_alloc_lock_offset <span class="token operator">=</span> <span class="token function">sign64_extend</span><span class="token punctuation">(</span><span class="token punctuation">(</span>imm12 <span class="token operator"><<</span> 12u<span class="token punctuation">)</span><span class="token punctuation">,</span> 16u<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword control-flow">else</span> <span class="token punctuation">{</span> task_struct_alloc_lock_offset <span class="token operator">=</span> <span class="token function">sign64_extend</span><span class="token punctuation">(</span><span class="token punctuation">(</span>imm12<span class="token punctuation">)</span><span class="token punctuation">,</span> 16u<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// MOV (to/from SP) is an alias of ADD <Xd|SP>, <Xn|SP>, #0</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span>task_struct_alloc_lock_offset <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> task_struct_alloc_lock_offset <span class="token operator">=</span> <span class="token constant">UZERO</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> #ifdef <span class="token constant">CONFIG_DEBUG</span> <span class="token function">logkm</span><span class="token punctuation">(</span><span class="token string">"task_struct_fs_offset=0x%llx\n"</span><span class="token punctuation">,</span> task_struct_fs_offset<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">logkm</span><span class="token punctuation">(</span><span class="token string">"task_struct_alloc_lock_offset=0x%llx\n"</span><span class="token punctuation">,</span> task_struct_alloc_lock_offset<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">logkm</span><span class="token punctuation">(</span><span class="token string">"fs_struct_pwd_offset=0x%llx\n"</span><span class="token punctuation">,</span> fs_struct_pwd_offset<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">logkm</span><span class="token punctuation">(</span><span class="token string">"fs_struct_lock_offset=0x%llx\n"</span><span class="token punctuation">,</span> fs_struct_lock_offset<span class="token punctuation">)</span><span class="token punctuation">;</span> #endif <span class="token comment">/* CONFIG_DEBUG */</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span>task_struct_fs_offset <span class="token operator">==</span> <span class="token constant">UZERO</span> <span class="token operator">||</span> task_struct_alloc_lock_offset <span class="token operator">==</span> <span class="token constant">UZERO</span> <span class="token operator">||</span> fs_struct_pwd_offset <span class="token operator">==</span> <span class="token constant">UZERO</span> <span class="token operator">||</span> fs_struct_lock_offset <span class="token operator">==</span> <span class="token constant">UZERO</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword control-flow">return</span> <span class="token operator">-</span><span class="token number">11</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword control-flow">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">static</span> long <span class="token function">inline_hook_init</span><span class="token punctuation">(</span><span class="token parameter"><span class="token keyword">const</span> char<span class="token operator">*</span> args<span class="token punctuation">,</span> <span class="token keyword">const</span> char<span class="token operator">*</span> event<span class="token punctuation">,</span> <span class="token keyword">void</span><span class="token operator">*</span> __user reserved</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> int rc <span class="token operator">=</span> <span class="token function">inline_hook_control0</span><span class="token punctuation">(</span>args<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span>rc <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword control-flow">return</span> rc<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">kfunc_lookup_name</span><span class="token punctuation">(</span>d_path<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">kfunc_lookup_name</span><span class="token punctuation">(</span>kern_path<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">kfunc_lookup_name</span><span class="token punctuation">(</span>_raw_spin_lock<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">kfunc_lookup_name</span><span class="token punctuation">(</span>_raw_spin_unlock<span class="token punctuation">)</span><span class="token punctuation">;</span> rc <span class="token operator">=</span> <span class="token function">calculate_offsets</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span>rc <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword control-flow">return</span> rc<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">lookup_name</span><span class="token punctuation">(</span>do_filp_open<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">hook_func</span><span class="token punctuation">(</span>do_filp_open<span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> do_filp_open_before<span class="token punctuation">,</span> do_filp_open_after<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">static</span> long <span class="token function">inline_hook_exit</span><span class="token punctuation">(</span><span class="token parameter"><span class="token keyword">void</span><span class="token operator">*</span> __user reserved</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">unhook_func</span><span class="token punctuation">(</span>do_filp_open<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token constant">KPM_INIT</span><span class="token punctuation">(</span>inline_hook_init<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token constant">KPM_CTL0</span><span class="token punctuation">(</span>inline_hook_control0<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token constant">KPM_EXIT</span><span class="token punctuation">(</span>inline_hook_exit<span class="token punctuation">)</span><span class="token punctuation">;</span> |
JavaScript
这个模块主要是hook VFS层do_sys_open, do_sys_open是open/openat的一个实现. VFS层是比syscal 更底层的实现

具体代码分析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
int rc <span class="token operator">=</span> <span class="token function">inline_hook_control0</span><span class="token punctuation">(</span>args<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span>rc <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword control-flow">return</span> rc<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">kfunc_lookup_name</span><span class="token punctuation">(</span>d_path<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">kfunc_lookup_name</span><span class="token punctuation">(</span>kern_path<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">kfunc_lookup_name</span><span class="token punctuation">(</span>_raw_spin_lock<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">kfunc_lookup_name</span><span class="token punctuation">(</span>_raw_spin_unlock<span class="token punctuation">)</span><span class="token punctuation">;</span> rc <span class="token operator">=</span> <span class="token function">calculate_offsets</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span>rc <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword control-flow">return</span> rc<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">lookup_name</span><span class="token punctuation">(</span>do_filp_open<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">hook_func</span><span class="token punctuation">(</span>do_filp_open<span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> do_filp_open_before<span class="token punctuation">,</span> do_filp_open_after<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
JavaScript
声明do_filp_open函数指针
1 2 3 4 |
struct file<span class="token operator">*</span> <span class="token punctuation">(</span><span class="token operator">*</span>do_filp_open<span class="token punctuation">)</span><span class="token punctuation">(</span>int dfd<span class="token punctuation">,</span> struct filename<span class="token operator">*</span> pathname<span class="token punctuation">,</span> <span class="token keyword">const</span> struct open_flags<span class="token operator">*</span> op<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token literal-property property">第一个参数</span><span class="token operator">:</span> 目录文件描述符 <span class="token literal-property property">第二个参数</span><span class="token operator">:</span> 文件名结构体指针 <span class="token literal-property property">第三个参数</span><span class="token operator">:</span> 打开标志结构体指针 |
JavaScript
inline_hook_control0函数是设置文件编号, 假设是2
char hosts_target[] = “/data/adb/hosts/0”;
变成:
char hosts_target[] = “/data/adb/hosts/2”;
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<span class="token keyword">static</span> long <span class="token function">inline_hook_control0</span><span class="token punctuation">(</span><span class="token parameter"><span class="token keyword">const</span> char<span class="token operator">*</span> ctl_args<span class="token punctuation">,</span> char<span class="token operator">*</span> __user out_msg<span class="token punctuation">,</span> int outlen</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> char num <span class="token operator">=</span> ctl_args <span class="token operator">?</span> <span class="token operator">*</span>ctl_args <span class="token operator">:</span> <span class="token string">'1'</span><span class="token punctuation">;</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token function">unlikely</span><span class="token punctuation">(</span>num <span class="token operator"><</span> <span class="token string">'0'</span> <span class="token operator">||</span> num <span class="token operator">></span> <span class="token string">'9'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword control-flow">return</span> <span class="token operator">-</span><span class="token number">11</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> hosts_target<span class="token punctuation">[</span><span class="token number">16</span><span class="token punctuation">]</span> <span class="token operator">=</span> num<span class="token punctuation">;</span> char msg<span class="token punctuation">[</span><span class="token number">64</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token function">snprintf</span><span class="token punctuation">(</span>msg<span class="token punctuation">,</span> <span class="token function">sizeof</span><span class="token punctuation">(</span>msg<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"_(._.)_"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">compat_copy_to_user</span><span class="token punctuation">(</span>out_msg<span class="token punctuation">,</span> msg<span class="token punctuation">,</span> <span class="token function">sizeof</span><span class="token punctuation">(</span>msg<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword control-flow">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
JavaScript
查找并保存几个重要的内核函数地址
1 2 3 4 5 |
<span class="token comment">// 查找并保存几个重要的内核函数地址</span> <span class="token function">kfunc_lookup_name</span><span class="token punctuation">(</span>d_path<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 获取d_path函数的地址</span> <span class="token function">kfunc_lookup_name</span><span class="token punctuation">(</span>kern_path<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 获取kern_path函数的地址</span> <span class="token function">kfunc_lookup_name</span><span class="token punctuation">(</span>_raw_spin_lock<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 获取_raw_spin_lock函数的地址</span> <span class="token function">kfunc_lookup_name</span><span class="token punctuation">(</span>_raw_spin_unlock<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 获取_raw_spin_unlock函数的地址</span> |
JavaScript
hook do_filp_open
1 2 |
<span class="token function">lookup_name</span><span class="token punctuation">(</span>do_filp_open<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//获取do_filp_open的函数地址</span> <span class="token function">hook_func</span><span class="token punctuation">(</span>do_filp_open<span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> do_filp_open_before<span class="token punctuation">,</span> do_filp_open_after<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
JavaScript
do_filp_open_before的实现
获取参数filename指针, 再获取pathname , 判断绝对路径和相对路径
绝对路径判断相等, 则执行重定向和设置selinux allow = true, hook完成后会改回去false
相对路径则获取工作目录拼接成绝对路径, 再执行相同的逻辑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
<span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">do_filp_open_before</span><span class="token punctuation">(</span><span class="token class-name">hook_fargs3_t</span><span class="token operator">*</span> args<span class="token punctuation">,</span> <span class="token keyword">void</span><span class="token operator">*</span> udata<span class="token punctuation">)</span> <span class="token punctuation">{</span> args<span class="token operator">-></span>local<span class="token punctuation">.</span>data0 <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">//设置local.data0为0</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">unlikely</span><span class="token punctuation">(</span>hosts_target<span class="token punctuation">[</span><span class="token number">16</span><span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token char">'0'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">current_uid</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token comment">//判断current_uid()是否为0, 也就是判断当前用户是否为root用户</span> <span class="token keyword">return</span><span class="token punctuation">;</span> <span class="token keyword">struct</span> <span class="token class-name">filename</span><span class="token operator">*</span> pathname <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">filename</span><span class="token operator">*</span><span class="token punctuation">)</span>args<span class="token operator">-></span>arg1<span class="token punctuation">;</span> <span class="token comment">//文件name struct</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">unlikely</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">strcmp</span><span class="token punctuation">(</span>pathname<span class="token operator">-></span>name<span class="token punctuation">,</span> hosts_source<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//判断路径是否== /system/etc/hosts</span> args<span class="token operator">-></span>local<span class="token punctuation">.</span>data0 <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">uint64_t</span><span class="token punctuation">)</span>pathname<span class="token operator">-></span>name<span class="token punctuation">;</span> <span class="token comment">//保存old pathname</span> pathname<span class="token operator">-></span>name <span class="token operator">=</span> hosts_target<span class="token punctuation">;</span> <span class="token comment">//重定向到新的目录/data/adb/hosts/2</span> <span class="token function">set_priv_selinx_allow</span><span class="token punctuation">(</span>current<span class="token punctuation">,</span> true<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//设置selinux权限</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">unlikely</span><span class="token punctuation">(</span><span class="token function">endWith</span><span class="token punctuation">(</span>pathname<span class="token operator">-></span>name<span class="token punctuation">,</span> <span class="token string">"hosts"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//判断是否hosts结尾, 相对路径模式</span> <span class="token keyword">struct</span> <span class="token class-name">task_struct</span><span class="token operator">*</span> task <span class="token operator">=</span> current<span class="token punctuation">;</span> <span class="token class-name">spinlock_t</span> task_lock <span class="token operator">=</span> <span class="token operator">*</span><span class="token punctuation">(</span><span class="token class-name">spinlock_t</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">uintptr_t</span><span class="token punctuation">)</span>task <span class="token operator">+</span> task_struct_alloc_lock_offset<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">spin_lock</span><span class="token punctuation">(</span><span class="token operator">&</span>task_lock<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">struct</span> <span class="token class-name">fs_struct</span><span class="token operator">*</span> fs <span class="token operator">=</span> <span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">fs_struct</span><span class="token operator">*</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">uintptr_t</span><span class="token punctuation">)</span>task <span class="token operator">+</span> task_struct_fs_offset<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">likely</span><span class="token punctuation">(</span>fs<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// spinlock_t fs_lock = *(spinlock_t*)((uintptr_t)fs + fs_struct_lock_offset);</span> <span class="token comment">// spin_lock(&fs_lock);</span> <span class="token function">spin_lock</span><span class="token punctuation">(</span><span class="token operator">&</span>fs<span class="token operator">-></span>lock<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">struct</span> <span class="token class-name">path</span><span class="token operator">*</span> pwd <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">path</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">uintptr_t</span><span class="token punctuation">)</span>fs <span class="token operator">+</span> fs_struct_pwd_offset<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">likely</span><span class="token punctuation">(</span>pwd<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">char</span> buf<span class="token punctuation">[</span>PATH_MAX<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&</span>buf<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> PATH_MAX<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">char</span><span class="token operator">*</span> pwd_path <span class="token operator">=</span> <span class="token function">d_path</span><span class="token punctuation">(</span>pwd<span class="token punctuation">,</span> buf<span class="token punctuation">,</span> PATH_MAX<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">ifdef</span> <span class="token expression">DEBUG</span></span> <span class="token function">logkm</span><span class="token punctuation">(</span><span class="token string">"pwd_path=%s\n"</span><span class="token punctuation">,</span> pwd_path<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span> <span class="token comment">/* DEBUG */</span></span> <span class="token operator">*</span> buf <span class="token operator">=</span> <span class="token char">'\0'</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>pathname<span class="token operator">-></span>name<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">!=</span> <span class="token char">'/'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">strncat</span><span class="token punctuation">(</span>buf<span class="token punctuation">,</span> pwd_path<span class="token punctuation">,</span> <span class="token function">strlen</span><span class="token punctuation">(</span>pwd_path<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">strncat</span><span class="token punctuation">(</span>buf<span class="token punctuation">,</span> <span class="token string">"/"</span><span class="token punctuation">,</span> <span class="token function">strlen</span><span class="token punctuation">(</span><span class="token string">"/"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">strncat</span><span class="token punctuation">(</span>buf<span class="token punctuation">,</span> pathname<span class="token operator">-></span>name<span class="token punctuation">,</span> <span class="token function">strlen</span><span class="token punctuation">(</span>pathname<span class="token operator">-></span>name<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">ifdef</span> <span class="token expression">DEBUG</span></span> <span class="token function">logkm</span><span class="token punctuation">(</span><span class="token string">"full_path=%s\n"</span><span class="token punctuation">,</span> buf<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span> <span class="token comment">/* DEBUG */</span></span> <span class="token keyword">struct</span> <span class="token class-name">path</span> path<span class="token punctuation">;</span> <span class="token keyword">int</span> err <span class="token operator">=</span> <span class="token function">kern_path</span><span class="token punctuation">(</span>buf<span class="token punctuation">,</span> LOOKUP_FOLLOW<span class="token punctuation">,</span> <span class="token operator">&</span>path<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">likely</span><span class="token punctuation">(</span><span class="token operator">!</span>err<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&</span>buf<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> PATH_MAX<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">char</span><span class="token operator">*</span> hosts_name <span class="token operator">=</span> <span class="token function">d_path</span><span class="token punctuation">(</span><span class="token operator">&</span>path<span class="token punctuation">,</span> buf<span class="token punctuation">,</span> PATH_MAX<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">ifdef</span> <span class="token expression">DEBUG</span></span> <span class="token function">logkm</span><span class="token punctuation">(</span><span class="token string">"hosts_name=%s\n"</span><span class="token punctuation">,</span> hosts_name<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span> <span class="token comment">/* DEBUG */</span></span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">likely</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">IS_ERR</span><span class="token punctuation">(</span>hosts_name<span class="token punctuation">)</span> <span class="token operator">&&</span> <span class="token operator">!</span><span class="token function">strcmp</span><span class="token punctuation">(</span>hosts_name<span class="token punctuation">,</span> hosts_source<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//判断组装后的完整路径相等, 执行重定向操作</span> args<span class="token operator">-></span>local<span class="token punctuation">.</span>data0 <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">uint64_t</span><span class="token punctuation">)</span>pathname<span class="token operator">-></span>name<span class="token punctuation">;</span> pathname<span class="token operator">-></span>name <span class="token operator">=</span> hosts_target<span class="token punctuation">;</span> <span class="token function">set_priv_selinx_allow</span><span class="token punctuation">(</span>task<span class="token punctuation">,</span> true<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token function">spin_unlock</span><span class="token punctuation">(</span><span class="token operator">&</span>fs<span class="token operator">-></span>lock<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">spin_unlock</span><span class="token punctuation">(</span><span class="token operator">&</span>task_lock<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
C
do_filp_open_after的实现
1 2 3 4 5 6 7 |
<span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">do_filp_open_after</span><span class="token punctuation">(</span><span class="token parameter">hook_fargs3_t<span class="token operator">*</span> args<span class="token punctuation">,</span> <span class="token keyword">void</span><span class="token operator">*</span> udata</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword control-flow">if</span> <span class="token punctuation">(</span><span class="token function">unlikely</span><span class="token punctuation">(</span>args<span class="token operator">-</span><span class="token operator">></span>local<span class="token punctuation">.</span><span class="token property-access">data0</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">set_priv_selinx_allow</span><span class="token punctuation">(</span>current<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//seliux = false</span> struct filename<span class="token operator">*</span> pathname <span class="token operator">=</span> <span class="token punctuation">(</span>struct filename<span class="token operator">*</span><span class="token punctuation">)</span>args<span class="token operator">-</span><span class="token operator">></span>arg1<span class="token punctuation">;</span> pathname<span class="token operator">-</span><span class="token operator">></span>name <span class="token operator">=</span> <span class="token punctuation">(</span>char<span class="token operator">*</span><span class="token punctuation">)</span>args<span class="token operator">-</span><span class="token operator">></span>local<span class="token punctuation">.</span><span class="token property-access">data0</span><span class="token punctuation">;</span> <span class="token comment">//还原pathname</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
JavaScript
编译(Ubuntu)
官方编译指南: https://github.com/bmax121/KernelPatch/blob/main/doc/en/build.md
先下载交叉编译
下载 AArch64 bare-metal target (aarch64-none-elf)解压
设置环境变量
1 2 |
<span class="token keyword module">export</span> <span class="token constant">PATH</span><span class="token operator">=</span>$<span class="token constant">PATH</span><span class="token operator">:</span><span class="token operator">/</span>work<span class="token operator">/</span>test<span class="token operator">/</span>arm<span class="token operator">-</span>gnu<span class="token operator">-</span>toolchain<span class="token operator">-</span><span class="token number">13.3</span><span class="token punctuation">.</span><span class="token property-access">rel1</span><span class="token operator">-</span>x86_64<span class="token operator">-</span>aarch64<span class="token operator">-</span>none<span class="token operator">-</span>elf<span class="token operator">/</span>bin <span class="token keyword module">export</span> <span class="token constant">TARGET_COMPILE</span><span class="token operator">=</span>aarch64<span class="token operator">-</span>none<span class="token operator">-</span>elf<span class="token operator">-</span> |
JavaScript
编译
1 2 |
cd <span class="token operator">/</span>work<span class="token operator">/</span>test<span class="token operator">/</span><span class="token maybe-class-name">APatch_kpm</span><span class="token operator">/</span>hosts_redirect make |
JavaScript
完成!
KPM模块安装
- 作者:拓森Leo
- 链接:https://www.uzilol.cn/article/12dbf20f-1d11-802a-8cad-cf296b4a0950
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。