免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: Godbach
打印 上一主题 下一主题

Linux下实现劫持系统调用的总结 [复制链接]

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
51 [报告]
发表于 2010-01-19 13:13 |只看该作者
原帖由 ubuntuer 于 2010-1-19 13:06 发表

刚看了w.z.t  hi.baidu上的最新的一篇文章...深有感触!!!看的心里酸酸的


是啊,你们都很强啊。

论坛徽章:
0
52 [报告]
发表于 2010-01-19 13:20 |只看该作者
原帖由 Godbach 于 2010-1-19 13:13 发表


是啊,你们都很强啊。

唉  他懂那么多东西 写过那么多东西  老大居然说他不懂网络
还好我没选择阿里巴巴

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
53 [报告]
发表于 2010-01-19 13:26 |只看该作者
原帖由 ubuntuer 于 2010-1-19 13:20 发表

唉  他懂那么多东西 写过那么多东西  老大居然说他不懂网络
还好我没选择阿里巴巴


呵呵,那么说估计是有前后语境的。

工作的时候,不时的会遇上一些不顺心的事,不管你在MS, Intel或者是小公司。看你怎么看待问题了。。

论坛徽章:
5
摩羯座
日期:2014-07-22 09:03:552015元宵节徽章
日期:2015-03-06 15:50:392015亚冠之大阪钢巴
日期:2015-06-12 16:01:352015年中国系统架构师大会
日期:2015-06-29 16:11:2815-16赛季CBA联赛之四川
日期:2018-12-17 14:10:21
54 [报告]
发表于 2010-01-19 14:49 |只看该作者
原帖由 ubuntuer 于 2010-1-19 13:20 发表

唉  他懂那么多东西 写过那么多东西  老大居然说他不懂网络
还好我没选择阿里巴巴


很正常,毕竟术业有专攻,更何况W.Z.T兄刚毕业不久

论坛徽章:
0
55 [报告]
发表于 2010-01-21 01:42 |只看该作者
个人认为武断地清除和设置 cr0 的权限位也不合理,更合理的是,保存原来的 cr0,干完坏事之后再恢复回去。

多嘴说点题内话,用 kprobe 这类``官方''提供的方法来插入自己的逻辑很不美,受制于人。要做到真正意义的劫持, fork/vfork/clone/execve 这一系列的系统调用,唯一的方法是:RTFC,搞懂了 entry.S,解决方案就呼之欲出。

首先要明确,fork/vfork/clone/execve 这一系列系统调用比较特殊,系统调用表里的对应项不像其它系统调用那样是 C 函数地址,而是汇编代码的地址 (stub_XXXX),在这些 stub_XXXX 前头一段注释这么说:

/*
 * Certain special system calls that need to save a complete full stack frame.
 */


对 execve,看内核怎么玩的:

ENTRY(stub_execve)
    CFI_STARTPROC
    popq %r11
    CFI_ADJUST_CFA_OFFSET -8
    CFI_REGISTER rip, r11
    SAVE_REST
    FIXUP_TOP_OF_STACK %r11
    movq %rsp, %rcx
    call sys_execve
    RESTORE_TOP_OF_STACK %r11
    movq %rax,RAX(%rsp)
    RESTORE_REST
    jmp int_ret_from_sys_call
    CFI_ENDPROC
END(stub_execve)


如果像劫持其它系统调用那样把系统调用表对应 __NR_execve 的那项改成了自己实现的 C 函数地址,并且在该 C 函数内妄图调用原始的系统调用例程 (oops, 是 stub_execve),必死无疑,因为寄存器全乱了 (所以所谓的栈要调平衡一说并不准确,而是内核汇编代码将要放入栈的寄存器值被破坏了)。要么:
1. 整明白内核那段汇编是干什么的,要保存/恢复那些寄存器,自己照样做,多挂几次机,就想明白了 有些宏在 calling.h 中定义。要么:
2. 要是实在不想和底层机制玩命,有一个投机取巧的方法,看到那句可爱的:``call sys_execve'' 了没有,找到它 (它的 opcode 是 0xe9 .. .. .. .. ),把后面的操作数,也就是一个 C 函数, sys_execve 地址的偏移,换成自己实现的一个 asmlinkage 的 C 函数的偏移值即可,这样在自己的 C 函数里就可以在调用 sys_execve 之前之后为所欲为,因为 sys_execve 是 asmlinkage 的,编译器替我们保证参数正确。

要劫持 fork/vfork/clone 也只需要那么一点点技巧,看内核代码:
.macro PTREGSCALL label,func,arg
        .globl \label
\label:
        leaq        \func(%rip),%rax
        leaq    -ARGOFFSET+8(%rsp),\arg /* 8 for return address */
        jmp        ptregscall_common
END(\label)
        .endm
...
PTREGSCALL stub_clone, sys_clone, %r8
...
ENTRY(ptregscall_common)
        popq %r11
        CFI_ADJUST_CFA_OFFSET -8
        CFI_REGISTER rip, r11
        SAVE_REST
        movq %r11, %r15
        CFI_REGISTER rip, r15
        FIXUP_TOP_OF_STACK %r11
        call *%rax
        RESTORE_TOP_OF_STACK %r11
        movq %r15, %r11
        CFI_REGISTER rip, r11
        RESTORE_REST
        pushq %r11
        CFI_ADJUST_CFA_OFFSET 8
        CFI_REL_OFFSET rip, 0
        ret
        CFI_ENDPROC
END(ptregscall_common)

看看,又是 jmp 又是 call 的,应该清楚要做什么了。

注意:2.6.29开始,PTREGSCALL 宏的定义变了,于是 hack 的方式要跟着变。

[ 本帖最后由 vupiggy 于 2010-1-20 18:50 编辑 ]

论坛徽章:
0
56 [报告]
发表于 2010-01-21 09:09 |只看该作者
原帖由 vupiggy 于 2010-1-21 01:42 发表
个人认为武断地清除和设置 cr0 的权限位也不合理,更合理的是,保存原来的 cr0,干完坏事之后再恢复回去。

多嘴说点题内话,用 kprobe 这类``官方''提供的方法来插入自己的逻辑很不美,受制于人。要做到真正 ...


直接改写CR0确实不保险, 我们的做法是直接改sys_call_table地址的属性。


  1. int set_page_rwe(long unsigned int _addr)
  2. {
  3.         struct page *pg;
  4.         pgprot_t prot;

  5.         pg = virt_to_page(_addr);
  6.         prot.pgprot = VM_READ | VM_WRITE | VM_EXEC;

  7.         return change_page_attr(pg, 1, prot);
  8. }
复制代码


另外兄弟提到的直接改offset的方法, 我在《高级linux kernel inline hook技术》中提出过了。这个才是比较保险的hook, 呵呵

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
57 [报告]
发表于 2010-01-21 10:13 |只看该作者
个人认为武断地清除和设置 cr0 的权限位也不合理,更合理的是,保存原来的 cr0,干完坏事之后再恢复回去。

如果你保存了CR0的之后,在某些情况下又修改了CR0,再恢复的时候不就出现问题了

论坛徽章:
0
58 [报告]
发表于 2010-07-08 11:07 |只看该作者
好东东。。。 顶一个。

论坛徽章:
0
59 [报告]
发表于 2010-07-08 17:00 |只看该作者
实现原理分析

论坛徽章:
0
60 [报告]
发表于 2010-07-09 13:03 |只看该作者
顶一下,谢谢了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP