32位程序获取32/64位进程文件地址通用方法

博客 分享
0 296
优雅殿下
优雅殿下 2022-02-01 10:54:47
悬赏:0 积分 收藏

32位程序获取32/64位进程文件地址通用方法

32位程序获取32/64位进程文件地址通用方法一般来说,限于32位程序GetModuleFileNameEx对于64位程序来说是不管用的,我们如果需要在32位程序获得64位进程的运行目录可能需要用到wow64或者是QueryFullProcessImageName。但是前者虽然通用,但是实现起来过于复杂,还需要用到汇编,后者API不是通用的。

32位程序获取32/64位进程文件地址通用方法

引子

一般来说,限于32位程序GetModuleFileNameEx对于64位程序来说是不管用的,我们如果需要在32位程序获得64位进程的运行目录可能需要用到wow64或者是QueryFullProcessImageName

但是

前者虽然通用,但是实现起来过于复杂,还需要用到汇编,后者

Minimum supported clientWindows Vista [desktop apps only]
Minimum supported serverWindows Server 2008 [desktop apps only]

上为ms docs给出的限制条件,显然无法支持到诸如XP之类的系统

显然这个API不是通用的,那么如果我们需要一个通用且方便的方法怎么办呢?

这时候就可以祭出我们的GetProcessImageFileNameA

Minimum supported clientWindows XP [desktop apps only]
Minimum supported serverWindows Server 2003 [desktop apps only]
Target PlatformWindows
Headerpsapi.h
LibraryKernel32.lib on Windows 7 and Windows Server 2008 R2; Psapi.lib (if PSAPI_VERSION=1) on Windows 7 and Windows Server 2008 R2; Psapi.lib on Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP
DLLKernel32.dll on Windows 7 and Windows Server 2008 R2; Psapi.dll (if PSAPI_VERSION=1) on Windows 7 and Windows Server 2008 R2; Psapi.dll on Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP

支持还是蛮全的

但是注意到这个API返回的是Native Path(\\**\****),而不是我们熟悉的Dos Path(X:\**\***)

所以我们还需要QueryDosDeviceA进行转换

值得一提的是,根据这个API所属DLL的变更,我们有理由认为QueryFullProcessImageName实际上就是这个API的封装

代码实现

/*    Created on: 2022-02-01    Created by: Icys*/#include <iostream>#include <cstring>#include <windows.h>#include <psapi.h>#include <cstring>//将Nt文件路径转为Dos文件路径std::string NTFilePath2DosFilePath(std::string name){    char szDriveStr[MAX_PATH] = {0};    char szDeviceStr[MAX_PATH] = {0};    char szDrive[3] = {0};    int cchDevName = 0;    if (GetLogicalDriveStringsA(sizeof(szDriveStr), szDriveStr) == 0)    {        return "";    }    for (int i = 0; szDriveStr[i]; i += 4)    {        memcpy(szDrive, szDriveStr + i, 2);        if (!QueryDosDeviceA(szDrive, szDeviceStr, sizeof(szDeviceStr)))        {            return "";        }        cchDevName = lstrlenA(szDeviceStr);        if (strnicmp(szDeviceStr, name.c_str(), cchDevName) == 0) //比较前缀        {            name.replace(0, cchDevName, szDrive);            return name;        }    }    return "";}std::string GetProcessPath(int PID){    auto hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, PID);    if (!hProcess)        return "";    char *FileNativePath = new char[MAX_PATH + 1];    if (!GetProcessImageFileNameA(hProcess, FileNativePath, MAX_PATH + 1))        return "";    std::string FilePath = NTFilePath2DosFilePath(FileNativePath);    delete[] FileNativePath;    return FilePath;}int main(){    std::cout << GetProcessPath(15572) << std::endl;    return 0;}

后记

本文由Icys编纂并发表,仅发表于CNBLOG,如果在其他地方所见,均为未经允许的盗窃。

posted @ 2022-02-01 10:10 Icys 阅读(12) 评论(0) 编辑 收藏 举报
回帖
    优雅殿下

    优雅殿下 (王者 段位)

    2018 积分 (2)粉丝 (47)源码

    小小码农,大大世界

     

    温馨提示

    亦奇源码

    最新会员