Joh*_*ith 4 windows kernel system-calls sysenter
我正在尝试编写一些程序来直接调用系统调用而不通过 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...
}
Run Code Online (Sandbox Code Playgroud)
当程序尝试执行 sysenter 指令时,程序会因访问冲突而崩溃:
CALL DWORD PTR DS:[EAX+EDX*4] // Access Violation when reading [00000128]
EAX == 0x00000000
EDX == 0x0000004D
Run Code Online (Sandbox Code Playgroud)
我试图在所需的系统调用中使用内核调试器放置一个硬件断点,但执行流程没有到达那里......
我猜这个问题与堆栈顺序/深度有关。
非常感谢!
解决了:
我想问题是我试图在不加载 user32 和 gdi32 dll 的情况下执行 win32k 系统调用。
刚刚添加:
LoadLibraryW(L"user32.dll");
LoadLibraryW(L"gdi32.dll");
Run Code Online (Sandbox Code Playgroud)
问题解决了..
如果有人更清楚为什么不加载这些 dll 会发生这种情况,我会很高兴知道:)
SYSENTER 和 SYSEXIT 操作码的行为与正常的 call/ret 操作码不同。
SYSENTER 和 SYSEXIT peform 都跳转到预定义的地址(一个在内核空间,另一个在用户空间)。
具体来说,SYSEXIT 设置为跳转到 ntdll 中的 KiFastSystemCallRet。通常ntdll中导出的系统程序调用KiFastSystemCall,而不是直接使用SYSENTER。让我们看看 ntdll 中的 KiFastSystemCall 和 KiFastSystemCallRet:
KiFastSystemCall: mov edx, esp
sysenter
KiFastSystemCallRet: retn
Run Code Online (Sandbox Code Playgroud)
您的代码将导致系统过程从内核返回到 RETN 指令,这意味着返回到您在 arg3 中的任何地址。我不知道为什么加载 user32 和 gdi32 会改变任何东西,也许这与 arg3 的值有关。
无论如何,自己调用内核系统过程的最安全方法是使用 KiFastSystemCall。您也可以编写自己的代码,记住从内核模式返回时的第一个操作码将是 RETN,因此您的代码需要在堆栈顶部具有返回地址。
| 归档时间: |
|
| 查看次数: |
2739 次 |
| 最近记录: |