zoukankan      html  css  js  c++  java
  • 利用挂钩KeUserModeCallBack实现防止Dll注入

    http://bbs.pediy.com/thread-145687.htm

    http://www.pediy.com/kssd/pediy11/104918.html

    KeUserModeCallback的基础知识
    我们都知道一个普通的系统调用,它的过程大概是这样的(以OpenProcess为例):
    kernel32!OpenProcess -> ntdll!ZwOpenProcess -> ntdll!KiFastSystemCall -> sysenter -> nt!KiFastCallEntry -> nt!NtOpenProcess -> nt!KiFastCallEntry(返回后)-> nt!KiServiceExit -> sysexit -> ntdll!KiFastSystemCallRet -> kernel32!OpenProcess(返回后)
    这是一个ring3->ring0->ring3的过程。
    而KeUserModeCallback的过程是这样的
    nt!KeUserModeCallback -> nt!KiCallUserMode -> nt!KiServiceExit -> ntdll!KiUserCallbackDispatcher -> 回调函数 -> int2B -> nt!KiCallbackReturn -> nt!KeUserModeCallback(调用后)
    这是一个ring0->ring3->ring0的过程,在堆栈准备完毕后,借用KiServiceExit的力量回到了ring3,它的着陆点是KiUserCallbackDispatcher,然后KiUserCallbackDispatcher从PEB中取出KernelCallbackTable的基址,再以ApiIndex作为索引在这个表中查找对应的回调函数并调用,调用完之后再int2B触发nt!KiCallbackReturn再次进入内核,修正堆栈后跳回KeUserModeCallback,完成调用。
    大致的流程是这样的,只要搞清楚传入的参数是如何使用并如何影响到最后的执行结果,就知道怎么去调用了。
    需要注意的地方是:
    (1) ring3的指令只能访问ring3的内存地址,所以如果需要访问数据,必须放在ring3可以访问到的内存中。所以在准备参数的过程中,通常是使用ZwAllocateVirtualMemory来申请ring3内存,其它方法如使用已有的内存,或放在栈中(_ClientLoadLibrary的方法)等都是可以的,只是访问数据时小有差别罢了。 
    (2)KeUserModeCallback的调用需要用户态栈的参与,因此内核线程无法调用KeUserModeCallback,必须在某个ring3线程的上下文中才可以。

    爱程序 不爱bug 爱生活 不爱黑眼圈 我和你们一样 我和你们不一样 我不是凡客 我要做geek
  • 相关阅读:
    java9
    java8
    java7
    java6
    java5
    java4
    java-list-分组
    Termux中安装gcc-7/gfortran-7实操过程,安装成功可以编译Fortran,c/c++
    安卓手机牛逼软件Termux中安装Archlinux,安装Jdk
    c++语言的组合类的使用,用组合类的方法计算两点间距离。
  • 原文地址:https://www.cnblogs.com/yifi/p/6480704.html
Copyright © 2011-2022 走看看