【问题标题】:Windows 7 x86 perform a direct system call using sysenterWindows 7 x86 使用 sysenter 执行直接系统调用
【发布时间】:2013-11-14 05:38:53
【问题描述】:

我正在尝试编写一些程序来直接调用系统调用而不通过ntdll.dll

我的代码(Visual Studio 语法...):

#include <windows.h>

int main()
{
   _asm{
        push arg1
        push arg2
        push arg3
        mov eax,syscall_id
        mov edx,esp
        _emit 0xf
        _emit 0x34 //sysenter opcodes...
       }

当程序尝试执行 sysenter 指令时,程序会因访问冲突而崩溃:

CALL DWORD PTR DS:[EAX+EDX*4] // Access Violation when reading [00000128]

EAX == 0x00000000
EDX == 0x0000004D

我尝试使用内核调试器在所需的系统调用中放置一个硬件断点,但执行流程没有到达那里...

我猜这个问题与堆栈顺序/深度有关。

非常感谢!

已解决:

我猜问题是我试图在不加载 user32 和 gdi32 dll 的情况下执行 win32k 系统调用。

刚刚添加:

LoadLibraryW(L"user32.dll");
LoadLibraryW(L"gdi32.dll");

问题解决了..

如果有人知道为什么在不加载这些 dll 的情况下会发生这种情况,我会很高兴知道 :)

【问题讨论】:

  • 可能是您调用了在 GDI32.DLL 中实现的系统调用,因为它确实添加了一些内核级函数。
  • 你好约翰。上面的汇编代码是否在汇编程序下编译?我似乎遇到了 A2008 语法错误。谢谢

标签: windows kernel system-calls sysenter


【解决方案1】:

SYSENTER 和 SYSEXIT 操作码的行为与正常的 call/ret 操作码不同。

SYSENTER 和 SYSEXIT 都会跳转到预定义的地址(一个在内核空间,另一个在用户空间)。

具体来说,SYSEXIT 设置为跳转到 ntdll 中的 KiFastSystemCallRet。通常ntdll中导出的系统过程调用KiFastSystemCall,而不是直接使用SYSENTER。再来看看ntdll中的KiFastSystemCall和KiFastSystemCallRet:

KiFastSystemCall:     mov edx, esp
                      sysenter
KiFastSystemCallRet:  retn

您的代码将导致系统过程从内核返回到 RETN 指令,这意味着返回到您在 arg3 中的任何地址。我不知道为什么加载 user32 和 gdi32 会改变什么,也许它与 arg3 的值有关。

无论如何,自行调用内核系统过程的最安全方法是使用 KiFastSystemCall。您也可以编写自己的代码,记住从内核模式返回时的第一个操作码是 RETN,因此您的代码需要在堆栈顶部具有返回地址。

【讨论】:

    猜你喜欢
    • 2013-08-23
    • 1970-01-01
    • 2012-02-26
    • 2011-01-09
    • 2022-07-09
    • 2022-01-08
    • 2012-02-16
    • 2012-12-30
    • 2019-07-20
    相关资源
    最近更新 更多