修改命令行参数

时间:2014-04-17 06:10:36

标签: c++ winapi command-line

我有一个Win32 C ++应用程序,我需要修改应用程序中的命令行参数。具体来说,我想以GetCommandLineW()返回我的新参数的方式编辑命令行参数。

信不信由你,这是有效的(因为我们有一个指向字符数组的非const指针):

LPTSTR args = GetCommandLineW();
LPTSTR new_args = L"foo --bar=baz";
wmemcpy(args, new_args, lstrlenW(new_args));

// ...
LPTSTR args2 = GetGommentLineW(); // <- equals "foo --bar=baz"

但我不知道Windows为LPTSTR提供的GetCommandLineW()分配的内存有多长。

还有其他办法吗?或者是否有人知道是否为命令行参数分配了可预测的内存量?

3 个答案:

答案 0 :(得分:5)

GetCommandLineW()不分配任何内存。它只是返回一个指向缓冲区的指针,该缓冲区在创建进程时由进程的PEB结构中的OS分配。该缓冲区在该过程的生命周期中存在。

答案 1 :(得分:0)

修改函数返回的最干净,最安全的方法是修改函数。安装绕行程序,以便从进程内部对函数的任何调用都重新路由到您提供的函数。

答案 2 :(得分:0)

使用以下代码检查CommandLine(unicode)字符串所在的PEB结构。

在我的计算机上,在CommandLine之后是ImagePathName,同时在x86和x64下,因此我认为前者也不会有更多空间。向该缓冲区写入更长的字符串可能会导致溢出。

#include <winnt.h>
#include <winternl.h>


int main()
{
    // Thread Environment Block (TEB)
#if defined(_M_X64) // x64
    PTEB tebPtr = (PTEB)__readgsqword((DWORD) & (*(NT_TIB*)NULL).Self);
#else // x86
    PTEB tebPtr = (PTEB)__readfsdword((DWORD) & (*(NT_TIB*)NULL).Self);
#endif
    // Process Environment Block (PEB)
    PPEB pebPtr = tebPtr->ProcessEnvironmentBlock;
    PRTL_USER_PROCESS_PARAMETERS ppPtr = pebPtr->ProcessParameters;

    printf("ImagePathName:\tlen=%d maxlen=%d ptr=%p\n", ppPtr->ImagePathName.Length, ppPtr->ImagePathName.MaximumLength, ppPtr->ImagePathName.Buffer);
    printf("CommandLine:\tlen=%d maxlen=%d ptr=%p\n", ppPtr->CommandLine.Length, ppPtr->CommandLine.MaximumLength, ppPtr->CommandLine.Buffer);
    printf("GetCommandLineA:\tptr=%p\n", GetCommandLineA());
    printf("GetCommandLineW:\tptr=%p\n", GetCommandLineW());
    printf("Addr Delta between CommandLine and ImagePathName: %d\n", (char*)ppPtr->CommandLine.Buffer - (char*)ppPtr->ImagePathName.Buffer);
}