我在linux下劫持了系统调用write ,然后在hached_write函数里面如何获得PID呢?

fdl19881 2012-05-15 10:34:12
我在linux下劫持了系统调用write ,然后在hacked_write函数里面如何获得PID呢?
hached_write应该是运行在进程的上下文中,该如何调用函数获得进程的PID?
劫持的方法是编写内核模块,获得sys_call_table ,
然后保存orig_write = sys_call_table[__NR_write];
sys_call_table[__NR_write] = hacked_write
这样劫持的。
#include <linux/syscalls.h>
然后调用sys_getpid()
但是insmod时出现hookwrite: Unknown symbol sys_getpid

当然我使用
long (*orig_getpid)(void);
orig_getpid = sys_call_table[__NR_getpid];
然后在hacked_write里使用orig_getpid()就能得到pid ,, 这个是可以成功,我已经试验了。

请问还有没有更优雅些的方法获得pid呢?
...全文
195 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
xingqianghaoren 2014-05-22
  • 打赏
  • 举报
回复
楼主,你好,我现在也在做系统调用劫持,但是我劫持write操作出现了死机现象,劫持mkdir是可以的,请问你的write是怎么成功劫持的呢? 以下是我的代码,能否帮我分析一下哪里不对? 谢谢了! #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> #include <asm/unistd.h> MODULE_DESCRIPTION("My kernel module"); MODULE_AUTHOR("root (root@10h212.xjtu.edu.cn)"); MODULE_LICENSE("$LICENSE$"); unsigned int sys_table; //int (*orig_write)(const char *name, int mod); asmlinkage long (*orig_write)(unsigned int fd, const char __user * buf, size_t count) = NULL; struct idt { unsigned short limit; unsigned int base; }__attribute__((packed)); struct idt_gate { unsigned short off1; unsigned short sel; unsigned char nome,flags; unsigned short off2; }__attribute__((packed)); unsigned int get_idt_base() { unsigned int base; struct idt idt_table; __asm__ __volatile__("sidt %0":"=m"(idt_table)); base=idt_table.base; return base; } unsigned int get_sys_call_entry(unsigned int idt_base) { struct idt_gate sys_call; memcpy(&sys_call,idt_base+8*0x80,sizeof(struct idt_gate)); unsigned int sys_call_entry=(sys_call.off2 << 16) | sys_call.off1; return sys_call_entry; } unsigned int get_sys_call_table_entry(unsigned int sys_call_entry,char * exp,char exp_len,unsigned int cope) { char * begin=sys_call_entry; char * end=sys_call_entry+cope; for(;begin<end;begin++) { if(begin[0]==exp[0]&&begin[1]==exp[1]&&begin[2]==exp[2]) return *((unsigned int *)(begin+3)); } return 0; } void setback_cr0(unsigned int val) { asm volatile ("movl %%eax, %%cr0" : : "a"(val) ); } unsigned int clear_cr0_save() { unsigned int cr0 = 0; unsigned int ret; __asm__ __volatile__ ("movl %%cr0, %%eax":"=a"(cr0)); ret = cr0; cr0 &= 0xfffeffff; asm volatile ("movl %%eax, %%cr0":: "a"(cr0)); return ret; } asmlinkage long my_write(unsigned int fd, char *buf,unsigned int count) { if(1) { printk(KERN_INFO"write fd = %d\n", fd); printk(KERN_INFO"buf = %s\n", buf); unsigned long iii = 0; while(1) { iii++; if(iii > 2394967000) break; } } (*orig_write)(fd, buf, count); void ** table=(void **)sys_table; // table[__NR_write]=orig_write; // r = write(fd, buf, count); // table[__NR_write]=my_write; } // new mkdir asmlinkage long my_mkdir(const char *name,int mod) { printk(KERN_INFO"mkdir call is intercepted\n"); } asmlinkage long my_open(const char *name,int mod) { printk(KERN_INFO"open call is intercepted\n"); } static int syscall_info_init_module(void) { unsigned int idt_base=get_idt_base(); printk( KERN_INFO"the idt base address is %x\n",idt_base ); unsigned int sys_call_entry=get_sys_call_entry(idt_base); printk( KERN_INFO"the sys call entry is %x\n",sys_call_entry ); // unsigned int sys_table=get_sys_call_table_entry(sys_call_entry,"\xff\x14\x85",3,100); sys_table=get_sys_call_table_entry(sys_call_entry,"\xff\x14\x85",3,100); void ** table=(void **)sys_table; orig_write=table[__NR_write]; //wp clear unsigned int cr0=clear_cr0_save(); // intercept mkdir call table[__NR_write]=my_write; // table[__NR_open]=my_mkoep; //set wp bit setback_cr0(cr0); printk( KERN_INFO"the sys table is %x\n",sys_table ); return 0; } static void syscall_info_exit_module(void) { void ** table=(void **)sys_table; printk( KERN_INFO "Module syscall_info exit\n" ); table[__NR_write]=orig_write; } module_init(syscall_info_init_module); module_exit(syscall_info_exit_module);
fdl19881 2012-05-15
  • 打赏
  • 举报
回复
2.6的
[Quote=引用 1 楼 的回复:]

内核版本?
[/Quote]
deep_pro 2012-05-15
  • 打赏
  • 举报
回复
内核版本?
fdl19881 2012-05-15
  • 打赏
  • 举报
回复
好吧,,了解了。。 对内核不熟悉,只能在网上看+试验。
谢谢
[Quote=引用 3 楼 的回复:]
就算是2.6的内核 ,2.6.12 和2.6.39 的task_struct 变化相当大
你没有办法写一个通用的c代码,从current的task_struct里直接取出pid
所以为了通用,你还是掉被劫持内核的api
Unknown symbol 是因为sys_getpid不是一个导出符号,不能随意在内核其他模块调用。你不是已经能从sys_call_table里掉系统原有的sys_get……
[/Quote]
deep_pro 2012-05-15
  • 打赏
  • 举报
回复

就算是2.6的内核 ,2.6.12 和2.6.39 的task_struct 变化相当大
你没有办法写一个通用的c代码,从current的task_struct里直接取出pid
所以为了通用,你还是掉被劫持内核的api
Unknown symbol 是因为sys_getpid不是一个导出符号,不能随意在内核其他模块调用。你不是已经能从sys_call_table里掉系统原有的sys_getpid吗,这样的方法才是能通用2.6的

4,437

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 内核源代码研究区
社区管理员
  • 内核源代码研究区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