(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\n");
            return;
        }
        //KdPrint(("ZwQueryInformationProcess地址---0x%08X\n", ZwQueryInformationProcess));
    }

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

    if (status != STATUS_INFO_LENGTH_MISMATCH){
        DbgPrint("查詢進程名長度失敗ulLen:%d,status = 0x%08X\n", ulLen, status);
        return;
    }
    pBuffer = ExAllocatePool(PagedPool, ulLen);

    if (pBuffer == NULL){
        DbgPrint("ExAllocatePool Failed\n");
        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] = '\0';
        else
            *(pszProcessPath + astring.Length) = '\0';
        
        RtlFreeAnsiString(&astring);
        
    }
    

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

關於DOS路徑轉NT路徑的,參考這篇文章:http://www.cnblogs.com/Lthis/p/4693118.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM