C/C++ 获取进程完整目录

简介: 输出特定进程所在位置的完整路径,并输出路径。

输出特定进程所在位置的完整路径,并输出路径。

方法1 定位某个进程(比如 QQMusic.exe)所在的全路径,下面是代码:

string GetProcessInfo(HANDLE hProcess,char* processName)
{
    PROCESSENTRY32* pinfo = new PROCESSENTRY32; //进程信息 (pinfo->dwSize = sizeof(PROCESSENTRY32);)
    MODULEENTRY32* minfo = new MODULEENTRY32; //模块信息 (minfo->dwSize = sizeof(MODULEENTRY32);)
    char shortpath[MAX_PATH];                //保存路径变量

    int flag = Process32First(hProcess,pinfo);    // 从第一个进程开始
    while(flag){

        // 如果是 QQMusic.exe 这个进程
        if(strcmp(pinfo->szExeFile, processName) == 0){

            // 创建进程快照
            HANDLE hModule = CreateToolhelp32Snapshot(
                TH32CS_SNAPMODULE,        //(DWORD) 快照返回的对象,TH32CS_SNAPMODULE 是指 "特定进程的使用模块的列表"
                pinfo->th32ProcessID    //(DWORD) 要获取快照进程的PID,当前进程/系统列表 快照时设为0
                ); 

            // 把第一个模块信息给 minfo
            Module32First(
                hModule,  //(HANDLE) CreateToolhelp32Snapshot 的返回句柄
                minfo     // (LPMODULEENTRY32)  接收模块信息
                );    

            // 把文件路径给 shortpath
            GetShortPathName(
                minfo->szExePath,    //  文件路径(但最好不要用这个,因为这个碰到中文会出现乱码)
                shortpath,        // 用来接收 minfo->szExePath 兼容中文的值
                256            // 缓冲区大小
                ); 

            return shortpath;
        }
        
        // 下一个进程
        flag = Process32Next(hProcess, pinfo);
    }

    return NULL;
}

int main()
{
    HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); // 创建进程快照
    PROCESSENTRY32 process = {sizeof(PROCESSENTRY32)};    // 用来接收 hProcessSnap 的信息
    
    // 遍历进程快照
    while (Process32Next(hProcessSnap,&process)){
        // 找到 QQMusic.exe 进程
        string processName = process.szExeFile; // char* 转 string
        if(processName == "QQMusic.exe"){
            string s_exePath = GetProcessInfo(hProcessSnap,"QQMusic.exe"); // 进程的全路径 
            cout << s_exePath << endl;
            break;
        }
    }
    
    return 0;
}

image.png

方法2 第一种方法有些 bug,下面说下另一种方法

另一种方法:

    HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); // 创建进程快照
    PROCESSENTRY32 process = {sizeof(PROCESSENTRY32)};    // 用来接收 hProcessSnap 的信息
    
    // 遍历进程快照
    while (Process32Next(hProcessSnap,&process)){
        // 获取进程名
        string processName = process.szExeFile;
        cout << processName << endl;
        
        // 获取全路径
        char chpath[MAX_PATH];
        HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process.th32ProcessID);
        GetModuleFileNameEx(hProcess,NULL,chpath,sizeof(chpath));
        cout << chpath << endl;
        
        cout << "-------------------" << endl;
    }

但是注意,这种方法不能获取路径在 system32 的进程路径,其余正常:

image.png

方法3(推荐) 目前没有发现 Bug,无法读取应用程序拒绝访问的进程路径,其他没有问题。

// dos 文件路径转 windows 文件路径
BOOL DosPathToNtPath(LPTSTR pszDosPath, LPTSTR pszNtPath)
{
    TCHAR            szDriveStr[500];
    TCHAR            szDrive[3];
    TCHAR            szDevName[100];
    INT                cchDevName;
    INT                i;
    
    //检查参数
    if(!pszDosPath || !pszNtPath )
        return FALSE;
 
    //获取本地磁盘字符串
    if(GetLogicalDriveStrings(sizeof(szDriveStr), szDriveStr))
    {
        for(i = 0; szDriveStr[i]; i += 4)
        {
            if(!lstrcmpi(&(szDriveStr[i]), _T("A:\\")) || !lstrcmpi(&(szDriveStr[i]), _T("B:\\"))){continue;}

            szDrive[0] = szDriveStr[i];
            szDrive[1] = szDriveStr[i + 1];
            szDrive[2] = '\0';
            // 查询 Dos 设备名
            if(!QueryDosDevice(szDrive, szDevName, 100)){return FALSE;}
                
            // 命中
            cchDevName = lstrlen(szDevName);
            if(_tcsnicmp(pszDosPath, szDevName, cchDevName) == 0){
                // 复制驱动器
                lstrcpy(pszNtPath, szDrive);

                // 复制路径
                lstrcat(pszNtPath, pszDosPath + cchDevName);
 
                return TRUE;
            }            
        }
    }
 
    lstrcpy(pszNtPath, pszDosPath);
    
    return FALSE;
}

