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

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

关于命令行参数


进程创建进程时,会传一个命令行给它,一般其第一个内容是其可执行文件的名称,因为在调用 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

(0)
上一篇 2026年3月17日 下午12:35
下一篇 2026年3月17日 下午12:36


相关推荐

  • GTX 750等低配显卡如何玩转Deepfakes?[通俗易懂]

    GTX 750等低配显卡如何玩转Deepfakes?[通俗易懂]这里说的Deepfakes软件还是DeepFaceLab,人工智能换脸,是使用深度学习方法来实现的。而深度学习程序对电脑配置要求是非常高的,尤其是跑模型这个环节。很多低配电脑,根本就跑步起来。比如像GTX750,1G显存。默认情况下这种配置肯定跑不了这个程序,但是通过自定义参数也能跑。这对于低配玩家来说绝对是个好消息。首先,你需要获取的DFL的版本为DeepFaceLabCUDA…

    2022年5月20日
    157
  • 算法分析与设计论文

    算法分析与设计论文1:递归算法程序直接或间接调用自身的编程技巧称为递归算法(Recursion)。递归算法是一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法。它通常把一个大型复杂的问题转化为一个与原问题

    2022年8月2日
    8
  • leetcode-46全排列[通俗易懂]

    leetcode-46全排列[通俗易懂]原题链接给定一个 没有重复 数字的序列,返回其所有可能的全排列。示例:输入: [1,2,3]输出:[ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1]]题解回溯即可class Solution {public: vector<vector<int> >res; vector<int>t; void dfs(int num,int len,vecto

    2022年8月9日
    5
  • 7.1科技新闻

    7.1科技新闻时尚 3D 打印让骨折患者和石膏说再见 通常 骨折的患者为了让骨头复位或固定 往往要打上石膏 提及石膏 这类医学用品不仅笨重 庞大 还影响美观 现在 利用 nbsp 3D nbsp 打印技术 这些令人厌恶的的存在因素或会所改变 威锋网 nbsp 6 nbsp 月 nbsp 30 nbsp 日讯 nbsp 据外站 nbsp The nbsp Verge nbsp 报道 惠灵顿维多利亚大学的学生 nbsp Jake nbsp Evill nbsp 推出了一款与 nbsp 3D nbsp 打印技术相关的概念

    2026年3月26日
    2
  • GPT对话框删除还能恢复吗?恢复方式成功率分析

    GPT对话框删除还能恢复吗?恢复方式成功率分析

    2026年3月16日
    2
  • web前端开发面试中常见的算法题(JS)

    web前端开发面试中常见的算法题(JS)前言最近在准备秋招,做过了大大小小的公司的面试题,发现除了基础知识外,算法还是挺重要的。特意整理了一些常见的算法题,添加了自己的理解并实现。除此之外,建议大家还可以刷刷《剑指offer》(但我还没刷完?,任重道远呐)。此外,左神在牛客网上也有算法课程,听了基础班的感觉还不错,起码让我这个算法小白也能快速地理解了很多问题,知识付费的时代,这个真的是良心课程了。就我个人而言的话,平时为了解决一…

    2022年6月29日
    35

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号