CreateProcess
时,若
applicationname参数为空(大多数情况都为空),则
CreateProcess
将会去解析命令行参数以此获得进程映像文件的完整路径.一般应用双引号
"PathName"
将完整路径包括起来,否则应用空格与其余命令行参数隔开,具体解析方式这里不详述
首先是头文件,一些结构体的定义:(适用于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;
}