关于命令行参数
进程创建进程时,会传一个命令行给它,一般其第一个内容是其可执行文件的名称,因为在调用 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 32 BOOL 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 only ProcessPooledUsageAndLimits, 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; // HotpatchInformation PVOID* ReadOnlyStaticServerData; PVOID AnsiCodePageData; // PCPTABLEINFO PVOID OemCodePageData; // PCPTABLEINFO PVOID UnicodeCaseTableData; // PNLSTABLEINFO ULONG NumberOfProcessors; ULONG NtGlobalFlag; LARGE_INTEGER CriticalSectionTimeout; SIZE_T HeapSegmentReserve; SIZE_T HeapSegmentCommit; SIZE_T HeapDeCommitTotalFreeThreshold; SIZE_T HeapDeCommitFreeBlockThreshold; ULONG NumberOfHeaps; ULONG MaximumNumberOfHeaps; PVOID* ProcessHeaps; // PHEAP PVOID 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_DATA UNICODE_STRING CSDVersion; PVOID ActivationContextData; // ACTIVATION_CONTEXT_DATA PVOID ProcessAssemblyStorageMap; // ASSEMBLY_STORAGE_MAP PVOID SystemDefaultActivationContextData; // ACTIVATION_CONTEXT_DATA PVOID SystemAssemblyStorageMap; // ASSEMBLY_STORAGE_MAP SIZE_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; // pContextData PVOID 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; // REDSTONE3 ULONG 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 memory if ((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; }
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/224152.html原文链接:https://javaforall.net
