函数结构介绍

每一个进程都有一个PEB数据块(PEB:Process Environment Block),这个进程环境块信息(如下结构体),
结构体 PROCESS_BASIC_INFORMATION 中的PebBaseAddress指向PEB,

  1. typedef struct _PROCESS_BASIC_INFORMATION {
  2. PVOID Reserved1;
  3. PPEB PebBaseAddress;
  4. PVOID Reserved2[2];
  5. ULONG_PTR UniqueProcessId;
  6. PVOID Reserved3;
  7. } PROCESS_BASIC_INFORMATION;
  8. typedef PROCESS_BASIC_INFORMATION *PPROCESS_BASIC_INFORMATION;
  1. //PEB
  2. typedef struct _PEB {
  3. BYTE Reserved1[2];
  4. BYTE BeingDebugged;
  5. BYTE Reserved2[1];
  6. PVOID Reserved3[2];
  7. PPEB_LDR_DATA Ldr;
  8. PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
  9. PVOID Reserved4[3];
  10. PVOID AtlThunkSListPtr;
  11. PVOID Reserved5;
  12. ULONG Reserved6;
  13. PVOID Reserved7;
  14. ULONG Reserved8;
  15. ULONG AtlThunkSListPtr32;
  16. PVOID Reserved9[45];
  17. BYTE Reserved10[96];
  18. PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
  19. BYTE Reserved11[128];
  20. PVOID Reserved12[1];
  21. ULONG SessionId;
  22. } PEB, *PPEB;

每个PEB中有_RTL_USER_PROCESS_PARAMETERS 结构体,是一个指针,指针指向另一个结构体UNICODE_STRING,这个结构体里面有一个CommandLine命令行参数。
所以要获得其他进程的命令行参数CommandLine,首先要获得其他进程的PEB结构体,通过_RTL_USER_PROCESS_PARAMETERS 得到它的结构体,结构体里面有CommandLine;

  1. typedef struct _RTL_USER_PROCESS_PARAMETERS {
  2. BYTE Reserved1[16];
  3. PVOID Reserved2[10];
  4. UNICODE_STRING ImagePathName;
  5. UNICODE_STRING CommandLine;
  6. } RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;

UNICODE_STRING 指向一个结构体,该结构体中的Buffer存储命令行信息。

  1. typedef struct _UNICODE_STRING {
  2. USHORT Length;
  3. USHORT MaximumLength;
  4. PWSTR Buffer;
  5. } UNICODE_STRING;
  6. typedef UNICODE_STRING *PUNICODE_STRING;
  7. typedef const UNICODE_STRING *PCUNICODE_STRING;

如何获得其他进程的PEB结构体信息。

  1. NTSTATUS WINAPI NtQueryInformationProcess(
  2. __in HANDLE ProcessHandle,//进程句柄
  3. __in PROCESSINFOCLASS ProcessInformationClass,// ProcessBasicInformation
  4. __out PVOID ProcessInformation,//PROCESS_BASIC_INFORMATION
  5. __in ULONG ProcessInformationLength,//前边结构体的大小
  6. __out_opt PULONG ReturnLength//返回值的大小。
  7. );

示例代码

  1. #include<Windows.h>
  2. #include<tchar.h>
  3. #include<Winternl.h>
  4. typedef NTSTATUS (WINAPI *QT)(HANDLE,PROCESSINFOCLASS,PVOID,ULONG,PULONG);
  5. TCHAR* GetProcessCommandLine(HANDLE hProcess)
  6. {
  7. HMODULE hModule=0;
  8. QT NtQuery;
  9. hModule=LoadLibrary(L"Ntdll.dll");
  10. if(hModule)
  11. {
  12. NtQuery=(QT)GetProcAddress(hModule,"NtQueryInformationProcess");
  13. if(NtQuery==NULL)
  14. return 0;
  15. }
  16. else
  17. return 0;
  18. PROCESS_BASIC_INFORMATION pi={0};
  19. NTSTATUS re=NtQuery(hProcess,
  20. ProcessBasicInformation,&pi,sizeof(pi),NULL);
  21. /*
  22. 在pi中,pi.PebBaseAddress指向PEB,那么这个指针指向的地址,是那个地址呢?
  23. 这个指针指向的地址,是word进程中的地址!!!
  24. */
  25. if(!NT_SUCCESS(re))
  26. {
  27. //_tprintf(L"OK");
  28. return 0;
  29. }
  30. PEB peb;
  31. RTL_USER_PROCESS_PARAMETERS para;
  32. //peb.ProcessParameters->CommandLine.Buffer
  33. ReadProcessMemory(hProcess,pi.PebBaseAddress,&peb,sizeof(peb),NULL);
  34. ReadProcessMemory(hProcess,peb.ProcessParameters,&para,sizeof(para),NULL);
  35. TCHAR* CommandLine=(TCHAR*)malloc(sizeof(TCHAR)*1024);
  36. ReadProcessMemory(hProcess,para.CommandLine.Buffer,CommandLine,1024*2,NULL);
  37. //TCHAR* CommandLine = (TCHAR*)malloc(sizeof(TCHAR) * 1024);
  38. //ReadProcessMemory(hProcess, pi.PebBaseAddress->ProcessParameters->CommandLine.Buffer,CommandLine, 1024 * 2, NULL);
  39. //pi.PebBaseAddress->ProcessParameters->CommandLine.Buffer
  40. //_tprintf(L"%s\n",CommandLine);
  41. //MessageBox(NULL,CommandLine,L"OK",MB_OK);
  42. CloseHandle(hProcess);
  43. FreeLibrary(hModule);
  44. return CommandLine;
  45. }
  46. int _tmain(int argc,TCHAR* argv[])
  47. {
  48. HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,1544);
  49. TCHAR* str=GetProcessCommandLine(hProcess);
  50. MessageBox(NULL,str,L"OK",MB_OK);
  51. free(str);
  52. return 0;
  53. }