// 获取进程全路径
BOOL GetProcessFullPath(DWORD dwPID,string &fullPath){
    TCHAR        szImagePath[MAX_PATH];
    TCHAR        pszFullPath[MAX_PATH];
    HANDLE        hProcess;
    
    // 初始化失败
    if(!pszFullPath){return FALSE;}
    pszFullPath[0] = '\0';

    // 获取进程句柄失败
    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, dwPID);
    if(!hProcess){return FALSE;}
        
    // 获取进程完整路径失败
    if(!GetProcessImageFileName(
        hProcess,                    // 进程句柄
        szImagePath,                // 接收进程所属文件全路径的指针
        MAX_PATH                    // 缓冲区大小
    )){
        CloseHandle(hProcess);
        return FALSE;
    }
 
    // 路径转换失败
    if(!DosPathToNtPath(szImagePath, pszFullPath)){
        CloseHandle(hProcess);
        return FALSE;
    }
 
    CloseHandle(hProcess);
 
    // 导出文件全路径
    fullPath = pszFullPath;

    return TRUE;
}

调用例子:

tring str_filePath;
GetProcessFullPath(进程ID,str_filePath);
相关文章
|
2月前
|
监控 安全 数据安全/隐私保护
C++ 邮件槽ShellCode跨进程传输
在计算机安全领域,进程间通信(IPC)一直是一个备受关注的话题。在本文中,我们将探讨如何使用Windows邮件槽(Mailslot)实现ShellCode的跨进程传输。邮件槽提供了一种简单而有效的单向通信机制,使得任何进程都能够成为邮件槽服务器,并通过`UDP`通信向其他进程发送数据。
|
2月前
|
存储 监控 安全
C++ 共享内存ShellCode跨进程传输
在计算机安全领域,ShellCode是一段用于利用系统漏洞或执行特定任务的机器码。为了增加攻击的难度,研究人员经常探索新的传递`ShellCode`的方式。本文介绍了一种使用共享内存的方法,通过该方法,两个本地进程可以相互传递ShellCode,从而实现一种巧妙的本地传输手段。如果你问我为何在本地了还得这样传,那我只能说在某些时候我们可能会将`ShellCode`打散,而作为客户端也不需要时时刻刻在本地存放`ShellCode`代码,这能保证客户端的安全性。
|
2月前
|
算法 编译器 API
C++ MiniZip实现目录压缩与解压
Zlib是一个开源的数据压缩库,提供了一种通用的数据压缩和解压缩算法。它最初由`Jean-Loup Gailly`和`Mark Adler`开发,旨在成为一个高效、轻量级的压缩库,其被广泛应用于许多领域,包括网络通信、文件压缩、数据库系统等。其压缩算法是基于`DEFLATE`算法,这是一种无损数据压缩算法,通常能够提供相当高的压缩比。在Zlib项目中的`contrib`目录下有一个`minizip`子项目,minizip实际上不是`zlib`库的一部分,而是一个独立的开源库,用于处理ZIP压缩文件格式。它提供了对ZIP文件的创建和解压的简单接口。minizip在很多情况下与`zlib`一起使用
C++ MiniZip实现目录压缩与解压
|
2月前
|
存储 安全 C++
C++ LibCurl实现Web隐藏目录扫描
LibCurl是一个开源的免费的多协议数据传输开源库,该框架具备跨平台性,开源免费,并提供了包括HTTP、FTP、SMTP、POP3等协议的功能,使用libcurl可以方便地进行网络数据传输操作,如发送HTTP请求、下载文件、发送电子邮件等。它被广泛应用于各种网络应用开发中,特别是涉及到数据传输的场景。本章将是`《C++ LibCurl 库的使用方法》`的扩展篇,在前一篇文章中我们简单实现了LibCurl对特定页面的访问功能,本文将继续扩展该功能,并以此实现Web隐藏目录扫描功能。
C++ LibCurl实现Web隐藏目录扫描
|
4月前
|
Linux
Linux中查看端口被哪个进程占用、进程调用的配置文件、目录等
Linux中查看端口被哪个进程占用、进程调用的配置文件、目录等
|
5月前
|
程序员 C++ Windows
Windows C++ 启动子进程并绑定子进程,主进程结束关闭后自动结束关闭子进程
在Windows平台上主进程启动子进程,并使主进程结束关闭后自动结束关闭子进程
68 0
|
6月前
|
存储 算法 C++
4.5 C++ Boost 文件目录操作库
在Boost库出现之前,C++对于文件和目录的操作需要调用底层接口操作,非常不友好,而且不同平台的接口差异也很大,难以移植。但是,Boost库中的filesystem库可以解决这个问题,它是一个可移植的文件系统操作库,可以跨平台的操作目录、文件等,并提供了友好的操作方法,并且在不失性能的情况下提供了良好的抽象和封装。Boost 库是一个由C/C++语言的开发者创建并更新维护的开源类库,其提供了许多功能强大的程序库和工具,用于开发高质量、可移植、高效的C应用程序。Boost库可以作为标准C库的后备,通常被称为准标准库,是C标准化进程的重要开发引擎之一。使用Boost库可以加速C应用程序的开发过程
|
6月前
|
消息中间件 Unix Linux
进程与线程 -- C/C++(二)
进程: 进程有独立的地址空间 Linux为每个进程创建task_struct 每个进程都参与内核调度,互不影响
60 0
|
6月前
|
Linux Shell 调度
进程与线程 -- C/C++(一)
程序概念: 存放在磁盘上的指令和数据的有序集合(文件) 静态的
43 0
|
10月前
|
Shell Linux Android开发
Android C++系列:Linux进程(三)
如果一个进程已经终止,但是它的父进程尚未调用wait或waitpid对它进行清理,这时 的进程状态称为僵尸(Zombie)进程。任何进程在刚终止时都是僵尸进程,正常情况下,僵 尸进程都立刻被父进程清理了,为了观察到僵尸进程
77 0

热门文章

最新文章

相关产品

  • 云迁移中心
  • 相关实验场景

    更多