zoukankan      html  css  js  c++  java
  • (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

  • 相关阅读:
    手写Linq To Object
    4、IOC--内置Unity容器的使用
    WebApi 基于JWT实现Token签名认证
    软件架构师之路--观察者模式
    EF--封装三层架构IOC
    EF--主外键关系导航属性
    EF--EntityState相互转换
    证明task线程是来源于线程池的,线程重用
    3、IOC--手写Unity容器--链式依赖--第N层依赖注入
    2、IOC--手写Unity容器--第一层依赖注入
  • 原文地址:https://www.cnblogs.com/Lthis/p/4781952.html
Copyright © 2011-2022 走看看