免费教程_免费网赚教程_破解版软件-寂涯网络学习基地

当前位置: 主页 > 系统综合 > linux > 使用kprobes进行内核修改(4)

使用kprobes进行内核修改(4)

时间:2012-02-20 21:01来源:未知 整理:寂涯网络 点击:


long do_sys_open(int dfd, const char _user *filename, int flags, int mode) { char *tmp = getname(fllename); int fd = PTR_ERR(tmp); if(!IS_ERR(tmp)) {
fd = get_unused_fd_flags(flags); if(fd>=0) {
struct file *f= do_fllp_open(dfd, tmp, flags, mode, 0); if(IS_ERR(f)) {
put_unused_fd(fd); fd = PTR_ERR(f);
} else {
/* 通知 fsnotify_open() */ fsnotify_open(f->f_path.dentry);
/* 将 fd 与/dev/nul 关联 */ fd_install(fd, f);
trace_do_sys_open(tmp, flags, mode);
putname(tmp);
return fd;
 使用fd_install()将新的文件描述符与对应的文件(files_struct *)相关联。
void fd_install(unsigned int fd, struct file *file) { struct flles_struct *files = current->files; struct fdtable *fdt; spin_lock(&files->file_lock); fdt = files_fdtable(files);
BUG_ON(fdt->fd[fd] !=NULL); rcu_assign_pointer(fdt->fd[fd], file); spin_unlock(&flles->flle_lock);
图 10. Fd_install(M^^o
因为^0的^^已经是个很普通的话题了,因此本文将用一些其他的kpr0be例子。首先 我们来讨论匕6〖口『(^6的实现。我们将看到更多的kprobes限制。
4. Kretprobes 实现
Kretprobe的实现很有趣,因为其很多创新性并且是很优秀的工程代码。摘自 kprobes. txt: 当调用作818161_^^1口『(^6 0时,1^?:(^368在函数的入口点建立了一"i^ kprobeo当该函
数被调用时并且该kprobe被触发了,kprobes保存一份返回地址并且将返回地址替换成我 们的地址。新地址所在的位置是任意的一段代码,例如nop指令。 /usr/src/linux/kerne/kprobes. c 中的 register_kretprobe()f(^$nT^
int _kprobes register_kretprobe(struct kretprobe *rp) { int ret — 0;
struct kretprobe_instance *inst; inti; ~
void *addr;
...<codc^*...
rp->kp .pre_handler = pre_handler_kretprobe; rp->kp.post_handler = NULL; rp->kp. fault_handler = NULL; rp->kp.break_handler = NULL;
...<codc^5*...
图10.register_kretprobe()代码。
当 kretprobe 被触发时,pre_handler_kretprobe ()将调用 pre_handler_kretprobe (),
该函数将保存原始的返回地址并插入新的返回地址: 
void _kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs)
unsigned long *sara = stack_addr(regs); ri->ret_addr = (kprobe_opcode_t *) *sara;
*sara = (unsigned long) &kretprobe_trampoline;
图 11. ArchXf probea 0代码。
代码的最后一行是将返回地址设置为新的地址,叫做trampoline。Trampoline是用汇编代码定义的,在x86上的定义如下^:
asm volatile (
'global kretprobetrampolineW’ nkretprobe_trampoline: W’
’’ subl $16, %spW’
’’ pushl 0/fsW’
" pushl 0/esW’
" pushl %isW’
’’ pushl %axW’
" pushl %ebpW’
" pushl %diW’
" pushl %siW’
’’ pushl %dxW’
’’ pushl %cxW’
’’ pushl 0々bxW’
’’ movl %sp, %axW’
’’ call tampoline_handler^i??
’’ movl 56^>esp), %dxW’
?? movl %dx, 52%esp)h"
’’ movl %eax, 56(%esp^n"
’’ popl 0々bxW’
’’ popl %cxW’
’’ popl %dxW’
°/csiW?
o/edM"
°/ebpW
%axW'
$24,%e;
#endif
图 12. X86 上 trampoline 的定义。 当寄存器状态已经保存到栈上后上述代码将调用trampoline_handler(),该函数将执行 与其关联的处理函数。下面是trampoline_handler()
static _used _kprobes void *trampoline_handler(struct pt_regs *regs) { struct kretprobe_instance *ri = NULL; struct hlist_head *head, empty_rp; struct hlist_node *node, *tmp; unsigned long flags, orig_ret_address = 0;
unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline; DsfIT_HLIST_HEAD(&empty_rp); ~
kretprobe_hash_lock(current, &head, &flags);
#ifdef CONFIG_X86_64
regs->cs = KERNEL CS;
#else
regs->cs = KERNEL CS | get_kemel_rpl(); regs->gs = 0;
#endif
regs->ip = trampoline_address; regs->orig_ax = ~0UL;
hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { if (ri->task != current) continue; if (ri->rp && ri->rp->handler) {
—get_cpu_var(current_kprobe) = &ri->rp->kp; get_kprobe_ctlbUc()->kprobe_status = KPROBE_HIT_ACTWE; ri->rp->handler(ri, regs);
—get_cpu_var(current_kprobe) = NULL;
} "" " orig_ret_address = (unsigned long)ri->ret_addr; recycle_rp_mst(ri, &empty_rp); if (orig_ret_address != trampoline_address) break;

本页地址 http://www.jybase.net/linux/20120220779.html

百度搜索更多

谷歌搜索更多

顶一下
(0)
0%
踩一下
(1)
100%
------分隔线----------------------------

评价:
昵称: 验证码:点击我更换图片
推荐内容
赞助商
赞助商


关于本站免责声明视频更新google百度地图视频地图RRS订阅

如有什么问题请在本站留言,或发邮件到 hxt167#foxmail.com