Skip to content

Commit 02b279e

Browse files
回滚至2.2版本
1 parent 234d1f7 commit 02b279e

File tree

4 files changed

+19
-53
lines changed

4 files changed

+19
-53
lines changed

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,9 @@
2424
目前只在5.10以及5.15两个版本通过测试,理论上5.10以上版本都能正常使用。
2525

2626
# 一些疑惑
27-
在内核使用uprobe_register函数注册uprobe挂载点的时候在一些特殊情况下会出现实际注册的函数偏移与传入的函数偏移不一致的问题,至于为什么会这样,
28-
我翻阅linux内核源码发现问题出现于[内存地址计算错误](https://elixir.bootlin.com/linux/v5.15.74/source/kernel/events/uprobes.c#L1004),从这里开始内存地址就出现了偏差,我推测是内存页计算有偏差,但是具体原因不清楚。
27+
~~在内核使用uprobe_register函数注册uprobe挂载点的时候在一些特殊情况下会出现实际注册的函数偏移与传入的函数偏移不一致的问题,至于为什么会这样, 我翻阅linux内核源码发现问题出现于内存地址计算错误,从这里开始内存地址就出现了偏差,我推测是内存页计算有偏差,但是具体原因不清楚。~~
28+
答案已经找到了,原来是我一开始就理解错了,传递给uprobe_register函数的偏移值压根就不是函数的文件偏移,而是要经过其他运算得到,简单来说就是函数地址减去所在内存段的基地址再加上该内存段内存区域的偏移量所得的值。
29+
计算示例如下:
30+
以下图片展示了一个so文件在maps文件中的区域段
31+
![计算示例](./pic/偏移计算.JPG)
32+
假如一个函数的地址为0x7626323000,那要hook这个函数那传给uprobe_register函数的偏移值应该为0x7626323000-0x7626322000+0x90000=0x91000.

kernel_trace.c

Lines changed: 13 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,10 @@
1111
#include <syscall.h>
1212
#include <asm/current.h>
1313
#include <hook.h>
14-
#include <linux/err.h>
1514
#include "kernel_trace.h"
1615

1716
KPM_NAME("kernel_trace");
18-
KPM_VERSION("3.0.0");
17+
KPM_VERSION("2.2.0");
1918
KPM_LICENSE("GPL v2");
2019
KPM_AUTHOR("Test");
2120
KPM_DESCRIPTION("use uprobe trace some fun in kpm");
@@ -30,27 +29,26 @@ void (*rcu_read_unlock)(void) = 0;
3029
int (*trace_printk)(unsigned long ip, const char *fmt, ...) = 0;
3130

3231
void *show_map_vma_addr;
33-
void *build_map_info_addr;
3432

3533

3634
char file_name[MAX_PATH_LEN];
3735
uid_t target_uid = -1;
3836
unsigned long fun_offsets[MAX_HOOK_NUM];
39-
unsigned long test_fun_addr;
4037
int hook_num = 0;
4138
struct rb_root fun_info_tree = RB_ROOT;
4239
static struct inode *inode;
4340
unsigned long module_base = 0;
4441
static struct uprobe_consumer trace_uc;
45-
static long long addr_fixer = 0;
4642

4743

4844

4945
void before_show_map_vma(hook_fargs2_t *args, void *udata)
5046
{
47+
struct seq_file* o_seq_file;
5148
struct vm_area_struct *ovma;
5249
unsigned long start, end;
5350

51+
o_seq_file = (struct seq_file*)args->arg0;
5452
ovma = (struct vm_area_struct*)args->arg1;
5553
start = ovma->vm_start;
5654
end = ovma->vm_end;
@@ -60,21 +58,6 @@ void before_show_map_vma(hook_fargs2_t *args, void *udata)
6058
}
6159
}
6260

