Created
March 28, 2023 00:35
-
-
Save skissane/210359e4645edbc19a93998cc4009d2b to your computer and use it in GitHub Desktop.
Tool to dump CallNtPowerInformation(GetPowerRequestList) results
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define _WIN32_WINNT 0x0602 | |
#define UMDF_USING_NTSTATUS | |
#include <stdio.h> | |
#include <windows.h> | |
#include <powerbase.h> | |
#include <stdbool.h> | |
#include <ntstatus.h> | |
#include <shlobj.h> | |
#pragma comment(lib, "PowrProf.lib") | |
typedef NTSTATUS PowerInformationWithPrivileges_t( | |
POWER_INFORMATION_LEVEL InformationLevel, | |
PVOID InputBuffer, | |
ULONG InputBufferLength, | |
PVOID OutputBuffer, | |
ULONG OutputBufferLength | |
); | |
static PowerInformationWithPrivileges_t* PowerInformationWithPrivileges = NULL; | |
NTSTATUS QueryPowerInformationLevel(POWER_INFORMATION_LEVEL InformationLevel, void** OutBuf, ULONG* OutSize) { | |
if (PowerInformationWithPrivileges == NULL) { | |
// Call LoadModule to load powrprof.dll | |
HMODULE hPowrProf = LoadLibraryA("powrprof.dll"); | |
if (hPowrProf == NULL) { | |
printf("ERROR: LoadLibraryA(\"powrprof.dll\") failed with error %d\n", GetLastError()); | |
return STATUS_UNSUCCESSFUL; | |
} | |
// Use GetProcAddress to get PowerInformationWithPrivileges function from hPowrProf | |
// and stick it in PowerInformationWithPrivileges global variable | |
PowerInformationWithPrivileges = (PowerInformationWithPrivileges_t*)GetProcAddress(hPowrProf, "PowerInformationWithPrivileges"); | |
if (PowerInformationWithPrivileges == NULL) { | |
printf("ERROR: GetProcAddress(\"PowerInformationWithPrivileges\") failed with error %d\n", GetLastError()); | |
return STATUS_UNSUCCESSFUL; | |
} | |
} | |
if (OutSize != NULL) *OutSize = 0; | |
ULONG OutputBufferLength = 0x40; | |
PVOID OutputBuffer = malloc(OutputBufferLength); | |
if (OutputBuffer == NULL) { | |
printf("ERROR: malloc() could not allocate %lu bytes\n", OutputBufferLength); | |
return STATUS_NO_MEMORY; | |
} | |
while (true) { | |
NTSTATUS status = PowerInformationWithPrivileges(InformationLevel, NULL, 0, OutputBuffer, OutputBufferLength); | |
if (status == STATUS_BUFFER_TOO_SMALL) { | |
// Resize the buffer | |
OutputBufferLength *= 2; | |
PVOID NewOutputBuffer = realloc(OutputBuffer, OutputBufferLength); | |
if (NewOutputBuffer == NULL) { | |
printf("ERROR: realloc() could not resize the buffer to %lu bytes\n", OutputBufferLength); | |
free(OutputBuffer); | |
return STATUS_NO_MEMORY; | |
} | |
OutputBuffer = NewOutputBuffer; | |
} | |
else if (status == STATUS_SUCCESS) { | |
if (OutSize != NULL) *OutSize = OutputBufferLength; | |
*OutBuf = OutputBuffer; | |
return status; | |
} | |
else { | |
free(OutputBuffer); | |
return status; | |
} | |
} | |
} | |
int main(int argc, char* argv[]) { | |
printf("GetPowerRequestList tool\n\n"); | |
if (!IsUserAnAdmin()) { | |
printf("ERROR: You must run this program as an administrator\n"); | |
return 1; | |
} | |
void* OutBuf = NULL; | |
ULONG OutSize = 0; | |
NTSTATUS status = QueryPowerInformationLevel(GetPowerRequestList, &OutBuf, &OutSize); | |
if (status != STATUS_SUCCESS) { | |
printf("ERROR: GetPowerRequestList failed with status=%08x\n", status); | |
return 1; | |
} | |
SIZE_T* count = (SIZE_T*)OutBuf; | |
printf("GetPowerRequestList entry count=%zu\n", count[0]); | |
for (int i = 0; i < count[0]; i++) { | |
SIZE_T startOffset = count[i + 1]; | |
SIZE_T endOffset = i == count[0] - 1 ? OutSize : count[i + 2]; | |
SIZE_T size = endOffset - startOffset; | |
printf("GetPowerRequestList entry %d: startOffset=%zu endOffset=%zu size=%zu\n", | |
i, startOffset, endOffset, size); | |
// Dump all text found in entry | |
printf("\t["); | |
WCHAR* ptr = (WCHAR*)((SIZE_T)OutBuf + startOffset); | |
bool spaceOut = true; | |
for (int j = 0; j < (size / 2); j++) { | |
int ch = ptr[j]; | |
if (ch > 0x20 && ch < 0x7f) { | |
spaceOut = false; | |
printf("%c", ptr[j]); | |
} | |
else if (!spaceOut) { | |
printf(" "); | |
spaceOut = true; | |
} | |
} | |
printf("]\n"); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment