0

我正在尝试在用户模式下调用本机 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\文档\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;
}

`
4

1 回答 1

1

这是赠品:

NtOpenKey@@YAJPEAPEAXKPEAU_OBJECT_ATTRIBUTES@@@Z

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

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


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

于 2017-01-16T00:59:28.320 回答