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

Winapi 在用户模式下调用本机(Nt)API,winapi,ntdll,Winapi,Ntdll,我试图在用户模式下调用本机API(NtOpenKey)。我看到链接器出现问题。我真的很困惑,这里缺少什么。我怎样才能做到这一点?我在这里附上我的代码。ntdll.lib已添加到项目(链接) 错误58错误LNK2001:未解析的外部符号“\uuuu declspec(dllimport)long”\uuu cdecl NtOpenKey(void**,unsigned long,struct\u OBJECT\u ATTRIBUTES*)”(\uuuuuu imp\uuu?NtOpenKey@@y

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

错误58错误LNK2001:未解析的外部符号“\uuuu declspec(dllimport)long”\uuu cdecl NtOpenKey(void**,unsigned long,struct\u OBJECT\u ATTRIBUTES*)”(\uuuuuu imp\uuu?NtOpenKey@@yajpeapeakpeau\u OBJECT\u ATTRIBUTES@@@Z)C:\Users\santhi.ragipati\documents\visual studio 2013\Projects\NtRegistry\NtRegistry\NtRegistry\NtRegistry.obj NtRegistry

谢谢 桑提 `//NtRegistry.cpp:定义控制台应用程序的入口点。 //

#包括
#包括
#包括
#包括
NTSYSAPI NTSTATUS NTAPI NtOpenKey(
_外型钥匙手柄,
_进入所需的访问掩码,
_In_uPobject_属性ObjectAttributes
);
int _tmain(int argc,_TCHAR*argv[]
{
HANDLE handleRegKey=NULL;
对于(int n=0;n<1;n++)
{
NTSTATUS status=NULL;
UNICODE_字符串注册表键名;
对象属性对象属性;
RTLinitUnicode字符串(&RegistryKeyName,L“\\Registry\\Machine\\Software\\MyCompany\\MyApp”);
InitializeObjectAttributes(&ObjectAttributes),
&RegistryKeyName,
OBJ_不区分大小写| OBJ_内核|句柄,
NULL,//句柄
无效);
状态=NtOpenKey(&handleRegKey,(访问掩码)KEY\U READ,&ObjectAttributes);
如果(NT_成功(状态)=错误)
{
打破
}
}//从注册表项获取帧位置。
//所有这些都在注册表中完成。
if(NULL!=handleRegKey)
{
NtClose(handleRegKey);
}
返回0;
}
`
这是赠品:

NtOpenKey@@YAJPEAPEAXKPEAU_OBJECT_ATTRIBUTES@@@Z

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

向声明中添加
extern“c”
将解决此问题



顺便说一句,您可能不想设置
OBJ\u KERNEL\u HANDLE
标志,因为它要求一个您无法使用的句柄。我猜Windows会忽略它,并为您提供一个用户模式句柄,但总比“抱歉”好。

可能与我在MSDN文档中定义的NtOpenKey完全相同,我也尝试过使用ZwOpenKey。这两个函数我都不太走运。我在这里提到的,看起来函数用C++链接声明,而不是C链接。您可能需要在声明中添加
extern“c”
。它也应该是
\uu stdcall
而不是
\uu cdecl
,但我猜这是一个64位的构建,所以没有区别。对于在用户模式下使用
OBJ_KERNEL_HANDLE
的内容,我想在DLL main中读取注册表,因为我不能使用Advapi,我必须使用本机API在DLL main中读取注册表。
NtOpenKey@@YAJPEAPEAXKPEAU_OBJECT_ATTRIBUTES@@@Z