Created
January 12, 2021 11:56
-
-
Save KunYi/7dc997ae005ebb4aaea7cb563b80cfd2 to your computer and use it in GitHub Desktop.
System reserved memory analysis on Windows
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
| // 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