简体   繁体   English

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

[英]Not able to include ntifs.h in win32 project

I tried to use the function called NTCreateFile . 我试图使用名为NTCreateFile的函数。 When I compiled it gave me an error saying "_NTCreateFile identifier not found". 当我编译它时给了我一个错误,说“找不到_NTCreateFile标识符”。 I inlcuded the header winternl.h . 我包含了标题winternl.h So next I tried to use ZwCreatFile , as per MSDN I included ntifs.h , but I am not able to include that header. 接下来我尝试使用ZwCreatFile ,根据MSDN我包括ntifs.h ,但我无法包含该标头。 It says "not able to open/find the directory". 它说“无法打开/找到目录”。 I am using V@2008. 我正在使用V @ 2008。 What is the problem? 问题是什么? Am I missing anything? 我错过了什么吗?

EDIT1: EDIT1:

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;
}

When it tries to call that it gives the following error in a Message box. 当它试图调用它在消息框中给出以下错误。 ERROR: Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. 错误:运行时检查失败#0 - ESP的值未在函数调用中正确保存。 This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention. 这通常是调用使用一个调用约定声明的函数和使用不同调用约定声明的函数指针的结果。

If you read the MSDN documentation , the first paragraph says: 如果您阅读MSDN文档 ,第一段说:

Note Before using this function, please read Calling Internal APIs . 注意在使用此功能之前,请阅读Calling Internal API

Which says that: (I highlighted the important parts) 其中说:(我突出了重要部分)

The Winternl.h header file exposes prototypes of internal Windows APIs. Winternl.h头文件公开了内部Windows API的原型。 There is no associated import library, so developers must use run-time dynamic linking to call the functions described in this header file. 没有关联的导入库, 因此开发人员必须使用运行时动态链接来调用此头文件中描述的函数

The functions and structures in Winternl.h are internal to the operating system and subject to change from one release of Windows to the next, and possibly even between service packs for each release. Winternl.h中的函数和结构是操作系统的内部结构,可能会从一个Windows版本更改为下一个版本,甚至可能在每个版本的Service Pack之间发生变化。 To maintain the compatibility of your application, you should use the equivalent public functions instead. 要保持应用程序的兼容性,您应该使用等效的公共函数。 Further information is available in the header file, Winternl.h, and the documentation for each function. 有关详细信息,请参见头文件Winternl.h以及每个函数的文档。

If you do use these functions, you can access them through run-time dynamic linking using LoadLibrary and GetProcAddress . 如果使用这些函数,则可以使用LoadLibraryGetProcAddress通过运行时动态链接访问它们 This gives your code an opportunity to respond gracefully if the function has been changed or removed from the operating system. 如果函数已从操作系统更改或删除,则可以使代码有机会正常响应。 Signature changes, however, may not be detectable. 但是,可能无法检测到签名更改。

So you'll have to load the functions you want to use from NtDll.dll before being able to use them. 因此,您必须先从NtDll.dll加载要使用的函数,然后才能使用它们。

Here is a non-tested example code sample: 这是一个未经测试的示例代码示例:

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

ZwCreateFile is part of the Windows Driver Kit, not the Windows SDK. ZwCreateFile是Windows驱动程序工具包的一部分,而不是Windows SDK。 You would need to install the driver kit. 您需要安装驱动程序工具包。 Some macros and types used by NTCreateFile also require WDK headers. NTCreateFile使用的某些宏和类型也需要WDK头。 That is clearly stated in the documentation on MSDN. MSDN上的文档中明确说明了这一点。

As clearly indicated by the error message, you got the calling convention wrong, you dropped NTAPI. 正如错误消息所明确指出的那样,您的调用约定错误,您删除了NTAPI。 It should be: 它应该是:

typedef NTSTATUS (__stdcall * fp_CreatFile)(
  // etc..
);

Properly initializing myAttributes would normally be important. 正确初始化myAttributes通常很重要。 I don't see you do anything that would warrant calling the undocumented native API function. 我没有看到你做任何可以保证调用未记录的本机API函数。 Stick with CreateFile() as long as you can. 只要你愿意,坚持使用CreateFile()。

Several possibilities: 几种可能性:

  • You say the error message is "_NTCreateFile identifier not found". 您说错误消息是“找不到_NTCreateFile标识符”。 The name of the API is NtCreateFile() (note the lowercase 't'). API的名称是NtCreateFile() (注意小写的't')。 It's possible that you're simply using the wrong name. 您可能只是使用了错误的名称。

  • ntifs.h and related link libraries are included in the Windows Driver Kit (WDK), which can be downloaded from here: http://www.microsoft.com/whdc/devtools/wdk/wdkpkg.mspx . ntifs.h和相关链接库包含在Windows驱动程序工具包(WDK)中,可从此处下载: http//www.microsoft.com/whdc/devtools/wdk/wdkpkg.mspx You should be able to use the WDK to do what you want a bit more directly than using dynamic linking. 您应该能够使用WDK比使用动态链接更直接地执行您想要的操作。 but then you generally have to buy into a whole new build system or figure out how to integrate the headers and libraries into your current build. 但是你通常需要购买一个全新的构建系统,或者弄清楚如何将头文件和库集成到你当前的构建中。

  • You can use the dynamic linking technique outlined by ereOn . 您可以使用ereOn概述动态链接技术

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM