• Delphi 获取进程路径及命令行参数


    Delphi 获取进程路径及命令行参数, 但有的进程获取时会报错,不知为啥

    type
      PVOID64 = UINT64;
    
      _UNICODE_STRING = packed record
        Length : USHORT;
        MaximumLength : USHORT;
        Buffer : PWideChar;
      end;
      UNICODE_STRING = _UNICODE_STRING;
      PUNICODE_STRING =^_UNICODE_STRING;
    
      _UNICODE_STRING64 = packed record
        Length : USHORT;
        MaximumLength : USHORT;
        Fill : DWORD;
        Buffer : PVOID64;
      end;
      UNICODE_STRING64 = _UNICODE_STRING64;
      PUNICODE_STRING64 =^_UNICODE_STRING64;
    
      __PEB = packed record
        Filler : array [0..3] of DWORD;
        ProcessParameters : DWORD;
      end;
    
      __PEB64 = packed record
        Filler : array [0..3] of PVOID64;
        ProcessParameters : PVOID64;
      end;
    
      _CURDIR = packed record
        DosPath : UNICODE_STRING;
        Handle : THANDLE;
      end;
    
      _CURDIR64 = packed record
        DosPath : UNICODE_STRING64;
        Handle : PVOID64;
      end;
    
      _RTL_USER_PROCESS_PARAMETERS = packed record
        MaximumLength   :DWORD;
        Length          :DWORD;
        Flags           :DWORD;
        DebugFlags      :DWORD;
        ConsoleHandle   :THandle;
        ConsoleFlags    :DWORD;
        StandardInput   :THandle;
        StandardOutput  :THandle;
        StandardError   :THandle;
        //////////////////////////
        DosPath         :UNICODE_STRING;    //CurrentDirectory
        Handle          :THANDLE;
        //////////////////////////
        DllPath         :UNICODE_STRING;
        ImagePathName   :UNICODE_STRING;
        CmdLine         :UNICODE_STRING;
      end;
    
      _RTL_USER_PROCESS_PARAMETERS64 = record
        MaximumLength   :DWORD;
        Length          :DWORD;
        Flags           :DWORD;
        DebugFlags      :DWORD;
        ConsoleHandle   :PVOID64;
        ConsoleFlags    :DWORD;
        StandardInput   :PVOID64;
        StandardOutput  :PVOID64;
        StandardError   :PVOID64;
        //////////////////////////
        CurrentDirectory:_CURDIR64;
        //////////////////////////
        DllPath         :UNICODE_STRING64;
        ImagePathName   :UNICODE_STRING64;
        CmdLine         :UNICODE_STRING64;
      end;
    
      _PROCESS_BASIC_INFORMATION = packed record
        Reserved1       :PVOID;
        PebBaseAddress  :PVOID;
        Reserved2       :Array [0..1] of PVOID;
        UniqueProcessId :PVOID;
        Reserved3       :PVOID;
      end;
      PROCESS_BASIC_INFORMATION  =_PROCESS_BASIC_INFORMATION;
      PPROCESS_BASIC_INFORMATION =^_PROCESS_BASIC_INFORMATION;
    
      _PROCESS_BASIC_INFORMATION64 = packed record
        Reserved1       :PVOID64;
        PebBaseAddress  :PVOID64;
        Reserved2       :Array [0..1] of PVOID64;
        UniqueProcessId :PVOID64;
        Reserved3       :PVOID64;
      end;
      PROCESS_BASIC_INFORMATION64  =_PROCESS_BASIC_INFORMATION64;
      PPROCESS_BASIC_INFORMATION64 =^_PROCESS_BASIC_INFORMATION64;
    
      TNtQueryInformationProcess = function(a:THANDLE;b:UINT;c:PVOID;d:ULONG;e:PULONG):LONG; stdcall;
      TNtReadVirtualMemory = function(ProcessHandle:THANDLE; BaseAddress:PVOID; Buffer:PVOID; NumberOfBytesToRead:ULONG; NumberOfBytesReaded:PULONG):LONG; stdcall;
      TNtReadVirtualMemory64 = function(ProcessHandle:THANDLE; BaseAddress:PVOID64; Buffer:PVOID; NumberOfBytesToRead:UINT64; NumberOfBytesReaded:PUINT64):LONG; stdcall;
      TISWOW64PROCESS = function(hProcess:THANDLE; var Wow64Process:BOOL):BOOL; stdcall;
    
      function GetProcessImagePathAndCmdLine(hProcess:THandle; var ImagePath:string; var CmdLine:string):Boolean;
    
    
    implementation
    
    
    function GetProcessImagePathAndCmdLine32(hProcess:THandle; var ImagePath:string; var CmdLine:string):Boolean;
    var
      pbi : PROCESS_BASIC_INFORMATION;
      pfnNtQueryInformationProcess : TNtQueryInformationProcess;
      pfnNtReadVirtualMemory : TNtReadVirtualMemory;
      dwSize:DWORD;
      size:SIZE_T;
      iReturn:Integer;
      pAddrPEB:PVOID;
      PEB:__PEB;
      stBlock:_RTL_USER_PROCESS_PARAMETERS;
      PathBuffer : PByte;
    begin
      Result := False;
      @pfnNtQueryInformationProcess := GetProcAddress(GetModuleHandle('ntdll.dll'),'NtQueryInformationProcess');
      @pfnNtReadVirtualMemory := GetProcAddress(GetModuleHandle('ntdll.dll'),'NtReadVirtualMemory');
    
      if ( Assigned(pfnNtQueryInformationProcess) ) then
      begin
        pAddrPEB := nil;
        iReturn := pfnNtQueryInformationProcess(hProcess,0,@pbi,sizeof(pbi),@dwSize);
        pAddrPEB := pbi.PebBaseAddress;
        // NtQueryInformationProcess returns a negative value if it fails
        if (iReturn >= 0) then
        begin
          // 1. Find the Process Environment Block
          size := dwSize;
          if ( ERROR_SUCCESS <> pfnNtReadVirtualMemory(hProcess, pAddrPEB, @PEB, sizeof(PEB), PULONG(@size)) ) then
          begin
            // Call GetLastError() if you need to know why
            Exit;
          end;
          // 2. From this PEB, get the address of the block containing
          // a pointer to the CmdLine
          if ( ERROR_SUCCESS <> pfnNtReadVirtualMemory(hProcess, PVOID(PEB.ProcessParameters), @stBlock, sizeof(stBlock), PULONG(@size))) then
          begin
            // Call GetLastError() if you need to know why
            Exit;
          end;
          // 3. Get the ImagePathName
          if (stBlock.ImagePathName.MaximumLength <= 1024) then
          begin
            PathBuffer := GetMemory(stBlock.ImagePathName.MaximumLength);
            FillChar(PathBuffer^,stBlock.ImagePathName.MaximumLength,0);
            if (stBlock.ImagePathName.MaximumLength <= 1024) and ( ERROR_SUCCESS = pfnNtReadVirtualMemory(hProcess, PVOID(stBlock.ImagePathName.Buffer), PVOID(PathBuffer), stBlock.ImagePathName.Length*sizeof(Char), PULONG(@size))) then
            begin    // Call GetLastError() if you need to know why
              SetString(ImagePath,PChar(PathBuffer),stBlock.ImagePathName.Length div 2);
              Result := True;
            end;
            FreeMemory(PathBuffer);
          end;
            // 4. Get the CmdLine
          if (stBlock.CmdLine.MaximumLength <= 1024) then
          begin
            PathBuffer := GetMemory(stBlock.CmdLine.MaximumLength);
            FillChar(PathBuffer^,stBlock.CmdLine.MaximumLength,0);
            if ( ERROR_SUCCESS = pfnNtReadVirtualMemory(hProcess, PVOID(stBlock.CmdLine.Buffer), PVOID(PathBuffer), stBlock.CmdLine.Length*sizeof(Char), PULONG(@size))) then
            begin    // Call GetLastError() if you need to know why
              SetString(CmdLine,PChar(PathBuffer),stBlock.CmdLine.Length div 2);
              Result := True;
            end;
            FreeMemory(PathBuffer);
          end;
        end;
      end;
    end;
    
    
    function GetProcessImagePathAndCmdLine64(hProcess:THandle; var ImagePath:string; var CmdLine:string):Boolean;
    var
      pbi : PROCESS_BASIC_INFORMATION64;
      pfnNtQueryInformationProcess : TNtQueryInformationProcess;
      pfnNtReadVirtualMemory : TNtReadVirtualMemory64;
      dwSize:DWORD;
      size:UINT64;
      iReturn:Integer;
      pAddrPEB:PVOID64;
      PEB:__PEB64;
      stBlock:_RTL_USER_PROCESS_PARAMETERS64;
      PathBuffer : PByte;
    begin
      Result := False;
      @pfnNtQueryInformationProcess := GetProcAddress(GetModuleHandle('ntdll.dll'),'NtWow64QueryInformationProcess64');
      @pfnNtReadVirtualMemory := GetProcAddress(GetModuleHandle('ntdll.dll'),'NtWow64ReadVirtualMemory64');
    
      if ( Assigned(pfnNtQueryInformationProcess) ) then
      begin
        pAddrPEB := 0;
        iReturn := pfnNtQueryInformationProcess(hProcess,0,@pbi,sizeof(pbi),PULONG(@dwSize));
        pAddrPEB := pbi.PebBaseAddress;
        // NtQueryInformationProcess returns a negative value if it fails
        if (iReturn >= 0) then
        begin
          // 1. Find the Process Environment Block
          size := dwSize;
          if ( ERROR_SUCCESS <> pfnNtReadVirtualMemory(hProcess, pAddrPEB, @PEB, sizeof(PEB), PUINT64(@size)) ) then
          begin
            // Call GetLastError() if you need to know why
            Exit;
          end;
          // 2. From this PEB, get the address of the block containing
          // a pointer to the CmdLine
          if ( ERROR_SUCCESS <> pfnNtReadVirtualMemory(hProcess, PEB.ProcessParameters, @stBlock, sizeof(stBlock), PUINT64(@size))) then
          begin
            // Call GetLastError() if you need to know why
            Exit;
          end;
          // 3. Get the ImagePathName
          PathBuffer := GetMemory(stBlock.ImagePathName.MaximumLength);
          FillChar(PathBuffer^,stBlock.ImagePathName.MaximumLength,0);
          if ( ERROR_SUCCESS = pfnNtReadVirtualMemory(hProcess, stBlock.ImagePathName.Buffer, PVOID(PathBuffer), stBlock.ImagePathName.Length*sizeof(Char), PUINT64(@size))) then
          begin    // Call GetLastError() if you need to know why
            SetString(ImagePath,PChar(PathBuffer),stBlock.ImagePathName.Length div 2);
            Result := True;
          end;
          // 4. Get the CmdLine
          FreeMemory(PathBuffer);
          PathBuffer := GetMemory(stBlock.CmdLine.MaximumLength);
          FillChar(PathBuffer^,stBlock.CmdLine.MaximumLength,0);
          if ( ERROR_SUCCESS = pfnNtReadVirtualMemory(hProcess, stBlock.CmdLine.Buffer, PVOID(PathBuffer), stBlock.CmdLine.Length*sizeof(Char), PUINT64(@size))) then
          begin    // Call GetLastError() if you need to know why
            SetString(CmdLine,PChar(PathBuffer),stBlock.CmdLine.Length div 2);
            Result := True;
          end;
          FreeMemory(PathBuffer);
        end;
      end;
    end;
    
    function GetProcessImagePathAndCmdLine(hProcess:THandle; var ImagePath:string; var CmdLine:string):Boolean;
    var
      fn:TISWOW64PROCESS;
    begin
      Result := False;
      try
        fn := GetProcAddress(GetModuleHandle('kernel32'),'IsWow64Process');
        if Assigned(fn) then
        begin
          Result := GetProcessImagePathAndCmdLine64(hProcess,ImagePath,CmdLine);
        end else
        begin
          Result := GetProcessImagePathAndCmdLine32(hProcess,ImagePath,CmdLine);
        end;
      Except
      end;
    end;
  • 相关阅读:
    使用postman时请求参数中包含特殊字符问题,如加号传到后台变成空格
    okhttp3报错:java.lang.NoClassDefFoundError: kotlin/jvm/internal/Intrinsics
    Eclipse的知识积累
    partition 取数据中相同字段数据中取时间最大的一个值 并只保留一条
    理解Session缓存机制 操纵持久化对象
    Hibernate的检索策略
    LINQ介绍
    .Net 一对一的双向关联Map写法
    Hibernate多态查询
    NHibernate实战[转 2012 gogogo]
  • 原文地址:https://www.cnblogs.com/wlmbz/p/3594660.html
Copyright © 2020-2023  润新知