Reputation: 9826
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?
Upvotes: 2
Views: 2035
Reputation: 410
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);
}
Upvotes: 1
Reputation: 612784
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.
Upvotes: 1
Reputation: 595305
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.
Upvotes: 6