【问题标题】: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:恶意软件所做的一切都是程序可以做的事情。无论您对此进行多少研究,都不会发现任何恶意软件可以做程序无法做的事情。然而,隐藏有关进程的信息是恶意软件的特征之一。
  • 而且我一直认为恶意软件的特征是对其他进程或系统进行恶意操作。所以现在禁止触摸自己的记忆——很好。

标签: c++ windows winapi command-line command-line-arguments


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    我想你必须修改你的进程的PEBRTL_USER_PROCESS_PARAMETERS 部分(例如参见http://en.wikipedia.org/wiki/Process_Environment_Blockhttp://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,它会被子进程继承,不会像命令行那么容易被外人看到。

    【讨论】:

    • 您将能够在进程资源管理器中看到它们。我想您可以在阅读后将其设置为虚拟值
    猜你喜欢
    • 1970-01-01
    • 2012-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-25
    • 2019-07-20
    • 2018-04-22
    • 2012-10-07
    相关资源
    最近更新 更多