63-
void after_build_map_info(hook_fargs3_t *args, void *udata)
64-
{
65-
struct map_info *tret = (struct map_info *)args->ret;
66-
bool is_register = (bool)args->arg2;
67-
unsigned long tvaddr = tret->vaddr;
68-
long long fun_offset = (long long)args->arg1;
69-
70-
if(addr_fixer==0 && tvaddr!=test_fun_addr){
71-
addr_fixer = test_fun_addr < tvaddr ? (-(tvaddr-test_fun_addr)) : (test_fun_addr-tvaddr);
72-
logkd("+Test-Log+ addr_fixer:%lld\n",addr_fixer);
73-
args->ret = ERR_PTR(-TRACE_FLAG);
74-
return;
75-
}
76-
}
77-
7861
void before_mincore(hook_fargs3_t *args, void *udata){
7962
int trace_flag = (int)syscall_argn(args, 1);
8063
if(trace_flag<TRACE_FLAG || trace_flag>TRACE_FLAG+CLEAR_UPROBE){
@@ -103,15 +86,7 @@ void before_mincore(hook_fargs3_t *args, void *udata){
10386
goto error_out;
10487
}
10588
// logkd("+Test-Log+ fun_name:%s,fun_offset:0x%llx\n",fun_name,fun_offset);
106-
if(addr_fixer==0){
107-
test_fun_addr = module_base+fun_offset;
108-
}
109-
int hret = uprobe_register(inode,fun_offset+addr_fixer,&trace_uc);
110-
111-
if(hret==-TRACE_FLAG){
112-
hret = uprobe_register(inode,fun_offset+addr_fixer,&trace_uc);
113-
}
114-
89+
int hret = uprobe_register(inode,fun_offset,&trace_uc);
11590
if(hret<0){
11691
logke("+Test-Log+ set uprobe error in 0x%llx\n",fun_offset);
11792
goto error_out;
@@ -125,14 +100,12 @@ void before_mincore(hook_fargs3_t *args, void *udata){
125100
if(trace_info==SET_MODULE_BASE){
126101
module_base = (unsigned long)syscall_argn(args, 0);
127102
logkd("+Test-Log+ set module_base:0x%llx\n",module_base);
128-
addr_fixer = 0;
129103
goto success_out;
130104
}
131105

132106
if(trace_info==SET_TARGET_UID){
133107
target_uid = (uid_t)syscall_argn(args, 0);
134108
logkd("+Test-Log+ set target_uid:%d\n",target_uid);
135-
addr_fixer = 0;
136109
goto success_out;
137110
}
138111

@@ -149,19 +122,17 @@ void before_mincore(hook_fargs3_t *args, void *udata){
149122
inode = igrab(path.dentry->d_inode);
150123
path_put(&path);
151124
logkd("+Test-Log+ success set file inode\n");
152-
addr_fixer = 0;
153125
goto success_out;
154126
}
155127

156128
if(trace_info==CLEAR_UPROBE){
157129
rcu_read_unlock();//解锁,不然内核会崩
158130
for (int i = 0; i < hook_num; ++i) {
159-
uprobe_unregister(inode,fun_offsets[i]+addr_fixer,&trace_uc);
131+
uprobe_unregister(inode,fun_offsets[i],&trace_uc);
160132
}
161133
hook_num = 0;
162134
destroy_entire_tree(&fun_info_tree);
163135
logkd("+Test-Log+ success clear all uprobes\n");
164-
addr_fixer = 0;
165136
goto success_out;
166137
}
167138

@@ -186,8 +157,13 @@ static int trace_handler(struct uprobe_consumer *self, struct mpt_regs *regs){
186157
if(uid==target_uid){
187158
fun_offset = regs->pc-module_base;
188159
tfun = search_key_value(&fun_info_tree,fun_offset);
189-
if(likely(tfun)){
160+
if(tfun){
190161
goto target_out;
162+
}else{
163+
tfun = search_key_value(&fun_info_tree,fun_offset- 0x1000);
164+
if(likely(tfun)){
165+
goto target_out;
166+
}
191167
}
192168
}else{
193169
goto no_target_out;
@@ -227,7 +203,6 @@ static long kernel_trace_init(const char *args, const char *event, void *__user
227203
trace_printk = (typeof(trace_printk))kallsyms_lookup_name("__trace_printk");
228204

229205
show_map_vma_addr = (void *)kallsyms_lookup_name("show_map_vma");
230-
build_map_info_addr = (void *)kallsyms_lookup_name("build_map_info");
231206

232207
logkd("+Test-Log+ mtask_pid_nr_ns:%llx\n",mtask_pid_nr_ns);
233208
logkd("+Test-Log+ uprobe_register:%llx\n",uprobe_register);
@@ -246,12 +221,11 @@ static long kernel_trace_init(const char *args, const char *event, void *__user
246221
logkd("+Test-Log+ trace_printk:%llx\n",trace_printk);
247222

248223
logkd("+Test-Log+ show_map_vma_addr:%llx\n",show_map_vma_addr);
249-
logkd("+Test-Log+ build_map_info_addr:%llx\n",build_map_info_addr);
250224

251225
if(!(mtask_pid_nr_ns && uprobe_register && uprobe_unregister
252226
&& kern_path && igrab && path_put && rcu_read_unlock
253227
&& rb_erase && rb_insert_color && rb_first && trace_printk
254-
&& show_map_vma_addr && build_map_info_addr)){
228+
&& show_map_vma_addr)){
255229
logke("+Test-Log+ can not find some fun addr\n");
256230
return -1;
257231
}
@@ -270,11 +244,6 @@ static long kernel_trace_init(const char *args, const char *event, void *__user
270244
return -1;
271245
}
272246

273-
err = hook_wrap2(build_map_info_addr,NULL,after_build_map_info,0);
274-
if(err){
275-
logke("+Test-Log+ hook build_map_info error\n");
276-
return -1;
277-
}
278247

279248
logkd("+Test-Log+ success init\n");
280249
return 0;
@@ -291,10 +260,9 @@ static long kernel_trace_exit(void *__user reserved)
291260
{
292261
inline_unhook_syscall(__NR_mincore, before_mincore, 0);
293262
unhook(show_map_vma_addr);
294-
unhook(build_map_info_addr);
295263
rcu_read_unlock();//解锁,不然内核会崩
296264
for (int i = 0; i < hook_num; ++i) {
297-
uprobe_unregister(inode,fun_offsets[i]+addr_fixer,&trace_uc);
265+
uprobe_unregister(inode,fun_offsets[i],&trace_uc);
298266
}
299267
logkd("+Test-Log+ success clear all uprobes\n");
300268
destroy_entire_tree(&fun_info_tree);

kernel_trace.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,4 @@ struct vm_area_struct {
8181
unsigned long vm_end;
8282
};
8383

84-
struct map_info {
85-
struct map_info *next;
86-
struct mm_struct *mm;
87-
unsigned long vaddr;
88-
};
89-
9084
struct pid_namespace;

pic/偏移计算.JPG

22.1 KB
Loading

0 commit comments

Comments
 (0)