如何找到Windows内核函数的地址?

在这种情况下,我试图找到CreateThread。

可以通过调试器完成吗? Olly /免疫力?

评论

如果您的意思是使用ollydbg 2.01 alt + e->右键单击kernel32.dll中的CreateThread,请右键单击所有模块中的显示名称,然后开始键入CreateThread并双击结果行

#1 楼

可以使用NtQuerySystemInformationLoadLibraryExGetProcAddress的组合以编程方式完成。

下面的代码可能无法完美运行,因为我没有Windows框来构建它进行测试。但是,它应该向正确的方向移动。

#include "stdafx.h"

#include <string.h>
#include <windows.h>

enum { SystemModuleInformation = 11 };

typedef struct _RTL_PROCESS_MODULE_INFORMATION {
    ULONG Section;
    PVOID MappedBase;
    PVOID ImageBase;
    ULONG ImageSize;
    ULONG Flags;
    USHORT LoadOrderIndex;
    USHORT InitOrderIndex;
    USHORT LoadCount;
    USHORT OffsetToFileName;
    CHAR FullPathName[256];
} RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION;

typedef struct _RTL_PROCESS_MODULES {
    ULONG NumberOfModules;
    RTL_PROCESS_MODULE_INFORMATION Modules[1];
} RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES;

typedef NTSTATUS (*NtQuerySystemInformationFunc)(
    _In_      DWORD SystemInformationClass,
    _Inout_   PVOID                    SystemInformation,
    _In_      ULONG                    SystemInformationLength,
    _Out_opt_ PULONG                   ReturnLength
);

ULONG64 GetKernelFunctionAddress(LPCSTR Name) {
    NtQuerySystemInformationFunc NtQuerySystemInformation = NULL;
    HMODULE hKernel = NULL;
    HMODULE hNtdll = NULL;
    ULONG64 KernelBase = NULL;
    ULONG64 KernelFunctionAddress = NULL;
    RTL_PROCESS_MODULES ModuleInfo = { 0 };

    // Get the address of NtQuerySystemInformation
    hNtdll = GetModuleHandle("ntdll");
    NtQuerySystemInformation = (NtQuerySystemInformationFunc)GetProcAddress(hNtdll, "NtQuerySystemInformation");

    // Get the base address of the kernel
    NtQuerySystemInformation(SystemModuleInformation, &ModuleInfo, sizeof(ModuleInfo), NULL);
    KernelBase = (ULONG64)ModuleInfo.Modules[0].ImageBase;

    // Load the kernel
    hKernel = LoadLibraryEx(strrchr(ModuleInfo.Modules[0].FullPathName, '\') + 1, 0, LOAD_LIBRARY_AS_IMAGE_RESOURCE);

    // Look up the function in the kernel
    KernelFunctionAddress = (ULONG64)GetProcAddress(hKernel, Name);

    // Adjust the address based on the kernel load address
    KernelFunctionAddress -= (ULONG64)hKernel;
    KernelFunctionAddress += KernelBase;

    return KernelFunctionAddress;
}


评论


聪明的方法!即使我给出了不同的答案,我还是对你投了赞成票;)

–詹森·格夫纳(Jason Geffner)
16年5月12日在13:23

#2 楼

在WinDbg中,您可以使用x命令。例如,

kd> x nt!NtCreateThread
830e4fda          nt!NtCreateThread (<no parameter info>)


当我在上面查找NtCreateThread函数的地址时,WinDbg会告诉我说NtCreateThread是在地址0x830e4fda上。

(您可能想使用LiveKd代替,因为它比连接远程内核调试器更容易。)

评论


击败我!不要忘了,如果您试图捕获本机API调用(这对于钩子或内省会更好),则您想使用x ntdll!ZwCreateThread!

– grepNstepN
16年8月12日在22:00

#3 楼

在Ollydbg中,您可以选择反汇编窗口并点击CTRL + g。将显示一个对话框,只需在其中输入CreateThread。搜索是区分大小写的。

编辑

这不适用于Windows内核功能,但它适用于被调试程序导入的DLL中的任何功能。由于您正在搜索CreateThread地址,因此我认为这就是您从问题中得到的意思。

评论


这不适用于Windows内核功能。 OllyDbg无权访问内核的地址空间。

–詹森·格夫纳(Jason Geffner)
16年5月12日在13:24

@JasonGeffner你是对的!因为我只看到OP在寻找通用DLL函数的地址,所以我混用了术语。答案已被编辑。

– ubnix
16年5月12日在14:38