Многие Win32 API предназначены для того, чтобы сообщать вам правильный размер буфера, вызывая его с нулевым указателем и задавая 0 для ReturnLength. Nt API обычно работают немного по-другому:
Вы просто передаете ему буфер произвольного размера, и он сообщит вам, если он хочет большего, возвращая STATUS_INFO_LENGTH_MISMATCH
.
Я также рекомендую использовать библиотеку Jedi Api вместо того, чтобы переводить функции / заголовки (Nt Api) самостоятельно.
EDIT : Похоже, вы пытаетесь прочитать класс ProcessBasicInformation, который имеет фиксированный размер и не возвращает указатель на PEB, но указатель на PROCESS_BASIC_INFORMATION
struct / record.
Вот пример того, что вы пытаетесь сделать:
// uses JwaNative
function TDebugThread.ReadPEB: Boolean;
var
nts: NTSTATUS;
pbi: PROCESS_BASIC_INFORMATION;
dwBytes: DWORD;
begin
Result := False;
nts := NtQueryInformationProcess(pi.hProcess,
ProcessBasicInformation, @pbi, SizeOf(pbi), @dwBytes);
if nts <> STATUS_SUCCESS then
Exit;
New(PEB);
Result := ReadProcessMemory(pi.hProcess, pbi.PebBaseAddress, PEB, SizeOf(PEB^),
@dwBytes);
end;
Ниже приведен пример использования NtQuerySystemInformation
(полный пример можно найти в моем GitHub хранилище ).
{ TProcessList }
constructor TProcessList.Create(const AOwnsObjects: Boolean = True);
var
Current: PSystemProcesses;
SystemProcesses : PSystemProcesses;
dwSize: DWORD;
nts: NTSTATUS;
begin
inherited Create(AOwnsObjects);
dwSize := 200000;
SystemProcesses := AllocMem(dwSize);
nts := NtQuerySystemInformation(SystemProcessesAndThreadsInformation,
SystemProcesses, dwSize, @dwSize);
while nts = STATUS_INFO_LENGTH_MISMATCH do
begin
ReAllocMem(SystemProcesses, dwSize);
nts := NtQuerySystemInformation(SystemProcessesAndThreadsInformation,
SystemProcesses, dwSize, @dwSize);
end;
if nts = STATUS_SUCCESS then
begin
Current := SystemProcesses;
while True do
begin
Self.Add(TProcess.Create(Current^));
if Current^.NextEntryDelta = 0 then
Break;
Current := PSYSTEM_PROCESSES(DWORD_PTR(Current) + Current^.NextEntryDelta);
end;
end;
FreeMem(SystemProcesses);
end;
Редактировать : чтобы ответить на комментарий @ScienceAmateur, следующий тестовый код всегда возвращает 0 для ReturnLength:
uses
Windows,
System.SysUtils,
Rtti,
JwaNative,
JwaWinType,
JwaNtSecApi,
JwaNtStatus;
function NtStatusErrorMessage(const nts: NTSTATUS): String;
begin
Result := SysErrorMessage(LsaNtStatusToWinError(nts));
end;
var
nts: NTSTATUS;
pic: PROCESS_INFORMATION_CLASS;
Buffer: Pointer;
pil: DWORD;
ReturnLength: DWORD;
begin
for pic := Low(PROCESS_INFORMATION_CLASS) to High(PROCESS_INFORMATION_CLASS) do
begin
Buffer := nil;
pil := 0;
ReturnLength := 0;
nts := NtQueryInformationProcess(GetCurrentProcess,
ProcessBasicInformation, Buffer, pil, @ReturnLength);
WriteLn(Format('%s: returned 0x%.8x and ReturnLength: %d', [TRttiEnumerationType.GetName(pic), nts, ReturnLength]));
end;
WriteLn('Finished.');
if DebugHook <> 0 then
ReadLn;
Выход:
ProcessBasicInformation: returned 0xC0000004 and ReturnLength: 0
ProcessQuotaLimits: returned 0xC0000004 and ReturnLength: 0
ProcessIoCounters: returned 0xC0000004 and ReturnLength: 0
ProcessVmCounters: returned 0xC0000004 and ReturnLength: 0
ProcessTimes: returned 0xC0000004 and ReturnLength: 0
ProcessBasePriority: returned 0xC0000004 and ReturnLength: 0
ProcessRaisePriority: returned 0xC0000004 and ReturnLength: 0
ProcessDebugPort: returned 0xC0000004 and ReturnLength: 0
ProcessExceptionPort: returned 0xC0000004 and ReturnLength: 0
ProcessAccessToken: returned 0xC0000004 and ReturnLength: 0
ProcessLdtInformation: returned 0xC0000004 and ReturnLength: 0
ProcessLdtSize: returned 0xC0000004 and ReturnLength: 0
ProcessDefaultHardErrorMode: returned 0xC0000004 and ReturnLength: 0
ProcessIoPortHandlers: returned 0xC0000004 and ReturnLength: 0
ProcessPooledUsageAndLimits: returned 0xC0000004 and ReturnLength: 0
ProcessWorkingSetWatch: returned 0xC0000004 and ReturnLength: 0
ProcessUserModeIOPL: returned 0xC0000004 and ReturnLength: 0
ProcessEnableAlignmentFaultFixup: returned 0xC0000004 and ReturnLength: 0
ProcessPriorityClass: returned 0xC0000004 and ReturnLength: 0
ProcessWx86Information: returned 0xC0000004 and ReturnLength: 0
ProcessHandleCount: returned 0xC0000004 and ReturnLength: 0
ProcessAffinityMask: returned 0xC0000004 and ReturnLength: 0
ProcessPriorityBoost: returned 0xC0000004 and ReturnLength: 0
ProcessDeviceMap: returned 0xC0000004 and ReturnLength: 0
ProcessSessionInformation: returned 0xC0000004 and ReturnLength: 0
ProcessForegroundInformation: returned 0xC0000004 and ReturnLength: 0
ProcessWow64Information: returned 0xC0000004 and ReturnLength: 0
ProcessImageFileName: returned 0xC0000004 and ReturnLength: 0
ProcessLUIDDeviceMapsEnabled: returned 0xC0000004 and ReturnLength: 0
ProcessBreakOnTermination: returned 0xC0000004 and ReturnLength: 0
ProcessDebugObjectHandle: returned 0xC0000004 and ReturnLength: 0
ProcessDebugFlags: returned 0xC0000004 and ReturnLength: 0
ProcessHandleTracing: returned 0xC0000004 and ReturnLength: 0
MaxProcessInfoClass: returned 0xC0000004 and ReturnLength: 0