【问题标题】:calling native(Nt) API in user mode在用户模式下调用 native(Nt) API
【发布时间】:2017-01-14 02:55:28
【问题描述】:

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

错误 58 错误 LNK2001: 无法解析的外部符号 "__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

谢谢 桑蒂 `// 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;
}

`

【问题讨论】:

  • 我完全按照 MSDN 文档中的方式定义了 NtOpenKey,我也尝试使用 ZwOpenKey。我对这两个功能都没有运气。我按照这里提到的osronline.com/article.cfm?article=91
  • 看起来函数是用 C++ 链接而不是 C 链接声明的。您可能需要在声明中添加extern "c"。它也应该是 __stdcall 而不是 __cdecl 但我猜这是一个 64 位版本,所以没有区别。
  • 你在用户模式下使用OBJ_KERNEL_HANDLE 做什么?
  • 我想在 DLL main 中读取注册表,因为我不能使用 Advapi,我必须使用原生 API 来读取 DLL main 中的注册表。

标签: winapi ntdll


【解决方案1】:

这是赠品:

NtOpenKey@@YAJPEAPEAXKPEAU_OBJECT_ATTRIBUTES@@@Z

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

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


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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-14
    • 2011-03-05
    • 2011-07-27
    • 2011-06-13
    • 1970-01-01
    • 1970-01-01
    • 2019-07-14
    相关资源
    最近更新 更多