(ring0)Windows内核根据PID获取进程全路径

最近在写ARK,发现Windows在内核并没有直接提供这样的内核API,没办法,自己手动实现吧。网上搜了一堆,写了个函数

头文件中定义

typedef NTSTATUS(*ZWQUERYINFORMATIONPROCESS) (
__in HANDLE ProcessHandle,
__in PROCESSINFOCLASS ProcessInformationClass,
__out_bcount(ProcessInformationLength) PVOID ProcessInformation,
__in ULONG ProcessInformationLength,
__out_opt PULONG ReturnLength
);

extern ZWQUERYINFORMATIONPROCESS ZwQueryInformationProcess;

CPP中

// 要用到的核心API定义
ZWQUERYINFORMATIONPROCESS ZwQueryInformationProcess;
// 
// 功能:获取当前进程路径,但只实现了获取DOS路径名称,需要手动将路径转为NT路径
// Code By Lthis
VOID getProcessPath(
    IN  HANDLE hProcess,
    OUT PCHAR pszProcessPath
)
{
    NTSTATUS status;
    ANSI_STRING astring;
    PVOID pBuffer = NULL;
    ULONG ulLen = 0;

    // 获取 ZwQueryInformationProcess
    if (NULL == ZwQueryInformationProcess) {
        UNICODE_STRING routineName;
        RtlInitUnicodeString(&routineName, L"ZwQueryInformationProcess");

        ZwQueryInformationProcess =
            (ZWQUERYINFORMATIONPROCESS)MmGetSystemRoutineAddress(&routineName);
        
        if (NULL == ZwQueryInformationProcess) {
            DbgPrint("Cannot resolve ZwQueryInformationProcess
");
            return;
        }
        //KdPrint(("ZwQueryInformationProcess地址---0x%08X
", ZwQueryInformationProcess));
    }

    // 开始查询
    status = ZwQueryInformationProcess(
        hProcess,
        ProcessImageFileName,
        NULL,
        0,
        &ulLen
        );

    if (status != STATUS_INFO_LENGTH_MISMATCH){
        DbgPrint("查询进程名长度失败ulLen:%d,status = 0x%08X
", ulLen, status);
        return;
    }
    pBuffer = ExAllocatePool(PagedPool, ulLen);

    if (pBuffer == NULL){
        DbgPrint("ExAllocatePool Failed
");
        return;
    }
    status = ZwQueryInformationProcess(
        hProcess,
        ProcessImageFileName,
        pBuffer,
        ulLen,
        &ulLen
        );


    if (NT_SUCCESS(status)){
        RtlUnicodeStringToAnsiString(&astring, (PUNICODE_STRING)pBuffer, TRUE);
        strncpy(pszProcessPath, astring.Buffer, astring.Length);
        
        if(astring.Length >= MAX_PATH)
            pszProcessPath[MAX_PATH-1] = '';
        else
            *(pszProcessPath + astring.Length) = '';
        
        RtlFreeAnsiString(&astring);
        
    }
    

    if (pBuffer){
        ExFreePool(pBuffer);
    }
}

关于DOS路径转NT路径的,参考这篇文章:http://www.cnblogs.com/Lthis/p/4693118.html

原文地址:https://www.cnblogs.com/Lthis/p/4781952.html