2017-01-14 66 views
0

我試圖在用戶模式下調用本機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://stackoverflow.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位版本,所以沒有什麼區別。 –

回答

1

這是贈品:

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

這是典型的C++名稱重整;因爲可以重載函數,但是在導出和導入時使用的函數名稱必須是唯一的,所以修改名稱以包含參數列表的描述。

向聲明添加extern "c"將解決問題。


順便說一句,你可能不希望設置OBJ_KERNEL_HANDLE標誌,因爲它要求一個手柄,你將無法使用。我猜Windows會忽略它,並且無論如何給你一個用戶模式的句柄,但是比抱歉更安全。