在 Windows 中获取另一个进程命令行

2024-03-10

我正在尝试获取另一个进程的命令行参数(在 WinXP 32 位上)。

我执行以下操作:

hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_TERMINATE, FALSE, ProcList.proc_id_as_numbers[i]);

BytesNeeded = sizeof(PROCESS_BASIC_INFORMATION);
ZwQueryInformationProcess(hProcess, ProcessBasicInformation, UserPool, sizeof(PROCESS_BASIC_INFORMATION), &BytesNeeded);
pbi = (PPROCESS_BASIC_INFORMATION)UserPool;

BytesNeeded = sizeof(PEB);
res = ZwReadVirtualMemory(hProcess, pbi->PebBaseAddress, UserPool, sizeof(PEB), &BytesNeeded);
/* zero value returned */
peb = (PPEB)UserPool;

BytesNeeded = sizeof(RTL_USER_PROCESS_PARAMETERS);
res = ZwReadVirtualMemory(hProcess, peb->ProcessParameters, UserPool, sizeof(RTL_USER_PROCESS_PARAMETERS), &BytesNeeded);
ProcParam = (PRTL_USER_PROCESS_PARAMETERS)UserPool;

第一次通话后,pbi.UniqueProcessID是正确的。

但是,打电话之后ZwReadVirtualMemory(),我得到了我的进程的命令行,而不是请求的命令行。

我也用过ReadProcessMemory() & NtQueryInformationProcess(),但得到相同的结果。

有人可以帮忙吗?

On 这个论坛主题 http://forum.sysinternals.com/get-commandline-of-running-processes_topic6510_page1.html,据说这段代码可以工作。不幸的是,我无法在该论坛上发帖询问他们。


看起来 ZwReadVirtualMemory 只被调用一次。这还不够。必须为每个级别的指针间接调用它。换句话说,当您检索指针时,它指向其他进程的地址空间。您无法直接读取它。您必须再次调用 ZwReadVirtualMemory。对于这些数据结构,ZwReadVirtualMemory 必须被调用 3 次:一次读取 PEB(这就是上面代码的作用),一次读取 RTL_USER_PROCESS_PARAMETERS,一次读取 UNICODE_STRING 的缓冲区。 以下代码片段对我有用(为了清楚起见,省略了错误处理,我使用记录的 ReadProcessMemory API 而不是 ZwReadVirtualMemory):

        LONG status = NtQueryInformationProcess(hProcess,
                                                0,
                                                pinfo,
                                                sizeof(PVOID)*6,
                                                NULL);
        PPEB ppeb = (PPEB)((PVOID*)pinfo)[1];
        PPEB ppebCopy = (PPEB)malloc(sizeof(PEB));
        BOOL result = ReadProcessMemory(hProcess,
                                        ppeb,
                                        ppebCopy,
                                        sizeof(PEB),
                                        NULL);

        PRTL_USER_PROCESS_PARAMETERS pRtlProcParam = ppebCopy->ProcessParameters;
        PRTL_USER_PROCESS_PARAMETERS pRtlProcParamCopy =
            (PRTL_USER_PROCESS_PARAMETERS)malloc(sizeof(RTL_USER_PROCESS_PARAMETERS));
        result = ReadProcessMemory(hProcess,
                                   pRtlProcParam,
                                   pRtlProcParamCopy,
                                   sizeof(RTL_USER_PROCESS_PARAMETERS),
                                   NULL);
        PWSTR wBuffer = pRtlProcParamCopy->CommandLine.Buffer;
        USHORT len =  pRtlProcParamCopy->CommandLine.Length;
        PWSTR wBufferCopy = (PWSTR)malloc(len);
        result = ReadProcessMemory(hProcess,
                                   wBuffer,
                                   wBufferCopy, // command line goes here
                                   len,
                                   NULL);

为什么我们看到自己进程的命令行?这是因为流程以类似的方式布置。命令行和 PEB 相关结构可能具有相同的地址。因此,如果您错过了 ReadProcessMemory,您最终会完全使用本地进程的命令行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Windows 中获取另一个进程命令行 的相关文章

随机推荐