当我们使用ProcessExplorer的时候,发现它可以得到各个进程的启动参数(也就是在查看一个进程的属性里,在commandline里面显示的内容)。但是翻遍了MSDN也没有对应的API可以去作这样的事情,最开始的时候很无奈,只好先用内存查看器,看一下commmandline在内存啥位置,然后再用ReadProcessMemory去读一个尽可能大的块出来,虽然简单,但是不可靠,而且有时候读出来的东西后面是一堆无用的数据,影响美观。
经常不断的搜索,终于找到了方法:
1.先用OpenProcess 打开目标进程的进程空间,得到句柄
2.使用NtQueryInformationProcess这个API去读取进程里面的PE块的基地址也就是:PebBaseAddress
3.继续使用ReadProcessMemory,从这个PebBaseAddress,开始读取PEB(PE Block),这时候可以得到ProcessParameters,进程的参数地址
4.继续使用ReadProcessMemory,从这个ProcessParameters,开始读取PROCESS_PARAMETERS,这时候可以得到CommandLine.Length和CommandLine.Buffer,也就是启动参数的长度和启动参数的地址。
5.最后再使用ReadProcessMemory,根据记动参数的地址和长度去读取启动参数。特别要注意的事情是,如果在unicode的系统中,这时候读到的启动参数也是unicode的,所以得定义对应的字串类型去读取,不然打印出来的字串只有第一个字母(比如说参数是:abc,如果用ansi的字串,结果就是:a\0b\0c\0,\0这个就表示字串的结束了)。
最后,如果发现在第2步的时候出现读取错误,这时候应该是程序没有debug的权限了,可以用以下方法来提升程序的权限:
1.先用LookupPrivilegeValue来查看能否拥有:SeDebugPrivilege这个权限
2.如果可以,就用以下代码来提升权限:
Privileges.Privileges[0].Luid:=DebugNameValue;
Privileges.Privileges[0].Attributes:=SE_PRIVILEGE_ENABLED;
Result:=AdjustTokenPrivileges(TokenHandle,False,Privileges,SizeOf(Privileges),nil,RetLen);