函数结构介绍
每一个进程都有一个PEB数据块(PEB:Process Environment Block),这个进程环境块信息(如下结构体),
结构体 PROCESS_BASIC_INFORMATION 中的PebBaseAddress指向PEB,
typedef struct _PROCESS_BASIC_INFORMATION {
PVOID Reserved1;
PPEB PebBaseAddress;
PVOID Reserved2[2];
ULONG_PTR UniqueProcessId;
PVOID Reserved3;
} PROCESS_BASIC_INFORMATION;
typedef PROCESS_BASIC_INFORMATION *PPROCESS_BASIC_INFORMATION;
//PEB
typedef struct _PEB {
BYTE Reserved1[2];
BYTE BeingDebugged;
BYTE Reserved2[1];
PVOID Reserved3[2];
PPEB_LDR_DATA Ldr;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
PVOID Reserved4[3];
PVOID AtlThunkSListPtr;
PVOID Reserved5;
ULONG Reserved6;
PVOID Reserved7;
ULONG Reserved8;
ULONG AtlThunkSListPtr32;
PVOID Reserved9[45];
BYTE Reserved10[96];
PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
BYTE Reserved11[128];
PVOID Reserved12[1];
ULONG SessionId;
} PEB, *PPEB;
每个PEB中有_RTL_USER_PROCESS_PARAMETERS 结构体,是一个指针,指针指向另一个结构体UNICODE_STRING,这个结构体里面有一个CommandLine命令行参数。
所以要获得其他进程的命令行参数CommandLine,首先要获得其他进程的PEB结构体,通过_RTL_USER_PROCESS_PARAMETERS 得到它的结构体,结构体里面有CommandLine;
typedef struct _RTL_USER_PROCESS_PARAMETERS {
BYTE Reserved1[16];
PVOID Reserved2[10];
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
UNICODE_STRING 指向一个结构体,该结构体中的Buffer存储命令行信息。
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;
typedef const UNICODE_STRING *PCUNICODE_STRING;
如何获得其他进程的PEB结构体信息。
NTSTATUS WINAPI NtQueryInformationProcess(
__in HANDLE ProcessHandle,//进程句柄
__in PROCESSINFOCLASS ProcessInformationClass,// ProcessBasicInformation
__out PVOID ProcessInformation,//PROCESS_BASIC_INFORMATION
__in ULONG ProcessInformationLength,//前边结构体的大小
__out_opt PULONG ReturnLength//返回值的大小。
);
示例代码
#include<Windows.h>
#include<tchar.h>
#include<Winternl.h>
typedef NTSTATUS (WINAPI *QT)(HANDLE,PROCESSINFOCLASS,PVOID,ULONG,PULONG);
TCHAR* GetProcessCommandLine(HANDLE hProcess)
{
HMODULE hModule=0;
QT NtQuery;
hModule=LoadLibrary(L"Ntdll.dll");
if(hModule)
{
NtQuery=(QT)GetProcAddress(hModule,"NtQueryInformationProcess");
if(NtQuery==NULL)
return 0;
}
else
return 0;
PROCESS_BASIC_INFORMATION pi={0};
NTSTATUS re=NtQuery(hProcess,
ProcessBasicInformation,&pi,sizeof(pi),NULL);
/*
在pi中,pi.PebBaseAddress指向PEB,那么这个指针指向的地址,是那个地址呢?
这个指针指向的地址,是word进程中的地址!!!
*/
if(!NT_SUCCESS(re))
{
//_tprintf(L"OK");
return 0;
}
PEB peb;
RTL_USER_PROCESS_PARAMETERS para;
//peb.ProcessParameters->CommandLine.Buffer
ReadProcessMemory(hProcess,pi.PebBaseAddress,&peb,sizeof(peb),NULL);
ReadProcessMemory(hProcess,peb.ProcessParameters,¶,sizeof(para),NULL);
TCHAR* CommandLine=(TCHAR*)malloc(sizeof(TCHAR)*1024);
ReadProcessMemory(hProcess,para.CommandLine.Buffer,CommandLine,1024*2,NULL);
//TCHAR* CommandLine = (TCHAR*)malloc(sizeof(TCHAR) * 1024);
//ReadProcessMemory(hProcess, pi.PebBaseAddress->ProcessParameters->CommandLine.Buffer,CommandLine, 1024 * 2, NULL);
//pi.PebBaseAddress->ProcessParameters->CommandLine.Buffer
//_tprintf(L"%s\n",CommandLine);
//MessageBox(NULL,CommandLine,L"OK",MB_OK);
CloseHandle(hProcess);
FreeLibrary(hModule);
return CommandLine;
}
int _tmain(int argc,TCHAR* argv[])
{
HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,1544);
TCHAR* str=GetProcessCommandLine(hProcess);
MessageBox(NULL,str,L"OK",MB_OK);
free(str);
return 0;
}