如何清除进程命令行?

8
我希望能够从内部清空命令行,使得在任务管理器/进程资源管理器中查看我的进程时,命令行条目为空。
如果可能的话,我希望在当前运行的进程内完成此操作,而不是重新启动进程。

你想制作一些恶意软件吗?很遗憾,已经有一些可信的答案了。 - Cheers and hth. - Alf
不是,但这是一个多进程的解决方案,我希望尽可能地使其安全。其中一个通过命令行传递秘钥启动另一个,我只是试图在启动例程处理完之后将其删除。 - Joe Jordan
@Alf:修改进程命令行有什么恶意吗?这是一个程序可以做的事情,因为它拥有自己的内存。例如,请阅读http://blogs.msdn.com/b/oldnewthing/archive/2009/02/23/9440784.aspx。 - Joey
@Joey:所有恶意软件所做的事情都是程序可以做的。无论你如何研究,你都不会发现任何恶意软件做出程序无法完成的事情。然而,隐藏有关进程的信息是恶意软件的一个特征。 - Cheers and hth. - Alf
1
我一直认为恶意软件的特征是对其他进程或系统执行恶意操作。现在触及自己的内存也被禁止了,真好。 - Joey
@joe 跨越进程边界并不是恶意行为的先决条件。大多数情况下,恶意软件也不会跨越安全边界。然而,掩盖应用程序留下的痕迹(就像这个问题试图做的那样)对于任何恶意活动来说都很常见。虽然我还没有决定是否应该更害怕恶意软件本身,还是像这样自由共享明文秘密的应用程序,并在未经保护的通道上进行后期尝试来保护已经被入侵的系统。这是作者故意为之的。 - IInspectable
3个回答

14
我想您需要修改进程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;
}

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

alt text

而不是之前看到的以下内容

alt text


@Joe:你确定你重新启动了TaskManager进程吗? - Oleg
2
@Joe:我现在可以重现你描述的问题,情况如下:1)程序被编译为32位应用程序;2)程序在64位操作系统(Windows 7 x64)上以非管理员身份启动;3)使用64位任务管理器。如果使用“C:\Windows\SysWOW64\taskmgr.exe”或Process Explorer,或者将程序编译为X64 而不更改代码,则在我的测试程序中可以删除程序参数。64位exe的使用对您是否是一个选项?您可以使用IsWow64Process测试是否在64位上运行,并重新启动另一个exe。 - Oleg
1
Oleg:不幸的是,使用64位exe不是一个选项(重写这个VB6应用程序。我知道...)。有什么想法可以强制它在64位Windows上与32位可执行文件一起工作? - Joe Jordan
1
@Joe:应用程序之间有很多其他的通信方式。子UI应用程序可以通过参数获取对象的句柄,例如管道的句柄或内存映射对象的句柄。在子UI应用程序读取信息后,对象可以被删除。因此,没有人会看到明文的秘密密钥。您可以参考http://msdn.microsoft.com/en-us/library/ms682499(VS.85).aspx的示例,但需要进行一些更改,因为子进程是GUI而不是控制台应用程序。如果您在实现此场景时遇到问题,我可以向您发布一个使用C语言编写的小例子。 - Oleg
@Oleg,我该如何在Python中使用winappdbg实现这个功能?我有一个类似的问题在这里 - Shuman
显示剩余8条评论

2

根据您上面的评论,您可能希望考虑通过环境变量传递秘钥。如果在父进程环境中设置秘钥,则子进程将继承该秘钥,而且与命令行相比,它不会那么容易被外部人员看到。


1
您可以在进程管理器中看到它们。读取后,您可以将其设置为虚拟值。 - Anders

1
你可以尝试调用 GetCommandLine API 函数,然后将第一个字节设置为 0。即:
LPTSTR cmdline = GetCommandLine();
*cmdline = '\0';

我真的不知道那是否有效或可能带来什么后果,但或许值得一试。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接