无法在 win32 项目中包含 ntifs.h

kid*_*ddo 5 c winapi kernel

我尝试使用名为NTCreateFile. 当我编译时,它给了我一个错误提示“_NTCreateFile identifier not found”。我包括标题winternl.h。所以接下来我尝试使用ZwCreatFile,根据我包含的 MSDN ntifs.h,但我无法包含该标题。它说“无法打开/找到目录”。我正在使用 V@2008。问题是什么?我错过了什么吗?

编辑1:

typedef NTSTATUS (*fp_CreatFile)(
    OUT PHANDLE FileHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN PLARGE_INTEGER AllocationSize OPTIONAL,
    IN ULONG FileAttributes,
    IN ULONG ShareAccess,
    IN ULONG CreateDisposition,
    IN ULONG CreateOptions,
    IN PVOID EaBuffer OPTIONAL,
    IN ULONG EaLength
    );
OBJECT_ATTRIBUTES myAttributes;

int _tmain(int argc, _TCHAR* argv[])
{
    fp_CreatFile myFunction;
    HMODULE module = LoadLibrary(L"ntdll.dll");
    if(NULL != module)
    {
        myFunction = (fp_CreatFile)GetProcAddress(module,"NtCreateFile");
    }

    UNICODE_STRING string;
    IO_STATUS_BLOCK fileStatus;
    string.Length = 56;
    string.Buffer = L"C:\\user\\kiddo\\Desktop\\7zFM.exe";
    string.MaximumLength = 56;

    HANDLE fileHandle;
    myAttributes.ObjectName = &string;
    myAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
    long mystatus = myFunction(&fileHandle,FILE_GENERIC_READ,&myAttributes ,&fileStatus,NULL,FILE_ATTRIBUTE_NORMAL,FILE_SHARE_READ,
        NULL,NULL,NULL,NULL);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当它尝试调用它时,它会在消息框中给出以下错误。 错误: 运行时检查失败 #0 - ESP 的值未在函数调用中正确保存。这通常是调用一个用一个调用约定声明的函数和一个用不同调用约定声明的函数指针的结果。

ere*_*eOn 6

如果您阅读MSDN 文档,第一段说:

注意 使用该函数前,请阅读调用内部API

其中说:(我强调了重要部分)

Winternl.h 头文件公开了内部 Windows API 的原型。没有关联的导入库, 因此开发人员必须使用运行时动态链接来调用 此头文件中描述的函数

Winternl.h 中的函数和结构是操作系统内部的,并且会随着 Windows 的一个版本到下一个版本发生变化,甚至可能在每个版本的 Service Pack 之间发生变化。为了保持应用程序的兼容性,您应该改用等效的公共函数。头文件 Winternl.h 和每个函数的文档中提供了更多信息。

如果确实使用了这些函数,则可以使用LoadLibraryGetProcAddress通过运行时动态链接访问它们。如果函数已被更改或从操作系统中删除,这使您的代码有机会优雅地响应。但是,签名更改可能无法检测到。

因此,您必须先加载要使用的函数,NtDll.dll然后才能使用它们。

这是一个未经测试的示例代码示例:

typedef NTSTATUS (__stdcall *NtCreateFile)(
    OUT PHANDLE FileHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN PLARGE_INTEGER AllocationSize OPTIONAL,
    IN ULONG FileAttributes,
    IN ULONG ShareAccess,
    IN ULONG CreateDisposition,
    IN ULONG CreateOptions,
    IN PVOID EaBuffer OPTIONAL,
    IN ULONG EaLength
    );

NtCreateFile _NtCreateFile = (NtCreateFile)GetProcAddress(GetModuleHandle("ntdll.dll"),"NtCreateFile");

// You can now use the function
_NtCreateFile(/* params */);

// Don't forget the release the resources
Run Code Online (Sandbox Code Playgroud)