我有一个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()
分配的内存有多长。
还有其他办法吗?或者是否有人知道是否为命令行参数分配了可预测的内存量?
答案 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);
}