简体   繁体   中英

Modify Command Line Arguments

I have a Win32 C++ application and I need to modify the command line arguments in the application. Specifically, I want to edit the command line arguments in such a way that GetCommandLineW() returns my new arguments.

Believe it or not, this works (since we have a non-const pointer to the character array):

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

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

But I don't know how long much memory Windows allocates for the LPTSTR provided by GetCommandLineW() .

Is there another way to do this? Or does anyone know if there is a predictable amount of memory allocated for the command line arguments?

GetCommandLineW() does not allocate any memory. It simply returns a pointer to a buffer that is allocated by the OS in the process's PEB structure when the process is created. That buffer exists for the lifetime of the process.

The cleanest and safest way to modify what that function returns is to modify the function. Install a detour so that any calls to the function from inside your process are re-routed to a function that you provide.

Use the following code to inspect on PEB structure, where the CommandLine (unicode) string lies.

On my machine, under both x86 and x64 CommandLine is right after ImagePathName , so I think there won't be more space for the former one either. Writing a longer string to that buffer does might cause an overflow.

#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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM