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),望大侠们有空帮忙看看,谢谢!
----------------------------------------------
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;
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;
----------------------------------------------