在用户模式下调用本地(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; 
} 

` 
+0

可能重复[什么是未定义的引用/无法解析的外部符号错误,以及如何解决它?](http://*.com/questions/12573816/what-is-an-undefined-reference-unresolved- external-symbol-error-and-how-do-i-fix) –

+0

我完全像在MSDN文档中那样定义了NtOpenKey,我也尝试过使用ZwOpenKey。这两个功能我都没有运气。我按照这里提到的http://www.osronline.com/article.cfm?article=91 – sreeR

+1

看起来像使用C++连接而不是C连接声明函数。您可能需要将“extern”c“'添加到声明中。它也应该是'__stdcall'而不是'__cdecl',但我猜这是一个64位版本,所以没有什么区别。 –

这是赠品:

[email protected]@[email protected]@@Z 

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

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


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