Skip to content

Instantly share code, notes, and snippets.

@KunYi
Created January 12, 2021 11:56
Show Gist options
  • Select an option

  • Save KunYi/7dc997ae005ebb4aaea7cb563b80cfd2 to your computer and use it in GitHub Desktop.

Select an option

Save KunYi/7dc997ae005ebb4aaea7cb563b80cfd2 to your computer and use it in GitHub Desktop.
System reserved memory analysis on Windows
// System reserved memory analysis on Windows.cpp : Defines the entry point for the console application.
// the code from http://www.lab-z.com/revmem/
#include "stdafx.h"
#include <Windows.h>
#include <strsafe.h>
#include <tchar.h>
HKEY m_hKey;
#define OffSet(type, field) ((size_t)&(((type*)0)->field))
#pragma pack(1)
//
// Physical address.
//
typedef LARGE_INTEGER PHYSICAL_ADDRESS, *PPHYSICAL_ADDRESS;
typedef struct _CM_PARTIAL_RESOURCE_DESCRIPTOR {
UCHAR Type;
UCHAR ShareDisposition;
USHORT Flags;
union {
//
// Range of resources, inclusive. These are physical, bus relative.
// It is known that Port and Memory below have the exact same layout
// as Generic.
//
struct {
PHYSICAL_ADDRESS Start;
ULONG Length;
} Generic;
//
//
struct {
PHYSICAL_ADDRESS Start;
ULONG Length;
} Port;
//
//
struct {
#if defined(NT_PROCESSOR_GROUPS)
USHORT Level;
USHORT Group;
#else
ULONG Level;
#endif
ULONG Vector;
KAFFINITY Affinity;
} Interrupt;
//
// Values for message signaled interrupts are distinct in the
// raw and translated cases.
//
struct {
union {
struct {
#if defined(NT_PROCESSOR_GROUPS)
USHORT Group;
#else
USHORT Reserved;
#endif
USHORT MessageCount;
ULONG Vector;
KAFFINITY Affinity;
} Raw;
struct {
#if defined(NT_PROCESSOR_GROUPS)
USHORT Level;
USHORT Group;
#else
ULONG Level;
#endif
ULONG Vector;
KAFFINITY Affinity;
} Translated;
} DUMMYUNIONNAME;
} MessageInterrupt;
//
// Range of memory addresses, inclusive. These are physical, bus
// relative. The value should be the same as the one passed to
// HalTranslateBusAddress().
//
struct {
PHYSICAL_ADDRESS Start; // 64 bit physical addresses.
ULONG Length;
} Memory;
//
// Physical DMA channel.
//
struct {
ULONG Channel;
ULONG Port;
ULONG Reserved1;
} Dma;
struct {
ULONG Channel;
ULONG RequestLine;
UCHAR TransferWidth;
UCHAR Reserved1;
UCHAR Reserved2;
UCHAR Reserved3;
} DmaV3;
//
// Device driver private data, usually used to help it figure
// what the resource assignments decisions that were made.
//
struct {
ULONG Data[3];
} DevicePrivate;
//
// Bus Number information.
//
struct {
ULONG Start;
ULONG Length;
ULONG Reserved;
} BusNumber;
//
// Device Specific information defined by the driver.
// The DataSize field indicates the size of the data in bytes. The
// data is located immediately after the DeviceSpecificData field in
// the structure.
//
struct {
ULONG DataSize;
ULONG Reserved1;
ULONG Reserved2;
} DeviceSpecificData;
// The following structures provide support for memory-mapped
// IO resources greater than MAXULONG
struct {
PHYSICAL_ADDRESS Start;
ULONG Length40;
} Memory40;
struct {
PHYSICAL_ADDRESS Start;
ULONG Length48;
} Memory48;
struct {
PHYSICAL_ADDRESS Start;
ULONG Length64;
} Memory64;
struct {
UCHAR Class;
UCHAR Type;
UCHAR Reserved1;
UCHAR Reserved2;
ULONG IdLowPart;
ULONG IdHighPart;
} Connection;
} u;
} CM_PARTIAL_RESOURCE_DESCRIPTOR, *PCM_PARTIAL_RESOURCE_DESCRIPTOR;
//
// A Partial Resource List is what can be found in the ARC firmware
// or will be generated by ntdetect.com.
// The configuration manager will transform this structure into a Full
// resource descriptor when it is about to store it in the regsitry.
//
// Note: There must a be a convention to the order of fields of same type,
// (defined on a device by device basis) so that the fields can make sense
// to a driver (i.e. when multiple memory ranges are necessary).
//
typedef struct _CM_PARTIAL_RESOURCE_LIST {
USHORT Version;
USHORT Revision;
ULONG Count;
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1];
} CM_PARTIAL_RESOURCE_LIST, *PCM_PARTIAL_RESOURCE_LIST;
//
// Define the I/O bus interface types.
//
typedef enum _INTERFACE_TYPE {
InterfaceTypeUndefined = -1,
Internal,
Isa,
Eisa,
MicroChannel,
TurboChannel,
PCIBus,
VMEBus,
NuBus,
PCMCIABus,
CBus,
MPIBus,
MPSABus,
ProcessorInternal,
InternalPowerBus,
PNPISABus,
PNPBus,
Vmcs,
ACPIBus,
MaximumInterfaceType
}INTERFACE_TYPE, *PINTERFACE_TYPE;
//
// A Full Resource Descriptor is what can be found in the registry.
// This is what will be returned to a driver when it queries the registry
// to get device information; it will be stored under a key in the hardware
// description tree.
//
// Note: There must a be a convention to the order of fields of same type,
// (defined on a device by device basis) so that the fields can make sense
// to a driver (i.e. when multiple memory ranges are necessary).
//
typedef struct _CM_FULL_RESOURCE_DESCRIPTOR {
INTERFACE_TYPE InterfaceType; // unused for WDM
ULONG BusNumber; // unused for WDM
CM_PARTIAL_RESOURCE_LIST PartialResourceList;
} CM_FULL_RESOURCE_DESCRIPTOR, *PCM_FULL_RESOURCE_DESCRIPTOR;
//
// The Resource list is what will be stored by the drivers into the
// resource map via the IO API.
//
typedef struct _CM_RESOURCE_LIST {
ULONG Count;
CM_FULL_RESOURCE_DESCRIPTOR List[1];
} CM_RESOURCE_LIST, *PCM_RESOURCE_LIST;
int main()
{
DWORD Index;
BYTE *v;
if (RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
TEXT("HARDWARE\\RESOURCEMAP\\System Resources\\Loader Reserved"),
0,
KEY_READ,
&m_hKey) != ERROR_SUCCESS)
{
printf("RegOpenKeyEx fail \n");
getchar();
exit(0);
}
BOOL bRet = FALSE;
LPSTR lpstrValue;
DWORD dwType = REG_SZ;
DWORD lpcbData;
DWORD r;
r = RegQueryValueEx(m_hKey,
TEXT(".Raw"),
NULL,
&dwType,
NULL,
&lpcbData);
if (r != ERROR_SUCCESS)
{
printf("Can't get data from registry\n");
getchar();
exit(0);
}
bRet = FALSE;
lpstrValue = (LPSTR)malloc(lpcbData);
r = RegQueryValueEx(m_hKey,
TEXT(".Raw"),
NULL,
&dwType,
(BYTE*)(LPCTSTR)lpstrValue,
&lpcbData);
if (r != ERROR_SUCCESS)
{
printf("fail\n");
getchar();
exit(0);
}
for (Index = 0; Index < lpcbData; Index++) {
if (Index % 16 == 0) { printf("\n"); }
v = (BYTE*)lpstrValue;
printf("%02X ", *(v + Index));
}
PCM_RESOURCE_LIST res= (PCM_RESOURCE_LIST)lpstrValue;
PCM_PARTIAL_RESOURCE_LIST Partial;
DWORD Index1;
for (Index = 0; Index < res->Count; Index++)
{
printf("\nInteface type: %d\n Bus Number: %d\n",
res->List[Index].InterfaceType,
res->List[Index].BusNumber);
Partial = (PCM_PARTIAL_RESOURCE_LIST) &res->List[Index].PartialResourceList;
printf(" Version: %d\n Revision: %d\n Counter: %x\n",
Partial->Version,
Partial->Revision,
Partial->Count);
for (Index1 = 0; Index1 < Partial->Count; Index1++) {
//printf("%d\n", Partial->PartialDescriptors[Index1].Type);
if (Partial->PartialDescriptors[Index1].Type == 3) {
printf("Start:%016I64x Length:%x \n",
Partial->PartialDescriptors[Index1].u.Memory.Start,
Partial->PartialDescriptors[Index1].u.Memory.Length
);
}
}
}
free(lpstrValue);
getchar();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment