我试图在用户模式下调用本机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;
}
`
答案 0 :(得分:1)
这是赠品:
NtOpenKey@@YAJPEAPEAXKPEAU_OBJECT_ATTRIBUTES@@@Z
这是典型的C ++名称修改;由于函数可以重载,但导出和导入时使用的函数名必须是唯一的,因此修改名称以包含参数列表的描述。
在声明中添加extern "c"
将解决问题。
顺便说一下,您可能不想设置OBJ_KERNEL_HANDLE
标志,因为它要求您无法使用的句柄。我猜Windows会忽略它,无论如何都会给你一个用户模式的句柄,但比抱歉更安全。