2017-01-14 2 views
0

사용자 모드에서 기본 API (NtOpenKey)를 호출하려고합니다. 나는 링커 문제를보고있다. 나는 정말로 혼란 스럽다, 여기에서 놓치고있는 것이있다. 이 일을 어떻게 성취 할 수 있습니까? 나는 여기에 나의 코드를 붙이고있다. ntdll.lib 프로젝트 (링크)사용자 모드에서 native (Nt) API 호출

오류 58 오류 LNK2001에 추가 : 확인되지 않은 외부 기호 "__declspec (같이 DllImport) 긴 __cdecl NtOpenKey (무효 * *, 부호 없음 long, 구조체 _OBJECT_ATTRIBUTES *)"(__imp_ NtOpenKey @@ YAJPEAPEAXKPEAU_OBJECT_ATTRIBUTES @@@ Z) C : \ 사용자 \ santhi.ragipati 비주얼 스튜디오 2013 \ 문서 프로젝트 \ \ 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

[정의되지 않은 참조/확인되지 않은 외부 기호 오류 란 무엇이며 어떻게 수정합니까?] (http://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved- 외부 기호 오류 및 어떻게해야합니까?) –

+0

MSDN 문서에서와 마찬가지로 NtOpenKey를 정확하게 정의 했으므로 ZwOpenKey도 시도했습니다. 나는 두 가지 기능 모두에 운이 없었습니다. 나는 여기에 언급 된대로 따라 갔다. http://www.osronline.com/article.cfm?article=91 – sreeR

+1

함수가 C 링키지 대신 C++ 링키지로 선언 된 것처럼 보인다. 아마도 선언문에'extern "c"'를 추가해야 할 것이다. 그것은 또한'__cdecl'보다는'__stdcall'이어야합니다. 그러나 이것은 차이점이 없도록 64 비트 빌드라고 추측합니다. –

답변

1

이 는 공짜였다

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

엉망으로 C++ 이름의 전형이다; 함수는 오버로드 될 수 있기 때문에 익스포트 W 임포트 할 때 사용되는 함수 이름은 고유해야하며, 인수 목록의 설명을 포함하도록 이름이 수정됩니다.

선언에 extern "c"을 추가하면 문제가 해결됩니다. 당신이 사용할 수 없습니다 핸들을 요구하기 때문에


덧붙여, 당신은 아마의 OBJ_KERNEL_HANDLE 플래그를 설정하지 않습니다. 나는 Windows가 그것을 무시하고 어쨌든 사용자 모드 핸들을 제공 할 것이라고 추측하지만 미안한 것보다 안전합니다.

관련 문제