在用户模式下调用本地(Nt)API
问题描述:
我试图在用户模式下调用本机API(NtOpenKey)。我看到链接器问题。我很困惑,这里缺少什么。我怎样才能做到这一点?我在这里附上我的代码。 ntdll.lib被添加到项目中(链接)在用户模式下调用本地(Nt)API
错误58错误LNK2001:无法解析的外部符号 “__declspec(dllimport的)长__cdecl NtOpenKey(void *的*,无符号长,结构_OBJECT_ATTRIBUTES *)”(__imp_ NtOpenKey @@ YAJPEAPEAXKPEAU_OBJECT_ATTRIBUTES @@@ Z)C:\用户\ santhi.ragipati \文件\的Visual Studio 2013 \项目\ NT注册表\ NT注册表\ NtRegistry.obj NT注册表
感谢 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;
}
`
答
这是赠品:
[email protected]@[email protected]@@Z
这是典型的C++名称重整;因为可以重载函数,但是在导出和导入时使用的函数名称必须是唯一的,所以修改名称以包含参数列表的描述。
向声明添加extern "c"
将解决问题。
顺便说一句,你可能不希望设置OBJ_KERNEL_HANDLE
标志,因为它要求一个手柄,你将无法使用。我猜Windows会忽略它,并且无论如何给你一个用户模式的句柄,但是比抱歉更安全。
可能重复[什么是未定义的引用/无法解析的外部符号错误,以及如何解决它?](http://*.com/questions/12573816/what-is-an-undefined-reference-unresolved- external-symbol-error-and-how-do-i-fix) –
我完全像在MSDN文档中那样定义了NtOpenKey,我也尝试过使用ZwOpenKey。这两个功能我都没有运气。我按照这里提到的http://www.osronline.com/article.cfm?article=91 – sreeR
看起来像使用C++连接而不是C连接声明函数。您可能需要将“extern”c“'添加到声明中。它也应该是'__stdcall'而不是'__cdecl',但我猜这是一个64位版本,所以没有什么区别。 –