X64-R3层通过PEB获取进程命令行参数

关于命令行参数



进程创建进程时,会传一个命令行给它,一般其第一个内容是其可执行文件的名称,因为在调用 CreateProcess时,若 applicationname参数为空(大多数情况都为空),则 CreateProcess将会去解析命令行参数以此获得进程映像文件的完整路径.一般应用双引号 "PathName"将完整路径包括起来,否则应用空格与其余命令行参数隔开,具体解析方式这里不详述



获取命令行参数by PEB



其实64位与32位通过PEB获取进程信息并无太大区别,这里就当练练手,其余如加载模块,环境变量等值都可以通过这种方法获得,下面上代码:

首先是头文件,一些结构体的定义:(适用于64位)

#pragma once
#include 
#include
#include
using namespace std;#ifdef _WIN64
typedef unsigned long __w64 duint;
typedef signed long __w64   dsint;
#endif // _WIN64#define RTL_MAX_DRIVE_LETTERS 32BOOL EnableSeDebugPrivilege(IN const CHAR*  PriviledgeName, BOOL IsEnable);typedef struct _PROCESS_BASIC_INFORMATION
{PVOID Reserved1;PVOID PebBaseAddress;PVOID Reserved2[2];ULONG_PTR UniqueProcessId;PVOID Reserved3;
} PROCESS_BASIC_INFORMATION;
typedef PROCESS_BASIC_INFORMATION* PPROCESS_BASIC_INFORMATION;typedef struct _UNICODE_STRING
{USHORT Length;USHORT MaximumLength;PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;typedef struct _CURDIR
{UNICODE_STRING DosPath;HANDLE Handle;
} CURDIR, *PCURDIR;typedef struct _RTL_DRIVE_LETTER_CURDIR
{USHORT Flags;USHORT Length;ULONG TimeStamp;UNICODE_STRING DosPath;
} RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR;
typedef enum _PROCESSINFOCLASS
{ProcessBasicInformation,ProcessQuotaLimits,ProcessIoCounters,ProcessVmCounters,ProcessTimes,ProcessBasePriority,ProcessRaisePriority,ProcessDebugPort,ProcessExceptionPort,ProcessAccessToken,ProcessLdtInformation,ProcessLdtSize,ProcessDefaultHardErrorMode,ProcessIoPortHandlers,          // Note: this is kernel mode onlyProcessPooledUsageAndLimits,ProcessWorkingSetWatch,ProcessUserModeIOPL,ProcessEnableAlignmentFaultFixup,ProcessPriorityClass,ProcessWx86Information,ProcessHandleCount,ProcessAffinityMask,ProcessPriorityBoost,ProcessDeviceMap,ProcessSessionInformation,ProcessForegroundInformation,ProcessWow64Information,ProcessImageFileName,ProcessLUIDDeviceMapsEnabled,ProcessBreakOnTermination,ProcessDebugObjectHandle,ProcessDebugFlags,ProcessHandleTracing,ProcessIoPriority,ProcessExecuteFlags,ProcessResourceManagement,ProcessCookie,ProcessImageInformation,MaxProcessInfoClass             // MaxProcessInfoClass should always be the last enum
} PROCESSINFOCLASS;typedef struct _RTL_USER_PROCESS_PARAMETERS
{ULONG MaximumLength;ULONG Length;ULONG Flags;ULONG DebugFlags;HANDLE ConsoleHandle;ULONG ConsoleFlags;HANDLE StandardInput;HANDLE StandardOutput;HANDLE StandardError;CURDIR CurrentDirectory;UNICODE_STRING DllPath;UNICODE_STRING ImagePathName;UNICODE_STRING CommandLine;PWCHAR 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 CurrentDirectories[RTL_MAX_DRIVE_LETTERS];ULONG_PTR EnvironmentSize;ULONG_PTR EnvironmentVersion;PVOID PackageDependencyData;ULONG ProcessGroupId;ULONG LoaderThreads;
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;typedef struct _PEB_LDR_DATA
{ULONG Length;BOOLEAN Initialized;HANDLE SsHandle;LIST_ENTRY InLoadOrderModuleList;LIST_ENTRY InMemoryOrderModuleList;LIST_ENTRY InInitializationOrderModuleList;PVOID EntryInProgress;BOOLEAN ShutdownInProgress;HANDLE ShutdownThreadId;
} PEB_LDR_DATA, *PPEB_LDR_DATA;
typedef ULONG GDI_HANDLE_BUFFER[60];
typedef struct _PEB
{BOOLEAN InheritedAddressSpace;BOOLEAN ReadImageFileExecOptions;BOOLEAN BeingDebugged;union{BOOLEAN BitField;struct{BOOLEAN ImageUsesLargePages : 1;BOOLEAN IsProtectedProcess : 1;BOOLEAN IsImageDynamicallyRelocated : 1;BOOLEAN SkipPatchingUser32Forwarders : 1;BOOLEAN IsPackagedProcess : 1;BOOLEAN IsAppContainer : 1;BOOLEAN IsProtectedProcessLight : 1;BOOLEAN IsLongPathAwareProcess : 1;} s1;} u1;HANDLE Mutant;PVOID ImageBaseAddress;PPEB_LDR_DATA Ldr;PRTL_USER_PROCESS_PARAMETERS ProcessParameters;PVOID SubSystemData;PVOID ProcessHeap;PRTL_CRITICAL_SECTION FastPebLock;PVOID AtlThunkSListPtr;PVOID IFEOKey;union{ULONG CrossProcessFlags;struct{ULONG ProcessInJob : 1;ULONG ProcessInitializing : 1;ULONG ProcessUsingVEH : 1;ULONG ProcessUsingVCH : 1;ULONG ProcessUsingFTH : 1;ULONG ProcessPreviouslyThrottled : 1;ULONG ProcessCurrentlyThrottled : 1;ULONG ReservedBits0 : 25;} s2;} u2;union{PVOID KernelCallbackTable;PVOID UserSharedInfoPtr;} u3;ULONG SystemReserved[1];ULONG AtlThunkSListPtr32;PVOID ApiSetMap;ULONG TlsExpansionCounter;PVOID TlsBitmap;ULONG TlsBitmapBits[2];PVOID ReadOnlySharedMemoryBase;PVOID SharedData; // HotpatchInformationPVOID* ReadOnlyStaticServerData;PVOID AnsiCodePageData; // PCPTABLEINFOPVOID OemCodePageData; // PCPTABLEINFOPVOID UnicodeCaseTableData; // PNLSTABLEINFOULONG NumberOfProcessors;ULONG NtGlobalFlag;LARGE_INTEGER CriticalSectionTimeout;SIZE_T HeapSegmentReserve;SIZE_T HeapSegmentCommit;SIZE_T HeapDeCommitTotalFreeThreshold;SIZE_T HeapDeCommitFreeBlockThreshold;ULONG NumberOfHeaps;ULONG MaximumNumberOfHeaps;PVOID* ProcessHeaps; // PHEAPPVOID GdiSharedHandleTable;PVOID ProcessStarterHelper;ULONG GdiDCAttributeList;PRTL_CRITICAL_SECTION LoaderLock;ULONG OSMajorVersion;ULONG OSMinorVersion;USHORT OSBuildNumber;USHORT OSCSDVersion;ULONG OSPlatformId;ULONG ImageSubsystem;ULONG ImageSubsystemMajorVersion;ULONG ImageSubsystemMinorVersion;ULONG_PTR ActiveProcessAffinityMask;GDI_HANDLE_BUFFER GdiHandleBuffer;PVOID PostProcessInitRoutine;PVOID TlsExpansionBitmap;ULONG TlsExpansionBitmapBits[32];ULONG SessionId;ULARGE_INTEGER AppCompatFlags;ULARGE_INTEGER AppCompatFlagsUser;PVOID pShimData;PVOID AppCompatInfo; // APPCOMPAT_EXE_DATAUNICODE_STRING CSDVersion;PVOID ActivationContextData; // ACTIVATION_CONTEXT_DATAPVOID ProcessAssemblyStorageMap; // ASSEMBLY_STORAGE_MAPPVOID SystemDefaultActivationContextData; // ACTIVATION_CONTEXT_DATAPVOID SystemAssemblyStorageMap; // ASSEMBLY_STORAGE_MAPSIZE_T MinimumStackCommit;PVOID* FlsCallback;LIST_ENTRY FlsListHead;PVOID FlsBitmap;ULONG FlsBitmapBits[FLS_MAXIMUM_AVAILABLE / (sizeof(ULONG) * 8)];ULONG FlsHighIndex;PVOID WerRegistrationData;PVOID WerShipAssertPtr;PVOID pUnused; // pContextDataPVOID pImageHeaderHash;union{ULONG TracingFlags;struct{ULONG HeapTracingEnabled : 1;ULONG CritSecTracingEnabled : 1;ULONG LibLoaderTracingEnabled : 1;ULONG SpareTracingBits : 29;} s3;} u4;ULONGLONG CsrServerReadOnlySharedMemoryBase;PVOID TppWorkerpListLock;LIST_ENTRY TppWorkerpList;PVOID WaitOnAddressHashTable[128];PVOID TelemetryCoverageHeader; // REDSTONE3ULONG CloudFileFlags;
} PEB, *PPEB;
//以上为64位下的结构体,摘自开源调试器x64dbg的代码typedef NTSTATUS(NTAPI *pfn)(__in HANDLE ProcessHandle,__in PROCESSINFOCLASS ProcessInformationClass,__out_bcount(ProcessInformationLength) PVOID ProcessInformation,__in ULONG ProcessInformationLength,__out_opt PULONG ReturnLength);void*  GetPEBLocation(HANDLE hProcess);BOOL getcommandlineaddr(duint* addr, HANDLE hProcess);
BOOL MemoryReadSafe(HANDLE hProcess, LPVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead);

然后是cpp文件c++

#include "CMD.h"pfn NtQueryInformationProcess = NULL;
BOOL EnableSeDebugPrivilege(IN const CHAR*  PriviledgeName, BOOL IsEnable)
{// 打开权限令牌HANDLE  ProcessHandle = GetCurrentProcess();HANDLE  TokenHandle = NULL;TOKEN_PRIVILEGES TokenPrivileges = { 0 };if (!OpenProcessToken(ProcessHandle, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &TokenHandle)){return FALSE;}LUID             v1;if (!LookupPrivilegeValueA(NULL, PriviledgeName, &v1))      // 通过权限名称查找uID{CloseHandle(TokenHandle);TokenHandle = NULL;return FALSE;}TokenPrivileges.PrivilegeCount = 1;     // 要提升的权限个数TokenPrivileges.Privileges[0].Attributes = IsEnable == TRUE ? SE_PRIVILEGE_ENABLED : 0;    // 动态数组,数组大小根据Count的数目TokenPrivileges.Privileges[0].Luid = v1;if (!AdjustTokenPrivileges(TokenHandle, FALSE, &TokenPrivileges,sizeof(TOKEN_PRIVILEGES), NULL, NULL)){CloseHandle(TokenHandle);TokenHandle = NULL;return FALSE;}CloseHandle(TokenHandle);TokenHandle = NULL;return TRUE;
}void*  GetPEBLocation(HANDLE hProcess)//获得PEB的VA
{ULONG RequiredLen = 0;void* PebAddress = 0;PROCESS_BASIC_INFORMATION myProcessBasicInformation[5] = { 0 };if (NtQueryInformationProcess(hProcess, ProcessBasicInformation, myProcessBasicInformation, sizeof(PROCESS_BASIC_INFORMATION), &RequiredLen) == STATUS_SUCCESS){PebAddress = (void*)myProcessBasicInformation->PebBaseAddress;}else{if (NtQueryInformationProcess(hProcess, ProcessBasicInformation, myProcessBasicInformation, RequiredLen, &RequiredLen) == STATUS_SUCCESS){PebAddress = (void*)myProcessBasicInformation->PebBaseAddress;}}return PebAddress;
}
BOOL  MemoryReadSafe(HANDLE hProcess, LPVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead)//非常便捷的函数,可以记下来
{SIZE_T ueNumberOfBytesRead = 0;SIZE_T* pNumBytes = 0;DWORD dwProtect = 0;BOOL retValue = false;//read memoryif ((hProcess == 0) || (lpBaseAddress == 0) || (lpBuffer == 0) || (nSize == 0)){return false;}if (!lpNumberOfBytesRead){pNumBytes = &ueNumberOfBytesRead;}else{pNumBytes = lpNumberOfBytesRead;}if (!ReadProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, pNumBytes)){if (VirtualProtectEx(hProcess, lpBaseAddress, nSize, PAGE_EXECUTE_READWRITE, &dwProtect))//修改保护属性{if (ReadProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, pNumBytes)){retValue = TRUE;}VirtualProtectEx(hProcess, lpBaseAddress, nSize, dwProtect, &dwProtect);}}else{retValue = TRUE;}return retValue;
}BOOL getcommandlineaddr(duint* addr,HANDLE hProcess)
{duint pprocess_parameters;duint Addr = (duint)GetPEBLocation(hProcess);//获得PEB地址if (Addr == 0){return false;}if (!hProcess) { return FALSE; }SIZE_T NumberOfBytesRead;if (!MemoryReadSafe(hProcess, (LPVOID)((Addr) + offsetof(PEB, ProcessParameters)),&pprocess_parameters, sizeof(duint), &NumberOfBytesRead))//根据偏移获得命令行地址{return false;}*addr = (pprocess_parameters)+offsetof(RTL_USER_PROCESS_PARAMETERS, CommandLine);return TRUE;
}void main() {duint* CmdAddr = NULL;HANDLE hProcess = NULL;DWORD ProcessId = 0;HMODULE NtdllModuleBase = NULL;PUNICODE_STRING CmdLine;WCHAR* CmdLineBuffer = NULL;SIZE_T NumberOfBytesRead = 0;if (EnableSeDebugPrivilege("SeDebugPrivilege", TRUE) == FALSE){goto EXIT;}NtdllModuleBase = GetModuleHandle(L"Ntdll.dll");if (NtdllModuleBase == NULL){goto EXIT;}NtQueryInformationProcess = (pfn)GetProcAddress(NtdllModuleBase, "NtQueryInformationProcess");if (NtQueryInformationProcess == NULL){int a = GetLastError();goto EXIT;}cout << "输入进程id" << endl;cin >> ProcessId;hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);CmdAddr = (duint*)malloc(sizeof(duint*));CmdLine = (PUNICODE_STRING)malloc(sizeof(UNICODE_STRING));CmdLineBuffer = (WCHAR*)malloc(1024);getcommandlineaddr(CmdAddr,hProcess);if (!MemoryReadSafe(hProcess, (LPVOID)*CmdAddr, (LPVOID)CmdLine, sizeof(UNICODE_STRING), &NumberOfBytesRead))//获得命令行地址{printf("ERROR\n");goto EXIT;}if (!MemoryReadSafe(hProcess, (LPVOID)CmdLine->Buffer, (LPVOID)CmdLineBuffer, 1024, &NumberOfBytesRead))//命令行是一个UNICODE_STRING结构,还要读取一次读取命令行的BUFEER{printf("ERROR\n");goto EXIT;}printf("%S", CmdLineBuffer);EXIT:if (CmdAddr != NULL){free(CmdAddr);}if (CmdLine!= NULL){free(CmdLine);}if (CmdLineBuffer != NULL){free(CmdLineBuffer);}EnableSeDebugPrivilege("SeDebugPrivilege", FALSE);getchar();return;
}

下面是运行结果:
这里写图片描述


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部