Win32环境下从ntdll.dll调用Nt函数,C++

Posted

技术标签:

【中文标题】Win32环境下从ntdll.dll调用Nt函数,C++【英文标题】:Calling Nt function from ntdll.dll in Win32 environment, C++ 【发布时间】:2012-04-21 23:05:29 【问题描述】:

我想从 ntdll.dll 中调用一些 Nt 函数,我正在这样做。

对于调用: NtTestAlert() ,您需要典型的 ntcall 内核例程,可通过 int 2Eh 访问。 (从这里我得到了 Nt 函数http://undocumented.ntinternals.net/)

代码也未完成,我得到:

*error C2664: '_ntcall' : 无法将参数 1 从 'int' 转换为 'MESS (_stdcall )'

#include <iostream>
#include <windows.h>
#include <Ntsecapi.h>

using namespace std;

typedef int(__stdcall MESS)(unsigned int);

void __ntcall(MESS *msg)

    __asm
    
        int 2Eh;
    


int main(void)

    MESS *me = 0;
    int result = 0;

    HINSTANCE__ *hModule= LoadLibrary(L"C:\\Windows\\System32\\ntdll.dll");

    if(hModule != 0)
    
        me = (MESS*)GetProcAddress(hModule, "NtTestAlert");

        if(me != 0)
        
            unsigned int type = 1;

            result = (__ntcall((*me)(type)));
        
        else
        
            cout << "Error Load function!" << endl;
        

        FreeLibrary(hModule);
    
    else
    
        cout << "Error load Dll!" << endl;
    

    return 0;

【问题讨论】:

【参考方案1】:

您只需调用您检索其指针的函数。 int 2Eh 是一种旧的(自 XP SP2 以来已过时)进行系统调用的方法。当调用(仅通过正常方式)一个 NTDLL 函数时,这就是下面发生的事情。你不必在意这些。

旁注:您似乎混淆了更多概念。 NtTestAlert 不带参数。

NTSYSAPI NTSTATUS NTAPI NtTestAlert();

这样就可以转换为(您的MESS 类型):

typedef NTSTATUS(__stdcall *TFNNtTestAlert)();

一个基于你的例子:

#include <iostream>
#include <windows.h>
#include <tchar.h>
#include <Ntsecapi.h>

using namespace std;

typedef NTSTATUS (__stdcall *TFNNtTestAlert)();
// NTSTATUS is LONG, in case that isn't defined in the above headers

int main(void)

    HMODULE hModule=GetModuleHandle(TEXT("ntdll.dll"));

    if(hModule != 0)
    
        TFNNtTestAlert pfnNtTestAlert = (TFNNtTestAlert)GetProcAddress(hModule, "NtTestAlert");

        if(pfnNtTestAlert != 0)
        
            result = pfnNtTestAlert();
        
        else
        
            cout << "Error Load function!" << endl;
            return 1;
        
    
    else
    
        cout << "Error load Dll!" << endl;
        return 2;
    

    return 0;

系统调用机制:

Windows 中的系统调用机制在某些时候使用int 2Eh(现在是sysenter)来传递用户模式堆栈上的参数、系统调用的索引,然后调用调度程序。然后,这会将线程转换为内核模式,在内核模式中检查来自用户模式堆栈的参数,然后继续处理。这是一个非常粗略的大纲。我建议您阅读 Gary Nebbett 关于该主题的书。

【讨论】:

以上是关于Win32环境下从ntdll.dll调用Nt函数,C++的主要内容,如果未能解决你的问题,请参考以下文章

08系统调用

关于在WIN32调用一些Zw系列的文件操作函数

将用户模式 ​​dll 中的高级函数映射到 NTDLL.dll

基于Wrk和ReactOS源码分析APC机制的记录

本地系统服务例程:Nt和Zw系列函数

读取 ntdll.dll + offset 会导致访问冲突