简体   繁体   English

如何从Windows内核空间中的任意地址获取模块映像名称?

[英]How to get module image name from an arbitrary address in Windows kernel space?

I'm trying to see how I can get a loaded module image name from an arbitrary address from the kernel code. 我正在尝试查看如何从内核代码的任意地址获取已加载的模块映像名称。

In user mode I would do this: 在用户模式下,我可以这样做:

void* pAddr;
VOID* pBase;
WCHAR buff[MAX_PATH] = {0};

//Get address of some function in some module (just to test it)
pAddr = GetProcAddress(GetModuleHandle(L"kernel32.dll"), "GetCurrentProcess");

//Get module base address
RtlPcToFileHeader(pAddr, &pBase);

//Get module image file name
GetModuleFileNameEx(GetCurrentProcess(), (HMODULE)pBase, buff, SIZEOF(buff));

Is there a way to do the same in kernel mode if I have pAddr that can point to some address in kernel or user space? 如果我有pAddr可以指向内核或用户空间中的某个地址,是否可以在内核模式下执行相同的操作?


EDIT: While waiting for the answer I came up with my own code (using undocumented way of traversing PEB): 编辑:在等待答案的同时,我想出了自己的代码(使用未记录的遍历PEB的方式):

#ifdef CALLING_FROM_KERNEL_MODE
//Kernel mode
TEB* pTEB = (TEB*)PsGetCurrentThreadTeb();

#else
//User mode

#if defined(_M_X64)
//64-bit
TEB* pTEB = reinterpret_cast<TEB*>(__readgsqword(reinterpret_cast<DWORD_PTR>(&static_cast<NT_TIB*>(nullptr)->Self)));
#else
//32-bit
TEB* pTEB = reinterpret_cast<TEB*>(__readfsdword(reinterpret_cast<DWORD_PTR>(&static_cast<NT_TIB*>(nullptr)->Self)));
#endif

#endif

PEB* p_PEB = pTEB->ProcessEnvironmentBlock;
PEB_LDR_DATA* pPLD = p_PEB->Ldr;

const WCHAR* pModName = NULL;

LIST_ENTRY* pLE = &pPLD->InMemoryOrderModuleList;
LIST_ENTRY* pLE_Head = pLE;
while(pLE_Head != pLE->Flink)
{
    PLDR_DATA_TABLE_ENTRY pLDTE = CONTAINING_RECORD(pLE, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);

    size_t szcbSizeOfImg = (size_t)pLDTE->Reserved3[1];
    if((size_t)pAddr - (size_t)pLDTE->DllBase < szcbSizeOfImg)
    {
        pModName = pLDTE->FullDllName.Buffer;

        break;
    }

    pLE = pLE->Flink;
}

The problem is that although it works from a user-mode, from a kernel mode PsGetCurrentThreadTeb() seems to return NULL . 问题是,尽管它是从用户模式运行的,但从内核模式PsGetCurrentThreadTeb()似乎返回NULL Does this mean kernel threads do not have a TEB ? 这是否意味着内核线程没有TEB

this can be done by creating list of all loaded modules via ZwQuerySystemInformation with SystemModuleInformation 这可以通过使用ZwQuerySystemInformationSystemModuleInformation创建所有已加载模块的列表来完成

void fgt(PVOID *Callers, ULONG Count)
{
    NTSTATUS status;

    ULONG cb = 0x10000;
    do 
    {
        status = STATUS_INSUFFICIENT_RESOURCES;

        if (PRTL_PROCESS_MODULES prpm = (PRTL_PROCESS_MODULES)ExAllocatePool(PagedPool, cb))
        {
            if (0 <= (status = NtQuerySystemInformation(SystemModuleInformation, prpm, cb, &cb)))
            {
                do 
                {
                    PVOID Caller = *Callers++;

                    if (ULONG NumberOfModules = prpm->NumberOfModules)
                    {
                        PRTL_PROCESS_MODULE_INFORMATION Modules = prpm->Modules;

                        do 
                        {
                            if ((SIZE_T)Caller - (SIZE_T)Modules->ImageBase < Modules->ImageSize)
                            {
                                DbgPrint("%p> %s\n", Caller, Modules->FullPathName);
                                break;
                            }
                        } while (Modules++, --NumberOfModules);
                    }

                } while (--Count);
            }
            ExFreePool(prpm);
        }

    } while (status == STATUS_INFO_LENGTH_MISMATCH);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在内核模块中获取数组的地址,以便能够在用户空间应用程序中使用它? - How to get the address of an array in kernel module so I'll be able to use it within a user-space application? 如何获取内核模块中的真实文件名 - How to get the real file name in kernel module 如何在模块中包含任意内核头文件? - How to include an arbitrary kernel header file in a module? 如何迁移 kernel 模块中的任意进程? - How to migrate an arbitrary process in a kernel module? 如何从内核空间获取sockfd? - How to get sockfd from kernel space? 从当前模块中获取 Linux Kernel 模块名称 - Get Linux Kernel module name from current module 如何在kernel模块(B)中调用kernel模块(A)的函数和变量,然后向用户空间发送通知? - How to call functions and variables from the kernel module (A) in the kernel module (B) and then send notification to the user space? 如何从用户空间C读取内核模块(/ dev)文件 - How to read a kernel module (/dev) file from user space C 如何从内核模块扫描用户空间内存 - How to scan user-space memory from a kernel module 如何将 char *array(属于用户地址空间)传递给 kernel 模块中的 tasklet 或 workqueue? - How to pass a char *array (belonging to the user address space) to a tasklet or workqueue in a kernel module?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM