如何清除进程命令行?

Posted

技术标签:

【中文标题】如何清除进程命令行?【英文标题】:How to clear a process command line? 【发布时间】:2011-04-28 21:53:36 【问题描述】:

我想从内部清除我的进程的命令行。例如,在任务管理器/进程资源管理器中查看我的进程时,命令行条目将为空。

如果可能,我想在当前运行的进程中执行此操作,而不是重新启动该进程。

【问题讨论】:

你想制造一些恶意软件?可惜已经有了一些似是而非的答案。 不,但这是一个多进程解决方案,我希望尽可能安全。一个使用通过命令行传递的密钥启动另一个,我只是尝试在启动例程处理后将其删除。 @Alf:修改进程的命令行有什么恶意软件?这是一个程序可以做的事情,因为它是它自己的内存。例如阅读blogs.msdn.com/b/oldnewthing/archive/2009/02/23/9440784.aspx。 @Joey:恶意软件所做的一切都是程序可以做的事情。无论您对此进行多少研究,都不会发现任何恶意软件可以做程序无法做的事情。然而,隐藏有关进程的信息是恶意软件的特征之一。 而且我一直认为恶意软件的特征是对其他进程或系统进行恶意操作。所以现在禁止触摸自己的记忆——很好。 【参考方案1】:

您可以尝试调用GetCommandLine API 函数,然后将第一个字节设置为 0。即:

LPTSTR cmdline = GetCommandLine();
*cmdline = '\0';

老实说,我不知道这是否可行或可能的后果是什么,但它可能值得一试。

【讨论】:

【参考方案2】:

我想你必须修改你的进程的PEB 的RTL_USER_PROCESS_PARAMETERS 部分(例如参见http://en.wikipedia.org/wiki/Process_Environment_Block 和http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Process/PEB.html)。您可以尝试使用NtQueryInformationProcess 获取PEB。然后你可以修改ProcessParameters.CommandLine。我希望它会起作用。

已更新:我验证了我的建议。有用。下面的测试程序证明了这一点:

#include <Windows.h>
#include <Winternl.h> // for PROCESS_BASIC_INFORMATION and ProcessBasicInformation
#include <stdio.h>
#include <tchar.h>

typedef NTSTATUS (NTAPI *PFN_NT_QUERY_INFORMATION_PROCESS) (
    IN HANDLE ProcessHandle,
    IN PROCESSINFOCLASS ProcessInformationClass,
    OUT PVOID ProcessInformation,
    IN ULONG ProcessInformationLength,
    OUT PULONG ReturnLength OPTIONAL);

int main()

    HANDLE hProcess = OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
                                   FALSE, GetCurrentProcessId());
    PROCESS_BASIC_INFORMATION pbi;
    ULONG ReturnLength;
    PFN_NT_QUERY_INFORMATION_PROCESS pfnNtQueryInformationProcess =
        (PFN_NT_QUERY_INFORMATION_PROCESS) GetProcAddress (
            GetModuleHandle(TEXT("ntdll.dll")), "NtQueryInformationProcess");
    NTSTATUS status = pfnNtQueryInformationProcess (
        hProcess, ProcessBasicInformation,
        (PVOID)&pbi, sizeof(pbi), &ReturnLength);
    // remove full information about my command line
    pbi.PebBaseAddress->ProcessParameters->CommandLine.Length = 0;

    getchar(); // wait till we can verify the results
    return 0;

如果我们用一些参数启动程序,我们会看到

而不是之前看到的以下

【讨论】:

@Joe:我更新了我的答案,让你更容易使用NtQueryInformationProcess Oleg,终于可以试试这个了(Win7-64),当以管理员身份运行时,它似乎可以完全工作,但是当以标准用户权限运行时,TaskManager 仍然可以显示命令行。有趣的是,Process Explorer 在这两种权限场景中都不会显示传递的命令行。 @Joe:我现在可以重现您在以下情况下描述的问题:1)程序被编译为 32 位应用程序 2)程序在 64 位操作系统上启动(Windows 7 x64) 作为非管理员 3) 一使用 64 位 TaskManager。如果使用“C:\Windows\SysWOW64\taskmgr.exe”或 Process Explorer,或者使用 X64 编译程序代码中没有任何更改,则可以在我的测试程序中删除程序参数。您可以选择使用 64 位 exe 吗?例如,您可以使用IsWow64Process 测试您是否在 64 位上运行并重新启动另一个 exe。 Oleg:不幸的是,不能选择使用 64 位 exe(为 VB6 应用程序重新编写它。我知道...)。关于如何强制它在 64 位 Windows 上使用 32 位可执行文件的任何想法? @Joe:应用程序可以通过许多其他方式进行通信。子 UI 应用程序可以获取对象的句柄作为参数,例如管道的句柄或内存映射对象的句柄。子 UI-app 读取信息后,可以删除对象。因此,没有人会将密钥视为明文。您可以按照示例 msdn.microsoft.com/en-us/library/ms682499(VS.85).aspx 进行操作,但由于 GUI 中的子进程而不是控制台应用程序中的子进程,请进行一些更改。如果你在实现这个场景时遇到问题,我可以用 C 语言向你发布一个小例子。【参考方案3】:

根据您上面的评论,您可能希望考虑通过环境变量传递密钥。如果在父进程环境中设置key,它会被子进程继承,不会像命令行那么容易被外人看到。

【讨论】:

您将能够在进程资源管理器中看到它们。我想您可以在阅读后将其设置为虚拟值

以上是关于如何清除进程命令行?的主要内容,如果未能解决你的问题,请参考以下文章

MFC C++ 应用程序:如何在任务管理器中清除命令行参数?

如何使用命令行清除 laravel 中的缓存?

ActiveMQ - 通过命令行删除/清除所有队列

使用命令行清除 Android 设备的 DNS 缓存

如何获得一个bash子进程的命令行上的进程id

如何获取启动进程的命令行