0

I am trying to call native API(NtOpenKey) in user mode. I am seeing linker problem. I am really confused, what is missing here. How can I achieve doing this? I am attaching my code here. ntdll.lib is added to the project(link)

Error 58 error LNK2001: unresolved external symbol "__declspec(dllimport) long __cdecl NtOpenKey(void * *,unsigned long,struct _OBJECT_ATTRIBUTES *)" (__imp_?NtOpenKey@@YAJPEAPEAXKPEAU_OBJECT_ATTRIBUTES@@@Z) C:\Users\santhi.ragipati\documents\visual studio 2013\Projects\NtRegistry\NtRegistry\NtRegistry.obj NtRegistry

Thanks Santhi `// NtRegistry.cpp : Defines the entry point for the console application. //

#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;
}

`
sreeR
  • 59
  • 6
  • Possible duplicate of [What is an undefined reference/unresolved external symbol error and how do I fix it?](http://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – Ken White Jan 14 '17 at 02:57
  • I defined the NtOpenKey exactly as in MSDN document, I tried with ZwOpenKey too. I didn't have luck with the both functions. I followed as mentioned here http://www.osronline.com/article.cfm?article=91 – sreeR Jan 14 '17 at 03:59
  • 1
    Looks like the function is being declared with C++ linkage instead of C linkage. You probably need to add `extern "c"` to the declaration. It should also be `__stdcall` rather than `__cdecl` but I'm guessing this is a 64-bit build so there's no difference. – Harry Johnston Jan 14 '17 at 04:13
  • for what you using `OBJ_KERNEL_HANDLE` in user mode ? – RbMm Jan 14 '17 at 09:37
  • I wanted to read registry in DLL main, as I cannot use Advapi, I had to use native APIs to read registry in DLL main. – sreeR Jan 16 '17 at 18:34

1 Answers1

1

This was the giveaway:

NtOpenKey@@YAJPEAPEAXKPEAU_OBJECT_ATTRIBUTES@@@Z

That's typical of C++ name mangling; since functions can be overloaded, but the function name used when exporting and importing must be unique, the name is modified to include a description of the argument list.

Adding extern "c" to the declaration will resolve the problem.


Incidentally, you probably don't want to set the OBJ_KERNEL_HANDLE flag, since it asks for a handle that you won't be able to use. I'm guessing Windows will ignore it, and give you a user-mode handle anyway, but better safe than sorry.

Harry Johnston
  • 35,639
  • 6
  • 68
  • 158