Reputation: 1099
I have successfully wrote a script to get memory consumption (TProcessMemoryCounters) of any process. However I need to run my program elevated (run as admin) in order to get these information for some system or elevated process (otherwise OpenProcess
returns ERROR_ACCESS_DENIED). Programs like Process Explorer didn't need elevated mode.
My script to get memory information of a process:
function GetProcessMemory(ProcID: Cardinal): Cardinal;
var
MemCounters: TProcessMemoryCounters;
HProc: THandle;
begin
Result:= 0;
HProc:= OpenProcess(
PROCESS_QUERY_LIMITED_INFORMATION //or SYNCHRONIZE
, False, ProcID);
//HProc: 5 = ERROR_ACCESS_DENIED
if GetProcessMemoryInfo(HProc, @MemCounters, SizeOf(TProcessMemoryCounters)) then
Result :=
MemCounters.WorkingSetSize;
end;
With the following script I got memory information for all process, but still my program needs to be elevated:
function EnableDebugPriv(): Boolean;
const
SE_DEBUG_NAME = 'SeDebugPrivilege';
var
HToken: NativeUInt;
LUID: Int64;
Tkp: TTokenPrivileges;
AA: Cardinal;
begin
OpenProcessToken(GetCurrentProcess,
TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,
HToken
);
LookupPrivilegeValue(nil, SE_DEBUG_NAME, LUID);
Tkp.PrivilegeCount:= 1;
Tkp.Privileges[0].Luid:= LUID;
Tkp.Privileges[0].Attributes:= SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(HToken, False, Tkp, SizeOf(Tkp), nil, AA);
CloseHandle(HToken);
end;
Q: How to make my script get memory information of all process (include systems) without elevated mode?
Upvotes: 0
Views: 864
Reputation: 595349
To use GetProcessMemoryInfo()
, you must specify the PROCESS_VM_READ
access right as well, as stated by the documentation:
Process
A handle to the process. The handle must have the
PROCESS_QUERY_INFORMATION
orPROCESS_QUERY_LIMITED_INFORMATION
access right and thePROCESS_VM_READ
access right. For more information, see Process Security and Access Rights.Windows Server 2003 and Windows XP: The handle must have the
PROCESS_QUERY_INFORMATION
andPROCESS_VM_READ
access rights.
You are also leaking the handle if it were able to be opened successfully.
Try this instead:
function GetProcessMemory(ProcID: DWORD): DWORD;
var
MemCounters: TProcessMemoryCounters;
HProc: THandle;
begin
Result := 0;
HProc := OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION or PROCESS_VM_READ, False, ProcID);
if HProc <> 0 then
begin
if GetProcessMemoryInfo(HProc, @MemCounters, SizeOf(TProcessMemoryCounters)) then
Result := MemCounters.WorkingSetSize;
CloseHandle(HProc);
end;
end;
Upvotes: 2