ntquerysysteminformtion and it's struct - size not mismatch and other doubts


Hello

I'm curious why the API ntquerysysteminformtion return size that is different from the sum of all nextEntryOffsets. I call the API with a SYSTEM_PROCESS_INFORMATION structure, and it returns the size of the struct populated as expected.

However if I loop into all entries and sum the NextEntryOffset and do a comparison with the size returned with the API it never mismatch.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//call to API

int sum = 0;
pCurrent = nullptr;
pfw = (_SYSTEM_PROCESS_INFORMATION*)si;

do {

            pCurrent = pfw;
            pfw = (_SYSTEM_PROCESS_INFORMATION*)((PUCHAR)pCurrent + pfw->NextEntryOffset);

           sum += pCurrent->NextEntryOffset;

} while (pCurrent->NextEntryOffset != 0);


If I print the value of sum variable and length returned by API they are always not equal.

How to discover / calculate the correct size of each entry if there is no field on the structure for this? My guess is that it's not working because on the last entry the NextEntryOffset is null, but this is weird, because I dont see a way to calculate the real size of each entry without just believe on the returned length. I guess that there is a way, right?

I was reading unofficial documentation and it describe that the start of its output buffer and irregularly throughout the buffer when given specific information classes like mine. I don't understand how it work, but I assume that for example if there is an pointer to another structure this pointer size + the size of the data or other struct pointed is calculated as part of the total size which may be dynamically, correct?

I also tried see if the field offsets works as expected on this unoffical documentation, but I failed to access it contents. It work for example to see the supposed address of UniqueProcessId, however I can't find a way to see the value inside this address to confirm.

1
2
PVOID tmp = pCurrent + 0x50;
wprintf(L"ID: %d", *tmp);


It fails. I can call the structure like pCurrent.UniqueProcessId and it works. But how to move on the data without depends on the struct? Examples codes are very welcome.

Thank so much.
Last edited on
Topic archived. No new replies allowed.