在用户模式下调用本机(Nt)API

时间:2017-01-14 02:55:29

标签: winapi ntdll

我试图在用户模式下调用本机API(NtOpenKey)。我看到了链接器问题。我真的很困惑,这里缺少什么。我怎样才能做到这一点?我在这里附上我的代码。 ntdll.lib被添加到项目(链接)

错误58错误LNK2001:未解析的外部符号" __ declspec(dllimport)long __cdecl NtOpenKey(void * *,unsigned long,struct _OBJECT_ATTRIBUTES *)" (__imp_?NtOpenKey @@ YAJPEAPEAXKPEAU_OBJECT_ATTRIBUTES @@@ Z)C:\ Users \ santhi.ragipati \ documents \ visual studio 2013 \ Projects \ NtRegistry \ NtRegistry \ NtRegistry.obj NtRegistry

由于 Santhi     `// NtRegistry.cpp:定义控制台应用程序的入口点。     //

#include <tchar.h>
#include <Windows.h>
#include <Winternl.h>
#include <ntstatus.h>

NTSYSAPI NTSTATUS NTAPI NtOpenKey(
    _Out_ PHANDLE            KeyHandle,
   _In_  ACCESS_MASK        DesiredAccess,
    _In_  POBJECT_ATTRIBUTES ObjectAttributes
    );


 int _tmain(int argc, _TCHAR* argv[])
{

    HANDLE              handleRegKey = NULL;
    for (int n = 0; n < 1; n++)
    {
        NTSTATUS           status = NULL;
        UNICODE_STRING     RegistryKeyName;
        OBJECT_ATTRIBUTES  ObjectAttributes;

        RtlInitUnicodeString(&RegistryKeyName, L"\\Registry\\Machine\\Software\\MyCompany\\MyApp");
        InitializeObjectAttributes(&ObjectAttributes,
            &RegistryKeyName,
            OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
            NULL,    // handle
            NULL);
        status = NtOpenKey(&handleRegKey, (ACCESS_MASK)KEY_READ, &ObjectAttributes);


        if (NT_SUCCESS(status) == FALSE)
        {
            break;
        }
    } // Get the Frame location from the registry key.

    // All done with the registry.
    if (NULL != handleRegKey)
    {
        NtClose(handleRegKey);
    }

    return 0;
}

`

1 个答案:

答案 0 :(得分:1)

这是赠品:

NtOpenKey@@YAJPEAPEAXKPEAU_OBJECT_ATTRIBUTES@@@Z

这是典型的C ++名称修改;由于函数可以重载,但导出和导入时使用的函数名必须是唯一的,因此修改名称以包含参数列表的描述。

在声明中添加extern "c"将解决问题。

顺便说一下,您可能不想设置OBJ_KERNEL_HANDLE标志,因为它要求您无法使用的句柄。我猜Windows会忽略它,无论如何都会给你一个用户模式的句柄,但比抱歉更安全。