DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: eschen
今日帖子: 15
在线用户: 35
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 cenunus (cenunus) ▲▲▲▲▲ -
注册会员
2019/6/14 12:55:13
标题:
获取进程命令行的函数错误,求助! 浏览:662
加入我的收藏
楼主: function TForm1.Process_CmdLine(mProcessID: THandle): WideString;
var
  vProcess: THandle;
  vProcessBasicInformation: PROCESS_BASIC_INFORMATION;
  vPEB: PEB;
  vNumberOfBytesRead: SIZE_T;
  vProcessParameters: PROCESS_PARAMETERS;
begin
//设计 Zswang 2006-09-09 wjhu111#21cn.com 尊重作者,转贴请注明出处
  Result := '';
  vProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, mProcessID);
  if vProcess = 0 then Exit;
  try
    if NtQueryInformationProcess(
      vProcess,
      ProcessBasicInformation,
      @vProcessBasicInformation,
      SizeOf(vProcessBasicInformation),
      nil) <> 0 then Exit;
    if not ReadProcessMemory(vProcess,
      vProcessBasicInformation.PebBaseAddress,
      @vPEB,
      SizeOf(vPEB),
      vNumberOfBytesRead) then Exit;
    if not ReadProcessMemory(vProcess,
      vPEB.ProcessParameters,
      @vProcessParameters,
      SizeOf(vProcessParameters),
      vNumberOfBytesRead) then Exit;
    SetLength(Result, vProcessParameters.CommandLine.Length div 2);
    if not ReadProcessMemory(vProcess,
      vProcessParameters.CommandLine.Buffer,
      @Result[1],
      vProcessParameters.CommandLine.Length,
      vNumberOfBytesRead) then Exit;
  finally
    CloseHandle(vProcess);
  end;
end;
这个程序在读内存时出现299错误(GetLastError),望大侠们有空帮忙看看,谢谢!
----------------------------------------------
作者:
男 xuchuantao (暗黑天使) ▲▲▲▲△ -
注册会员
2019/6/14 22:03:34
1楼: 你系统是64位还是32位,你要读取命令行的进程是32还是64的?32位程序和64程序PEB是不兼容的.
----------------------------------------------
按此在新窗口浏览图片
作者:
男 xuchuantao (暗黑天使) ▲▲▲▲△ -
注册会员
2019/6/14 22:04:42
2楼: https://blog.csdn.net/qq_27011361/article/details/79911641
----------------------------------------------
按此在新窗口浏览图片
作者:
男 xuchuantao (暗黑天使) ▲▲▲▲△ -
注册会员
2019/6/14 22:32:21
3楼: unit ProcessImagePathAndCmdLine;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;

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;

end.
----------------------------------------------
按此在新窗口浏览图片
作者:
男 xuchuantao (暗黑天使) ▲▲▲▲△ -
注册会员
2019/6/14 22:32:52
4楼: function Process_CmdLine(mProcessID: THandle): String;
  var
    vProcess: THandle;
    vProcessBasicInformation: PROCESS_BASIC_INFORMATION;
    vPEB: PEB;     ImagePath: string;
    vNumberOfBytesRead: SIZE_T;
    vProcessParameters: PROCESS_PARAMETERS;
  begin
    result := '';
    vProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False,
      mProcessID);
    if vProcess = 0 then
      Exit;
    try  GetProcessImagePathAndCmdLine(vProcess,ImagePath,result);
     { if NtQueryInformationProcess(vProcess, ProcessBasicInformation,
        @vProcessBasicInformation, SizeOf(vProcessBasicInformation), nil) <> 0
      then
        Exit;
      if not ReadProcessMemory(vProcess,
        vProcessBasicInformation.PebBaseAddress, @vPEB, SizeOf(vPEB),
        vNumberOfBytesRead) then
        Exit;
      if not ReadProcessMemory(vProcess, vPEB.ProcessParameters,
        @vProcessParameters, SizeOf(vProcessParameters), vNumberOfBytesRead)
      then
        Exit;
      SetLength(result, vProcessParameters.CommandLine.Length div 2);
      if not ReadProcessMemory(vProcess, vProcessParameters.CommandLine.Buffer,
        @result[1], vProcessParameters.CommandLine.Length, vNumberOfBytesRead)
      then
        Exit;    //}
    finally
      CloseHandle(vProcess);
    end;
  end;
----------------------------------------------
按此在新窗口浏览图片
作者:
男 xuchuantao (暗黑天使) ▲▲▲▲△ -
注册会员
2019/6/14 22:33:29
5楼: 代码出处;https://www.cnblogs.com/wlmbz/archive/2014/03/11/3594660.html
----------------------------------------------
按此在新窗口浏览图片
作者:
男 xuchuantao (暗黑天使) ▲▲▲▲△ -
注册会员
2019/6/14 22:38:35
6楼: 博主的代码可以兼容32和64位进程,但是稳定性方面的问题,有时会崩溃.
----------------------------------------------
按此在新窗口浏览图片
作者:
男 janker (janker) ★☆☆☆☆ -
盒子活跃会员
2019/6/14 23:41:39
7楼: xuchuantao (暗黑天使)
大侠,是泉州的?
----------------------------------------------
-
作者:
男 xuchuantao (暗黑天使) ▲▲▲▲△ -
注册会员
2019/6/15 14:38:58
8楼: 我是桂林阳朔的
----------------------------------------------
按此在新窗口浏览图片
作者:
男 janker (janker) ★☆☆☆☆ -
盒子活跃会员
2019/6/15 22:06:23
9楼: 哈哈,误会了,大侠你这个是什么?
此帖子包含附件:
PNG 图像
大小:12.5K
----------------------------------------------
-
作者:
男 cenunus (cenunus) ▲▲▲▲▲ -
注册会员
2019/6/15 23:00:54
10楼: 感谢 xuchuantao ,代码测试有效!
----------------------------------------------
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2019/6/17 0:35:49
11楼: 这个代码一看就有问题。肯定不稳定。
结构翻译全部有问题。
----------------------------------------------
--
作者:
男 xuchuantao (暗黑天使) ▲▲▲▲△ -
注册会员
2019/6/17 19:25:44
12楼: 楼上的你的对64位进程无效,别以为别人不会去测试。
----------------------------------------------
按此在新窗口浏览图片
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v2.1 版权所有 页面执行31.25毫秒 RSS