如何获取其他进程命令行信息
每一个进程都有一个PEB数据块(PEB:Process Environment Block),这个进程环境块信息(如下结构体),
每个PEB中有_RTL_USER_PROCESS_PARAMETERS 结构体,是一个指针,指向一个结构体,这个结构体里面有一个CommandLine
命令行参数。所以要获得其他进程的命令行参数CommandLine,首先要获得其他进程的PEB结构体,通过_RTL_USER_PROCESS_PARAMETERS
得到它的结构体,结构体里面有CommandLine;
#include<Winternl.h>
typedef struct _PEB {//PEB结构 BYTE Reserved1[2]; BYTE BeingDebugged; BYTE Reserved2[1]; PVOID Reserved3[2]; PPEB_LDR_DATA Ldr; PRTL_USER_PROCESS_PARAMETERS ProcessParameters; BYTE Reserved4[104]; PVOID Reserved5[52]; PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine; BYTE Reserved6[128]; PVOID Reserved7[1]; ULONG SessionId; } PEB, *PPEB;
ntdll!_PEB+0x000InheritedAddressSpace : ??
+0x001ReadImageFileExecOptions : ??
+0x002BeingDebugged : ??
+0x003SpareBool : ??
+0x004Mutant : ????
+0x008ImageBaseAddress : ????
+0x00cLdr : ????
+0x010ProcessParameters : _RTL_USER_PROCESS_PARAMETERS(如下)
+0x014SubSystemData : ????
+0x018ProcessHeap : ????
+0x01cFastPebLock : ????
+0x020FastPebLockRoutine : ????
+0x024 FastPebUnlockRoutine : ????
+0x028 EnvironmentUpdateCount : ??
+0x02c KernelCallbackTable : ????
+0x030 SystemReserved : [1] ??
+0x034 AtlThunkSListPtr32 : ??
+0x038 FreeList : ????
+0x03c TlsExpansionCounter : ??
+0x040 TlsBitmap : ????
+0x044 TlsBitmapBits : [2] ??
+0x04c ReadOnlySharedMemoryBase : ????
+0x050 ReadOnlySharedMemoryHeap : ????
+0x054 ReadOnlyStaticServerData : ????
+0x058 AnsiCodePageData : ????
+0x05c OemCodePageData : ????
+0x060 UnicodeCaseTableData : ????
+0x064 NumberOfProcessors : ??
+0x068 NtGlobalFlag : ??
+0x070 CriticalSectionTimeout : _LARGE_INTEGER
+0x078 HeapSegmentReserve : ??
+0x07c HeapSegmentCommit : ??
+0x080 HeapDeCommitTotalFreeThreshold : ??
+0x084 HeapDeCommitFreeBlockThreshold : ??
+0x088 NumberOfHeaps : ??
+0x08c MaximumNumberOfHeaps : ??
+0x090 ProcessHeaps : ????
+0x094 GdiSharedHandleTable : ????
+0x098 ProcessStarterHelper : ????
+0x09c GdiDCAttributeList : ??
+0x0a0 LoaderLock : ????
+0x0a4 OSMajorVersion : ??
+0x0a8 OSMinorVersion : ??
+0x0ac OSBuildNumber : ??
+0x0ae OSCSDVersion : ??
+0x0b0 OSPlatformId : ??
+0x0b4 ImageSubsystem : ??
+0x0b8 ImageSubsystemMajorVersion : ??
+0x0bc ImageSubsystemMinorVersion : ??
+0x0c0 ImageProcessAffinityMask : ??
+0x0c4 GdiHandleBuffer : [34] ??
+0x14c PostProcessInitRoutine : ????
+0x150 TlsExpansionBitmap : ????
+0x154 TlsExpansionBitmapBits : [32] ??
+0x1d4 SessionId : ??
+0x1d8 AppCompatFlags : _ULARGE_INTEGER
+0x1e0 AppCompatFlagsUser : _ULARGE_INTEGER
+0x1e8 pShimData : ????
+0x1ec AppCompatInfo : ????
+0x1f0 CSDVersion : _UNICODE_STRING
+0x1f8 ActivationContextData : ????
+0x1fc ProcessAssemblyStorageMap : ????
+0x200 SystemDefaultActivationContextData : ????
+0x204 SystemAssemblyStorageMap : ????
+0x208 MinimumStackCommit : ??
struct RTL_USER_PROCESS_PARAMETERS |
typedef struct _RTL_USER_PROCESS_PARAMETERS
{
ULONG MaximumLength;
ULONG Length;
ULONG Flags;
ULONG DebugFlags;
PVOID ConsoleHandle;
ULONG ConsoleFlags;
PVOID StandardInput;
PVOID StandardOutput;
PVOID StandardError;
CURDIR CurrentDirectory;
UNICODE_STRING DllPath;
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
PVOID Environment;
ULONG StartingX;
ULONG StartingY;
ULONG CountX;
ULONG CountY;
ULONG CountCharsX;
ULONG CountCharsY;
ULONG FillAttribute;
ULONG WindowFlags;
ULONG ShowWindowFlags;
UNICODE_STRING WindowTitle;
UNICODE_STRING DesktopInfo;
UNICODE_STRING ShellInfo;
UNICODE_STRING RuntimeData;
RTL_DRIVE_LETTER_CURDIR CurrentDirectores[32];
ULONG EnvironmentSize;
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
NtQueryInformationProcess
NTSTATUS WINAPI NtQueryInformationProcess( _In_ HANDLE ProcessHandle, //进程句柄 _In_ PROCESSINFOCLASS ProcessInformationClass,//ProcessBasicInformation _Out_ PVOID ProcessInformation, //PROCESS_BASIC_INFORMATION结构体 _In_ ULONG ProcessInformationLength, //前面结构体的大小 _Out_opt_ PULONG ReturnLength //返回值的大小 );
#include
#include
#include
typedef NTSTATUS (WINAPI *QT)(HANDLE,PROCESSINFOCLASS,PVOID,ULONG,PULONG);//NtQueryInformationProcess
/*
写成一个函数,来获得所有的PEB结构体信息
*/
TCHAR* GetProcessCommandLine(HANDLE hProcess)
{
HMODULE hModule = 0;
QT NtQuery = { 0 };
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\n");
return 0;
}
PEB peb;
RTL_USER_PROCESS_PARAMETERS para;
ReadProcessMemory(hProcess, pi.PebBaseAddress, &peb, sizeof(peb), NULL); //将pi.PebBaseAddress的信息读取到peb中
ReadProcessMemory(hProcess, peb.ProcessParameters, ¶, sizeof(para), NULL);
TCHAR* CommandLine=(TCHAR*)malloc(sizeof(TCHAR)*1024);
ReadProcessMemory(hProcess, para.CommandLine.Buffer, CommandLine, 1024 * 2, NULL);
// _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, 2144);
TCHAR *str = GetProcessCommandLine(hProcess);
MessageBox(NULL,str,L"OK",MB_OK);
free(str);
return 0;
}
/*
int _tmain(int argc,TCHAR* argv[])
{
HMODULE hModule = 0;
QT NtQuery = {0};
hModule = LoadLibrary(L"Ntdll.dll"); //如果不写,就会报无法动态装入的错误,所以在头部加上typedef NTSTATUS结构体信息
if (hModule)
{
NtQuery = (QT)GetProcAddress(hModule,"NtQueryInformationProcess");//第二个参数不能加L,因为是ASCII类型的
}
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,2144);
PROCESS_BASIC_INFORMATION pi = {0}; //初始化
NTSTATUS re = NtQuery(hProcess,
ProcessBasicInformation,&pi,sizeof(pi),NULL);
//在pi中,pi.PebBaseAddress指向PEB,那么这个指针指向的地址是哪个地址呢?
//这个指针指向的地址,是word进程的地址
if (NT_SUCCESS(re)) //是一个宏,来判断NTSTATUS返回类型是否成功
{
// _tprintf(L"OK\n");
}
PEB peb;
RTL_USER_PROCESS_PARAMETERS para;
//这个函数用来读取其他进程中的内存地址
ReadProcessMemory(hProcess,pi.PebBaseAddress,&peb,sizeof(peb),NULL);
ReadProcessMemory(hProcess,peb.ProcessParameters,¶,sizeof(para),NULL);
TCHAR CommandLine[1024];
ReadProcessMemory(hProcess,para.CommandLine.Buffer,CommandLine,1024*2,NULL);//*2是UNICODE字符
_tprintf(L"%s\n", CommandLine);
MessageBox(NULL,CommandLine,L"ok",MB_OK);
_gettchar();
CloseHandle(hProcess);
FreeLibrary(hModule);
return 0;
}
*/