├── .gitignore ├── README.md ├── Release.7z ├── VisualUefi-master.zip ├── dist ├── bootx64.efi ├── pipe │ ├── PacketDotNet.dll │ ├── SharpPcap.dll │ ├── System.Buffers.dll │ ├── System.Buffers.xml │ ├── System.Memory.dll │ ├── System.Memory.xml │ ├── System.Numerics.Vectors.dll │ ├── System.Numerics.Vectors.xml │ ├── System.Runtime.CompilerServices.Unsafe.dll │ ├── System.Runtime.CompilerServices.Unsafe.xml │ ├── System.Text.Encoding.CodePages.dll │ ├── System.Text.Encoding.CodePages.xml │ ├── pipe.exe │ └── pipe.exe.config ├── startup.nsh ├── windbg.efi ├── windbg.pdb └── wireshark │ ├── gcrypt.dll │ ├── kdnet.lua │ └── luagcrypt.dll ├── ext ├── edk2-hv-net.7z.001 ├── edk2-hv-net.7z.002 ├── edk2-hv-net.7z.003 └── luagcrypt │ ├── libgcrypt_libgcrypt-1.10.3-1_msvc16.zip │ ├── libgcrypt_libgcrypt-1.10.3-1_msvc16 │ ├── include │ │ ├── gcrypt.h │ │ └── gpg-error.h │ ├── libgcrypt.pdb │ └── licenses │ │ ├── libgcrypt.txt │ │ └── libgpg-error.txt │ ├── lua-5.2_Win64_dll10_lib.zip │ ├── lua-5.2_Win64_dll10_lib │ ├── include │ │ ├── lauxlib.h │ │ ├── lua.h │ │ ├── lua.hpp │ │ ├── luaconf.h │ │ └── lualib.h │ └── lua52.dll │ ├── luagcrypt.sln │ └── luagcrypt │ ├── Source.def │ ├── luagcrypt.c │ ├── luagcrypt.vcxproj │ └── luagcrypt.vcxproj.filters ├── img ├── hv.png ├── windbg.png └── wireshark.png ├── pipe ├── pipe.sln └── pipe │ ├── App.config │ ├── NativeMethods.cs │ ├── PacketWriter.cs │ ├── Program.cs │ ├── Properties │ └── AssemblyInfo.cs │ ├── Utils.cs │ ├── WiresharkSender.cs │ ├── WmiScope.cs │ ├── packages.config │ └── pipe.csproj └── windbg ├── FtdiUsbSerialDxe ├── AutoGen.c ├── AutoGen1.c ├── DebugAgent.c ├── DebugAgent.h ├── DebugAgentDxe.c ├── DebugCommunicationLibSerialPort.c ├── DebugMp.c ├── DebugMp.h ├── DebugTimer.c ├── DebugTimer.h ├── FtdiUsbSerialDxe.vcxproj ├── Interrupt.asm ├── PEHelper.c ├── PEHelper.h ├── VsGlue.c ├── hvapi.c ├── kddll.h ├── ke.h ├── ketypes.h ├── vmbusdxe.c ├── wdbgexts.h ├── windbg.c └── windbgkd.h ├── GSStub.c ├── Library └── DebugCommunicationLib.h ├── UefiApplication ├── UefiApplication.vcxproj ├── hv.asm ├── hvapp.c ├── utils.c ├── vmbus.c └── windbgplugin.c ├── UefiDriver ├── UefiDriver.vcxproj ├── drvproto.h ├── ntint.h ├── shv.c ├── shv.h ├── shv_x.h ├── shvutil.c ├── shvvmx.c ├── shvvmxhv.c ├── shvvmxhvx64.asm ├── shvvp.c ├── uefi │ ├── shvos.c │ ├── shvosx64.asm │ ├── simplevisor.inf │ ├── uefi.default.props │ └── uefi.props └── vmx.h ├── apic-defs.h ├── hvdev.h ├── hvgdk.h ├── poc.default.props ├── poc.props ├── poc.sln ├── registers.h ├── rtlfuncs.h ├── uefiintsafe.h ├── utils.h └── windbg.h /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | [Xx]64/ 19 | [Xx]86/ 20 | [Bb]uild/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | scmrev.h 25 | 26 | # Make it possible to keep a local copy of the sacred IDA SDK 27 | # without accidentally committing it and receiving a takedown request 28 | # as a thank you for helping to expand the IDA plugin ecosystem 29 | 3rdparty/idasdk/ 30 | 31 | # Visual Studio 2015 cache/options directory 32 | .vs/ 33 | # Uncomment if you have tasks that create the project's static files in wwwroot 34 | #wwwroot/ 35 | 36 | # MSTest test Results 37 | [Tt]est[Rr]esult*/ 38 | [Bb]uild[Ll]og.* 39 | 40 | # NUNIT 41 | *.VisualState.xml 42 | TestResult.xml 43 | 44 | # Build Results of an ATL Project 45 | [Dd]ebugPS/ 46 | [Rr]eleasePS/ 47 | dlldata.c 48 | 49 | # DNX 50 | project.lock.json 51 | artifacts/ 52 | 53 | *_i.c 54 | *_p.c 55 | *_i.h 56 | *.ilk 57 | *.meta 58 | *.obj 59 | *.pch 60 | *.pgc 61 | *.pgd 62 | *.rsp 63 | *.sbr 64 | *.tlb 65 | *.tli 66 | *.tlh 67 | *.tmp 68 | *.tmp_proj 69 | *.log 70 | *.vspscc 71 | *.vssscc 72 | .builds 73 | *.pidb 74 | *.svclog 75 | *.scc 76 | 77 | # Chutzpah Test files 78 | _Chutzpah* 79 | 80 | # Visual C++ cache files 81 | ipch/ 82 | *.aps 83 | *.ncb 84 | *.opendb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | *.VC.db 89 | 90 | # Visual Studio profiler 91 | *.psess 92 | *.vsp 93 | *.vspx 94 | *.sap 95 | 96 | # TFS 2012 Local Workspace 97 | $tf/ 98 | 99 | # Guidance Automation Toolkit 100 | *.gpState 101 | 102 | # ReSharper is a .NET coding add-in 103 | _ReSharper*/ 104 | *.[Rr]e[Ss]harper 105 | *.DotSettings.user 106 | 107 | # JustCode is a .NET coding add-in 108 | .JustCode 109 | 110 | # TeamCity is a build add-in 111 | _TeamCity* 112 | 113 | # DotCover is a Code Coverage Tool 114 | *.dotCover 115 | 116 | # NCrunch 117 | _NCrunch_* 118 | .*crunch*.local.xml 119 | nCrunchTemp_* 120 | 121 | # MightyMoose 122 | *.mm.* 123 | AutoTest.Net/ 124 | 125 | # Web workbench (sass) 126 | .sass-cache/ 127 | 128 | # Installshield output folder 129 | [Ee]xpress/ 130 | 131 | # DocProject is a documentation generator add-in 132 | DocProject/buildhelp/ 133 | DocProject/Help/*.HxT 134 | DocProject/Help/*.HxC 135 | DocProject/Help/*.hhc 136 | DocProject/Help/*.hhk 137 | DocProject/Help/*.hhp 138 | DocProject/Help/Html2 139 | DocProject/Help/html 140 | 141 | # Click-Once directory 142 | publish/ 143 | 144 | # Publish Web Output 145 | *.[Pp]ublish.xml 146 | *.azurePubxml 147 | 148 | # TODO: Un-comment the next line if you do not want to checkin 149 | # your web deploy settings because they may include unencrypted 150 | # passwords 151 | #*.pubxml 152 | *.publishproj 153 | 154 | # NuGet Packages 155 | *.nupkg 156 | # The packages folder can be ignored because of Package Restore 157 | **/packages/* 158 | # except build/, which is used as an MSBuild target. 159 | !**/packages/build/ 160 | # Uncomment if necessary however generally it will be regenerated when needed 161 | #!**/packages/repositories.config 162 | # NuGet v3's project.json files produces more ignoreable files 163 | *.nuget.props 164 | *.nuget.targets 165 | 166 | # Microsoft Azure Build Output 167 | csx/ 168 | *.build.csdef 169 | 170 | # Microsoft Azure Emulator 171 | ecf/ 172 | rcf/ 173 | 174 | # Windows Store app package directory 175 | AppPackages/ 176 | BundleArtifacts/ 177 | 178 | # Visual Studio cache files 179 | # files ending in .cache can be ignored 180 | *.[Cc]ache 181 | # but keep track of directories ending in .cache 182 | !*.[Cc]ache/ 183 | 184 | # Others 185 | ClientBin/ 186 | [Ss]tyle[Cc]op.* 187 | ~$* 188 | *~ 189 | *.dbmdl 190 | *.dbproj.schemaview 191 | *.pfx 192 | *.publishsettings 193 | node_modules/ 194 | orleans.codegen.cs 195 | 196 | # RIA/Silverlight projects 197 | Generated_Code/ 198 | 199 | # Backup & report files from converting an old project file 200 | # to a newer Visual Studio version. Backup files are not needed, 201 | # because we have git ;-) 202 | _UpgradeReport_Files/ 203 | Backup*/ 204 | UpgradeLog*.XML 205 | UpgradeLog*.htm 206 | 207 | # SQL Server files 208 | *.mdf 209 | *.ldf 210 | 211 | # Business Intelligence projects 212 | *.rdl.data 213 | *.bim.layout 214 | *.bim_*.settings 215 | 216 | # Microsoft Fakes 217 | FakesAssemblies/ 218 | 219 | # GhostDoc plugin setting file 220 | *.GhostDoc.xml 221 | 222 | # Node.js Tools for Visual Studio 223 | .ntvs_analysis.dat 224 | 225 | # Visual Studio 6 build log 226 | *.plg 227 | 228 | # Visual Studio 6 workspace options file 229 | *.opt 230 | 231 | # Visual Studio LightSwitch build output 232 | **/*.HTMLClient/GeneratedArtifacts 233 | **/*.DesktopClient/GeneratedArtifacts 234 | **/*.DesktopClient/ModelManifest.xml 235 | **/*.Server/GeneratedArtifacts 236 | **/*.Server/ModelManifest.xml 237 | _Pvt_Extensions 238 | 239 | # LightSwitch generated files 240 | GeneratedArtifacts/ 241 | ModelManifest.xml 242 | 243 | # Paket dependency manager 244 | .paket/paket.exe 245 | 246 | # FAKE - F# Make 247 | .fake/ 248 | 249 | # ========================= 250 | # Windows detritus 251 | # ========================= 252 | 253 | # Windows image file caches 254 | Thumbs.db 255 | ehthumbs.db 256 | 257 | # Folder config file 258 | Desktop.ini 259 | 260 | # Recycle Bin used on file shares 261 | $RECYCLE.BIN/ 262 | 263 | # Mac crap 264 | .DS_Store 265 | *.depend 266 | *.lib 267 | *_*.i64 268 | *_*.idb 269 | *.dmp 270 | System32 271 | registry 272 | *.db -------------------------------------------------------------------------------- /Release.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/Release.7z -------------------------------------------------------------------------------- /VisualUefi-master.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/VisualUefi-master.zip -------------------------------------------------------------------------------- /dist/bootx64.efi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/dist/bootx64.efi -------------------------------------------------------------------------------- /dist/pipe/PacketDotNet.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/dist/pipe/PacketDotNet.dll -------------------------------------------------------------------------------- /dist/pipe/SharpPcap.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/dist/pipe/SharpPcap.dll -------------------------------------------------------------------------------- /dist/pipe/System.Buffers.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/dist/pipe/System.Buffers.dll -------------------------------------------------------------------------------- /dist/pipe/System.Buffers.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | System.Buffers 4 | 5 | 6 | 7 | Provides a resource pool that enables reusing instances of type . 8 | The type of the objects that are in the resource pool. 9 | 10 | 11 | Initializes a new instance of the class. 12 | 13 | 14 | Creates a new instance of the class. 15 | A new instance of the class. 16 | 17 | 18 | Creates a new instance of the class using the specifed configuration. 19 | The maximum length of an array instance that may be stored in the pool. 20 | The maximum number of array instances that may be stored in each bucket in the pool. The pool groups arrays of similar lengths into buckets for faster access. 21 | A new instance of the class with the specified configuration. 22 | 23 | 24 | Retrieves a buffer that is at least the requested length. 25 | The minimum length of the array. 26 | An array of type that is at least minimumLength in length. 27 | 28 | 29 | Returns an array to the pool that was previously obtained using the method on the same instance. 30 | A buffer to return to the pool that was previously obtained using the method. 31 | Indicates whether the contents of the buffer should be cleared before reuse. If clearArray is set to true, and if the pool will store the buffer to enable subsequent reuse, the method will clear the array of its contents so that a subsequent caller using the method will not see the content of the previous caller. If clearArray is set to false or if the pool will release the buffer, the array&#39;s contents are left unchanged. 32 | 33 | 34 | Gets a shared instance. 35 | A shared instance. 36 | 37 | 38 | -------------------------------------------------------------------------------- /dist/pipe/System.Memory.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/dist/pipe/System.Memory.dll -------------------------------------------------------------------------------- /dist/pipe/System.Numerics.Vectors.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/dist/pipe/System.Numerics.Vectors.dll -------------------------------------------------------------------------------- /dist/pipe/System.Runtime.CompilerServices.Unsafe.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/dist/pipe/System.Runtime.CompilerServices.Unsafe.dll -------------------------------------------------------------------------------- /dist/pipe/System.Text.Encoding.CodePages.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/dist/pipe/System.Text.Encoding.CodePages.dll -------------------------------------------------------------------------------- /dist/pipe/System.Text.Encoding.CodePages.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | System.Text.Encoding.CodePages 5 | 6 | 7 | 8 | Provides access to an encoding provider for code pages that otherwise are available only in the desktop .NET Framework. 9 | 10 | 11 | Returns the encoding associated with the specified code page identifier. 12 | The code page identifier of the preferred encoding which the encoding provider may support. 13 | The encoding associated with the specified code page identifier, or if the provider does not support the requested codepage encoding. 14 | 15 | 16 | Returns the encoding associated with the specified code page name. 17 | The code page name of the preferred encoding which the encoding provider may support. 18 | The encoding associated with the specified code page, or if the provider does not support the requested encoding. 19 | 20 | 21 | Returns an array that contains all the encodings that are supported by the . 22 | An array that contains all the supported encodings. 23 | 24 | 25 | Gets an encoding provider for code pages supported in the desktop .NET Framework but not in the current .NET Framework platform. 26 | An encoding provider that allows access to encodings not supported on the current .NET Framework platform. 27 | 28 | 29 | -------------------------------------------------------------------------------- /dist/pipe/pipe.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/dist/pipe/pipe.exe -------------------------------------------------------------------------------- /dist/pipe/pipe.exe.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /dist/startup.nsh: -------------------------------------------------------------------------------- 1 | load -nc fs0:windbg.efi -------------------------------------------------------------------------------- /dist/windbg.efi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/dist/windbg.efi -------------------------------------------------------------------------------- /dist/windbg.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/dist/windbg.pdb -------------------------------------------------------------------------------- /dist/wireshark/gcrypt.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/dist/wireshark/gcrypt.dll -------------------------------------------------------------------------------- /dist/wireshark/luagcrypt.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/dist/wireshark/luagcrypt.dll -------------------------------------------------------------------------------- /ext/edk2-hv-net.7z.001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/ext/edk2-hv-net.7z.001 -------------------------------------------------------------------------------- /ext/edk2-hv-net.7z.002: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/ext/edk2-hv-net.7z.002 -------------------------------------------------------------------------------- /ext/edk2-hv-net.7z.003: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/ext/edk2-hv-net.7z.003 -------------------------------------------------------------------------------- /ext/luagcrypt/libgcrypt_libgcrypt-1.10.3-1_msvc16.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/ext/luagcrypt/libgcrypt_libgcrypt-1.10.3-1_msvc16.zip -------------------------------------------------------------------------------- /ext/luagcrypt/libgcrypt_libgcrypt-1.10.3-1_msvc16/libgcrypt.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/ext/luagcrypt/libgcrypt_libgcrypt-1.10.3-1_msvc16/libgcrypt.pdb -------------------------------------------------------------------------------- /ext/luagcrypt/lua-5.2_Win64_dll10_lib.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/ext/luagcrypt/lua-5.2_Win64_dll10_lib.zip -------------------------------------------------------------------------------- /ext/luagcrypt/lua-5.2_Win64_dll10_lib/include/lauxlib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lauxlib.h,v 1.120 2011/11/29 15:55:08 roberto Exp $ 3 | ** Auxiliary functions for building Lua libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lauxlib_h 9 | #define lauxlib_h 10 | 11 | 12 | #include 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | 18 | 19 | /* extra error code for `luaL_load' */ 20 | #define LUA_ERRFILE (LUA_ERRERR+1) 21 | 22 | 23 | typedef struct luaL_Reg { 24 | const char *name; 25 | lua_CFunction func; 26 | } luaL_Reg; 27 | 28 | 29 | LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver); 30 | #define luaL_checkversion(L) luaL_checkversion_(L, LUA_VERSION_NUM) 31 | 32 | LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); 33 | LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); 34 | LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len); 35 | LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); 36 | LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, 37 | size_t *l); 38 | LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg, 39 | const char *def, size_t *l); 40 | LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg); 41 | LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); 42 | 43 | LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); 44 | LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, 45 | lua_Integer def); 46 | LUALIB_API lua_Unsigned (luaL_checkunsigned) (lua_State *L, int numArg); 47 | LUALIB_API lua_Unsigned (luaL_optunsigned) (lua_State *L, int numArg, 48 | lua_Unsigned def); 49 | 50 | LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); 51 | LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); 52 | LUALIB_API void (luaL_checkany) (lua_State *L, int narg); 53 | 54 | LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); 55 | LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname); 56 | LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname); 57 | LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); 58 | 59 | LUALIB_API void (luaL_where) (lua_State *L, int lvl); 60 | LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); 61 | 62 | LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, 63 | const char *const lst[]); 64 | 65 | LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname); 66 | LUALIB_API int (luaL_execresult) (lua_State *L, int stat); 67 | 68 | /* pre-defined references */ 69 | #define LUA_NOREF (-2) 70 | #define LUA_REFNIL (-1) 71 | 72 | LUALIB_API int (luaL_ref) (lua_State *L, int t); 73 | LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); 74 | 75 | LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename, 76 | const char *mode); 77 | 78 | #define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL) 79 | 80 | LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, 81 | const char *name, const char *mode); 82 | LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); 83 | 84 | LUALIB_API lua_State *(luaL_newstate) (void); 85 | 86 | LUALIB_API int (luaL_len) (lua_State *L, int idx); 87 | 88 | LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, 89 | const char *r); 90 | 91 | LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup); 92 | 93 | LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname); 94 | 95 | LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1, 96 | const char *msg, int level); 97 | 98 | LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, 99 | lua_CFunction openf, int glb); 100 | 101 | /* 102 | ** =============================================================== 103 | ** some useful macros 104 | ** =============================================================== 105 | */ 106 | 107 | 108 | #define luaL_newlibtable(L,l) \ 109 | lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1) 110 | 111 | #define luaL_newlib(L,l) (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) 112 | 113 | #define luaL_argcheck(L, cond,numarg,extramsg) \ 114 | ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) 115 | #define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) 116 | #define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) 117 | #define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) 118 | #define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) 119 | #define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) 120 | #define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) 121 | 122 | #define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) 123 | 124 | #define luaL_dofile(L, fn) \ 125 | (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) 126 | 127 | #define luaL_dostring(L, s) \ 128 | (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) 129 | 130 | #define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) 131 | 132 | #define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) 133 | 134 | #define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL) 135 | 136 | 137 | /* 138 | ** {====================================================== 139 | ** Generic Buffer manipulation 140 | ** ======================================================= 141 | */ 142 | 143 | typedef struct luaL_Buffer { 144 | char *b; /* buffer address */ 145 | size_t size; /* buffer size */ 146 | size_t n; /* number of characters in buffer */ 147 | lua_State *L; 148 | char initb[LUAL_BUFFERSIZE]; /* initial buffer */ 149 | } luaL_Buffer; 150 | 151 | 152 | #define luaL_addchar(B,c) \ 153 | ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \ 154 | ((B)->b[(B)->n++] = (c))) 155 | 156 | #define luaL_addsize(B,s) ((B)->n += (s)) 157 | 158 | LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); 159 | LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz); 160 | LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); 161 | LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); 162 | LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); 163 | LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); 164 | LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz); 165 | LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz); 166 | 167 | #define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE) 168 | 169 | /* }====================================================== */ 170 | 171 | 172 | 173 | /* 174 | ** {====================================================== 175 | ** File handles for IO library 176 | ** ======================================================= 177 | */ 178 | 179 | /* 180 | ** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and 181 | ** initial structure 'luaL_Stream' (it may contain other fields 182 | ** after that initial structure). 183 | */ 184 | 185 | #define LUA_FILEHANDLE "FILE*" 186 | 187 | 188 | typedef struct luaL_Stream { 189 | FILE *f; /* stream (NULL for incompletely created streams) */ 190 | lua_CFunction closef; /* to close stream (NULL for closed streams) */ 191 | } luaL_Stream; 192 | 193 | /* }====================================================== */ 194 | 195 | 196 | 197 | /* compatibility with old module system */ 198 | #if defined(LUA_COMPAT_MODULE) 199 | 200 | LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname, 201 | int sizehint); 202 | LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname, 203 | const luaL_Reg *l, int nup); 204 | 205 | #define luaL_register(L,n,l) (luaL_openlib(L,(n),(l),0)) 206 | 207 | #endif 208 | 209 | 210 | #endif 211 | 212 | 213 | -------------------------------------------------------------------------------- /ext/luagcrypt/lua-5.2_Win64_dll10_lib/include/lua.hpp: -------------------------------------------------------------------------------- 1 | // lua.hpp 2 | // Lua header files for C++ 3 | // <> not supplied automatically because Lua also compiles as C++ 4 | 5 | extern "C" { 6 | #include "lua.h" 7 | #include "lualib.h" 8 | #include "lauxlib.h" 9 | } 10 | -------------------------------------------------------------------------------- /ext/luagcrypt/lua-5.2_Win64_dll10_lib/include/lualib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lualib.h,v 1.43 2011/12/08 12:11:37 roberto Exp $ 3 | ** Lua standard libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lualib_h 9 | #define lualib_h 10 | 11 | #include "lua.h" 12 | 13 | 14 | 15 | LUAMOD_API int (luaopen_base) (lua_State *L); 16 | 17 | #define LUA_COLIBNAME "coroutine" 18 | LUAMOD_API int (luaopen_coroutine) (lua_State *L); 19 | 20 | #define LUA_TABLIBNAME "table" 21 | LUAMOD_API int (luaopen_table) (lua_State *L); 22 | 23 | #define LUA_IOLIBNAME "io" 24 | LUAMOD_API int (luaopen_io) (lua_State *L); 25 | 26 | #define LUA_OSLIBNAME "os" 27 | LUAMOD_API int (luaopen_os) (lua_State *L); 28 | 29 | #define LUA_STRLIBNAME "string" 30 | LUAMOD_API int (luaopen_string) (lua_State *L); 31 | 32 | #define LUA_BITLIBNAME "bit32" 33 | LUAMOD_API int (luaopen_bit32) (lua_State *L); 34 | 35 | #define LUA_MATHLIBNAME "math" 36 | LUAMOD_API int (luaopen_math) (lua_State *L); 37 | 38 | #define LUA_DBLIBNAME "debug" 39 | LUAMOD_API int (luaopen_debug) (lua_State *L); 40 | 41 | #define LUA_LOADLIBNAME "package" 42 | LUAMOD_API int (luaopen_package) (lua_State *L); 43 | 44 | 45 | /* open all previous libraries */ 46 | LUALIB_API void (luaL_openlibs) (lua_State *L); 47 | 48 | 49 | 50 | #if !defined(lua_assert) 51 | #define lua_assert(x) ((void)0) 52 | #endif 53 | 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /ext/luagcrypt/lua-5.2_Win64_dll10_lib/lua52.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/ext/luagcrypt/lua-5.2_Win64_dll10_lib/lua52.dll -------------------------------------------------------------------------------- /ext/luagcrypt/luagcrypt.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.34301.259 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "luagcrypt", "luagcrypt\luagcrypt.vcxproj", "{965998FD-C9DE-4812-8A10-C8189F12FB2A}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {965998FD-C9DE-4812-8A10-C8189F12FB2A}.Debug|x64.ActiveCfg = Debug|x64 17 | {965998FD-C9DE-4812-8A10-C8189F12FB2A}.Debug|x64.Build.0 = Debug|x64 18 | {965998FD-C9DE-4812-8A10-C8189F12FB2A}.Debug|x86.ActiveCfg = Debug|Win32 19 | {965998FD-C9DE-4812-8A10-C8189F12FB2A}.Debug|x86.Build.0 = Debug|Win32 20 | {965998FD-C9DE-4812-8A10-C8189F12FB2A}.Release|x64.ActiveCfg = Release|x64 21 | {965998FD-C9DE-4812-8A10-C8189F12FB2A}.Release|x64.Build.0 = Release|x64 22 | {965998FD-C9DE-4812-8A10-C8189F12FB2A}.Release|x86.ActiveCfg = Release|Win32 23 | {965998FD-C9DE-4812-8A10-C8189F12FB2A}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {EDBADF13-73FA-4DD9-AC87-F20FFE95ACA2} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /ext/luagcrypt/luagcrypt/Source.def: -------------------------------------------------------------------------------- 1 | LIBRARY luagcrypt 2 | EXPORTS 3 | luaopen_luagcrypt -------------------------------------------------------------------------------- /ext/luagcrypt/luagcrypt/luagcrypt.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {965998fd-c9de-4812-8a10-c8189f12fb2a} 25 | luagcrypt 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | DynamicLibrary 50 | false 51 | v142 52 | true 53 | Unicode 54 | Static 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | true 76 | 77 | 78 | false 79 | 80 | 81 | true 82 | 83 | 84 | false 85 | 86 | 87 | 88 | Level3 89 | true 90 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 91 | true 92 | 93 | 94 | Console 95 | true 96 | Source.def 97 | 98 | 99 | 100 | 101 | Level3 102 | true 103 | true 104 | true 105 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 106 | true 107 | 108 | 109 | Console 110 | true 111 | true 112 | true 113 | Source.def 114 | 115 | 116 | 117 | 118 | Level3 119 | true 120 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 121 | true 122 | 123 | 124 | Console 125 | true 126 | Source.def 127 | 128 | 129 | 130 | 131 | Level3 132 | true 133 | true 134 | true 135 | %(PreprocessorDefinitions) 136 | true 137 | F:\code\luagcrypt\libgcrypt_libgcrypt-1.10.3-1_msvc16\include;F:\code\luagcrypt\lua-5.2.4_Win64_dllw6_lib\include 138 | false 139 | EditAndContinue 140 | true 141 | false 142 | Disabled 143 | 144 | 145 | Windows 146 | true 147 | true 148 | true 149 | F:\code\luagcrypt\libgcrypt_libgcrypt-1.10.3-1_msvc16\lib\x64\gcrypt.lib;F:\code\luagcrypt\libgcrypt_libgcrypt-1.10.3-1_msvc16\lib\x64\libgcrypt.lib;F:\code\luagcrypt\lua-5.2_Win64_dll10_lib\lua52.lib;Kernel32.lib;%(AdditionalDependencies) 150 | DllMain 151 | false 152 | Source.def 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /ext/luagcrypt/luagcrypt/luagcrypt.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 | -------------------------------------------------------------------------------- /img/hv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/img/hv.png -------------------------------------------------------------------------------- /img/windbg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/img/windbg.png -------------------------------------------------------------------------------- /img/wireshark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/img/wireshark.png -------------------------------------------------------------------------------- /pipe/pipe.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.34301.259 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "pipe", "pipe\pipe.csproj", "{980F9F40-FA4D-441D-82C5-16DA9C7BACB6}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Debug|x64 = Debug|x64 12 | Release|Any CPU = Release|Any CPU 13 | Release|x64 = Release|x64 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {980F9F40-FA4D-441D-82C5-16DA9C7BACB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {980F9F40-FA4D-441D-82C5-16DA9C7BACB6}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {980F9F40-FA4D-441D-82C5-16DA9C7BACB6}.Debug|x64.ActiveCfg = Debug|x64 19 | {980F9F40-FA4D-441D-82C5-16DA9C7BACB6}.Debug|x64.Build.0 = Debug|x64 20 | {980F9F40-FA4D-441D-82C5-16DA9C7BACB6}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {980F9F40-FA4D-441D-82C5-16DA9C7BACB6}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {980F9F40-FA4D-441D-82C5-16DA9C7BACB6}.Release|x64.ActiveCfg = Release|x64 23 | {980F9F40-FA4D-441D-82C5-16DA9C7BACB6}.Release|x64.Build.0 = Release|x64 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {5D674411-05FC-4174-8105-2045E5395DC5} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /pipe/pipe/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /pipe/pipe/NativeMethods.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Win32.SafeHandles; 2 | using System; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace pipe 7 | { 8 | [StructLayout(LayoutKind.Sequential)] 9 | public struct OFFSET_INFO 10 | { 11 | /// DWORD->unsigned int 12 | public uint Offset; 13 | 14 | /// DWORD->unsigned int 15 | public uint OffsetHigh; 16 | } 17 | 18 | [StructLayout(LayoutKind.Explicit)] 19 | public struct DATA_INFO 20 | { 21 | /// Anonymous_ac6e4301_4438_458f_96dd_e86faeeca2a6 22 | [FieldOffset(0)] 23 | public OFFSET_INFO offsetInfo; 24 | 25 | /// PVOID->void* 26 | [FieldOffset(0)] 27 | public IntPtr Pointer; 28 | } 29 | 30 | 31 | 32 | [StructLayout(LayoutKind.Sequential)] 33 | public struct OVERLAPPED 34 | { 35 | /// ULONG_PTR->unsigned int 36 | public uint Internal; 37 | 38 | /// ULONG_PTR->unsigned int 39 | public uint InternalHigh; 40 | 41 | /// Anonymous_7416d31a_1ce9_4e50_b1e1_0f2ad25c0196 42 | public DATA_INFO DataInfo; 43 | 44 | /// HANDLE->void* 45 | public IntPtr hEvent; 46 | } 47 | public class Kernel32 48 | { 49 | 50 | /// Return Type: void 51 | ///dwErrorCode: DWORD->unsigned int 52 | ///dwNumberOfBytesTransfered: DWORD->unsigned int 53 | ///lpOverlapped: LPOVERLAPPED->_OVERLAPPED* 54 | public delegate void LPOVERLAPPED_COMPLETION_ROUTINE(uint dwErrorCode, uint dwNumberOfBytesTransfered, ref OVERLAPPED lpOverlapped); 55 | 56 | 57 | /// Return Type: BOOL->int 58 | ///hFile: HANDLE->void* 59 | ///lpBuffer: LPCVOID->void* 60 | ///nNumberOfBytesToWrite: DWORD->unsigned int 61 | ///lpOverlapped: LPOVERLAPPED->_OVERLAPPED* 62 | ///lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE 63 | [DllImport("kernel32.dll", EntryPoint = "WriteFileEx", SetLastError = true)] 64 | [return: MarshalAs(UnmanagedType.Bool)] 65 | public static extern bool WriteFileEx( 66 | [In] IntPtr hFile, [In] IntPtr lpBuffer, uint nNumberOfBytesToWrite, ref OVERLAPPED lpOverlapped, 67 | LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine); 68 | 69 | 70 | /// Return Type: BOOL->int 71 | ///hFile: HANDLE->void* 72 | ///lpBuffer: LPCVOID->void* 73 | ///nNumberOfBytesToWrite: DWORD->unsigned int 74 | ///lpNumberOfBytesWritten: LPDWORD->DWORD* 75 | ///lpOverlapped: LPOVERLAPPED->_OVERLAPPED* 76 | [DllImport("kernel32.dll", EntryPoint = "WriteFile", SetLastError = true)] 77 | [return: MarshalAs(UnmanagedType.Bool)] 78 | public static extern bool WriteFile( 79 | [In] IntPtr hFile, [In] IntPtr lpBuffer, uint nNumberOfBytesToWrite, ref uint lpNumberOfBytesWritten, IntPtr lpOverlapped); 80 | 81 | 82 | /// Return Type: BOOL->int 83 | ///hFile: HANDLE->void* 84 | ///lpBuffer: LPVOID->void* 85 | ///nNumberOfBytesToRead: DWORD->unsigned int 86 | ///lpNumberOfBytesRead: LPDWORD->DWORD* 87 | ///lpOverlapped: LPOVERLAPPED->_OVERLAPPED* 88 | [DllImport("kernel32.dll", EntryPoint = "ReadFile", SetLastError = true)] 89 | [return: MarshalAs(UnmanagedType.Bool)] 90 | public static extern bool ReadFile([In] IntPtr hFile, IntPtr lpBuffer, uint nNumberOfBytesToRead, ref uint lpNumberOfBytesRead, IntPtr lpOverlapped); 91 | 92 | /// Return Type: BOOL->int 93 | ///hFile: HANDLE->void* 94 | ///lpBuffer: LPVOID->void* 95 | ///nNumberOfBytesToRead: DWORD->unsigned int 96 | ///lpOverlapped: LPOVERLAPPED->_OVERLAPPED* 97 | ///lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE 98 | [DllImport("kernel32.dll", EntryPoint = "ReadFileEx", SetLastError = true)] 99 | [return: MarshalAs(UnmanagedType.Bool)] 100 | public static extern bool ReadFileEx( 101 | [In] IntPtr hFile, IntPtr lpBuffer, uint nNumberOfBytesToRead, ref OVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine); 102 | 103 | 104 | [DllImport("kernel32.dll", EntryPoint = "SleepEx", SetLastError = true)] 105 | public static extern uint SleepEx(uint dwMilliseconds, bool bAlertable); 106 | 107 | } 108 | 109 | public class Vmbuspiper 110 | { 111 | [DllImport("vmbuspiper.dll", EntryPoint = "VmbusPipeServerConnectPipe")] 112 | [return: MarshalAs(UnmanagedType.Bool)] 113 | public static extern 114 | bool VmbusPipeServerConnectPipe( 115 | [In] IntPtr PipeHandle, 116 | IntPtr Overlapped); 117 | 118 | 119 | [DllImport("vmbuspiper.dll", EntryPoint = "VmbusPipeServerOfferChannel")] 120 | public static extern SafeFileHandle VmbusPipeServerOfferChannel( 121 | [In] IntPtr Offer, 122 | uint OpenMode, 123 | uint PipeMode); 124 | 125 | } 126 | } -------------------------------------------------------------------------------- /pipe/pipe/PacketWriter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net; 5 | using System.Net.NetworkInformation; 6 | using System.Reflection; 7 | using System.Runtime.Remoting.Messaging; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using PacketDotNet; 11 | using SharpPcap; 12 | using SharpPcap.LibPcap; 13 | 14 | namespace pipe 15 | { 16 | class PacketWriter 17 | { 18 | private CaptureFileWriterDevice outdev = null; 19 | 20 | public static PacketWriter Current = new PacketWriter(); 21 | public PacketWriter() 22 | { 23 | string exepathdir = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); 24 | 25 | string pacpfilepath = System.IO.Path.Combine(exepathdir, "windbg-" + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + ".pcap"); 26 | 27 | outdev = new CaptureFileWriterDevice(pacpfilepath); 28 | outdev.Open(); 29 | } 30 | 31 | 32 | public byte[] WritePactet(byte[] buffer, bool fromhost) 33 | { 34 | EthernetPacket eth = null; 35 | IPv4Packet ip = null; 36 | UdpPacket udp = null; 37 | ushort PortClient = 51111; 38 | ushort PortServer = 51112; 39 | var LocalIp = IPAddress.Parse("192.168.0.1"); 40 | var fakeIp = IPAddress.Parse("192.168.0.2"); 41 | PhysicalAddress fakeMac = PhysicalAddress.Parse("001122334455"); 42 | PhysicalAddress BroadcastMac = PhysicalAddress.Parse("FFFFFFFFFFFF"); 43 | if (fromhost) 44 | { 45 | eth = new EthernetPacket(fakeMac, BroadcastMac, EthernetType.IPv4); 46 | ip = new IPv4Packet(fakeIp, LocalIp); 47 | udp = new UdpPacket(PortClient, PortServer); 48 | } 49 | else 50 | { 51 | eth = new EthernetPacket( BroadcastMac, fakeMac, EthernetType.IPv4); 52 | ip = new IPv4Packet(LocalIp,fakeIp); 53 | udp = new UdpPacket(PortServer,PortClient ); 54 | } 55 | 56 | eth.PayloadPacket = ip; 57 | ip.PayloadPacket = udp; 58 | udp.PayloadData = buffer; 59 | udp.UpdateCalculatedValues(); 60 | ip.UpdateCalculatedValues(); 61 | udp.UpdateUdpChecksum(); 62 | ip.UpdateIPChecksum(); 63 | outdev.Write(new ReadOnlySpan(eth.Bytes)); 64 | return eth.Bytes; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /pipe/pipe/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Management; 6 | using System.Text; 7 | using System.Threading; 8 | using System.Threading.Tasks; 9 | 10 | namespace pipe 11 | { 12 | class Program 13 | { 14 | 15 | private static string GuidSelector(string guid) => "SELECT * FROM Msvm_ComputerSystem WHERE Name='" + guid + "'"; 16 | private static string NameSelector(string name) => "SELECT * FROM Msvm_ComputerSystem WHERE ElementName='" + name + "'"; 17 | 18 | public static IMsvm_ComputerSystem GetVM(string name, WmiScope scope) => 19 | scope.QueryInstances(NameSelector(name)).FirstOrDefault(); 20 | 21 | public static IMsvm_ComputerSystem GetVMByGuid(string guid, WmiScope scope) => 22 | scope.QueryInstances(GuidSelector(guid)).FirstOrDefault(); 23 | 24 | private static Guid GetVMguid(string vmname, WmiScope scope) 25 | { 26 | 27 | 28 | IMsvm_ComputerSystem inst= GetVM(vmname, scope); 29 | string guid ="{"+ inst.Name+"}"; 30 | return Guid.Parse(guid) ; 31 | 32 | } 33 | private static void ProcessStartNoWindow(string exepath, string args,bool WaitForExit) 34 | { 35 | try 36 | { 37 | 38 | System.Diagnostics.Process p = new System.Diagnostics.Process(); 39 | p.StartInfo.FileName = exepath; 40 | p.StartInfo.Arguments = args; 41 | p.StartInfo.UseShellExecute = false; 42 | p.StartInfo.RedirectStandardError = true; 43 | p.StartInfo.RedirectStandardInput = true; 44 | p.StartInfo.RedirectStandardOutput = true; 45 | p.StartInfo.LoadUserProfile = true; 46 | p.StartInfo.WorkingDirectory = Environment.CurrentDirectory; 47 | p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 48 | Console.WriteLine(p.StartInfo.FileName+" " + p.StartInfo.Arguments); 49 | p.Start(); 50 | if (WaitForExit) 51 | { 52 | p.WaitForExit(); 53 | } 54 | } 55 | catch (Exception exception) 56 | { 57 | Console.Write(exception); 58 | } 59 | } 60 | private static void ProcessStartWindowMaximized(string exepath, string args) 61 | { 62 | try 63 | { 64 | 65 | System.Diagnostics.Process p = new System.Diagnostics.Process(); 66 | p.StartInfo.FileName = exepath; 67 | p.StartInfo.Arguments = args; 68 | p.StartInfo.UseShellExecute = false; 69 | p.StartInfo.RedirectStandardError = true; 70 | p.StartInfo.RedirectStandardInput = true; 71 | p.StartInfo.RedirectStandardOutput = true; 72 | p.StartInfo.LoadUserProfile = true; 73 | p.StartInfo.WorkingDirectory = Environment.CurrentDirectory; 74 | p.StartInfo.WindowStyle = ProcessWindowStyle.Maximized; 75 | Console.WriteLine(p.StartInfo.FileName + " " + p.StartInfo.Arguments); 76 | p.Start(); 77 | 78 | } 79 | catch (Exception exception) 80 | { 81 | Console.Write(exception); 82 | } 83 | } 84 | 85 | static void Main(string[] args) 86 | { 87 | if (args.Length == 0) 88 | { 89 | Console.WriteLine("[*]usage"); 90 | Console.WriteLine("[*]pipe.exe [pipeout] [pipein] [wirehsrakpipe]"); 91 | Console.WriteLine("[*]use default pipe"); 92 | } 93 | 94 | 95 | 96 | string pipeServer_pipe_name = "spy"; 97 | string pipeClient_pipe_name = "windbg"; 98 | string wirehsrakpipe = "bacnet"; 99 | 100 | if (args.Length > 0) 101 | { 102 | 103 | pipeServer_pipe_name = args[0]; 104 | } 105 | 106 | if (args.Length > 1) 107 | { 108 | pipeClient_pipe_name = args[1]; 109 | } 110 | 111 | 112 | if (args.Length > 2) 113 | { 114 | wirehsrakpipe = args[2]; 115 | } 116 | 117 | if (args.Length > 3) 118 | { 119 | if (args[3] == "auto") 120 | { 121 | ProcessStartNoWindow(@"C:\Windows\System32\taskkill.exe", "/f /im vmwp.exe", true); 122 | ProcessStartNoWindow(@"C:\Windows\System32\taskkill.exe", "/f /im windbg.exe",true); 123 | } 124 | } 125 | 126 | // var ws = new Wireshark.WiresharkSender("bacnet", pipeServer_pipe_name, pipeClient_pipe_name, 165); 127 | Wireshark.WiresharkSender ws = new Wireshark.WiresharkSender(pipeServer_pipe_name, pipeClient_pipe_name); 128 | 129 | if (args.Length > 2) 130 | { 131 | //"C:\Program Files\Wireshark\Wireshark.exe" -ni \\.\pipe\bacnet 132 | ws.WiresharCreate(wirehsrakpipe, 1); 133 | 134 | } 135 | 136 | if (args.Length > 3) 137 | { 138 | if (args[3] == "auto") 139 | { 140 | string windbgpath = @"C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe"; 141 | string argsdbg = "-k \"com:pipe,port=\\\\.\\pipe\\" + pipeServer_pipe_name + 142 | ",baud=115200,resets=0,reconnect\""; 143 | 144 | ProcessStartWindowMaximized(windbgpath, argsdbg); 145 | 146 | 147 | if (args.Length > 4) 148 | { 149 | WmiScope scope = new WmiScope(@"root\virtualization\v2"); 150 | string vmname = args[4]; 151 | Guid vmguid = GetVMguid(vmname, scope); 152 | 153 | 154 | ProcessStartNoWindow(@"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe", 155 | "-exec bypass -Command \"Stop-VM -Name " + vmname + " -TurnOff -Force\"", true); 156 | //string vhdxpath = @"F:\hyperv\testuefidbgvhdxv2\Virtual Hard Disks\testuefidbgvhdxv2.vhdx"; 157 | 158 | 159 | ManagementObject vmobj= WmiUtilities.GetVirtualMachine(vmname, scope.Scope); 160 | string vhdxpath = WmiUtilities.GetVhdSettingsPath(vmobj); 161 | 162 | Console.WriteLine("[*]use vhdxpath:=>"+ vhdxpath); 163 | // string vhdxpath = @"F:\hyperv\testuefidbgvhdxv2\Virtual Hard Disks\testuefidbgvhdxv2.vhdx"; 164 | ProcessStartNoWindow(@"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe", 165 | "-exec bypass -Command \"Dismount-VHD '"+ vhdxpath + "'\"", true); 166 | Thread.Sleep(5000); 167 | ProcessStartNoWindow(@"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe", 168 | "-exec bypass -Command \"Start-VM -Name " + vmname + "\"", true); 169 | 170 | if (System.Diagnostics.Process.GetProcessesByName("vmconnect").Length == 0) 171 | { 172 | string vmconnectarg = Environment.MachineName + " " + vmname; 173 | ; ProcessStartNoWindow(@"C:\Windows\System32\vmconnect.exe", 174 | vmconnectarg, false); 175 | } 176 | 177 | 178 | 179 | 180 | ws.PipeOfferChannel(vmguid); 181 | 182 | 183 | 184 | } 185 | 186 | } 187 | } 188 | 189 | Console.ReadLine(); 190 | Console.WriteLine("pipe exit"); 191 | } 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /pipe/pipe/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("pipe")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("pipe")] 13 | [assembly: AssemblyCopyright("Copyright © 2024")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // 将 ComVisible 设置为 false 会使此程序集中的类型 18 | //对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("980f9f40-fa4d-441d-82c5-16da9c7bacb6")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 33 | //通过使用 "*",如下所示: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /pipe/pipe/Utils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace pipe 6 | { 7 | 8 | public enum VmbusWindbgProtocol 9 | { 10 | NativeCom, 11 | VmbusChannelSync, 12 | VmbusChannelAsync, 13 | VmbusMirror 14 | } 15 | ; 16 | public class Utils 17 | { 18 | public static string HexDump(List bytes, int bytesPerLine = 16) 19 | { 20 | return HexDump(bytes.ToArray(), bytesPerLine); 21 | 22 | } 23 | 24 | public static string HexDump(byte[] bytes, int bytesPerLine = 16) 25 | { 26 | if (bytes == null) return ""; 27 | int bytesLength = bytes.Length; 28 | 29 | char[] HexChars = "0123456789ABCDEF".ToCharArray(); 30 | 31 | int firstHexColumn = 32 | 8 // 8 characters for the address 33 | + 3; // 3 spaces 34 | 35 | int firstCharColumn = firstHexColumn 36 | + bytesPerLine * 3 // - 2 digit for the hexadecimal value and 1 space 37 | + (bytesPerLine - 1) / 8 // - 1 extra space every 8 characters from the 9th 38 | + 2; // 2 spaces 39 | 40 | int lineLength = firstCharColumn 41 | + bytesPerLine // - characters to show the ascii value 42 | + Environment.NewLine.Length; // Carriage return and line feed (should normally be 2) 43 | 44 | char[] line = (new String(' ', lineLength - Environment.NewLine.Length) + Environment.NewLine).ToCharArray(); 45 | int expectedLines = (bytesLength + bytesPerLine - 1) / bytesPerLine; 46 | StringBuilder result = new StringBuilder(expectedLines * lineLength); 47 | 48 | for (int i = 0; i < bytesLength; i += bytesPerLine) 49 | { 50 | line[0] = HexChars[(i >> 28) & 0xF]; 51 | line[1] = HexChars[(i >> 24) & 0xF]; 52 | line[2] = HexChars[(i >> 20) & 0xF]; 53 | line[3] = HexChars[(i >> 16) & 0xF]; 54 | line[4] = HexChars[(i >> 12) & 0xF]; 55 | line[5] = HexChars[(i >> 8) & 0xF]; 56 | line[6] = HexChars[(i >> 4) & 0xF]; 57 | line[7] = HexChars[(i >> 0) & 0xF]; 58 | 59 | int hexColumn = firstHexColumn; 60 | int charColumn = firstCharColumn; 61 | 62 | for (int j = 0; j < bytesPerLine; j++) 63 | { 64 | if (j > 0 && (j & 7) == 0) hexColumn++; 65 | if (i + j >= bytesLength) 66 | { 67 | line[hexColumn] = ' '; 68 | line[hexColumn + 1] = ' '; 69 | line[charColumn] = ' '; 70 | } 71 | else 72 | { 73 | byte b = bytes[i + j]; 74 | line[hexColumn] = HexChars[(b >> 4) & 0xF]; 75 | line[hexColumn + 1] = HexChars[b & 0xF]; 76 | line[charColumn] = (b < 32 ? '·' : (char)b); 77 | } 78 | hexColumn += 3; 79 | charColumn++; 80 | } 81 | result.Append(line); 82 | result.Append(Environment.NewLine); 83 | } 84 | return result.ToString(); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /pipe/pipe/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /pipe/pipe/pipe.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {980F9F40-FA4D-441D-82C5-16DA9C7BACB6} 8 | Exe 9 | pipe 10 | pipe 11 | v4.7.2 12 | 512 13 | true 14 | true 15 | 16 | 17 | 18 | AnyCPU 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | true 38 | bin\x64\Debug\ 39 | DEBUG;TRACE 40 | full 41 | x64 42 | 7.3 43 | prompt 44 | true 45 | 46 | 47 | bin\x64\Release\ 48 | TRACE 49 | true 50 | pdbonly 51 | x64 52 | 7.3 53 | prompt 54 | true 55 | 56 | 57 | 58 | ..\packages\PacketDotNet.1.4.7\lib\net47\PacketDotNet.dll 59 | 60 | 61 | ..\packages\SharpPcap.6.3.0\lib\netstandard2.0\SharpPcap.dll 62 | 63 | 64 | 65 | ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll 66 | 67 | 68 | 69 | 70 | ..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll 71 | 72 | 73 | 74 | ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll 75 | 76 | 77 | ..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll 78 | 79 | 80 | ..\packages\System.Text.Encoding.CodePages.6.0.0\lib\net461\System.Text.Encoding.CodePages.dll 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | cmd.exe /c taskkill /f /im pipe.exe 105 | exit 0 106 | 107 | -------------------------------------------------------------------------------- /windbg/FtdiUsbSerialDxe/DebugAgentDxe.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/windbg/FtdiUsbSerialDxe/DebugAgentDxe.c -------------------------------------------------------------------------------- /windbg/FtdiUsbSerialDxe/DebugCommunicationLibSerialPort.c: -------------------------------------------------------------------------------- 1 | /** @file 2 | Debug Port Library implementation based on serial port. 3 | 4 | Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
5 | SPDX-License-Identifier: BSD-2-Clause-Patent 6 | 7 | **/ 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | /** 16 | Initialize the debug port. 17 | 18 | This function will initialize debug port to get it ready for data transmission. If 19 | certain Debug Communication Library instance has to save some private data in the 20 | stack, this function must work on the mode that doesn't return to the caller, then 21 | the caller needs to wrap up all rest of logic after DebugPortInitialize() into one 22 | function and pass it into DebugPortInitialize(). DebugPortInitialize() is 23 | responsible to invoke the passing-in function at the end of DebugPortInitialize(). 24 | 25 | If the parameter Function is not NULL, Debug Communication Library instance will 26 | invoke it by passing in the Context to be the first parameter. Debug Communication 27 | Library instance could create one debug port handle to be the second parameter 28 | passing into the Function. Debug Communication Library instance also could pass 29 | NULL to be the second parameter if it doesn't create the debug port handle. 30 | 31 | If the parameter Function is NULL, and Context is not NULL. At this time, Context 32 | is the debug port handle created by the previous Debug Communication Library 33 | instance. 34 | a) If the instance can understand and continue use the private data of the previous 35 | instance, it could return the same handle as passed in (as Context parameter). 36 | b) If the instance does not understand, or does not want to continue use the 37 | private data of the previous instance, it could ignore the input Context parameter 38 | and create the new handle to be returned. 39 | 40 | If Function() is NULL and Context is NULL, Debug Communication Library could create a 41 | new handle and return it. NULL is also a valid handle to be returned. 42 | 43 | @param[in] Context Context needed by callback function; it was optional. 44 | @param[in] Function Continue function called by Debug Communication library; 45 | it was optional. 46 | 47 | @return The debug port handle created by Debug Communication Library if Function 48 | is not NULL. 49 | 50 | **/ 51 | DEBUG_PORT_HANDLE 52 | EFIAPI 53 | DebugPortInitialize ( 54 | IN VOID *Context, 55 | IN DEBUG_PORT_CONTINUE Function 56 | ) 57 | { 58 | RETURN_STATUS Status; 59 | 60 | Status = SerialPortInitialize (); 61 | if (RETURN_ERROR (Status)) { 62 | DEBUG ((DEBUG_ERROR, "Debug Serial Port: Initialization failed!\n")); 63 | } 64 | 65 | if (Function != NULL) { 66 | Function (Context, NULL); 67 | } 68 | 69 | return NULL; 70 | } 71 | 72 | /** 73 | Read data from debug device and save the data in a buffer. 74 | 75 | Reads NumberOfBytes data bytes from a debug device into the buffer 76 | specified by Buffer. The number of bytes actually read is returned. 77 | If the return value is less than NumberOfBytes, then the rest operation failed. 78 | If NumberOfBytes is zero, then return 0. 79 | 80 | @param Handle Debug port handle. 81 | @param Buffer Pointer to the data buffer to store the data read from the debug device. 82 | @param NumberOfBytes Number of bytes which will be read. 83 | @param Timeout Timeout value for reading from debug device. It unit is Microsecond. 84 | 85 | @retval 0 Read data failed, no data is to be read. 86 | @retval >0 Actual number of bytes read from debug device. 87 | 88 | **/ 89 | UINTN 90 | EFIAPI 91 | DebugPortReadBuffer ( 92 | IN DEBUG_PORT_HANDLE Handle, 93 | IN UINT8 *Buffer, 94 | IN UINTN NumberOfBytes, 95 | IN UINTN Timeout 96 | ) 97 | { 98 | if ((NumberOfBytes != 1) || (Buffer == NULL) || (Timeout != 0)) { 99 | return 0; 100 | } 101 | 102 | return SerialPortRead (Buffer, 1); 103 | } 104 | 105 | /** 106 | Write data from buffer to debug device. 107 | 108 | Writes NumberOfBytes data bytes from Buffer to the debug device. 109 | The number of bytes actually written to the debug device is returned. 110 | If the return value is less than NumberOfBytes, then the write operation failed. 111 | If NumberOfBytes is zero, then return 0. 112 | 113 | @param Handle Debug port handle. 114 | @param Buffer Pointer to the data buffer to be written. 115 | @param NumberOfBytes Number of bytes to written to the debug device. 116 | 117 | @retval 0 NumberOfBytes is 0. 118 | @retval >0 The number of bytes written to the debug device. 119 | If this value is less than NumberOfBytes, then the read operation failed. 120 | 121 | **/ 122 | UINTN 123 | EFIAPI 124 | DebugPortWriteBuffer ( 125 | IN DEBUG_PORT_HANDLE Handle, 126 | IN UINT8 *Buffer, 127 | IN UINTN NumberOfBytes 128 | ) 129 | { 130 | return SerialPortWrite (Buffer, NumberOfBytes); 131 | } 132 | 133 | /** 134 | Polls a debug device to see if there is any data waiting to be read. 135 | 136 | Polls a debug device to see if there is any data waiting to be read. 137 | If there is data waiting to be read from the debug device, then TRUE is returned. 138 | If there is no data waiting to be read from the debug device, then FALSE is returned. 139 | 140 | @param Handle Debug port handle. 141 | 142 | @retval TRUE Data is waiting to be read from the debug device. 143 | @retval FALSE There is no data waiting to be read from the serial device. 144 | 145 | **/ 146 | BOOLEAN 147 | EFIAPI 148 | DebugPortPollBuffer ( 149 | IN DEBUG_PORT_HANDLE Handle 150 | ) 151 | { 152 | return SerialPortPoll (); 153 | } 154 | -------------------------------------------------------------------------------- /windbg/FtdiUsbSerialDxe/DebugMp.c: -------------------------------------------------------------------------------- 1 | /** @file 2 | Multi-Processor support functions implementation. 3 | 4 | Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
5 | SPDX-License-Identifier: BSD-2-Clause-Patent 6 | 7 | **/ 8 | 9 | #include "DebugAgent.h" 10 | 11 | GLOBAL_REMOVE_IF_UNREFERENCED DEBUG_MP_CONTEXT volatile mDebugMpContext = { 0, 0, 0, { 0 }, { 0 }, 0, 0, 0, 0, FALSE, FALSE }; 12 | 13 | GLOBAL_REMOVE_IF_UNREFERENCED DEBUG_CPU_DATA volatile mDebugCpuData = { 0 }; 14 | 15 | /** 16 | Acquire a spin lock when Multi-processor supported. 17 | 18 | It will block in the function if cannot get the access control. 19 | If Multi-processor is not supported, return directly. 20 | 21 | @param[in, out] MpSpinLock A pointer to the spin lock. 22 | 23 | **/ 24 | VOID 25 | AcquireMpSpinLock ( 26 | IN OUT SPIN_LOCK *MpSpinLock 27 | ) 28 | { 29 | if (!MultiProcessorDebugSupport ()) { 30 | return; 31 | } 32 | 33 | while (TRUE) { 34 | if (AcquireSpinLockOrFail (MpSpinLock)) { 35 | break; 36 | } 37 | 38 | CpuPause (); 39 | continue; 40 | } 41 | } 42 | 43 | /** 44 | Release a spin lock when Multi-processor supported. 45 | 46 | @param[in, out] MpSpinLock A pointer to the spin lock. 47 | 48 | **/ 49 | VOID 50 | ReleaseMpSpinLock ( 51 | IN OUT SPIN_LOCK *MpSpinLock 52 | ) 53 | { 54 | if (!MultiProcessorDebugSupport ()) { 55 | return; 56 | } 57 | 58 | ReleaseSpinLock (MpSpinLock); 59 | } 60 | 61 | /** 62 | Break the other processor by send IPI. 63 | 64 | @param[in] CurrentProcessorIndex Current processor index value. 65 | 66 | **/ 67 | VOID 68 | HaltOtherProcessors ( 69 | IN UINT32 CurrentProcessorIndex 70 | ) 71 | { 72 | DebugAgentMsgPrint (DEBUG_AGENT_INFO, "processor[%x]:Try to halt other processors.\n", CurrentProcessorIndex); 73 | if (!DebugAgentIsBsp (CurrentProcessorIndex)) { 74 | SetIpiSentByApFlag (TRUE); 75 | } 76 | 77 | mDebugMpContext.BreakAtCpuIndex = CurrentProcessorIndex; 78 | 79 | // 80 | // Set the debug viewpoint to the current breaking CPU. 81 | // 82 | SetDebugViewPoint (CurrentProcessorIndex); 83 | 84 | // 85 | // Send fixed IPI to other processors. 86 | // 87 | SendFixedIpiAllExcludingSelf (DEBUG_TIMER_VECTOR); 88 | } 89 | 90 | /** 91 | Get the current processor's index. 92 | 93 | @return Processor index value. 94 | 95 | **/ 96 | UINT32 97 | GetProcessorIndex ( 98 | VOID 99 | ) 100 | { 101 | UINT32 Index; 102 | UINT16 LocalApicID; 103 | 104 | LocalApicID = (UINT16)GetApicId (); 105 | 106 | AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock); 107 | 108 | for (Index = 0; Index < mDebugCpuData.CpuCount; Index++) { 109 | if (mDebugCpuData.ApicID[Index] == LocalApicID) { 110 | break; 111 | } 112 | } 113 | 114 | if (Index == mDebugCpuData.CpuCount) { 115 | mDebugCpuData.ApicID[Index] = LocalApicID; 116 | mDebugCpuData.CpuCount++; 117 | } 118 | 119 | ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock); 120 | 121 | return Index; 122 | } 123 | 124 | /** 125 | Check if the specified processor is BSP or not. 126 | 127 | @param[in] ProcessorIndex Processor index value. 128 | 129 | @retval TRUE It is BSP. 130 | @retval FALSE It isn't BSP. 131 | 132 | **/ 133 | BOOLEAN 134 | DebugAgentIsBsp ( 135 | IN UINT32 ProcessorIndex 136 | ) 137 | { 138 | MSR_IA32_APIC_BASE_REGISTER MsrApicBase; 139 | 140 | // 141 | // If there are less than 2 CPUs detected, then the currently executing CPU 142 | // must be the BSP. This avoids an access to an MSR that may not be supported 143 | // on single core CPUs. 144 | // 145 | if (mDebugCpuData.CpuCount < 2) { 146 | return TRUE; 147 | } 148 | 149 | MsrApicBase.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE); 150 | if (MsrApicBase.Bits.BSP == 1) { 151 | if (mDebugMpContext.BspIndex != ProcessorIndex) { 152 | AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock); 153 | mDebugMpContext.BspIndex = ProcessorIndex; 154 | ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock); 155 | } 156 | 157 | return TRUE; 158 | } else { 159 | return FALSE; 160 | } 161 | } 162 | 163 | /** 164 | Set processor stop flag bitmask in MP context. 165 | 166 | @param[in] ProcessorIndex Processor index value. 167 | @param[in] StopFlag TRUE means set stop flag. 168 | FALSE means clean break flag. 169 | 170 | **/ 171 | VOID 172 | SetCpuStopFlagByIndex ( 173 | IN UINT32 ProcessorIndex, 174 | IN BOOLEAN StopFlag 175 | ) 176 | { 177 | UINT8 Value; 178 | UINTN Index; 179 | 180 | AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock); 181 | 182 | Value = mDebugMpContext.CpuStopStatusMask[ProcessorIndex / 8]; 183 | Index = ProcessorIndex % 8; 184 | if (StopFlag) { 185 | Value = BitFieldWrite8 (Value, Index, Index, 1); 186 | } else { 187 | Value = BitFieldWrite8 (Value, Index, Index, 0); 188 | } 189 | 190 | mDebugMpContext.CpuStopStatusMask[ProcessorIndex / 8] = Value; 191 | 192 | ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock); 193 | } 194 | 195 | /** 196 | Set processor break flag bitmask in MP context. 197 | 198 | @param[in] ProcessorIndex Processor index value. 199 | @param[in] BreakFlag TRUE means set break flag. 200 | FALSE means clean break flag. 201 | 202 | **/ 203 | VOID 204 | SetCpuBreakFlagByIndex ( 205 | IN UINT32 ProcessorIndex, 206 | IN BOOLEAN BreakFlag 207 | ) 208 | { 209 | UINT8 Value; 210 | UINTN Index; 211 | 212 | AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock); 213 | 214 | Value = mDebugMpContext.CpuBreakMask[ProcessorIndex / 8]; 215 | Index = ProcessorIndex % 8; 216 | if (BreakFlag) { 217 | Value = BitFieldWrite8 (Value, Index, Index, 1); 218 | } else { 219 | Value = BitFieldWrite8 (Value, Index, Index, 0); 220 | } 221 | 222 | mDebugMpContext.CpuBreakMask[ProcessorIndex / 8] = Value; 223 | 224 | ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock); 225 | } 226 | 227 | /** 228 | Check if processor is stopped already. 229 | 230 | @param[in] ProcessorIndex Processor index value. 231 | 232 | @retval TRUE Processor is stopped already. 233 | @retval TRUE Processor isn't stopped. 234 | 235 | **/ 236 | BOOLEAN 237 | IsCpuStopped ( 238 | IN UINT32 ProcessorIndex 239 | ) 240 | { 241 | UINT8 CpuMask; 242 | 243 | CpuMask = (UINT8)(1 << (ProcessorIndex % 8)); 244 | 245 | if ((mDebugMpContext.CpuStopStatusMask[ProcessorIndex / 8] & CpuMask) != 0) { 246 | return TRUE; 247 | } else { 248 | return FALSE; 249 | } 250 | } 251 | 252 | /** 253 | Set the run command flag. 254 | 255 | @param[in] RunningFlag TRUE means run command flag is set. 256 | FALSE means run command flag is cleared. 257 | 258 | **/ 259 | VOID 260 | SetCpuRunningFlag ( 261 | IN BOOLEAN RunningFlag 262 | ) 263 | { 264 | AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock); 265 | mDebugMpContext.RunCommandSet = RunningFlag; 266 | ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock); 267 | } 268 | 269 | /** 270 | Set the current view point to be debugged. 271 | 272 | @param[in] ProcessorIndex Processor index value. 273 | 274 | **/ 275 | VOID 276 | SetDebugViewPoint ( 277 | IN UINT32 ProcessorIndex 278 | ) 279 | { 280 | AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock); 281 | mDebugMpContext.ViewPointIndex = ProcessorIndex; 282 | ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock); 283 | } 284 | 285 | /** 286 | Set the IPI send by BPS/AP flag. 287 | 288 | @param[in] IpiSentByApFlag TRUE means this IPI is sent by AP. 289 | FALSE means this IPI is sent by BSP. 290 | 291 | **/ 292 | VOID 293 | SetIpiSentByApFlag ( 294 | IN BOOLEAN IpiSentByApFlag 295 | ) 296 | { 297 | AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock); 298 | mDebugMpContext.IpiSentByAp = IpiSentByApFlag; 299 | ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock); 300 | } 301 | 302 | /** 303 | Check the next pending breaking CPU. 304 | 305 | @retval others There is at least one processor broken, the minimum 306 | index number of Processor returned. 307 | @retval -1 No any processor broken. 308 | 309 | **/ 310 | UINT32 311 | FindNextPendingBreakCpu ( 312 | VOID 313 | ) 314 | { 315 | UINT32 Index; 316 | 317 | for (Index = 0; Index < DEBUG_CPU_MAX_COUNT / 8; Index++) { 318 | if (mDebugMpContext.CpuBreakMask[Index] != 0) { 319 | return (UINT32)LowBitSet32 (mDebugMpContext.CpuBreakMask[Index]) + Index * 8; 320 | } 321 | } 322 | 323 | return (UINT32)-1; 324 | } 325 | 326 | /** 327 | Check if all processors are in running status. 328 | 329 | @retval TRUE All processors run. 330 | @retval FALSE At least one processor does not run. 331 | 332 | **/ 333 | BOOLEAN 334 | IsAllCpuRunning ( 335 | VOID 336 | ) 337 | { 338 | UINTN Index; 339 | 340 | for (Index = 0; Index < DEBUG_CPU_MAX_COUNT / 8; Index++) { 341 | if (mDebugMpContext.CpuStopStatusMask[Index] != 0) { 342 | return FALSE; 343 | } 344 | } 345 | 346 | return TRUE; 347 | } 348 | 349 | /** 350 | Check if the current processor is the first breaking processor. 351 | 352 | If yes, halt other processors. 353 | 354 | @param[in] ProcessorIndex Processor index value. 355 | 356 | @return TRUE This processor is the first breaking processor. 357 | @return FALSE This processor is not the first breaking processor. 358 | 359 | **/ 360 | BOOLEAN 361 | IsFirstBreakProcessor ( 362 | IN UINT32 ProcessorIndex 363 | ) 364 | { 365 | if (MultiProcessorDebugSupport ()) { 366 | if (mDebugMpContext.BreakAtCpuIndex != (UINT32)-1) { 367 | // 368 | // The current processor is not the first breaking one. 369 | // 370 | SetCpuBreakFlagByIndex (ProcessorIndex, TRUE); 371 | return FALSE; 372 | } else { 373 | // 374 | // If no any processor breaks, try to halt other processors 375 | // 376 | HaltOtherProcessors (ProcessorIndex); 377 | return TRUE; 378 | } 379 | } 380 | 381 | return TRUE; 382 | } 383 | -------------------------------------------------------------------------------- /windbg/FtdiUsbSerialDxe/DebugMp.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | Header file for Multi-Processor support. 3 | 4 | Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
5 | SPDX-License-Identifier: BSD-2-Clause-Patent 6 | 7 | **/ 8 | 9 | #ifndef _DEBUG_MP_H_ 10 | #define _DEBUG_MP_H_ 11 | 12 | #define DEBUG_CPU_MAX_COUNT 256 13 | 14 | typedef struct { 15 | UINT32 CpuCount; ///< Processor count 16 | UINT16 ApicID[DEBUG_CPU_MAX_COUNT]; ///< Record the local apic id for each processor 17 | } DEBUG_CPU_DATA; 18 | 19 | typedef struct { 20 | SPIN_LOCK MpContextSpinLock; ///< Lock for writing MP context 21 | SPIN_LOCK DebugPortSpinLock; ///< Lock for access debug port 22 | SPIN_LOCK MailboxSpinLock; ///< Lock for accessing mail box 23 | UINT8 CpuBreakMask[DEBUG_CPU_MAX_COUNT/8]; ///< Bitmask of all breaking CPUs 24 | UINT8 CpuStopStatusMask[DEBUG_CPU_MAX_COUNT/8]; ///< Bitmask of CPU stop status 25 | UINT32 ViewPointIndex; ///< Current view point to be debugged 26 | UINT32 BspIndex; ///< Processor index value of BSP 27 | UINT32 BreakAtCpuIndex; ///< Processor index value of the current breaking CPU 28 | UINT32 DebugTimerInitCount; ///< Record BSP's init timer count 29 | BOOLEAN IpiSentByAp; ///< TRUE: IPI is sent by AP. FALSE: IPI is sent by BSP 30 | BOOLEAN RunCommandSet; ///< TRUE: RUN command is executing. FALSE: RUN command has been executed. 31 | } DEBUG_MP_CONTEXT; 32 | 33 | extern DEBUG_MP_CONTEXT volatile mDebugMpContext; 34 | extern DEBUG_CPU_DATA volatile mDebugCpuData; 35 | 36 | /** 37 | Break the other processor by send IPI. 38 | 39 | @param[in] CurrentProcessorIndex Current processor index value. 40 | 41 | **/ 42 | VOID 43 | HaltOtherProcessors ( 44 | IN UINT32 CurrentProcessorIndex 45 | ); 46 | 47 | /** 48 | Get the current processor's index. 49 | 50 | @return Processor index value. 51 | 52 | **/ 53 | UINT32 54 | GetProcessorIndex ( 55 | VOID 56 | ); 57 | 58 | /** 59 | Acquire a spin lock when Multi-processor supported. 60 | 61 | It will block in the function if cannot get the access control. 62 | If Multi-processor is not supported, return directly. 63 | 64 | @param[in, out] MpSpinLock A pointer to the spin lock. 65 | 66 | **/ 67 | VOID 68 | AcquireMpSpinLock ( 69 | IN OUT SPIN_LOCK *MpSpinLock 70 | ); 71 | 72 | /** 73 | Release a spin lock when Multi-processor supported. 74 | 75 | @param[in, out] MpSpinLock A pointer to the spin lock. 76 | 77 | **/ 78 | VOID 79 | ReleaseMpSpinLock ( 80 | IN OUT SPIN_LOCK *MpSpinLock 81 | ); 82 | 83 | /** 84 | Check if the specified processor is BSP or not. 85 | 86 | @param[in] ProcessorIndex Processor index value. 87 | 88 | @retval TRUE It is BSP. 89 | @retval FALSE It isn't BSP. 90 | 91 | **/ 92 | BOOLEAN 93 | DebugAgentIsBsp ( 94 | IN UINT32 ProcessorIndex 95 | ); 96 | 97 | /** 98 | Set processor stop flag bitmask in MP context. 99 | 100 | @param[in] ProcessorIndex Processor index value. 101 | @param[in] StopFlag TRUE means set stop flag. 102 | FALSE means clean break flag. 103 | 104 | **/ 105 | VOID 106 | SetCpuStopFlagByIndex ( 107 | IN UINT32 ProcessorIndex, 108 | IN BOOLEAN StopFlag 109 | ); 110 | 111 | /** 112 | Set processor break flag bitmask in MP context. 113 | 114 | @param[in] ProcessorIndex Processor index value. 115 | @param[in] BreakFlag TRUE means set break flag. 116 | FALSE means clean break flag. 117 | 118 | **/ 119 | VOID 120 | SetCpuBreakFlagByIndex ( 121 | IN UINT32 ProcessorIndex, 122 | IN BOOLEAN BreakFlag 123 | ); 124 | 125 | /** 126 | Check if processor is stopped already. 127 | 128 | @param[in] ProcessorIndex Processor index value. 129 | 130 | @retval TRUE Processor is stopped already. 131 | @retval FALSE Processor isn't stopped. 132 | 133 | **/ 134 | BOOLEAN 135 | IsCpuStopped ( 136 | IN UINT32 ProcessorIndex 137 | ); 138 | 139 | /** 140 | Set the run command flag. 141 | 142 | @param[in] RunningFlag TRUE means run command flag is set. 143 | FALSE means run command flag is cleared. 144 | 145 | **/ 146 | VOID 147 | SetCpuRunningFlag ( 148 | IN BOOLEAN RunningFlag 149 | ); 150 | 151 | /** 152 | Set the current view point to be debugged. 153 | 154 | @param[in] ProcessorIndex Processor index value. 155 | 156 | **/ 157 | VOID 158 | SetDebugViewPoint ( 159 | IN UINT32 ProcessorIndex 160 | ); 161 | 162 | /** 163 | Set the IPI send by BPS/AP flag. 164 | 165 | @param[in] IpiSentByApFlag TRUE means this IPI is sent by AP. 166 | FALSE means this IPI is sent by BSP. 167 | 168 | **/ 169 | VOID 170 | SetIpiSentByApFlag ( 171 | IN BOOLEAN IpiSentByApFlag 172 | ); 173 | 174 | /** 175 | Check the next pending breaking CPU. 176 | 177 | @retval others There is at least one processor broken, the minimum 178 | index number of Processor returned. 179 | @retval -1 No any processor broken. 180 | 181 | **/ 182 | UINT32 183 | FindNextPendingBreakCpu ( 184 | VOID 185 | ); 186 | 187 | /** 188 | Check if all processors are in running status. 189 | 190 | @retval TRUE All processors run. 191 | @retval FALSE At least one processor does not run. 192 | 193 | **/ 194 | BOOLEAN 195 | IsAllCpuRunning ( 196 | VOID 197 | ); 198 | 199 | /** 200 | Check if the current processor is the first breaking processor. 201 | 202 | If yes, halt other processors. 203 | 204 | @param[in] ProcessorIndex Processor index value. 205 | 206 | @return TRUE This processor is the first breaking processor. 207 | @return FALSE This processor is not the first breaking processor. 208 | 209 | **/ 210 | BOOLEAN 211 | IsFirstBreakProcessor ( 212 | IN UINT32 ProcessorIndex 213 | ); 214 | 215 | #endif 216 | -------------------------------------------------------------------------------- /windbg/FtdiUsbSerialDxe/DebugTimer.c: -------------------------------------------------------------------------------- 1 | /** @file 2 | Code for debug timer to support debug agent library implementation. 3 | 4 | Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.
5 | SPDX-License-Identifier: BSD-2-Clause-Patent 6 | 7 | **/ 8 | 9 | #include "DebugAgent.h" 10 | 11 | /** 12 | Initialize CPU local APIC timer. 13 | 14 | @param[out] TimerFrequency Local APIC timer frequency returned. 15 | @param[in] DumpFlag If TRUE, dump Local APIC timer's parameter. 16 | 17 | @return 32-bit Local APIC timer init count. 18 | **/ 19 | UINT32 20 | InitializeDebugTimer ( 21 | OUT UINT32 *TimerFrequency, 22 | IN BOOLEAN DumpFlag 23 | ) 24 | { 25 | UINTN ApicTimerDivisor; 26 | UINT32 InitialCount; 27 | UINT32 ApicTimerFrequency; 28 | 29 | InitializeLocalApicSoftwareEnable (TRUE); 30 | GetApicTimerState (&ApicTimerDivisor, NULL, NULL); 31 | ApicTimerFrequency = PcdGet32 (PcdFSBClock) / (UINT32)ApicTimerDivisor; 32 | // 33 | // Cpu Local Apic timer interrupt frequency, it is set to 0.1s 34 | // 35 | InitialCount = (UINT32)DivU64x32 ( 36 | MultU64x64 ( 37 | ApicTimerFrequency, 38 | DEBUG_TIMER_INTERVAL 39 | ), 40 | 1000000u 41 | ); 42 | 43 | InitializeApicTimer (ApicTimerDivisor, InitialCount, TRUE, DEBUG_TIMER_VECTOR); 44 | // 45 | // Disable Debug Timer interrupt to avoid it is delivered before Debug Port 46 | // is initialized 47 | // 48 | DisableApicTimerInterrupt (); 49 | 50 | if (DumpFlag) { 51 | DEBUG ((DEBUG_INFO, "Debug Timer: FSB Clock = %d\n", PcdGet32 (PcdFSBClock))); 52 | DEBUG ((DEBUG_INFO, "Debug Timer: Divisor = %d\n", ApicTimerDivisor)); 53 | DEBUG ((DEBUG_INFO, "Debug Timer: Frequency = %d\n", ApicTimerFrequency)); 54 | DEBUG ((DEBUG_INFO, "Debug Timer: InitialCount = %d\n", InitialCount)); 55 | } 56 | 57 | if (TimerFrequency != NULL) { 58 | *TimerFrequency = ApicTimerFrequency; 59 | } 60 | 61 | return InitialCount; 62 | } 63 | 64 | /** 65 | Enable/Disable the interrupt of debug timer and return the interrupt state 66 | prior to the operation. 67 | 68 | If EnableStatus is TRUE, enable the interrupt of debug timer. 69 | If EnableStatus is FALSE, disable the interrupt of debug timer. 70 | 71 | @param[in] EnableStatus Enable/Disable. 72 | 73 | @retval TRUE Debug timer interrupt were enabled on entry to this call. 74 | @retval FALSE Debug timer interrupt were disabled on entry to this call. 75 | 76 | **/ 77 | BOOLEAN 78 | EFIAPI 79 | SaveAndSetDebugTimerInterrupt ( 80 | IN BOOLEAN EnableStatus 81 | ) 82 | { 83 | BOOLEAN OldDebugTimerInterruptState; 84 | 85 | OldDebugTimerInterruptState = GetApicTimerInterruptState (); 86 | 87 | if (OldDebugTimerInterruptState != EnableStatus) { 88 | if (EnableStatus) { 89 | EnableApicTimerInterrupt (); 90 | } else { 91 | DisableApicTimerInterrupt (); 92 | } 93 | 94 | // 95 | // Validate the Debug Timer interrupt state 96 | // This will make additional delay after Local Apic Timer interrupt state is changed. 97 | // Thus, CPU could handle the potential pending interrupt of Local Apic timer. 98 | // 99 | while (GetApicTimerInterruptState () != EnableStatus) { 100 | CpuPause (); 101 | } 102 | } 103 | 104 | return OldDebugTimerInterruptState; 105 | } 106 | 107 | /** 108 | Check if the timer is time out. 109 | 110 | @param[in] TimerCycle Timer initial count. 111 | @param[in] Timer The start timer from the begin. 112 | @param[in] TimeoutTicker Ticker number need time out. 113 | 114 | @return TRUE Timer time out occurs. 115 | @retval FALSE Timer does not time out. 116 | 117 | **/ 118 | BOOLEAN 119 | IsDebugTimerTimeout ( 120 | IN UINT32 TimerCycle, 121 | IN UINT32 Timer, 122 | IN UINT32 TimeoutTicker 123 | ) 124 | { 125 | UINT64 CurrentTimer; 126 | UINT64 Delta; 127 | 128 | CurrentTimer = GetApicTimerCurrentCount (); 129 | 130 | // 131 | // This timer counter counts down. Check for roll over condition. 132 | // If CurrentTimer is equal to Timer, it does not mean that roll over 133 | // happened. 134 | // 135 | if (CurrentTimer <= Timer) { 136 | Delta = Timer - CurrentTimer; 137 | } else { 138 | // 139 | // Handle one roll-over. 140 | // 141 | Delta = TimerCycle - (CurrentTimer - Timer) + 1; 142 | } 143 | 144 | return (BOOLEAN)(Delta >= TimeoutTicker); 145 | } 146 | -------------------------------------------------------------------------------- /windbg/FtdiUsbSerialDxe/DebugTimer.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | Header file for debug timer to support debug agent library implementation. 3 | 4 | Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.
5 | SPDX-License-Identifier: BSD-2-Clause-Patent 6 | 7 | **/ 8 | 9 | #ifndef _DEBUG_TIMER_H_ 10 | #define _DEBUG_TIMER_H_ 11 | 12 | /** 13 | Initialize CPU local APIC timer. 14 | 15 | @param[out] TimerFrequency Local APIC timer frequency returned. 16 | @param[in] DumpFlag If TRUE, dump Local APIC timer's parameter. 17 | 18 | @return 32-bit Local APIC timer init count. 19 | **/ 20 | UINT32 21 | InitializeDebugTimer ( 22 | OUT UINT32 *TimerFrequency, 23 | IN BOOLEAN DumpFlag 24 | ); 25 | 26 | /** 27 | Check if the timer is time out. 28 | 29 | @param[in] TimerCycle Timer initial count. 30 | @param[in] Timer The start timer from the begin. 31 | @param[in] TimeoutTicker Ticker number need time out. 32 | 33 | @return TRUE Timer time out occurs. 34 | @retval FALSE Timer does not time out. 35 | 36 | **/ 37 | BOOLEAN 38 | IsDebugTimerTimeout ( 39 | IN UINT32 TimerCycle, 40 | IN UINT32 Timer, 41 | IN UINT32 TimeoutTicker 42 | ); 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /windbg/FtdiUsbSerialDxe/FtdiUsbSerialDxe.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Release 6 | x64 7 | 8 | 9 | 10 | Win32Proj 11 | {DF325AB7-67A6-473E-93FF-16955AFBC064} 12 | 10.0 13 | 14 | 15 | 16 | Static 17 | v142 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | $(SolutionDir);E:\git\UEFIResearch\VisualUefi-master\poc\..\edk2\MdeModulePkg\Include;E:\git\UEFIResearch\VisualUefi-master\poc\..\edk2\UefiCpuPkg\Include;E:\git\UEFIResearch\VisualUefi-master\poc\..\edk2\SourceLevelDebugPkg\Include;E:\git\UEFIResearch\VisualUefi-master\poc\..\edk2\SourceLevelDebugPkg\Library\DebugAgent\DebugAgentCommon\X64;E:\git\UEFIResearch\VisualUefi-master\poc\..\edk2\SourceLevelDebugPkg\Include\Ia32;$(IncludePath) 32 | $(SolutionDir);$(LibraryPath) 33 | 34 | 35 | 36 | $(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/MdePkg/Library/RegisterFilterLibNull/RegisterFilterLibNull/OUTPUT/FilterLibNull.lib;$(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/MdePkg/Library/BaseCpuLib/BaseCpuLib/OUTPUT/BaseCpuLib.lib;$(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu/OUTPUT/SecPeiDxeTimerLibUefiCpu.lib;$(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib/OUTPUT/BaseXApicLib.lib;$(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/MdePkg/Library/BasePcdLibNull/BasePcdLibNull/OUTPUT/BasePcdLibNull.lib;$(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic/OUTPUT/BaseIoLibIntrinsic.lib;$(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/MdePkg/Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/BaseMemoryLib.lib;$(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/MdePkg/Library/BaseLib/BaseLib/OUTPUT/BaseLib.lib;$(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib/OUTPUT/BasePciCf8Lib.lib;$(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/MdePkg/Library/BasePciLibCf8/BasePciLibCf8/OUTPUT/BasePciLibCf8.lib;$(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull/OUTPUT/BasePlatformHookLibNull.lib;$(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib/OUTPUT/BaseDebugPrintErrorLevelLib.lib;$(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550/OUTPUT/BaseSerialPortLib16550.lib;$(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/MdePkg/Library/BasePrintLib/BasePrintLib/OUTPUT/BasePrintLib.lib;$(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort/OUTPUT/BaseDebugLibSerialPort.lib;$(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib/OUTPUT/UefiBootServicesTableLib.lib;$(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib/OUTPUT/UefiMemoryAllocationLib.lib;$(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib/OUTPUT/UefiRuntimeServicesTableLib.lib;$(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib/OUTPUT/UefiDevicePathLib.lib;$(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/MdePkg/Library/UefiLib/UefiLib/OUTPUT/UefiLib.lib;$(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug/OUTPUT/PeCoffExtraActionLib.lib;$(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib/OUTPUT/BasePeCoffGetEntryPointLib.lib;$(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib/OUTPUT/BaseSynchronizationLib.lib;$(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort/OUTPUT/DebugCommunicationLibSerialPort.lib;$(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/MdePkg/Library/DxeHobLib/DxeHobLib/OUTPUT/DxeHobLib.lib;$(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/MdeModulePkg/Library/BaseResetSystemLibNull/BaseResetSystemLibNull/OUTPUT/BaseResetSystemLibNull.lib;$(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint/OUTPUT/UefiDriverEntryPoint.lib;$(EDK2ROOT)\Build\SourceLevelDebugPkg\RELEASE_VS2019\X64\SourceLevelDebugPkg\Library\DebugAgent\DxeDebugAgentLib\OUTPUT\DxeDebugAgent\DxeDebugAgentLib.obj;$(EDK2ROOT)\Build\SourceLevelDebugPkg\RELEASE_VS2019\X64\SourceLevelDebugPkg\Library\DebugAgent\DxeDebugAgentLib\OUTPUT\DxeDebugAgent\SerialIo.obj;$(EDK2ROOT)\Build\SourceLevelDebugPkg\RELEASE_VS2019\X64\SourceLevelDebugPkg\Library\DebugAgent\DxeDebugAgentLib\OUTPUT\DebugAgentCommon\DebugMp.obj;$(EDK2ROOT)\Build\SourceLevelDebugPkg\RELEASE_VS2019\X64\SourceLevelDebugPkg\Library\DebugAgent\DxeDebugAgentLib\OUTPUT\DebugAgentCommon\DebugTimer.obj;$(EDK2ROOT)\Build\SourceLevelDebugPkg\RELEASE_VS2019\X64\SourceLevelDebugPkg\Library\DebugAgent\DxeDebugAgentLib\OUTPUT\DebugAgentCommon\X64\ArchDebugSupport.obj 37 | EFI Runtime 38 | true 39 | .xdata,ERW 40 | 4096 41 | true 42 | 43 | 44 | $(ProjectDir) 45 | true 46 | false 47 | Disabled 48 | _M_AMD64;%(PreprocessorDefinitions) 49 | true 50 | ProgramDatabase 51 | MultiThreaded 52 | false 53 | 54 | false 55 | false 56 | NotSet 57 | false 58 | false 59 | Disabled 60 | 61 | 62 | "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -exec bypass -Command "Stop-VM -Name testuefidbgvhdxv2 -TurnOff -Force" 63 | "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\symstore.exe" add /r /f "E:\git\UEFIResearch\VisualUefi-master\poc\x64\Release" /s "%SYMBOL_STORE%" /t niii 64 | "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -exec bypass -Command " Mount-VHD -Path 'F:\hyperv\testuefidbgvhdxv2\Virtual Hard Disks\testuefidbgvhdxv2.vhdx'" 65 | "C:\Windows\System32\xcopy.exe" $(TargetPath) "K:\" /E/H/C/I/Y/Q/R 66 | "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -exec bypass -Command "Dismount-VHD 'F:\hyperv\testuefidbgvhdxv2\Virtual Hard Disks\testuefidbgvhdxv2.vhdx'" 67 | 68 | 69 | "C:\Windows\System32\taskkill.exe" /f /im windbg.exe 70 | exit 0 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | Document 92 | 93 | 94 | -------------------------------------------------------------------------------- /windbg/FtdiUsbSerialDxe/PEHelper.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/windbg/FtdiUsbSerialDxe/PEHelper.c -------------------------------------------------------------------------------- /windbg/FtdiUsbSerialDxe/PEHelper.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/windbg/FtdiUsbSerialDxe/PEHelper.h -------------------------------------------------------------------------------- /windbg/FtdiUsbSerialDxe/VsGlue.c: -------------------------------------------------------------------------------- 1 | // 2 | // We support unload (but deny it) 3 | // 4 | extern const UINT8 _gDriverUnloadImageCount = 1; 5 | 6 | // 7 | // We require at least UEFI 2.0 8 | // 9 | extern const UINT32 _gUefiDriverRevision = 0x200; 10 | 11 | // 12 | // Our name 13 | // 14 | extern CHAR8 *gEfiCallerBaseName = "FtdiUsbSerialDxe"; 15 | 16 | EFI_STATUS 17 | EFIAPI 18 | FtdiUsbSerialUnload ( 19 | IN EFI_HANDLE ImageHandle 20 | ); 21 | 22 | EFI_STATUS 23 | EFIAPI 24 | FtdiUsbSerialEntryPoint ( 25 | IN EFI_HANDLE ImageHandle, 26 | IN EFI_SYSTEM_TABLE *SystemTable 27 | ); 28 | 29 | EFI_STATUS 30 | EFIAPI 31 | UefiUnload ( 32 | IN EFI_HANDLE ImageHandle 33 | ) 34 | { 35 | return FtdiUsbSerialUnload(ImageHandle); 36 | } 37 | 38 | EFI_STATUS 39 | EFIAPI 40 | UefiMain ( 41 | IN EFI_HANDLE ImageHandle, 42 | IN EFI_SYSTEM_TABLE *SystemTable 43 | ) 44 | { 45 | return FtdiUsbSerialEntryPoint(ImageHandle, SystemTable); 46 | } 47 | 48 | -------------------------------------------------------------------------------- /windbg/FtdiUsbSerialDxe/hvapi.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/windbg/FtdiUsbSerialDxe/hvapi.c -------------------------------------------------------------------------------- /windbg/FtdiUsbSerialDxe/kddll.h: -------------------------------------------------------------------------------- 1 | #ifndef _KDDLL_ 2 | #define _KDDLL_ 3 | 4 | typedef ULONG KDSTATUS; 5 | #define KdPacketReceived 0 6 | #define KdPacketTimedOut 1 7 | #define KdPacketNeedsResend 2 8 | 9 | NTSTATUS 10 | NTAPI 11 | KdDebuggerInitialize0( 12 | _In_opt_ PLOADER_PARAMETER_BLOCK LoaderBlock 13 | ); 14 | 15 | NTSTATUS 16 | NTAPI 17 | KdDebuggerInitialize1( 18 | _In_opt_ PLOADER_PARAMETER_BLOCK LoaderBlock 19 | ); 20 | 21 | KDSTATUS 22 | NTAPI 23 | KdReceivePacket( 24 | IN ULONG PacketType, 25 | OUT PSTRING MessageHeader, 26 | OUT PSTRING MessageData, 27 | OUT PULONG DataLength, 28 | IN OUT PKD_CONTEXT Context 29 | ); 30 | 31 | NTSTATUS 32 | NTAPI 33 | KdRestore( 34 | IN BOOLEAN SleepTransition 35 | ); 36 | 37 | NTSTATUS 38 | NTAPI 39 | KdSave( 40 | IN BOOLEAN SleepTransition 41 | ); 42 | 43 | VOID 44 | NTAPI 45 | KdSendPacket( 46 | IN ULONG PacketType, 47 | IN PSTRING MessageHeader, 48 | IN PSTRING MessageData, 49 | IN OUT PKD_CONTEXT Context 50 | ); 51 | 52 | NTSTATUS 53 | NTAPI 54 | KdD0Transition( 55 | VOID 56 | ); 57 | 58 | NTSTATUS 59 | NTAPI 60 | KdD3Transition( 61 | VOID 62 | ); 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /windbg/FtdiUsbSerialDxe/ke.h: -------------------------------------------------------------------------------- 1 | #ifndef __NTOSKRNL_INCLUDE_INTERNAL_AMD64_KE_H 2 | #define __NTOSKRNL_INCLUDE_INTERNAL_AMD64_KE_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #define X86_EFLAGS_TF 0x00000100 /* Trap flag */ 9 | #define X86_EFLAGS_IF 0x00000200 /* Interrupt Enable flag */ 10 | #define X86_EFLAGS_IOPL 0x00003000 /* I/O Privilege Level bits */ 11 | #define X86_EFLAGS_NT 0x00004000 /* Nested Task flag */ 12 | #define X86_EFLAGS_RF 0x00010000 /* Resume flag */ 13 | #define X86_EFLAGS_VM 0x00020000 /* Virtual Mode */ 14 | #define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */ 15 | 16 | #define X86_CR0_PE 0x00000001 /* enable Protected Mode */ 17 | #define X86_CR0_NE 0x00000020 /* enable native FPU error reporting */ 18 | #define X86_CR0_TS 0x00000008 /* enable exception on FPU instruction for task switch */ 19 | #define X86_CR0_EM 0x00000004 /* enable FPU emulation (disable FPU) */ 20 | #define X86_CR0_MP 0x00000002 /* enable FPU monitoring */ 21 | #define X86_CR0_WP 0x00010000 /* enable Write Protect (copy on write) */ 22 | #define X86_CR0_PG 0x80000000 /* enable Paging */ 23 | 24 | #define X86_CR4_PAE 0x00000020 /* enable physical address extensions */ 25 | #define X86_CR4_PGE 0x00000080 /* enable global pages */ 26 | #define X86_CR4_OSFXSR 0x00000200 /* enable FXSAVE/FXRSTOR instructions */ 27 | #define X86_CR4_OSXMMEXCPT 0x00000400 /* enable #XF exception */ 28 | 29 | /* EDX flags */ 30 | #define X86_FEATURE_FPU 0x00000001 /* x87 FPU is present */ 31 | #define X86_FEATURE_VME 0x00000002 /* Virtual 8086 Extensions are present */ 32 | #define X86_FEATURE_DBG 0x00000004 /* Debugging extensions are present */ 33 | #define X86_FEATURE_PSE 0x00000008 /* Page Size Extension is present */ 34 | #define X86_FEATURE_TSC 0x00000010 /* time stamp counters are present */ 35 | #define X86_FEATURE_PAE 0x00000040 /* physical address extension is present */ 36 | #define X86_FEATURE_CX8 0x00000100 /* CMPXCHG8B instruction present */ 37 | #define X86_FEATURE_SYSCALL 0x00000800 /* SYSCALL/SYSRET support present */ 38 | #define X86_FEATURE_MTTR 0x00001000 /* Memory type range registers are present */ 39 | #define X86_FEATURE_PGE 0x00002000 /* Page Global Enable */ 40 | #define X86_FEATURE_CMOV 0x00008000 /* "Conditional move" instruction supported */ 41 | #define X86_FEATURE_PAT 0x00010000 /* Page Attribute Table is supported */ 42 | #define X86_FEATURE_DS 0x00200000 /* Debug Store is present */ 43 | #define X86_FEATURE_MMX 0x00800000 /* MMX extension present */ 44 | #define X86_FEATURE_FXSR 0x01000000 /* FXSAVE/FXRSTOR instructions present */ 45 | #define X86_FEATURE_SSE 0x02000000 /* SSE extension present */ 46 | #define X86_FEATURE_SSE2 0x04000000 /* SSE2 extension present */ 47 | #define X86_FEATURE_HT 0x10000000 /* Hyper-Threading present */ 48 | 49 | /* ECX flags */ 50 | #define X86_FEATURE_SSE3 0x00000001 /* SSE3 is supported */ 51 | #define X86_FEATURE_MONITOR 0x00000008 /* SSE3 Monitor instructions supported */ 52 | #define X86_FEATURE_VMX 0x00000020 /* Virtual Machine eXtensions are available */ 53 | #define X86_FEATURE_SSSE3 0x00000200 /* Supplemental SSE3 are available */ 54 | #define X86_FEATURE_FMA3 0x00001000 /* Fused multiple-add supported */ 55 | #define X86_FEATURE_CX16 0x00002000 /* CMPXCHG16B instruction are available */ 56 | #define X86_FEATURE_PCID 0x00020000 /* Process Context IDentifiers are supported */ 57 | #define X86_FEATURE_SSE41 0x00080000 /* SSE 4.1 is supported */ 58 | #define X86_FEATURE_SSE42 0x00100000 /* SSE 4.2 is supported */ 59 | #define X86_FEATURE_POPCNT 0x00800000 /* POPCNT instruction is available */ 60 | #define X86_FEATURE_XSAVE 0x04000000 /* XSAVE family are available */ 61 | 62 | /* EDX extended flags */ 63 | #define X86_FEATURE_NX 0x00100000 /* NX support present */ 64 | 65 | #define X86_EXT_FEATURE_SSE3 0x00000001 /* SSE3 extension present */ 66 | #define X86_EXT_FEATURE_3DNOW 0x40000000 /* 3DNOW! extension present */ 67 | 68 | #define FRAME_EDITED 0xFFF8 69 | 70 | #define X86_MSR_GSBASE 0xC0000101 71 | #define X86_MSR_KERNEL_GSBASE 0xC0000102 72 | #define X86_MSR_EFER 0xC0000080 73 | #define X86_MSR_STAR 0xC0000081 74 | #define X86_MSR_LSTAR 0xC0000082 75 | #define X86_MSR_CSTAR 0xC0000083 76 | #define X86_MSR_SFMASK 0xC0000084 77 | 78 | #define EFER_SCE 0x0001 79 | #define EFER_LME 0x0100 80 | #define EFER_LMA 0x0400 81 | #define EFER_NXE 0x0800 82 | #define EFER_SVME 0x1000 83 | #define EFER_FFXSR 0x4000 84 | 85 | #define AMD64_TSS 9 86 | 87 | #define APIC_EOI_REGISTER 0xFFFFFFFFFFFE00B0ULL 88 | 89 | 90 | typedef struct _KIDT_INIT 91 | { 92 | UCHAR InterruptId; 93 | UCHAR Dpl; 94 | UCHAR IstIndex; 95 | PVOID ServiceRoutine; 96 | } KIDT_INIT, *PKIDT_INIT; 97 | 98 | #include 99 | typedef struct _KI_INTERRUPT_DISPATCH_ENTRY 100 | { 101 | UCHAR _Op_nop; 102 | UCHAR _Op_push; 103 | UCHAR _Vector; 104 | UCHAR _Op_jmp; 105 | ULONG RelativeAddress; 106 | } KI_INTERRUPT_DISPATCH_ENTRY, *PKI_INTERRUPT_DISPATCH_ENTRY; 107 | #include 108 | 109 | extern ULONG KeI386NpxPresent; 110 | extern ULONG KeI386XMMIPresent; 111 | extern ULONG KeI386FxsrPresent; 112 | extern ULONG KeI386CpuType; 113 | extern ULONG KeI386CpuStep; 114 | 115 | // 116 | // INT3 is 1 byte long 117 | // 118 | #define KD_BREAKPOINT_TYPE UCHAR 119 | #define KD_BREAKPOINT_SIZE sizeof(UCHAR) 120 | #define KD_BREAKPOINT_VALUE 0xCC 121 | 122 | 123 | 124 | 125 | // 126 | // One-liners for getting and setting special purpose registers in portable code 127 | // 128 | FORCEINLINE 129 | ULONG_PTR 130 | KeGetContextPc(PCONTEXT Context) 131 | { 132 | return Context->Rip; 133 | } 134 | 135 | FORCEINLINE 136 | VOID 137 | KeSetContextPc(PCONTEXT Context, ULONG_PTR ProgramCounter) 138 | { 139 | Context->Rip = ProgramCounter; 140 | } 141 | 142 | FORCEINLINE 143 | ULONG_PTR 144 | KeGetContextReturnRegister(PCONTEXT Context) 145 | { 146 | return Context->Rax; 147 | } 148 | 149 | FORCEINLINE 150 | VOID 151 | KeSetContextReturnRegister(PCONTEXT Context, ULONG_PTR ReturnValue) 152 | { 153 | Context->Rax = ReturnValue; 154 | } 155 | 156 | FORCEINLINE 157 | ULONG_PTR 158 | KeGetContextStackRegister(PCONTEXT Context) 159 | { 160 | return Context->Rsp; 161 | } 162 | 163 | FORCEINLINE 164 | ULONG_PTR 165 | KeGetContextFrameRegister(PCONTEXT Context) 166 | { 167 | return Context->Rbp; 168 | } 169 | 170 | FORCEINLINE 171 | VOID 172 | KeSetContextFrameRegister(PCONTEXT Context, ULONG_PTR Frame) 173 | { 174 | Context->Rbp = Frame; 175 | } 176 | 177 | FORCEINLINE 178 | ULONG_PTR 179 | KeGetTrapFramePc(PKTRAP_FRAME TrapFrame) 180 | { 181 | return TrapFrame->Rip; 182 | } 183 | 184 | FORCEINLINE 185 | PKTRAP_FRAME 186 | KiGetLinkedTrapFrame(PKTRAP_FRAME TrapFrame) 187 | { 188 | return (PKTRAP_FRAME)TrapFrame->TrapFrame; 189 | } 190 | 191 | FORCEINLINE 192 | ULONG_PTR 193 | KeGetTrapFrameStackRegister(PKTRAP_FRAME TrapFrame) 194 | { 195 | return TrapFrame->Rsp; 196 | } 197 | 198 | FORCEINLINE 199 | ULONG_PTR 200 | KeGetTrapFrameFrameRegister(PKTRAP_FRAME TrapFrame) 201 | { 202 | return TrapFrame->Rbp; 203 | } 204 | 205 | #define KdpGetParameterThree(Context) ((Context)->R8) 206 | #define KdpGetParameterFour(Context) ((Context)->R9) 207 | 208 | // 209 | // Macro to get trap and exception frame from a thread stack 210 | // 211 | #define KeGetTrapFrame(Thread) \ 212 | (PKTRAP_FRAME)((ULONG_PTR)((Thread)->InitialStack) - \ 213 | sizeof(KTRAP_FRAME)) 214 | 215 | // 216 | // Macro to get context switches from the PRCB 217 | // All architectures but x86 have it in the PRCB's KeContextSwitches 218 | // 219 | #define KeGetContextSwitches(Prcb) \ 220 | (Prcb->KeContextSwitches) 221 | 222 | // 223 | // Macro to get the second level cache size field name which differs between 224 | // CISC and RISC architectures, as the former has unified I/D cache 225 | // 226 | #define KiGetSecondLevelDCacheSize() ((PKIPCR)KeGetPcr())->SecondLevelCacheSize 227 | 228 | #define KeGetExceptionFrame(Thread) \ 229 | (PKEXCEPTION_FRAME)((ULONG_PTR)KeGetTrapFrame(Thread) - \ 230 | sizeof(KEXCEPTION_FRAME)) 231 | 232 | // 233 | // Returns the Interrupt State from a Trap Frame. 234 | // ON = TRUE, OFF = FALSE 235 | // 236 | #define KeGetTrapFrameInterruptState(TrapFrame) \ 237 | BooleanFlagOn((TrapFrame)->EFlags, EFLAGS_INTERRUPT_MASK) 238 | 239 | /* Diable interrupts and return whether they were enabled before */ 240 | FORCEINLINE 241 | BOOLEAN 242 | KeDisableInterrupts(VOID) 243 | { 244 | ULONG_PTR Flags; 245 | 246 | /* Get EFLAGS and check if the interrupt bit is set */ 247 | Flags = __readeflags(); 248 | 249 | /* Disable interrupts */ 250 | _disable(); 251 | return (Flags & EFLAGS_INTERRUPT_MASK) ? TRUE : FALSE; 252 | } 253 | 254 | /* Restore previous interrupt state */ 255 | FORCEINLINE 256 | VOID 257 | KeRestoreInterrupts(BOOLEAN WereEnabled) 258 | { 259 | if (WereEnabled) _enable(); 260 | } 261 | 262 | // 263 | // Invalidates the TLB entry for a specified address 264 | // 265 | FORCEINLINE 266 | VOID 267 | KeInvalidateTlbEntry(IN PVOID Address) 268 | { 269 | /* Invalidate the TLB entry for this address */ 270 | __invlpg(Address); 271 | } 272 | 273 | FORCEINLINE 274 | VOID 275 | KeFlushProcessTb(VOID) 276 | { 277 | /* Flush the TLB by resetting CR3 */ 278 | __writecr3(__readcr3()); 279 | } 280 | 281 | FORCEINLINE 282 | VOID 283 | KeSweepICache(IN PVOID BaseAddress, 284 | IN SIZE_T FlushSize) 285 | { 286 | // 287 | // Always sweep the whole cache 288 | // 289 | /*UNREFERENCED_PARAMETER(BaseAddress); 290 | UNREFERENCED_PARAMETER(FlushSize);*/ 291 | __wbinvd(); 292 | } 293 | 294 | 295 | FORCEINLINE 296 | VOID 297 | KiSendEOI(VOID) 298 | { 299 | /* Write 0 to the apic EOI register */ 300 | *((volatile ULONG*)APIC_EOI_REGISTER) = 0; 301 | } 302 | 303 | 304 | struct _KPCR; 305 | 306 | #endif 307 | 308 | 309 | 310 | 311 | VOID 312 | KiSetTrapContext( 313 | _Out_ PKTRAP_FRAME TrapFrame, 314 | _In_ PCONTEXT Context, 315 | _In_ KPROCESSOR_MODE RequestorMode); 316 | 317 | 318 | #ifdef __cplusplus 319 | } // extern "C" 320 | #endif 321 | 322 | /* EOF */ 323 | -------------------------------------------------------------------------------- /windbg/FtdiUsbSerialDxe/vmbusdxe.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/windbg/FtdiUsbSerialDxe/vmbusdxe.c -------------------------------------------------------------------------------- /windbg/FtdiUsbSerialDxe/windbg.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/windbg/FtdiUsbSerialDxe/windbg.c -------------------------------------------------------------------------------- /windbg/GSStub.c: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // Basic UEFI Libraries 4 | // 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | // 12 | // Boot and Runtime Services 13 | // 14 | #include 15 | #include 16 | 17 | 18 | 19 | 20 | #include "stdint.h" 21 | 22 | #include "utils.h" 23 | 24 | #include 25 | 26 | UINTN __security_cookie = 0; 27 | 28 | void __cdecl __security_init_cookie(void) 29 | { 30 | UINT64 Cookie = __rdtsc(); 31 | 32 | __security_cookie = (UINTN)Cookie; 33 | } 34 | 35 | __declspec(noreturn) void __cdecl __report_gsfailure(UINTN StackCookie) 36 | { 37 | 38 | __fastfail(0); 39 | CpuDeadLoop(); 40 | //return; 41 | } 42 | 43 | __declspec(noreturn) void __cdecl __report_rangecheckfailure() 44 | { 45 | 46 | __fastfail(0); 47 | CpuDeadLoop(); 48 | //return; 49 | } 50 | 51 | void __cdecl __security_check_cookie(UINTN cookie) 52 | { 53 | if (cookie == __security_cookie) { 54 | return; 55 | } 56 | 57 | __report_gsfailure(cookie); 58 | return; 59 | } 60 | 61 | void __GSHandlerCheck(void) 62 | { 63 | __fastfail(0); 64 | // dummy 65 | CpuDeadLoop(); 66 | return; 67 | } 68 | 69 | 70 | void __C_specific_handler(void) 71 | { 72 | __fastfail(0); 73 | // dummy 74 | CpuDeadLoop(); 75 | return; 76 | } -------------------------------------------------------------------------------- /windbg/Library/DebugCommunicationLib.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | Debug Communication Library definitions. 3 | 4 | Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
5 | SPDX-License-Identifier: BSD-2-Clause-Patent 6 | 7 | **/ 8 | 9 | #ifndef __DEBUG_COMMUNICATION_LIB_H__ 10 | #define __DEBUG_COMMUNICATION_LIB_H__ 11 | 12 | typedef VOID *DEBUG_PORT_HANDLE; 13 | 14 | /** 15 | Caller provided function to be invoked at the end of DebugPortInitialize(). 16 | 17 | Refer to the description for DebugPortInitialize() for more details. 18 | 19 | @param[in] Context The first input argument of DebugPortInitialize(). 20 | @param[in] DebugPortHandle Debug port handle created by Debug Communication Library. 21 | 22 | **/ 23 | typedef 24 | VOID 25 | (EFIAPI *DEBUG_PORT_CONTINUE)( 26 | IN VOID *Context, 27 | IN DEBUG_PORT_HANDLE DebugPortHandle 28 | ); 29 | 30 | /** 31 | Initialize the debug port. 32 | 33 | This function will initialize debug port to get it ready for data transmission. If 34 | certain Debug Communication Library instance has to save some private data in the 35 | stack, this function must work on the mode that doesn't return to the caller, then 36 | the caller needs to wrap up all rest of logic after DebugPortInitialize() into one 37 | function and pass it into DebugPortInitialize(). DebugPortInitialize() is 38 | responsible to invoke the passing-in function at the end of DebugPortInitialize(). 39 | 40 | If the parameter Function is not NULL, Debug Communication Library instance will 41 | invoke it by passing in the Context to be the first parameter. Debug Communication 42 | Library instance could create one debug port handle to be the second parameter 43 | passing into the Function. Debug Communication Library instance also could pass 44 | NULL to be the second parameter if it doesn't create the debug port handle. 45 | 46 | If the parameter Function is NULL, and Context is not NULL. At this time, Context 47 | is the debug port handle created by the previous Debug Communication Library 48 | instance. 49 | a) If the instance can understand and continue use the private data of the previous 50 | instance, it could return the same handle as passed in (as Context parameter). 51 | b) If the instance does not understand, or does not want to continue use the 52 | private data of the previous instance, it could ignore the input Context parameter 53 | and create the new handle to be returned. 54 | 55 | If Function() is NULL and Context is NULL, Debug Communication Library could create a 56 | new handle and return it. NULL is also a valid handle to be returned. 57 | 58 | @param[in] Context Context needed by callback function; it was optional. 59 | @param[in] Function Continue function called by Debug Communication library; 60 | it was optional. 61 | 62 | @return The debug port handle created by Debug Communication Library if Function 63 | is not NULL. 64 | 65 | **/ 66 | DEBUG_PORT_HANDLE 67 | EFIAPI 68 | DebugPortInitialize ( 69 | IN VOID *Context, 70 | IN DEBUG_PORT_CONTINUE Function 71 | ); 72 | 73 | /** 74 | Read data from debug device and save the data in a buffer. 75 | 76 | Reads NumberOfBytes data bytes from a debug device into the buffer 77 | specified by Buffer. The number of bytes actually read is returned. 78 | If the return value is less than NumberOfBytes, then the rest operation failed. 79 | If NumberOfBytes is zero, then return 0. 80 | 81 | @param Handle Debug port handle. 82 | @param Buffer Pointer to the data buffer to store the data read from the debug device. 83 | @param NumberOfBytes Number of bytes which will be read. 84 | @param Timeout Timeout value for reading from debug device. Its unit is Microsecond. 85 | 86 | @retval 0 Read data failed, no data is to be read. 87 | @retval >0 Actual number of bytes read from debug device. 88 | 89 | **/ 90 | UINTN 91 | EFIAPI 92 | DebugPortReadBuffer ( 93 | IN DEBUG_PORT_HANDLE Handle, 94 | IN UINT8 *Buffer, 95 | IN UINTN NumberOfBytes, 96 | IN UINTN Timeout 97 | ); 98 | 99 | /** 100 | Write data from buffer to debug device. 101 | 102 | Writes NumberOfBytes data bytes from Buffer to the debug device. 103 | The number of bytes actually written to the debug device is returned. 104 | If the return value is less than NumberOfBytes, then the write operation failed. 105 | If NumberOfBytes is zero, then return 0. 106 | 107 | @param Handle Debug port handle. 108 | @param Buffer Pointer to the data buffer to be written. 109 | @param NumberOfBytes Number of bytes to written to the debug device. 110 | 111 | @retval 0 NumberOfBytes is 0. 112 | @retval >0 The number of bytes written to the debug device. 113 | If this value is less than NumberOfBytes, then the write operation failed. 114 | 115 | **/ 116 | UINTN 117 | EFIAPI 118 | DebugPortWriteBuffer ( 119 | IN DEBUG_PORT_HANDLE Handle, 120 | IN UINT8 *Buffer, 121 | IN UINTN NumberOfBytes 122 | ); 123 | 124 | /** 125 | Polls a debug device to see if there is any data waiting to be read. 126 | 127 | Polls a debug device to see if there is any data waiting to be read. 128 | If there is data waiting to be read from the debug device, then TRUE is returned. 129 | If there is no data waiting to be read from the debug device, then FALSE is returned. 130 | 131 | @param Handle Debug port handle. 132 | 133 | @retval TRUE Data is waiting to be read from the debug device. 134 | @retval FALSE There is no data waiting to be read from the debug device. 135 | 136 | **/ 137 | BOOLEAN 138 | EFIAPI 139 | DebugPortPollBuffer ( 140 | IN DEBUG_PORT_HANDLE Handle 141 | ); 142 | 143 | #endif 144 | -------------------------------------------------------------------------------- /windbg/UefiApplication/UefiApplication.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Release 6 | x64 7 | 8 | 9 | 10 | Win32Proj 11 | {79D78FD5-8F41-442F-944E-81774DC9DF39} 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | $(SolutionDir);$(EDK_PATH)\MdePkg\Include;$(EDK_PATH)\MdePkg\Include\X64;$(EDK_PATH)\ShellPkg\Include;$(EDK_PATH)\CryptoPkg\Include 26 | 27 | 28 | 29 | UefiApplicationEntryPoint.lib;$(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug/OUTPUT/PeCoffExtraActionLib.lib;$(EDK2ROOT)/Build/SourceLevelDebugPkg/RELEASE_VS2019/X64/MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib/OUTPUT/BasePeCoffGetEntryPointLib.lib;%(AdditionalDependencies) 30 | EFI Application 31 | 4096 32 | .xdata,ERW 33 | true 34 | false 35 | 36 | 37 | false 38 | Disabled 39 | %(PreprocessorDefinitions) 40 | $(SolutionDir); 41 | false 42 | ProgramDatabase 43 | false 44 | false 45 | 46 | 47 | xcopy $(TargetPath) "E:\sym\UefiApplication.efi\0000000000000000000000000000000012000\" /E/H/C/I/Y/Q/R 48 | "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -exec bypass -Command "Stop-VM -Name testuefidbgvhdxv2 -TurnOff -Force" 49 | "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\symstore.exe" add /r /f "$(TargetPath)" /s "%SYMBOL_STORE%" /t niii 50 | "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -exec bypass -Command " Mount-VHD -Path 'F:\hyperv\testuefidbgvhdxv2\Virtual Hard Disks\testuefidbgvhdxv2.vhdx'" 51 | "C:\Windows\System32\xcopy.exe" $(TargetPath) "K:\" /E/H/C/I/Y/Q/R 52 | "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -exec bypass -Command "Dismount-VHD 'F:\hyperv\testuefidbgvhdxv2\Virtual Hard Disks\testuefidbgvhdxv2.vhdx'" 53 | 54 | 55 | "C:\Windows\System32\taskkill.exe" /f /im windbg.exe 56 | exit 0 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | Document 70 | 71 | 72 | -------------------------------------------------------------------------------- /windbg/UefiApplication/hv.asm: -------------------------------------------------------------------------------- 1 | 2 | EXTERN vtl_call_fn : QWORD 3 | EXTERN vtl_ret_fn : QWORD 4 | EXTERN signalflag : QWORD 5 | EXTERN signalvalue : QWORD 6 | EXTERN synic_message_page_val : QWORD 7 | EXTERN hv_vtl_ap_entry : PROC 8 | EXTERN hv_acquire_hypercall_input_page : PROC 9 | EXTERN hv_acquire_hypercall_output_page : PROC 10 | EXTERN ProcessSynicChannel : PROC 11 | EXTERN dumpbuf : PROC 12 | EXTERN DumpRspFunction : PROC 13 | 14 | EXTERN InitGlobalHvVtl1 : PROC 15 | EXTERN HvcallCodeVa : QWORD 16 | EXTERN HvcallCodeVaVTL1 : QWORD 17 | EXTERN SkiInitialMxCsr : DWORD 18 | 19 | .CODE 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | HVHyperCall PROC 29 | 30 | 31 | push rdi 32 | push rdx ; Store output PCPU_REG_64 33 | 34 | mov rsi, rcx 35 | 36 | ; 37 | ; Hypercall inputs 38 | ; RCX = Hypercall input value 39 | ; RDX = Input param GPA 40 | ; R8 = Output param GPA 41 | ; 42 | mov rcx, qword ptr [rsi+0h] 43 | mov rdx, qword ptr [rsi+8h] 44 | mov r8, qword ptr [rsi+10h] 45 | 46 | 47 | ; 48 | ; Extended fast hypercall (set it regardless) 49 | ; 50 | EXT_HYPERCALL_XMM_SETUP: 51 | movups xmm0, xmmword ptr[rsi+18h] 52 | movups xmm1, xmmword ptr[rsi+28h] 53 | movups xmm2, xmmword ptr[rsi+38h] 54 | movups xmm3, xmmword ptr[rsi+48h] 55 | movups xmm4, xmmword ptr[rsi+58h] 56 | movups xmm5, xmmword ptr [rsi+68h] 57 | push rsi 58 | 59 | MAKE_VMCALL: 60 | ;int 3 61 | vmcall 62 | 63 | pop rsi 64 | mov qword ptr [rsi+0h], rdx 65 | mov qword ptr [rsi+8h], r8 66 | movups xmmword ptr [rsi+10h], xmm0 67 | movups xmmword ptr [rsi+20h], xmm1 68 | movups xmmword ptr [rsi+30h], xmm2 69 | movups xmmword ptr [rsi+40h], xmm3 70 | movups xmmword ptr [rsi+50h], xmm4 71 | movups xmmword ptr [rsi+60h], xmm5 72 | 73 | pop rdx 74 | pop rdi 75 | 76 | ; 77 | ; RAX from vmcall is return code for our subroutine too 78 | ; 79 | ret 80 | HVHyperCall ENDP 81 | 82 | HVHyperCallHvCallInstallInterceptAsm PROC 83 | push rdi 84 | push rdx ; Store output PCPU_REG_64 85 | push rsi ; Store output PCPU_REG_64 86 | sub rsp ,100h 87 | 88 | call InitGlobalHvVtl1 89 | 90 | call hv_acquire_hypercall_input_page 91 | push rax 92 | call hv_acquire_hypercall_output_page 93 | mov r8,rax 94 | pop rdx 95 | mov rcx,-1 96 | mov qword ptr [rdx+0h],rcx 97 | mov rcx,0b00000002h 98 | mov qword ptr [rdx+8h],rcx 99 | mov rcx,2h 100 | mov qword ptr [rdx+10h],rcx 101 | mov rcx, 004dh 102 | call HvcallCodeVaVTL1 103 | call rax 104 | mov rcx,rax 105 | int 29h 106 | 107 | add rsp ,100h 108 | pop rsi 109 | pop rdx 110 | pop rdi 111 | 112 | ; 113 | ; RAX from vmcall is return code for our subroutine too 114 | ; 115 | ret 116 | HVHyperCallHvCallInstallInterceptAsm ENDP 117 | 118 | 119 | 120 | HVHyperCallHvCallInstallIntercept PROC 121 | 122 | 123 | push rdi 124 | push rdx ; Store output PCPU_REG_64 125 | push rsi ; Store output PCPU_REG_64 126 | 127 | sub rsp ,100h 128 | mov rcx,-1 129 | mov qword ptr [rsp+8h],rcx 130 | mov rcx,0b00000002h 131 | mov qword ptr [rsp+10h],rcx 132 | mov rcx,2h 133 | mov qword ptr [rsp+18h],rcx 134 | 135 | mov rsi, rsp 136 | 137 | ; 138 | ; Hypercall inputs 139 | ; RCX = Hypercall input value 140 | ; RDX = Input param GPA 141 | ; R8 = Output param GPA 142 | ; 143 | mov rcx, 01004dh 144 | mov rdx, qword ptr [rsi+8h] 145 | mov r8, qword ptr [rsi+10h] 146 | 147 | 148 | ; 149 | ; Extended fast hypercall (set it regardless) 150 | ; 151 | EXT_HYPERCALL_XMM_SETUP: 152 | movups xmm0, xmmword ptr[rsi+18h] 153 | movups xmm1, xmmword ptr[rsi+28h] 154 | movups xmm2, xmmword ptr[rsi+38h] 155 | movups xmm3, xmmword ptr[rsi+48h] 156 | movups xmm4, xmmword ptr[rsi+58h] 157 | movups xmm5, xmmword ptr [rsi+68h] 158 | 159 | xor rax,rax 160 | 161 | MAKE_VMCALL: 162 | ;int 3 163 | vmcall 164 | 165 | hlt 166 | 167 | mov qword ptr [rsi+0h], rdx 168 | mov qword ptr [rsi+8h], r8 169 | movups xmmword ptr [rsi+10h], xmm0 170 | movups xmmword ptr [rsi+20h], xmm1 171 | movups xmmword ptr [rsi+30h], xmm2 172 | movups xmmword ptr [rsi+40h], xmm3 173 | movups xmmword ptr [rsi+50h], xmm4 174 | movups xmmword ptr [rsi+60h], xmm5 175 | 176 | add rsp ,100h 177 | pop rsi 178 | pop rdx 179 | pop rdi 180 | 181 | ; 182 | ; RAX from vmcall is return code for our subroutine too 183 | ; 184 | ret 185 | HVHyperCallHvCallInstallIntercept ENDP 186 | 187 | 188 | 189 | MAKE_VMCALL: 190 | ;int 3 191 | vmcall 192 | ; 193 | ; RAX from vmcall is return code for our subroutine too 194 | ; 195 | ret 196 | 197 | CpuSleep PROC 198 | 199 | hlt 200 | 201 | CpuSleep ENDP 202 | 203 | CpuNOP PROC 204 | mov rcx ,rax 205 | ret 206 | CpuNOP ENDP 207 | 208 | HV_VTL_AP_ENTRY_HANDLER PROC 209 | 210 | mov rsp,rbp 211 | xor rcx,rcx 212 | xor rax,rax 213 | ldmxcsr SkiInitialMxCsr 214 | call HVHyperCallHvCallInstallInterceptAsm 215 | call hv_vtl_ap_entry 216 | mov rcx,1 217 | ;call vtl_ret_fn 218 | hlt 219 | jmp CpuSleep 220 | ret 221 | 222 | HV_VTL_AP_ENTRY_HANDLER ENDP 223 | 224 | 225 | 226 | ShvlpVtlCall PROC 227 | sub rsp, 138h 228 | lea rax, [rsp+100h] 229 | movups xmmword ptr [rsp+30h], xmm6 230 | movups xmmword ptr [rsp+40h], xmm7 231 | movups xmmword ptr [rsp+50h], xmm8 232 | movups xmmword ptr [rsp+60h], xmm9 233 | movups xmmword ptr [rsp+70h], xmm10 234 | movups xmmword ptr [rax-80h], xmm11 235 | movups xmmword ptr [rax-70h], xmm12 236 | movups xmmword ptr [rax-60h], xmm13 237 | movups xmmword ptr [rax-50h], xmm14 238 | movups xmmword ptr [rax-40h], xmm15 239 | mov [rax-8], rbp 240 | mov [rax], rbx 241 | mov [rax+8], rdi 242 | mov [rax+10h], rsi 243 | mov [rax+18h], r12 244 | mov [rax+20h], r13 245 | mov [rax+28h], r14 246 | mov [rax+30h], r15 247 | mov rax, vtl_call_fn 248 | xor ecx, ecx 249 | call rax ; ShvlpVtlCall 250 | mov rcx ,rax 251 | hlt 252 | jmp CpuSleep 253 | lea rcx, [rsp+100h] 254 | movups xmm6, xmmword ptr [rsp+30h] 255 | movups xmm7, xmmword ptr [rsp+40h] 256 | movups xmm8, xmmword ptr [rsp+50h] 257 | movups xmm9, xmmword ptr [rsp+60h] 258 | movups xmm10, xmmword ptr [rsp+70h] 259 | movups xmm11, xmmword ptr [rcx-80h] 260 | movups xmm12, xmmword ptr [rcx-70h] 261 | movups xmm13, xmmword ptr [rcx-60h] 262 | movups xmm14, xmmword ptr [rcx-50h] 263 | movups xmm15, xmmword ptr [rcx-40h] 264 | mov rbx, [rcx] 265 | mov rdi, [rcx+8] 266 | mov rsi, [rcx+10h] 267 | mov r12, [rcx+18h] 268 | mov r13, [rcx+20h] 269 | mov r14, [rcx+28h] 270 | mov r15, [rcx+30h] 271 | mov rbp, [rcx-8] 272 | add rsp, 138h 273 | ret 274 | ShvlpVtlCall ENDP 275 | 276 | 277 | 278 | 279 | hdlmsgint PROC 280 | mov signalflag,1 281 | 282 | sub rsp, 32 + 8 283 | call ProcessSynicChannel 284 | add rsp, 32 + 8 285 | 286 | IRETQ 287 | hdlmsgint ENDP 288 | 289 | 290 | 291 | 292 | EnableInterrupts PROC 293 | sti 294 | ret 295 | EnableInterrupts ENDP 296 | 297 | DisableInterrupts PROC 298 | cli 299 | ret 300 | DisableInterrupts ENDP 301 | 302 | DumpRsp PROC 303 | mov rcx,rsp 304 | sub rsp, 32 + 8 305 | call DumpRspFunction 306 | add rsp, 32 + 8 307 | ret 308 | DumpRsp ENDP 309 | END 310 | 311 | 312 | -------------------------------------------------------------------------------- /windbg/UefiApplication/hvapp.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/windbg/UefiApplication/hvapp.c -------------------------------------------------------------------------------- /windbg/UefiApplication/utils.c: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // Basic UEFI Libraries 4 | // 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | // 12 | // Boot and Runtime Services 13 | // 14 | #include 15 | #include 16 | 17 | // 18 | // Shell Library 19 | // 20 | #include 21 | 22 | 23 | #include "stdint.h" 24 | 25 | #include "utils.h" 26 | 27 | 28 | 29 | 30 | 31 | static void getByteString(uint32_t startaddr, uint8_t* bytesbuf, 32 | int bytesread) 33 | { 34 | 35 | 36 | 37 | if (bytesread < 1) { 38 | return; 39 | } 40 | 41 | if (bytesread > 16) { 42 | return; 43 | } 44 | 45 | 46 | //wchar_t* bytestr_tmp = (wchar_t*)L""; 47 | wchar_t* bytestr_hex = (wchar_t*)L""; 48 | uint8_t c[0x10]; 49 | for (int i = 0; i < bytesread; i++) { 50 | c[i] = *(bytesbuf + i); 51 | //bytestr_tmp = CatSPrint(bytestr_tmp, L"%02x ", c); 52 | } 53 | if (bytesread < 16) { 54 | for (int i = bytesread; i < 16; i++) { 55 | //bytestr_tmp = CatSPrint(bytestr_tmp, L"%02x ", 0); 56 | c[i] = 0; 57 | } 58 | } 59 | wchar_t* charstr_tmp = L""; 60 | for (int i = 0; i < bytesread; i++) { 61 | uint8_t cd = *(bytesbuf + i); 62 | if ((cd < 127) && (cd > 31) && (cd != 92) && (cd != 34) && 63 | (cd != 37)) // exclude '\'=92 and "=34 for JSON comp. 64 | { 65 | charstr_tmp = CatSPrint(charstr_tmp, L"%c", cd); 66 | } 67 | 68 | else { 69 | charstr_tmp = CatSPrint(charstr_tmp, L"."); 70 | } 71 | } 72 | int idx = 0; 73 | bytestr_hex = CatSPrint(bytestr_hex, L"%02x %02x %02x %02x ", c[idx], c[idx + 1], c[idx + 2], c[idx + 3]); 74 | idx += 4; 75 | bytestr_hex = CatSPrint(bytestr_hex, L"%02x %02x %02x %02x ", c[idx], c[idx + 1], c[idx + 2], c[idx + 3]); 76 | idx += 4; 77 | bytestr_hex = CatSPrint(bytestr_hex, L"%02x %02x %02x %02x ", c[idx], c[idx + 1], c[idx + 2], c[idx + 3]); 78 | idx += 4; 79 | bytestr_hex = CatSPrint(bytestr_hex, L"%02x %02x %02x %02x ", c[idx], c[idx + 1], c[idx + 2], c[idx + 3]); 80 | 81 | Print(L"%04x %s %s\n", startaddr, bytestr_hex, charstr_tmp); 82 | 83 | return; 84 | } 85 | 86 | static void hexdump(uint8_t* bytesbufRef, int size_len) 87 | { 88 | Print(L"hexdump! buf ptr:=> %016llx,len %08x!\n", bytesbufRef, size_len); 89 | int idx = size_len / 16; 90 | for (int i = 0; i <= idx; i++) { 91 | int len = (i * 16) + 16 > size_len ? size_len % 16 : 16; 92 | getByteString((i * 16), bytesbufRef + (i * 16), len); 93 | } 94 | return; 95 | } 96 | 97 | void dumpbuf(void* buf, int len) 98 | { 99 | hexdump((uint8_t*)buf, len); 100 | return; 101 | } 102 | 103 | void dumphex(void* buf, int len) 104 | { 105 | 106 | Print(L"{"); 107 | for (int i = 0; i < len; i++) { 108 | uint8_t c = *(((uint8_t*)buf) + i); 109 | if (i == len - 1) { 110 | Print(L"0x%02x};\r\n;", c); 111 | } 112 | else { 113 | Print(L"0x%02x,", c); 114 | } 115 | } 116 | } 117 | 118 | 119 | 120 | void 121 | hvresetmemory( 122 | void* dest, 123 | UINT32 count 124 | ) 125 | { 126 | gBS->SetMem(dest, count, 0); 127 | return; 128 | 129 | } 130 | void 131 | hvresetmemoryimp( 132 | void* dest, 133 | UINT32 count 134 | ) 135 | { 136 | UINT64* Pointer64 = (UINT64*)dest; 137 | if (count >= 8) 138 | { 139 | while (count >= 8) { 140 | *(Pointer64++) = 0; 141 | count -= 8; 142 | } 143 | } 144 | if (count > 0) { 145 | UINT8* Pointer = (UINT8*)Pointer64; 146 | while (count-- != 0) { 147 | *(Pointer++) = 0; 148 | } 149 | } 150 | return; 151 | } 152 | 153 | void* 154 | hvcopymemory( 155 | void* dest, 156 | void* src, 157 | UINT32 count 158 | ) { 159 | gBS->CopyMem(dest, src, count); 160 | return dest; 161 | } 162 | 163 | 164 | void* 165 | hvcopymemoryimp( 166 | void* dest, 167 | void* src, 168 | UINT32 count 169 | ) 170 | { 171 | 172 | UINT64* Pointer64; 173 | UINT64* Pointer264; 174 | UINT8* Pointer; 175 | UINT8* Pointer2; 176 | Pointer64 = (UINT64*)dest; 177 | Pointer264 = (UINT64*)src; 178 | if (count >= 8) 179 | { 180 | while (count >= 8) { 181 | *(Pointer64++) = *(Pointer264++); 182 | count -= 8; 183 | } 184 | } 185 | if (count > 0) { 186 | Pointer = (UINT8*)Pointer64; 187 | Pointer2 = (UINT8*)Pointer264; 188 | while (count-- != 0) { 189 | *(Pointer++) = *(Pointer2++); 190 | } 191 | } 192 | 193 | return dest; 194 | } 195 | 196 | 197 | 198 | 199 | 200 | void 201 | hvwcscpy( 202 | WCHAR* dest, 203 | WCHAR* src 204 | ) 205 | { 206 | WCHAR* Pointer = (WCHAR*)src; 207 | WCHAR* Pointer1 = (WCHAR*)dest; 208 | while (*Pointer != L'\0') { 209 | *Pointer1 = *Pointer; 210 | Pointer++; 211 | Pointer1++; 212 | } 213 | *Pointer1 = L'\0'; 214 | return; 215 | } 216 | 217 | 218 | int w2s(wchar_t* src, char* dest) 219 | { 220 | int idx = 0; 221 | 222 | wchar_t* Pointer = src; 223 | char* Pointer1 = dest; 224 | if (*Pointer == L'\0') 225 | { 226 | return idx; 227 | } 228 | 229 | while (TRUE) 230 | { 231 | if (*Pointer == L'\0') 232 | { 233 | *Pointer1 = '\0'; 234 | 235 | return idx; 236 | } 237 | else 238 | { 239 | *Pointer1 = (char)(*Pointer); 240 | Pointer++; 241 | Pointer1++; 242 | idx++; 243 | } 244 | 245 | } 246 | 247 | return idx; 248 | 249 | } -------------------------------------------------------------------------------- /windbg/UefiApplication/windbgplugin.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/windbg/UefiApplication/windbgplugin.c -------------------------------------------------------------------------------- /windbg/UefiDriver/UefiDriver.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Release 6 | x64 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | Win32Proj 29 | {DF325AB7-67A6-473E-93FF-16955AFBC063} 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | UefiDriverEntryPoint.lib;%(AdditionalDependencies) 46 | 47 | 48 | false 49 | 50 | 51 | -------------------------------------------------------------------------------- /windbg/UefiDriver/drvproto.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // 4 | // Custom Protocol GUID 5 | // 6 | #define EFI_SAMPLE_DRIVER_PROTOCOL_GUID \ 7 | { \ 8 | 0xd487ddb4, 0x008b, 0x11d9, {0xaf, 0xdc, 0x00, 0x10, 0x83, 0xff, 0xca, 0x4d } \ 9 | } 10 | extern EFI_GUID gEfiSampleDriverProtocolGuid; 11 | 12 | // 13 | // Custom Protocol Definition 14 | // 15 | typedef struct _EFI_SAMPLE_DRIVER_PROTOCOL 16 | { 17 | EFI_HANDLE SampleValue; 18 | } EFI_SAMPLE_DRIVER_PROTOCOL, *PEFI_SAMPLE_DRIVER_PROTOCOL; 19 | -------------------------------------------------------------------------------- /windbg/UefiDriver/ntint.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) Alex Ionescu. All rights reserved. 4 | 5 | Header Name: 6 | 7 | ntint.h 8 | 9 | Abstract: 10 | 11 | This header contains selected NT structures and functions from ntosp.h 12 | 13 | Author: 14 | 15 | Alex Ionescu (@aionescu) 16-Mar-2016 - Initial version 16 | 17 | Environment: 18 | 19 | Kernel mode only. 20 | 21 | --*/ 22 | 23 | #pragma once 24 | #pragma warning(disable:4201) 25 | #pragma warning(disable:4214) 26 | 27 | #define VOID void 28 | #define DECLSPEC_ALIGN(x) __declspec(align(x)) 29 | #define DECLSPEC_NORETURN __declspec(noreturn) 30 | #define FORCEINLINE __forceinline 31 | #define C_ASSERT(x) static_assert(x, "Error") 32 | #define UNREFERENCED_PARAMETER(x) (x) 33 | 34 | #ifndef TRUE 35 | #define TRUE 1 36 | #define FALSE 0 37 | #endif 38 | 39 | #define KERNEL_STACK_SIZE 24 * 1024 40 | 41 | typedef struct DECLSPEC_ALIGN(16) _M128A 42 | { 43 | UINT64 Low; 44 | INT64 High; 45 | } M128A, *PM128A; 46 | 47 | typedef struct DECLSPEC_ALIGN(16) _XSAVE_FORMAT 48 | { 49 | UINT16 ControlWord; 50 | UINT16 StatusWord; 51 | UINT8 TagWord; 52 | UINT8 Reserved1; 53 | UINT16 ErrorOpcode; 54 | UINT32 ErrorOffset; 55 | UINT16 ErrorSelector; 56 | UINT16 Reserved2; 57 | UINT32 DataOffset; 58 | UINT16 DataSelector; 59 | UINT16 Reserved3; 60 | UINT32 MxCsr; 61 | UINT32 MxCsr_Mask; 62 | M128A FloatRegisters[8]; 63 | M128A XmmRegisters[16]; 64 | UINT8 Reserved4[96]; 65 | } XSAVE_FORMAT, *PXSAVE_FORMAT; 66 | typedef XSAVE_FORMAT XMM_SAVE_AREA32, *PXMM_SAVE_AREA32; 67 | 68 | typedef struct DECLSPEC_ALIGN(16) _CONTEXT 69 | { 70 | UINT64 P1Home; 71 | UINT64 P2Home; 72 | UINT64 P3Home; 73 | UINT64 P4Home; 74 | UINT64 P5Home; 75 | UINT64 P6Home; 76 | UINT32 ContextFlags; 77 | UINT32 MxCsr; 78 | UINT16 SegCs; 79 | UINT16 SegDs; 80 | UINT16 SegEs; 81 | UINT16 SegFs; 82 | UINT16 SegGs; 83 | UINT16 SegSs; 84 | UINT32 EFlags; 85 | UINT64 Dr0; 86 | UINT64 Dr1; 87 | UINT64 Dr2; 88 | UINT64 Dr3; 89 | UINT64 Dr6; 90 | UINT64 Dr7; 91 | UINT64 Rax; 92 | UINT64 Rcx; 93 | UINT64 Rdx; 94 | UINT64 Rbx; 95 | UINT64 Rsp; 96 | UINT64 Rbp; 97 | UINT64 Rsi; 98 | UINT64 Rdi; 99 | UINT64 R8; 100 | UINT64 R9; 101 | UINT64 R10; 102 | UINT64 R11; 103 | UINT64 R12; 104 | UINT64 R13; 105 | UINT64 R14; 106 | UINT64 R15; 107 | UINT64 Rip; 108 | union 109 | { 110 | XMM_SAVE_AREA32 FltSave; 111 | struct 112 | { 113 | M128A Header[2]; 114 | M128A Legacy[8]; 115 | M128A Xmm0; 116 | M128A Xmm1; 117 | M128A Xmm2; 118 | M128A Xmm3; 119 | M128A Xmm4; 120 | M128A Xmm5; 121 | M128A Xmm6; 122 | M128A Xmm7; 123 | M128A Xmm8; 124 | M128A Xmm9; 125 | M128A Xmm10; 126 | M128A Xmm11; 127 | M128A Xmm12; 128 | M128A Xmm13; 129 | M128A Xmm14; 130 | M128A Xmm15; 131 | }; 132 | }; 133 | M128A VectorRegister[26]; 134 | UINT64 VectorControl; 135 | UINT64 DebugControl; 136 | UINT64 LastBranchToRip; 137 | UINT64 LastBranchFromRip; 138 | UINT64 LastExceptionToRip; 139 | UINT64 LastExceptionFromRip; 140 | } CONTEXT, *PCONTEXT; 141 | 142 | typedef union _LARGE_INTEGER 143 | { 144 | struct 145 | { 146 | UINT32 LowPart; 147 | INT32 HighPart; 148 | }u; 149 | UINT64 QuadPart; 150 | } LARGE_INTEGER, *PLARGE_INTEGER; 151 | -------------------------------------------------------------------------------- /windbg/UefiDriver/shv.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) Alex Ionescu. All rights reserved. 4 | 5 | Module Name: 6 | 7 | shv.c 8 | 9 | Abstract: 10 | 11 | This module implements the Driver Entry/Unload for the Simple Hyper Visor. 12 | 13 | Author: 14 | 15 | Alex Ionescu (@aionescu) 16-Mar-2016 - Initial version 16 | 17 | Environment: 18 | 19 | Kernel mode only. 20 | 21 | --*/ 22 | 23 | #include "shv.h" 24 | 25 | VOID 26 | ShvUnload ( 27 | VOID 28 | ) 29 | { 30 | // 31 | // Attempt to exit VMX root mode on all logical processors. This will 32 | // broadcast an interrupt which will execute the callback routine in 33 | // parallel on the LPs. 34 | // 35 | // Note that if SHV is not loaded on any of the LPs, this routine will not 36 | // perform any work, but will not fail in any way. 37 | // 38 | ShvOsRunCallbackOnProcessors(ShvVpUnloadCallback, NULL); 39 | 40 | // 41 | // Indicate unload 42 | // 43 | ShvOsDebugPrint("The SHV has been uninstalled.\n"); 44 | } 45 | 46 | INT32 47 | ShvLoad ( 48 | VOID 49 | ) 50 | { 51 | SHV_CALLBACK_CONTEXT callbackContext; 52 | 53 | // 54 | // Attempt to enter VMX root mode on all logical processors. This will 55 | // broadcast a DPC interrupt which will execute the callback routine in 56 | // parallel on the LPs. Send the callback routine the physical address of 57 | // the PML4 of the system process, which is what this driver entrypoint 58 | // should be executing in. 59 | // 60 | callbackContext.Cr3 = __readcr3(); 61 | callbackContext.FailureStatus = SHV_STATUS_SUCCESS; 62 | callbackContext.FailedCpu = -1; 63 | callbackContext.InitCount = 0; 64 | ShvOsRunCallbackOnProcessors(ShvVpLoadCallback, &callbackContext); 65 | 66 | // 67 | // Check if all LPs are now hypervised. Return the failure code of at least 68 | // one of them. 69 | // 70 | // Note that each VP is responsible for freeing its VP data on failure. 71 | // 72 | if (callbackContext.InitCount != ShvOsGetActiveProcessorCount()) 73 | { 74 | ShvOsDebugPrint("The SHV failed to initialize (0x%lX) Failed CPU: %d\n", 75 | callbackContext.FailureStatus, callbackContext.FailedCpu); 76 | return callbackContext.FailureStatus; 77 | } 78 | 79 | // 80 | // Indicate success. 81 | // 82 | ShvOsDebugPrint("The SHV has been installed.\n"); 83 | return SHV_STATUS_SUCCESS; 84 | } 85 | -------------------------------------------------------------------------------- /windbg/UefiDriver/shv.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) Alex Ionescu. All rights reserved. 4 | 5 | Header Name: 6 | 7 | shv.h 8 | 9 | Abstract: 10 | 11 | This header defines the structures and functions of the Simple Hyper Visor. 12 | 13 | Author: 14 | 15 | Alex Ionescu (@aionescu) 14-Mar-2016 - Initial version 16 | 17 | Environment: 18 | 19 | Kernel mode only. 20 | 21 | --*/ 22 | 23 | #pragma once 24 | #pragma warning(disable:4201) 25 | #pragma warning(disable:4214) 26 | 27 | #ifndef __BASE_H__ 28 | #include 29 | #endif 30 | #define _INC_MALLOC 31 | #include 32 | #include "ntint.h" 33 | #include "shv_x.h" 34 | 35 | typedef struct _SHV_VP_STATE 36 | { 37 | PCONTEXT VpRegs; 38 | uintptr_t GuestRip; 39 | uintptr_t GuestRsp; 40 | uintptr_t GuestEFlags; 41 | UINT16 ExitReason; 42 | UINT8 ExitVm; 43 | } SHV_VP_STATE, *PSHV_VP_STATE; 44 | 45 | typedef struct _SHV_CALLBACK_CONTEXT 46 | { 47 | UINT64 Cr3; 48 | volatile long InitCount; 49 | INT32 FailedCpu; 50 | INT32 FailureStatus; 51 | } SHV_CALLBACK_CONTEXT, *PSHV_CALLBACK_CONTEXT; 52 | 53 | SHV_CPU_CALLBACK ShvVpLoadCallback; 54 | SHV_CPU_CALLBACK ShvVpUnloadCallback; 55 | 56 | VOID 57 | ShvVmxEntry ( 58 | VOID 59 | ); 60 | 61 | INT32 62 | ShvVmxLaunchOnVp ( 63 | _In_ PSHV_VP_DATA VpData 64 | ); 65 | 66 | VOID 67 | ShvUtilConvertGdtEntry ( 68 | _In_ VOID* GdtBase, 69 | _In_ UINT16 Offset, 70 | _Out_ PVMX_GDTENTRY64 VmxGdtEntry 71 | ); 72 | 73 | UINT32 74 | ShvUtilAdjustMsr ( 75 | _In_ LARGE_INTEGER ControlValue, 76 | _In_ UINT32 DesiredValue 77 | ); 78 | 79 | PSHV_VP_DATA 80 | ShvVpAllocateData ( 81 | _In_ UINT32 CpuCount 82 | ); 83 | 84 | VOID 85 | ShvVpFreeData ( 86 | _In_ PSHV_VP_DATA Data, 87 | _In_ UINT32 CpuCount 88 | ); 89 | 90 | INT32 91 | ShvVmxLaunch ( 92 | VOID 93 | ); 94 | 95 | UINT8 96 | ShvVmxProbe ( 97 | VOID 98 | ); 99 | 100 | VOID 101 | ShvVmxEptInitialize ( 102 | _In_ PSHV_VP_DATA VpData 103 | ); 104 | 105 | DECLSPEC_NORETURN 106 | VOID 107 | ShvVpRestoreAfterLaunch ( 108 | VOID 109 | ); 110 | 111 | // 112 | // OS Layer 113 | // 114 | DECLSPEC_NORETURN 115 | VOID 116 | __cdecl 117 | ShvOsRestoreContext ( 118 | _In_ PCONTEXT ContextRecord 119 | ); 120 | 121 | VOID 122 | ShvOsCaptureContext ( 123 | _In_ PCONTEXT ContextRecord 124 | ); 125 | 126 | VOID 127 | ShvOsUnprepareProcessor ( 128 | _In_ PSHV_VP_DATA VpData 129 | ); 130 | 131 | INT32 132 | ShvOsPrepareProcessor ( 133 | _In_ PSHV_VP_DATA VpData 134 | ); 135 | 136 | INT32 137 | ShvOsGetActiveProcessorCount ( 138 | VOID 139 | ); 140 | 141 | INT32 142 | ShvOsGetCurrentProcessorNumber ( 143 | VOID 144 | ); 145 | 146 | VOID 147 | ShvOsFreeContiguousAlignedMemory ( 148 | _In_ VOID* BaseAddress, 149 | _In_ size_t Size 150 | ); 151 | 152 | VOID* 153 | ShvOsAllocateContigousAlignedMemory ( 154 | _In_ size_t Size 155 | ); 156 | 157 | UINT64 158 | ShvOsGetPhysicalAddress ( 159 | _In_ VOID* BaseAddress 160 | ); 161 | 162 | #ifndef __BASE_H__ 163 | VOID 164 | ShvOsDebugPrint ( 165 | _In_ const char* Format, 166 | ... 167 | ); 168 | #else 169 | VOID 170 | ShvOsDebugPrintWide ( 171 | _In_ const CHAR16* Format, 172 | ... 173 | ); 174 | #define ShvOsDebugPrint(format, ...) ShvOsDebugPrintWide(_CRT_WIDE(format), __VA_ARGS__) 175 | #endif 176 | 177 | VOID 178 | ShvOsRunCallbackOnProcessors ( 179 | _In_ PSHV_CPU_CALLBACK Routine, 180 | _In_opt_ VOID* Context 181 | ); 182 | 183 | extern PSHV_VP_DATA* ShvGlobalData; 184 | 185 | -------------------------------------------------------------------------------- /windbg/UefiDriver/shv_x.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) Alex Ionescu. All rights reserved. 4 | 5 | Header Name: 6 | 7 | shv_x.h 8 | 9 | Abstract: 10 | 11 | This header defines the externally visible structures and functions of the 12 | Simple Hyper Visor which are visible between the OS layer and SimpleVisor. 13 | 14 | Author: 15 | 16 | Alex Ionescu (@aionescu) 29-Aug-2016 - Initial version 17 | 18 | Environment: 19 | 20 | Kernel mode only. 21 | 22 | --*/ 23 | 24 | #pragma once 25 | 26 | #include "vmx.h" 27 | 28 | #define SHV_STATUS_SUCCESS 0 29 | #define SHV_STATUS_NOT_AVAILABLE -1 30 | #define SHV_STATUS_NO_RESOURCES -2 31 | #define SHV_STATUS_NOT_PRESENT -3 32 | 33 | #define _1GB (1 * 1024 * 1024 * 1024) 34 | #define _2MB (2 * 1024 * 1024) 35 | #define _In_ 36 | 37 | #define size_t UINT32 38 | 39 | 40 | struct _SHV_CALLBACK_CONTEXT; 41 | 42 | typedef 43 | void 44 | SHV_CPU_CALLBACK ( 45 | _In_ struct _SHV_CALLBACK_CONTEXT* Context 46 | ); 47 | typedef SHV_CPU_CALLBACK *PSHV_CPU_CALLBACK; 48 | 49 | typedef struct _SHV_SPECIAL_REGISTERS 50 | { 51 | UINT64 Cr0; 52 | UINT64 Cr3; 53 | UINT64 Cr4; 54 | UINT64 MsrGsBase; 55 | UINT16 Tr; 56 | UINT16 Ldtr; 57 | UINT64 DebugControl; 58 | UINT64 KernelDr7; 59 | KDESCRIPTOR Idtr; 60 | KDESCRIPTOR Gdtr; 61 | } SHV_SPECIAL_REGISTERS, *PSHV_SPECIAL_REGISTERS; 62 | 63 | typedef struct _SHV_MTRR_RANGE 64 | { 65 | UINT32 Enabled; 66 | UINT32 Type; 67 | UINT64 PhysicalAddressMin; 68 | UINT64 PhysicalAddressMax; 69 | } SHV_MTRR_RANGE, *PSHV_MTRR_RANGE; 70 | 71 | typedef struct _SHV_VP_DATA 72 | { 73 | union 74 | { 75 | DECLSPEC_ALIGN(PAGE_SIZE) UINT8 ShvStackLimit[KERNEL_STACK_SIZE]; 76 | struct 77 | { 78 | SHV_SPECIAL_REGISTERS SpecialRegisters; 79 | CONTEXT ContextFrame; 80 | UINT64 SystemDirectoryTableBase; 81 | LARGE_INTEGER MsrData[17]; 82 | SHV_MTRR_RANGE MtrrData[16]; 83 | UINT64 VmxOnPhysicalAddress; 84 | UINT64 VmcsPhysicalAddress; 85 | UINT64 MsrBitmapPhysicalAddress; 86 | UINT64 EptPml4PhysicalAddress; 87 | UINT32 EptControls; 88 | }; 89 | }; 90 | 91 | DECLSPEC_ALIGN(PAGE_SIZE) UINT8 MsrBitmap[PAGE_SIZE]; 92 | DECLSPEC_ALIGN(PAGE_SIZE) VMX_EPML4E Epml4[PML4E_ENTRY_COUNT]; 93 | DECLSPEC_ALIGN(PAGE_SIZE) VMX_PDPTE Epdpt[PDPTE_ENTRY_COUNT]; 94 | DECLSPEC_ALIGN(PAGE_SIZE) VMX_LARGE_PDE Epde[PDPTE_ENTRY_COUNT][PDE_ENTRY_COUNT]; 95 | 96 | DECLSPEC_ALIGN(PAGE_SIZE) VMX_VMCS VmxOn; 97 | DECLSPEC_ALIGN(PAGE_SIZE) VMX_VMCS Vmcs; 98 | } SHV_VP_DATA, *PSHV_VP_DATA; 99 | 100 | C_ASSERT(sizeof(SHV_VP_DATA) == (KERNEL_STACK_SIZE + (512 + 5) * PAGE_SIZE)); 101 | 102 | VOID 103 | _sldt ( 104 | _In_ UINT16* Ldtr 105 | ); 106 | 107 | VOID 108 | _ltr ( 109 | _In_ UINT16 Tr 110 | ); 111 | 112 | VOID 113 | _str ( 114 | _In_ UINT16* Tr 115 | ); 116 | 117 | VOID 118 | __lgdt ( 119 | _In_ VOID* Gdtr 120 | ); 121 | 122 | INT32 123 | ShvLoad ( 124 | VOID 125 | ); 126 | 127 | VOID 128 | ShvUnload ( 129 | VOID 130 | ); -------------------------------------------------------------------------------- /windbg/UefiDriver/shvutil.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) Alex Ionescu. All rights reserved. 4 | 5 | Module Name: 6 | 7 | shvutil.c 8 | 9 | Abstract: 10 | 11 | This module implements utility functions for the Simple Hyper Visor. 12 | 13 | Author: 14 | 15 | Alex Ionescu (@aionescu) 16-Mar-2016 - Initial version 16 | 17 | Environment: 18 | 19 | Kernel mode only. 20 | 21 | --*/ 22 | 23 | #include "shv.h" 24 | 25 | VOID 26 | ShvUtilConvertGdtEntry ( 27 | _In_ VOID* GdtBase, 28 | _In_ UINT16 Selector, 29 | _Out_ PVMX_GDTENTRY64 VmxGdtEntry 30 | ) 31 | { 32 | PKGDTENTRY64 gdtEntry; 33 | 34 | // 35 | // Reject LDT or NULL entries 36 | // 37 | if ((Selector == 0) || 38 | (Selector & SELECTOR_TABLE_INDEX) != 0) 39 | { 40 | VmxGdtEntry->Limit = VmxGdtEntry->AccessRights = 0; 41 | VmxGdtEntry->Base = 0; 42 | VmxGdtEntry->Selector = 0; 43 | VmxGdtEntry->Bits.Unusable = TRUE; 44 | return; 45 | } 46 | 47 | // 48 | // Read the GDT entry at the given selector, masking out the RPL bits. 49 | // 50 | gdtEntry = (PKGDTENTRY64)((uintptr_t)GdtBase + (Selector & ~RPL_MASK)); 51 | 52 | // 53 | // Write the selector directly 54 | // 55 | VmxGdtEntry->Selector = Selector; 56 | 57 | // 58 | // Use the LSL intrinsic to read the segment limit 59 | // 60 | VmxGdtEntry->Limit = __segmentlimit(Selector); 61 | 62 | // 63 | // Build the full 64-bit effective address, keeping in mind that only when 64 | // the System bit is unset, should this be done. 65 | // 66 | // NOTE: The Windows definition of KGDTENTRY64 is WRONG. The "System" field 67 | // is incorrectly defined at the position of where the AVL bit should be. 68 | // The actual location of the SYSTEM bit is encoded as the highest bit in 69 | // the "Type" field. 70 | // 71 | VmxGdtEntry->Base = ((gdtEntry->Bytes.BaseHigh << 24) | 72 | (gdtEntry->Bytes.BaseMiddle << 16) | 73 | (gdtEntry->BaseLow)) & 0xFFFFFFFF; 74 | VmxGdtEntry->Base |= ((gdtEntry->Bits.Type & 0x10) == 0) ? 75 | ((uintptr_t)gdtEntry->BaseUpper << 32) : 0; 76 | 77 | // 78 | // Load the access rights 79 | // 80 | VmxGdtEntry->AccessRights = 0; 81 | VmxGdtEntry->Bytes.Flags1 = gdtEntry->Bytes.Flags1; 82 | VmxGdtEntry->Bytes.Flags2 = gdtEntry->Bytes.Flags2; 83 | 84 | // 85 | // Finally, handle the VMX-specific bits 86 | // 87 | VmxGdtEntry->Bits.Reserved = 0; 88 | VmxGdtEntry->Bits.Unusable = !gdtEntry->Bits.Present; 89 | } 90 | 91 | UINT32 92 | ShvUtilAdjustMsr ( 93 | _In_ LARGE_INTEGER ControlValue, 94 | _In_ UINT32 DesiredValue 95 | ) 96 | { 97 | // 98 | // VMX feature/capability MSRs encode the "must be 0" bits in the high word 99 | // of their value, and the "must be 1" bits in the low word of their value. 100 | // Adjust any requested capability/feature based on these requirements. 101 | // 102 | DesiredValue &= ControlValue.u.HighPart; 103 | DesiredValue |= ControlValue.u.LowPart; 104 | return DesiredValue; 105 | } 106 | 107 | -------------------------------------------------------------------------------- /windbg/UefiDriver/shvvmxhvx64.asm: -------------------------------------------------------------------------------- 1 | ;++ 2 | ; 3 | ; Copyright (c) Alex Ionescu. All rights reserved. 4 | ; 5 | ; Module: 6 | ; 7 | ; shvvmxhvx64.asm 8 | ; 9 | ; Abstract: 10 | ; 11 | ; This module implements the AMD64-specific SimpleVisor VMENTRY routine. 12 | ; 13 | ; Author: 14 | ; 15 | ; Alex Ionescu (@aionescu) 16-Mar-2016 - Initial version 16 | ; 17 | ; Environment: 18 | ; 19 | ; Kernel mode only. 20 | ; 21 | ;-- 22 | 23 | .code 24 | 25 | extern ShvVmxEntryHandler:proc 26 | extern ShvOsCaptureContext:proc 27 | 28 | ShvVmxEntry PROC 29 | push rcx ; save the RCX register, which we spill below 30 | lea rcx, [rsp+8h] ; store the context in the stack, bias for 31 | ; the return address and the push we just did. 32 | call ShvOsCaptureContext ; save the current register state. 33 | ; note that this is a specially written function 34 | ; which has the following key characteristics: 35 | ; 1) it does not taint the value of RCX 36 | ; 2) it does not spill any registers, nor 37 | ; expect home space to be allocated for it 38 | jmp ShvVmxEntryHandler ; jump to the C code handler. we assume that it 39 | ; compiled with optimizations and does not use 40 | ; home space, which is true of release builds. 41 | ShvVmxEntry ENDP 42 | 43 | end 44 | -------------------------------------------------------------------------------- /windbg/UefiDriver/shvvp.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) Alex Ionescu. All rights reserved. 4 | 5 | Module Name: 6 | 7 | shvvp.c 8 | 9 | Abstract: 10 | 11 | This module implements Virtual Processor (VP) management for the Simple Hyper Visor. 12 | 13 | Author: 14 | 15 | Alex Ionescu (@aionescu) 16-Mar-2016 - Initial version 16 | 17 | Environment: 18 | 19 | Kernel mode only, IRQL DISPATCH_LEVEL. 20 | 21 | --*/ 22 | 23 | #include "shv.h" 24 | 25 | UINT8 26 | ShvIsOurHypervisorPresent ( 27 | VOID 28 | ) 29 | { 30 | INT32 cpuInfo[4]; 31 | 32 | // 33 | // Check if ECX[31h] ("Hypervisor Present Bit") is set in CPUID 1h 34 | // 35 | __cpuid(cpuInfo, 1); 36 | if (cpuInfo[2] & HYPERV_HYPERVISOR_PRESENT_BIT) 37 | { 38 | // 39 | // Next, check if this is a compatible Hypervisor, and if it has the 40 | // SimpleVisor signature 41 | // 42 | __cpuid(cpuInfo, HYPERV_CPUID_INTERFACE); 43 | if (cpuInfo[0] == ' vhS') 44 | { 45 | // 46 | // It's us! 47 | // 48 | return TRUE; 49 | } 50 | } 51 | 52 | // 53 | // No Hypervisor, or someone else's 54 | // 55 | return FALSE; 56 | } 57 | 58 | VOID 59 | ShvCaptureSpecialRegisters ( 60 | _In_ PSHV_SPECIAL_REGISTERS SpecialRegisters 61 | ) 62 | { 63 | // 64 | // Use compiler intrinsics to get the data we need 65 | // 66 | SpecialRegisters->Cr0 = __readcr0(); 67 | SpecialRegisters->Cr3 = __readcr3(); 68 | SpecialRegisters->Cr4 = __readcr4(); 69 | SpecialRegisters->DebugControl = __readmsr(MSR_DEBUG_CTL); 70 | SpecialRegisters->MsrGsBase = __readmsr(MSR_GS_BASE); 71 | SpecialRegisters->KernelDr7 = __readdr(7); 72 | _sgdt(&SpecialRegisters->Gdtr.Limit); 73 | __sidt(&SpecialRegisters->Idtr.Limit); 74 | 75 | // 76 | // Use OS-specific functions to get these two 77 | // 78 | _str(&SpecialRegisters->Tr); 79 | _sldt(&SpecialRegisters->Ldtr); 80 | } 81 | 82 | DECLSPEC_NORETURN 83 | VOID 84 | ShvVpRestoreAfterLaunch ( 85 | VOID 86 | ) 87 | { 88 | PSHV_VP_DATA vpData; 89 | 90 | // 91 | // Get the per-processor data. This routine temporarily executes on the 92 | // same stack as the hypervisor (using no real stack space except the home 93 | // registers), so we can retrieve the VP the same way the hypervisor does. 94 | // 95 | vpData = (PSHV_VP_DATA)((uintptr_t)_AddressOfReturnAddress() + 96 | sizeof(CONTEXT) - 97 | KERNEL_STACK_SIZE); 98 | 99 | // 100 | // Record that VMX is now enabled by returning back to ShvVpInitialize with 101 | // the Alignment Check (AC) bit set. 102 | // 103 | vpData->ContextFrame.EFlags |= EFLAGS_ALIGN_CHECK; 104 | 105 | // 106 | // And finally, restore the context, so that all register and stack 107 | // state is finally restored. 108 | // 109 | ShvOsRestoreContext(&vpData->ContextFrame); 110 | } 111 | 112 | INT32 113 | ShvVpInitialize ( 114 | _In_ PSHV_VP_DATA Data 115 | ) 116 | { 117 | INT32 status; 118 | 119 | // 120 | // Prepare any OS-specific CPU data 121 | // 122 | status = ShvOsPrepareProcessor(Data); 123 | if (status != SHV_STATUS_SUCCESS) 124 | { 125 | return status; 126 | } 127 | 128 | // Read the special control registers for this processor 129 | // Note: KeSaveStateForHibernate(&Data->HostState) can be used as a Windows 130 | // specific undocumented function that can also get this data. 131 | // 132 | ShvCaptureSpecialRegisters(&Data->SpecialRegisters); 133 | 134 | // 135 | // Then, capture the entire register state. We will need this, as once we 136 | // launch the VM, it will begin execution at the defined guest instruction 137 | // pointer, which we set to ShvVpRestoreAfterLaunch, with the registers set 138 | // to whatever value they were deep inside the VMCS/VMX initialization code. 139 | // By using RtlRestoreContext, that function sets the AC flag in EFLAGS and 140 | // returns here with our registers restored. 141 | // 142 | ShvOsCaptureContext(&Data->ContextFrame); 143 | if ((__readeflags() & EFLAGS_ALIGN_CHECK) == 0) 144 | { 145 | // 146 | // If the AC bit is not set in EFLAGS, it means that we have not yet 147 | // launched the VM. Attempt to initialize VMX on this processor. 148 | // 149 | status = ShvVmxLaunchOnVp(Data); 150 | } 151 | 152 | // 153 | // If we got here, the hypervisor is running :-) 154 | // 155 | return status; 156 | } 157 | 158 | VOID 159 | ShvVpUnloadCallback ( 160 | _In_ PSHV_CALLBACK_CONTEXT Context 161 | ) 162 | { 163 | INT32 cpuInfo[4]; 164 | PSHV_VP_DATA vpData; 165 | UNREFERENCED_PARAMETER(Context); 166 | 167 | // 168 | // Send the magic shutdown instruction sequence. It will return in EAX:EBX 169 | // the VP data for the current CPU, which we must free. 170 | // 171 | cpuInfo[0] = cpuInfo[1] = 0; 172 | __cpuidex(cpuInfo, 0x41414141, 0x42424242); 173 | 174 | // 175 | // If SimpleVisor is disabled for some reason, CPUID will return the values 176 | // of the highest valid CPUID. We use a magic value to make sure we really 177 | // are loaded and returned something valid. 178 | // 179 | if (cpuInfo[2] == 0x43434343) 180 | { 181 | __analysis_assume((cpuInfo[0] != 0) && (cpuInfo[1] != 0)); 182 | vpData = (PSHV_VP_DATA)((UINT64)cpuInfo[0] << 32 | (UINT32)cpuInfo[1]); 183 | ShvOsFreeContiguousAlignedMemory(vpData, sizeof(*vpData)); 184 | } 185 | } 186 | 187 | PSHV_VP_DATA 188 | ShvVpAllocateData ( 189 | _In_ UINT32 CpuCount 190 | ) 191 | { 192 | PSHV_VP_DATA data; 193 | 194 | // 195 | // Allocate a contiguous chunk of RAM to back this allocation 196 | // 197 | data = ShvOsAllocateContigousAlignedMemory(sizeof(*data) * CpuCount); 198 | if (data != NULL) 199 | { 200 | // 201 | // Zero out the entire data region 202 | // 203 | __stosq((UINT64*)data, 0, (sizeof(*data) / sizeof(UINT64)) * CpuCount); 204 | } 205 | 206 | // 207 | // Return what is hopefully a valid pointer, otherwise NULL. 208 | // 209 | return data; 210 | } 211 | 212 | VOID 213 | ShvVpFreeData ( 214 | _In_ PSHV_VP_DATA Data, 215 | _In_ UINT32 CpuCount 216 | ) 217 | { 218 | // 219 | // Free the contiguous chunk of RAM 220 | // 221 | ShvOsFreeContiguousAlignedMemory(Data, sizeof(*Data) * CpuCount); 222 | } 223 | 224 | VOID 225 | ShvVpLoadCallback ( 226 | _In_ PSHV_CALLBACK_CONTEXT Context 227 | ) 228 | { 229 | PSHV_VP_DATA vpData; 230 | INT32 status; 231 | 232 | vpData = NULL; 233 | 234 | // 235 | // Detect if the hardware appears to support VMX root mode to start. 236 | // No attempts are made to enable this if it is lacking or disabled. 237 | // 238 | if (!ShvVmxProbe()) 239 | { 240 | status = SHV_STATUS_NOT_AVAILABLE; 241 | goto Failure; 242 | } 243 | 244 | // 245 | // Allocate the per-VP data for this logical processor 246 | // 247 | vpData = ShvVpAllocateData(1); 248 | if (vpData == NULL) 249 | { 250 | status = SHV_STATUS_NO_RESOURCES; 251 | goto Failure; 252 | } 253 | 254 | // 255 | // First, capture the value of the PML4 for the SYSTEM process, so that all 256 | // virtual processors, regardless of which process the current LP has 257 | // interrupted, can share the correct kernel address space. 258 | // 259 | vpData->SystemDirectoryTableBase = Context->Cr3; 260 | 261 | // 262 | // Initialize the virtual processor 263 | // 264 | status = ShvVpInitialize(vpData); 265 | if (status != SHV_STATUS_SUCCESS) 266 | { 267 | // 268 | // Bail out, free the allocated per-processor data 269 | // 270 | goto Failure; 271 | } 272 | 273 | // 274 | // Our hypervisor should now be seen as present on this LP, as the SHV 275 | // correctly handles CPUID ECX features register. 276 | // 277 | if (ShvIsOurHypervisorPresent() == FALSE) 278 | { 279 | // 280 | // Free the per-processor data 281 | // 282 | status = SHV_STATUS_NOT_PRESENT; 283 | goto Failure; 284 | } 285 | 286 | // 287 | // This CPU is hyperjacked! 288 | // 289 | _InterlockedIncrement((volatile long*)&Context->InitCount); 290 | return; 291 | 292 | Failure: 293 | // 294 | // Return failure 295 | // 296 | if (vpData != NULL) 297 | { 298 | ShvVpFreeData(vpData, 1); 299 | } 300 | Context->FailedCpu = ShvOsGetCurrentProcessorNumber(); 301 | Context->FailureStatus = status; 302 | return; 303 | } 304 | -------------------------------------------------------------------------------- /windbg/UefiDriver/uefi/shvos.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) Alex Ionescu. All rights reserved. 4 | 5 | Module Name: 6 | 7 | shvos.c 8 | 9 | Abstract: 10 | 11 | This module implements the OS-facing UEFI stubs for SimpleVisor. 12 | 13 | Author: 14 | 15 | Alex Ionescu (@aionescu) 29-Aug-2016 - Initial version 16 | 17 | Environment: 18 | 19 | Kernel mode only. 20 | 21 | --*/ 22 | 23 | // 24 | // Basic UEFI Libraries 25 | // 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | // 33 | // Boot and Runtime Services 34 | // 35 | #include 36 | #include 37 | 38 | // 39 | // Multi-Processor Service 40 | // 41 | #include 42 | #include 43 | 44 | // 45 | // Variable Arguments (CRT) 46 | // 47 | //#include 48 | 49 | 50 | // 51 | // External SimpleVisor Headers 52 | // 53 | #include "..\ntint.h" 54 | #include "..\shv_x.h" 55 | 56 | // 57 | // We run on any UEFI Specification 58 | // 59 | extern CONST UINT32 _gUefiDriverRevision = 0; 60 | 61 | // 62 | // We support unload 63 | // 64 | const UINT8 _gDriverUnloadImageCount = 1; 65 | 66 | // 67 | // Our name 68 | // 69 | CHAR8 *gEfiCallerBaseName = "SimpleVisor"; 70 | 71 | // 72 | // PI Multi Processor Services Protocol 73 | // 74 | EFI_MP_SERVICES_PROTOCOL* _gPiMpService; 75 | 76 | // 77 | // TSS Segment we will use 78 | // 79 | #define KGDT64_SYS_TSS 0x60 80 | 81 | EFI_STATUS 82 | __forceinline 83 | ShvOsErrorToError ( 84 | INT32 Error 85 | ) 86 | { 87 | // 88 | // Convert the possible SimpleVisor errors into NT Hyper-V Errors 89 | // 90 | if (Error == SHV_STATUS_NOT_AVAILABLE) 91 | { 92 | return EFI_NOT_AVAILABLE_YET; 93 | } 94 | if (Error == SHV_STATUS_NO_RESOURCES) 95 | { 96 | return EFI_OUT_OF_RESOURCES; 97 | } 98 | if (Error == SHV_STATUS_NOT_PRESENT) 99 | { 100 | return EFI_NOT_FOUND; 101 | } 102 | if (Error == SHV_STATUS_SUCCESS) 103 | { 104 | return EFI_SUCCESS; 105 | } 106 | 107 | // 108 | // Unknown/unexpected error 109 | // 110 | return EFI_LOAD_ERROR; 111 | } 112 | 113 | VOID 114 | _str ( 115 | _In_ UINT16* Tr 116 | ) 117 | { 118 | // 119 | // Use the UEFI framework function 120 | // 121 | *Tr = AsmReadTr(); 122 | } 123 | 124 | VOID 125 | _sldt ( 126 | _In_ UINT16* Ldtr 127 | ) 128 | { 129 | // 130 | // Use the UEFI framework function 131 | // 132 | *Ldtr = AsmReadLdtr(); 133 | } 134 | 135 | VOID 136 | __lgdt ( 137 | _In_ IA32_DESCRIPTOR* Gdtr 138 | ) 139 | { 140 | // 141 | // Use the UEFI framework function 142 | // 143 | AsmWriteGdtr(Gdtr); 144 | } 145 | 146 | VOID 147 | ShvOsUnprepareProcessor ( 148 | _In_ PSHV_VP_DATA VpData 149 | ) 150 | { 151 | UNREFERENCED_PARAMETER(VpData); 152 | 153 | // 154 | // Nothing to do 155 | // 156 | } 157 | 158 | INT32 159 | ShvOsPrepareProcessor ( 160 | _In_ PSHV_VP_DATA VpData 161 | ) 162 | { 163 | PKGDTENTRY64 TssEntry, NewGdt; 164 | PKTSS64 Tss; 165 | KDESCRIPTOR Gdtr; 166 | 167 | // 168 | // Clear AC in case it's not been reset yet 169 | // 170 | __writeeflags(__readeflags() & ~EFLAGS_ALIGN_CHECK); 171 | 172 | // 173 | // Capture the current GDT 174 | // 175 | _sgdt(&Gdtr.Limit); 176 | 177 | // 178 | // Allocate a new GDT as big as the old one, or to cover selector 0x60 179 | // 180 | NewGdt = AllocateRuntimeZeroPool(MAX(Gdtr.Limit + 1, 181 | KGDT64_SYS_TSS + sizeof(*TssEntry))); 182 | if (NewGdt == NULL) 183 | { 184 | return SHV_STATUS_NO_RESOURCES; 185 | } 186 | 187 | // 188 | // Copy the old GDT 189 | // 190 | CopyMem(NewGdt, Gdtr.Base, Gdtr.Limit + 1); 191 | 192 | // 193 | // Allocate a TSS 194 | // 195 | Tss = AllocateRuntimeZeroPool(sizeof(*Tss)); 196 | if (Tss == NULL) 197 | { 198 | FreePool(NewGdt); 199 | return SHV_STATUS_NO_RESOURCES; 200 | } 201 | 202 | // 203 | // Fill out the TSS Entry 204 | // 205 | TssEntry = (PKGDTENTRY64)((UINT64)NewGdt + KGDT64_SYS_TSS); 206 | TssEntry->BaseLow = (UINT64)Tss & 0xffff; 207 | TssEntry->Bits.BaseMiddle = ((UINT64)Tss >> 16) & 0xff; 208 | TssEntry->Bits.BaseHigh = ((UINT64)Tss >> 24) & 0xff; 209 | TssEntry->BaseUpper = (UINT64)Tss >> 32; 210 | TssEntry->LimitLow = sizeof(KTSS64) - 1; 211 | TssEntry->Bits.Type = AMD64_TSS; 212 | TssEntry->Bits.Dpl = 0; 213 | TssEntry->Bits.Present = 1; 214 | TssEntry->Bits.System = 0; 215 | TssEntry->Bits.LongMode = 0; 216 | TssEntry->Bits.DefaultBig = 0; 217 | TssEntry->Bits.Granularity = 0; 218 | TssEntry->MustBeZero = 0; 219 | 220 | // 221 | // Load the new GDT 222 | // 223 | Gdtr.Base = NewGdt; 224 | Gdtr.Limit = KGDT64_SYS_TSS + sizeof(*TssEntry) - 1; 225 | _lgdt(&Gdtr.Limit); 226 | 227 | // 228 | // Load the task register 229 | // 230 | _ltr(KGDT64_SYS_TSS); 231 | return SHV_STATUS_SUCCESS; 232 | } 233 | 234 | VOID 235 | ShvOsRunCallbackOnProcessors ( 236 | _In_ PSHV_CPU_CALLBACK Routine, 237 | _In_ VOID* Context 238 | ) 239 | { 240 | // 241 | // Call the routine on the current CPU 242 | // 243 | Routine(Context); 244 | 245 | // 246 | // And then on all other processors 247 | // 248 | _gPiMpService->StartupAllAPs(_gPiMpService, 249 | Routine, 250 | TRUE, 251 | NULL, 252 | 0, 253 | Context, 254 | NULL); 255 | } 256 | 257 | VOID 258 | ShvOsFreeContiguousAlignedMemory ( 259 | _In_ VOID* BaseAddress, 260 | _In_ size_t Size 261 | ) 262 | { 263 | // 264 | // Free the memory 265 | // 266 | FreeAlignedPages(BaseAddress, EFI_SIZE_TO_PAGES(Size)); 267 | } 268 | 269 | VOID* 270 | ShvOsAllocateContigousAlignedMemory ( 271 | _In_ size_t Size 272 | ) 273 | { 274 | // 275 | // Allocate a contiguous chunk of RAM to back this allocation. 276 | // 277 | return AllocateAlignedRuntimePages(EFI_SIZE_TO_PAGES(Size), EFI_PAGE_SIZE); 278 | } 279 | 280 | UINT64 281 | ShvOsGetPhysicalAddress ( 282 | _In_ VOID* BaseAddress 283 | ) 284 | { 285 | // 286 | // UEFI runs with paging disabled 287 | // 288 | return (UINT64)BaseAddress; 289 | } 290 | 291 | INT32 292 | ShvOsGetCurrentProcessorNumber ( 293 | VOID 294 | ) 295 | { 296 | EFI_STATUS efiStatus; 297 | UINTN cpuIndex; 298 | 299 | // 300 | // Ask PI MP Services for the CPU index 301 | // 302 | efiStatus = _gPiMpService->WhoAmI(_gPiMpService, &cpuIndex); 303 | if (efiStatus != EFI_SUCCESS) 304 | { 305 | cpuIndex = ~0ULL; 306 | } 307 | 308 | // 309 | // Return the index 310 | // 311 | return (INT32)cpuIndex; 312 | } 313 | 314 | INT32 315 | ShvOsGetActiveProcessorCount ( 316 | VOID 317 | ) 318 | { 319 | EFI_STATUS efiStatus; 320 | UINTN cpuCount, enabledCpuCount; 321 | 322 | // 323 | // Ask PI MP Services for how many CPUs there are 324 | // 325 | efiStatus = _gPiMpService->GetNumberOfProcessors(_gPiMpService, 326 | &cpuCount, 327 | &enabledCpuCount); 328 | if (efiStatus != EFI_SUCCESS) 329 | { 330 | enabledCpuCount = 0; 331 | } 332 | 333 | // 334 | // Return the count 335 | // 336 | return (INT32)enabledCpuCount; 337 | } 338 | 339 | VOID 340 | ShvOsDebugPrintWide ( 341 | _In_ CHAR16* Format, 342 | ... 343 | ) 344 | { 345 | VA_LIST arglist; 346 | CHAR16* debugString; 347 | 348 | // 349 | // Call the debugger API 350 | // 351 | VA_START(arglist, Format); 352 | debugString = CatVSPrint(NULL, Format, arglist); 353 | Print(debugString); 354 | FreePool(debugString); 355 | VA_END(arglist); 356 | } 357 | 358 | EFI_STATUS 359 | EFIAPI 360 | UefiUnload ( 361 | IN EFI_HANDLE ImageHandle 362 | ) 363 | { 364 | // 365 | // Call the hypervisor unloadpoint 366 | // 367 | ShvUnload(); 368 | return EFI_SUCCESS; 369 | } 370 | 371 | EFI_STATUS 372 | EFIAPI 373 | UefiMain ( 374 | IN EFI_HANDLE ImageHandle, 375 | IN EFI_SYSTEM_TABLE* SystemTable 376 | ) 377 | { 378 | EFI_STATUS efiStatus; 379 | 380 | // 381 | // Find the PI MpService protocol used for multi-processor startup 382 | // 383 | efiStatus = gBS->LocateProtocol(&gEfiMpServiceProtocolGuidAux, 384 | NULL, 385 | &_gPiMpService); 386 | if (EFI_ERROR(efiStatus)) 387 | { 388 | Print(L"Unable to locate the MpServices protocol: %r\n", efiStatus); 389 | return efiStatus; 390 | } 391 | 392 | // 393 | // Call the hypervisor entrypoint 394 | // 395 | return ShvOsErrorToError(ShvLoad()); 396 | } 397 | 398 | -------------------------------------------------------------------------------- /windbg/UefiDriver/uefi/shvosx64.asm: -------------------------------------------------------------------------------- 1 | ;++ 2 | ; 3 | ; Copyright (c) Alex Ionescu. All rights reserved. 4 | ; 5 | ; Module: 6 | ; 7 | ; shvosx64.asm 8 | ; 9 | ; Abstract: 10 | ; 11 | ; This module implements AMD64-specific routines for the Simple Hyper Visor. 12 | ; 13 | ; Author: 14 | ; 15 | ; Alex Ionescu (@aionescu) 16-Mar-2016 - Initial version 16 | ; 17 | ; Environment: 18 | ; 19 | ; Kernel mode only. 20 | ; 21 | ;-- 22 | 23 | .code 24 | 25 | _ltr PROC 26 | ltr cx 27 | _ltr ENDP 28 | 29 | ShvOsCaptureContext PROC 30 | pushfq 31 | mov [rcx+78h], rax 32 | mov [rcx+80h], rcx 33 | mov [rcx+88h], rdx 34 | mov [rcx+0B8h], r8 35 | mov [rcx+0C0h], r9 36 | mov [rcx+0C8h], r10 37 | mov [rcx+0D0h], r11 38 | 39 | mov word ptr [rcx+38h], cs 40 | mov word ptr [rcx+3Ah], ds 41 | mov word ptr [rcx+3Ch], es 42 | mov word ptr [rcx+42h], ss 43 | mov word ptr [rcx+3Eh], fs 44 | mov word ptr [rcx+40h], gs 45 | 46 | mov [rcx+90h], rbx 47 | mov [rcx+0A0h], rbp 48 | mov [rcx+0A8h], rsi 49 | mov [rcx+0B0h], rdi 50 | mov [rcx+0D8h], r12 51 | mov [rcx+0E0h], r13 52 | mov [rcx+0E8h], r14 53 | mov [rcx+0F0h], r15 54 | 55 | lea rax, [rsp+10h] 56 | mov [rcx+98h], rax 57 | mov rax, [rsp+8] 58 | mov [rcx+0F8h], rax 59 | mov eax, [rsp] 60 | mov [rcx+44h], eax 61 | 62 | add rsp, 8 63 | ret 64 | ShvOsCaptureContext ENDP 65 | 66 | ShvOsRestoreContext PROC 67 | mov ax, [rcx+42h] 68 | mov [rsp+20h], ax 69 | mov rax, [rcx+98h] 70 | mov [rsp+18h], rax 71 | mov eax, [rcx+44h] 72 | mov [rsp+10h], eax 73 | mov ax, [rcx+38h] 74 | mov [rsp+8], ax 75 | mov rax, [rcx+0F8h] 76 | mov [rsp], rax 77 | 78 | mov rax, [rcx+78h] 79 | mov rdx, [rcx+88h] 80 | mov r8, [rcx+0B8h] 81 | mov r9, [rcx+0C0h] 82 | mov r10, [rcx+0C8h] 83 | mov r11, [rcx+0D0h] 84 | cli 85 | 86 | mov rbx, [rcx+90h] 87 | mov rsi, [rcx+0A8h] 88 | mov rdi, [rcx+0B0h] 89 | mov rbp, [rcx+0A0h] 90 | mov r12, [rcx+0D8h] 91 | mov r13, [rcx+0E0h] 92 | mov r14, [rcx+0E8h] 93 | mov r15, [rcx+0F0h] 94 | mov rcx, [rcx+80h] 95 | 96 | iretq 97 | ShvOsRestoreContext ENDP 98 | 99 | end 100 | -------------------------------------------------------------------------------- /windbg/UefiDriver/uefi/simplevisor.inf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/windbg/UefiDriver/uefi/simplevisor.inf -------------------------------------------------------------------------------- /windbg/UefiDriver/uefi/uefi.default.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | C:\Users\aione\Documents\GitHub\VisualUefi\edk2 6 | 7 | 8 | $(EDK_PATH)\MdePkg\Include;$(EDK_PATH)\MdePkg\Include\X64;$(EDK_PATH)\ShellPkg\Include;$(EDK_PATH)\CryptoPkg\Include 9 | $(EDK_PATH)\..\EDK-II\$(Platform)\Release 10 | 11 | 12 | Application 13 | false 14 | v141 15 | true 16 | Unicode 17 | 18 | 19 | 20 | $(EDK_PATH) 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /windbg/UefiDriver/uefi/uefi.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | .efi 7 | 8 | 9 | 10 | true 11 | Level4 12 | true 13 | true 14 | MinSpace 15 | true 16 | true 17 | AnySuitable 18 | SyncCThrow 19 | false 20 | false 21 | true 22 | $(EDK_PATH)\..\EDK-II\BaseLib\vshacks.h 23 | 24 | 25 | true 26 | false 27 | 28 | /Gs32768 %(AdditionalOptions) 29 | 30 | 31 | 32 | 33 | true 34 | UefiHiiLib.lib;UefiHiiServicesLib.lib;UefiSortLib.lib;UefiShellLib.lib;GlueLib.lib;BaseLib.lib;BaseDebugPrintErrorLevelLib.lib;BasePrintLib.lib;UefiLib.lib;UefiBootServicesTableLib.lib;UefiRuntimeServicesTableLib.lib;UefiDevicePathLibDevicePathProtocol.lib;UefiDebugLibConOut.lib;UefiMemoryLib.lib;UefiMemoryAllocationLib.lib;BaseSynchronizationLib.lib;UefiFileHandleLib.lib;UefiDriverEntryPoint.lib 35 | DebugFastLink 36 | EFI Boot Service Driver 37 | Driver 38 | true 39 | 40 | UseFastLinkTimeCodeGeneration 41 | 0 42 | 32 43 | false 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | /OPT:ICF=10 /IGNORE:4001 /IGNORE:4254 %(AdditionalOptions) 53 | .rdata=.data 54 | .xdata,D 55 | 56 | 57 | EfiMain 58 | 59 | 60 | -------------------------------------------------------------------------------- /windbg/apic-defs.h: -------------------------------------------------------------------------------- 1 | #ifndef _X86_APIC_DEFS_H_ 2 | #define _X86_APIC_DEFS_H_ 3 | 4 | /* 5 | * Abuse this header file to hold the number of max-cpus, making it available 6 | * both in C and ASM 7 | */ 8 | 9 | #define MAX_TEST_CPUS (255) 10 | 11 | /* 12 | * Constants for various Intel APICs. (local APIC, IOAPIC, etc.) 13 | * 14 | * Alan Cox , 1995. 15 | * Ingo Molnar , 1999, 2000 16 | */ 17 | #define IO_APIC_DEFAULT_PHYS_BASE 0xfec00000 18 | #define APIC_DEFAULT_PHYS_BASE 0xfee00000 19 | 20 | #define APIC_BSP (1UL << 8) 21 | #define APIC_EXTD (1UL << 10) 22 | #define APIC_EN (1UL << 11) 23 | 24 | #define APIC_ID 0x20 25 | 26 | #define APIC_LVR 0x30 27 | #define APIC_LVR_MASK 0xFF00FF 28 | #define GET_APIC_VERSION(x) ((x) & 0xFFu) 29 | #define GET_APIC_MAXLVT(x) (((x) >> 16) & 0xFFu) 30 | #ifdef CONFIG_X86_32 31 | # define APIC_INTEGRATED(x) ((x) & 0xF0u) 32 | #else 33 | # define APIC_INTEGRATED(x) (1) 34 | #endif 35 | #define APIC_XAPIC(x) ((x) >= 0x14) 36 | #define APIC_TASKPRI 0x80 37 | #define APIC_TPRI_MASK 0xFFu 38 | #define APIC_ARBPRI 0x90 39 | #define APIC_ARBPRI_MASK 0xFFu 40 | #define APIC_PROCPRI 0xA0 41 | #define APIC_EOI 0xB0 42 | #define APIC_EIO_ACK 0x0 43 | #define APIC_RRR 0xC0 44 | #define APIC_LDR 0xD0 45 | #define APIC_LDR_MASK (0xFFu << 24) 46 | #define GET_APIC_LOGICAL_ID(x) (((x) >> 24) & 0xFFu) 47 | #define SET_APIC_LOGICAL_ID(x) (((x) << 24)) 48 | #define APIC_ALL_CPUS 0xFFu 49 | #define APIC_DFR 0xE0 50 | #define APIC_DFR_CLUSTER 0x0FFFFFFFul 51 | #define APIC_DFR_FLAT 0xFFFFFFFFul 52 | #define APIC_SPIV 0xF0 53 | #define APIC_SPIV_FOCUS_DISABLED (1 << 9) 54 | #define APIC_SPIV_APIC_ENABLED (1 << 8) 55 | #define APIC_ISR 0x100 56 | #define APIC_ISR_NR 0x8 /* Number of 32 bit ISR registers. */ 57 | #define APIC_TMR 0x180 58 | #define APIC_IRR 0x200 59 | #define APIC_ESR 0x280 60 | #define APIC_ESR_SEND_CS 0x00001 61 | #define APIC_ESR_RECV_CS 0x00002 62 | #define APIC_ESR_SEND_ACC 0x00004 63 | #define APIC_ESR_RECV_ACC 0x00008 64 | #define APIC_ESR_SENDILL 0x00020 65 | #define APIC_ESR_RECVILL 0x00040 66 | #define APIC_ESR_ILLREGA 0x00080 67 | #define APIC_CMCI 0x2F0 68 | #define APIC_ICR 0x300 69 | #define APIC_DEST_SELF 0x40000 70 | #define APIC_DEST_ALLINC 0x80000 71 | #define APIC_DEST_ALLBUT 0xC0000 72 | #define APIC_ICR_RR_MASK 0x30000 73 | #define APIC_ICR_RR_INVALID 0x00000 74 | #define APIC_ICR_RR_INPROG 0x10000 75 | #define APIC_ICR_RR_VALID 0x20000 76 | #define APIC_INT_LEVELTRIG 0x08000 77 | #define APIC_INT_ASSERT 0x04000 78 | #define APIC_ICR_BUSY 0x01000 79 | #define APIC_DEST_LOGICAL 0x00800 80 | #define APIC_DEST_PHYSICAL 0x00000 81 | #define APIC_DM_FIXED 0x00000 82 | #define APIC_DM_LOWEST 0x00100 83 | #define APIC_DM_SMI 0x00200 84 | #define APIC_DM_REMRD 0x00300 85 | #define APIC_DM_NMI 0x00400 86 | #define APIC_DM_INIT 0x00500 87 | #define APIC_DM_STARTUP 0x00600 88 | #define APIC_DM_EXTINT 0x00700 89 | #define APIC_VECTOR_MASK 0x000FF 90 | #define APIC_ICR2 0x310 91 | #define GET_APIC_DEST_FIELD(x) (((x) >> 24) & 0xFF) 92 | #define SET_APIC_DEST_FIELD(x) ((x) << 24) 93 | #define APIC_LVTT 0x320 94 | #define APIC_LVTTHMR 0x330 95 | #define APIC_LVTPC 0x340 96 | #define APIC_LVT0 0x350 97 | #define APIC_LVT_TIMER_BASE_MASK (0x3 << 18) 98 | #define GET_APIC_TIMER_BASE(x) (((x) >> 18) & 0x3) 99 | #define SET_APIC_TIMER_BASE(x) (((x) << 18)) 100 | #define APIC_TIMER_BASE_CLKIN 0x0 101 | #define APIC_TIMER_BASE_TMBASE 0x1 102 | #define APIC_TIMER_BASE_DIV 0x2 103 | #define APIC_LVT_TIMER_MASK (3 << 17) 104 | #define APIC_LVT_TIMER_ONESHOT (0 << 17) 105 | #define APIC_LVT_TIMER_PERIODIC (1 << 17) 106 | #define APIC_LVT_TIMER_TSCDEADLINE (2 << 17) 107 | #define APIC_LVT_MASKED (1 << 16) 108 | #define APIC_LVT_LEVEL_TRIGGER (1 << 15) 109 | #define APIC_LVT_REMOTE_IRR (1 << 14) 110 | #define APIC_INPUT_POLARITY (1 << 13) 111 | #define APIC_SEND_PENDING (1 << 12) 112 | #define APIC_MODE_MASK 0x700 113 | #define GET_APIC_DELIVERY_MODE(x) (((x) >> 8) & 0x7) 114 | #define SET_APIC_DELIVERY_MODE(x, y) (((x) & ~0x700) | ((y) << 8)) 115 | #define APIC_MODE_FIXED 0x0 116 | #define APIC_MODE_NMI 0x4 117 | #define APIC_MODE_EXTINT 0x7 118 | #define APIC_LVT1 0x360 119 | #define APIC_LVTERR 0x370 120 | #define APIC_TMICT 0x380 121 | #define APIC_TMCCT 0x390 122 | #define APIC_TDCR 0x3E0 123 | #define APIC_SELF_IPI 0x3F0 124 | #define APIC_TDR_DIV_TMBASE (1 << 2) 125 | #define APIC_TDR_DIV_1 0xB 126 | #define APIC_TDR_DIV_2 0x0 127 | #define APIC_TDR_DIV_4 0x1 128 | #define APIC_TDR_DIV_8 0x2 129 | #define APIC_TDR_DIV_16 0x3 130 | #define APIC_TDR_DIV_32 0x8 131 | #define APIC_TDR_DIV_64 0x9 132 | #define APIC_TDR_DIV_128 0xA 133 | #define APIC_EILVT0 0x500 134 | #define APIC_EILVT_NR_AMD_K8 1 /* # of extended interrupts */ 135 | #define APIC_EILVT_NR_AMD_10H 4 136 | #define APIC_EILVT_LVTOFF(x) (((x) >> 4) & 0xF) 137 | #define APIC_EILVT_MSG_FIX 0x0 138 | #define APIC_EILVT_MSG_SMI 0x2 139 | #define APIC_EILVT_MSG_NMI 0x4 140 | #define APIC_EILVT_MSG_EXT 0x7 141 | #define APIC_EILVT_MASKED (1 << 16) 142 | #define APIC_EILVT1 0x510 143 | #define APIC_EILVT2 0x520 144 | #define APIC_EILVT3 0x530 145 | 146 | #define APIC_BASE_MSR 0x800 147 | 148 | #endif /* _X86_APIC_DEFS_H_ */ 149 | -------------------------------------------------------------------------------- /windbg/hvdev.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/windbg/hvdev.h -------------------------------------------------------------------------------- /windbg/poc.default.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | $(SolutionDir)..\edk2 6 | 7 | 8 | $(EDK_PATH)\MdePkg\Include;$(EDK_PATH)\MdePkg\Include\X64;$(EDK_PATH)\ShellPkg\Include;$(EDK_PATH)\CryptoPkg\Include 9 | $(SolutionDir)..\EDK-II\$(Platform)\$(Configuration) 10 | 11 | 12 | Application 13 | false 14 | $(DefaultPlatformToolset) 15 | true 16 | Unicode 17 | 18 | 19 | 20 | $(EDK_PATH) 21 | true 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /windbg/poc.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | $(SolutionDir)$(Platform)\$(Configuration)\obj\$(TargetName)\ 7 | $(SolutionDir)$(Platform)\$(Configuration)\ 8 | .efi 9 | 10 | 11 | ..\debugger\qemu.exe 12 | -name "VisualUEFI Debugger" -drive file=OVMF_CODE-need-smm.fd,if=pflash,format=raw,unit=0,readonly=on -drive file=OVMF_VARS-need-smm.fd,if=pflash,format=raw,unit=1 -drive file=fat:rw:..\samples\$(Platform)\$(Configuration)\,media=disk,if=virtio,format=raw -drive file=UefiShell.iso,format=raw -m 512 -machine q35,smm=on -nodefaults -vga std -global driver=cfi.pflash01,property=secure,value=on -global ICH9-LPC.disable_s3=1 13 | ..\..\debugger 14 | Script 15 | WindowsLocalDebugger 16 | 17 | 18 | 19 | true 20 | Level4 21 | true 22 | true 23 | MinSpace 24 | true 25 | true 26 | AnySuitable 27 | SyncCThrow 28 | false 29 | false 30 | true 31 | $(SolutionDir)..\EDK-II\BaseLib\vshacks.h 32 | 33 | 34 | true 35 | false 36 | 37 | /Gs32768 %(AdditionalOptions) 38 | 39 | 40 | 41 | 42 | true 43 | UefiHiiLib.lib;UefiHiiServicesLib.lib;UefiSortLib.lib;UefiShellLib.lib;GlueLib.lib;BaseLib.lib;BaseDebugPrintErrorLevelLib.lib;BasePrintLib.lib;UefiLib.lib;UefiBootServicesTableLib.lib;UefiRuntimeServicesTableLib.lib;UefiDevicePathLibDevicePathProtocol.lib;UefiDebugLibConOut.lib;UefiMemoryLib.lib;UefiMemoryAllocationLib.lib;BaseSynchronizationLib.lib;UefiFileHandleLib.lib 44 | DebugFastLink 45 | EFI Boot Service Driver 46 | Driver 47 | true 48 | 49 | UseFastLinkTimeCodeGeneration 50 | 0 51 | 32 52 | false 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | /OPT:ICF=10 /IGNORE:4001 /IGNORE:4254 /IGNORE:4281 %(AdditionalOptions) 62 | .rdata=.data 63 | .xdata,D 64 | 65 | 66 | EfiMain 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /windbg/poc.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.34301.259 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UefiApplication", "UefiApplication\UefiApplication.vcxproj", "{79D78FD5-8F41-442F-944E-81774DC9DF39}" 7 | ProjectSection(ProjectDependencies) = postProject 8 | {DF325AB7-67A6-473E-93FF-16955AFBC064} = {DF325AB7-67A6-473E-93FF-16955AFBC064} 9 | EndProjectSection 10 | EndProject 11 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UefiDriver", "UefiDriver\UefiDriver.vcxproj", "{DF325AB7-67A6-473E-93FF-16955AFBC063}" 12 | EndProject 13 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FtdiUsbSerialDxe", "FtdiUsbSerialDxe\FtdiUsbSerialDxe.vcxproj", "{DF325AB7-67A6-473E-93FF-16955AFBC064}" 14 | EndProject 15 | Global 16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 17 | Release|x64 = Release|x64 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {79D78FD5-8F41-442F-944E-81774DC9DF39}.Release|x64.ActiveCfg = Release|x64 21 | {79D78FD5-8F41-442F-944E-81774DC9DF39}.Release|x64.Build.0 = Release|x64 22 | {DF325AB7-67A6-473E-93FF-16955AFBC063}.Release|x64.ActiveCfg = Release|x64 23 | {DF325AB7-67A6-473E-93FF-16955AFBC063}.Release|x64.Build.0 = Release|x64 24 | {DF325AB7-67A6-473E-93FF-16955AFBC064}.Release|x64.ActiveCfg = Release|x64 25 | {DF325AB7-67A6-473E-93FF-16955AFBC064}.Release|x64.Build.0 = Release|x64 26 | EndGlobalSection 27 | GlobalSection(SolutionProperties) = preSolution 28 | HideSolutionNode = FALSE 29 | EndGlobalSection 30 | GlobalSection(ExtensibilityGlobals) = postSolution 31 | SolutionGuid = {A91357C2-47D0-4DCA-8614-0AB5CF386845} 32 | EndGlobalSection 33 | EndGlobal 34 | -------------------------------------------------------------------------------- /windbg/rtlfuncs.h: -------------------------------------------------------------------------------- 1 | /*++ NDK Version: 0098 2 | 3 | Copyright (c) Alex Ionescu. All rights reserved. 4 | 5 | Header Name: 6 | 7 | rtlfuncs.h 8 | 9 | Abstract: 10 | 11 | Function definitions for the Run-Time Library 12 | 13 | Author: 14 | 15 | Alex Ionescu (alexi@tinykrnl.org) - Updated - 27-Feb-2006 16 | 17 | --*/ 18 | 19 | #ifndef _RTLFUNCS_H 20 | #define _RTLFUNCS_H 21 | 22 | 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | 29 | 30 | // 31 | // List Functions 32 | // 33 | FORCEINLINE 34 | VOID 35 | InitializeListHeadUefi( 36 | _Out_ PLIST_ENTRY_UEFI ListHead 37 | ) 38 | { 39 | ListHead->Flink = ListHead->Blink = ListHead; 40 | return; 41 | } 42 | 43 | FORCEINLINE 44 | VOID 45 | InsertHeadListUefi( 46 | _Inout_ PLIST_ENTRY_UEFI ListHead, 47 | _Inout_ PLIST_ENTRY_UEFI Entry 48 | ) 49 | { 50 | PLIST_ENTRY_UEFI OldFlink; 51 | OldFlink = ListHead->Flink; 52 | Entry->Flink = OldFlink; 53 | Entry->Blink = ListHead; 54 | OldFlink->Blink = Entry; 55 | ListHead->Flink = Entry; 56 | } 57 | 58 | FORCEINLINE 59 | VOID 60 | InsertTailListUefi( 61 | _Inout_ PLIST_ENTRY_UEFI ListHead, 62 | _Inout_ PLIST_ENTRY_UEFI Entry 63 | ) 64 | { 65 | PLIST_ENTRY_UEFI OldBlink; 66 | OldBlink = ListHead->Blink; 67 | Entry->Flink = ListHead; 68 | Entry->Blink = OldBlink; 69 | OldBlink->Flink = Entry; 70 | ListHead->Blink = Entry; 71 | return; 72 | } 73 | 74 | _Must_inspect_result_ 75 | FORCEINLINE 76 | BOOLEAN 77 | IsListEmptyUefi( 78 | _In_ const PLIST_ENTRY_UEFI ListHead 79 | ) 80 | { 81 | return (BOOLEAN)(ListHead->Flink == ListHead); 82 | } 83 | 84 | 85 | FORCEINLINE 86 | int 87 | ListSizeUefi( 88 | _In_ const PLIST_ENTRY_UEFI ListHead 89 | ) 90 | { 91 | int idx = 0; 92 | PLIST_ENTRY_UEFI Entry = ListHead->Flink; 93 | if (Entry != ListHead) 94 | { 95 | idx = 1; 96 | } 97 | while (Entry->Flink != ListHead) 98 | { 99 | idx++; 100 | Entry = Entry->Flink; 101 | 102 | } 103 | return idx; 104 | } 105 | 106 | 107 | 108 | FORCEINLINE 109 | BOOLEAN 110 | RemoveEntryListUefi( 111 | _In_ PLIST_ENTRY_UEFI Entry) 112 | { 113 | PLIST_ENTRY_UEFI OldFlink; 114 | PLIST_ENTRY_UEFI OldBlink; 115 | 116 | OldFlink = Entry->Flink; 117 | OldBlink = Entry->Blink; 118 | OldFlink->Blink = OldBlink; 119 | OldBlink->Flink = OldFlink; 120 | return (BOOLEAN)(OldFlink == OldBlink); 121 | } 122 | 123 | FORCEINLINE 124 | PLIST_ENTRY_UEFI 125 | RemoveHeadListUefi( 126 | _Inout_ PLIST_ENTRY_UEFI ListHead) 127 | { 128 | PLIST_ENTRY_UEFI Flink; 129 | PLIST_ENTRY_UEFI Entry; 130 | 131 | Entry = ListHead->Flink; 132 | Flink = Entry->Flink; 133 | ListHead->Flink = Flink; 134 | Flink->Blink = ListHead; 135 | return Entry; 136 | } 137 | 138 | FORCEINLINE 139 | PLIST_ENTRY_UEFI 140 | RemoveTailListUefi( 141 | _Inout_ PLIST_ENTRY_UEFI ListHead) 142 | { 143 | PLIST_ENTRY_UEFI Blink; 144 | PLIST_ENTRY_UEFI Entry; 145 | 146 | Entry = ListHead->Blink; 147 | Blink = Entry->Blink; 148 | ListHead->Blink = Blink; 149 | Blink->Flink = ListHead; 150 | return Entry; 151 | } 152 | 153 | 154 | #ifdef __cplusplus 155 | } 156 | #endif 157 | 158 | #endif 159 | -------------------------------------------------------------------------------- /windbg/uefiintsafe.h: -------------------------------------------------------------------------------- 1 | /*! 2 | * \file intsafe.h 3 | * 4 | * \brief Windows helper functions for integer overflow prevention 5 | * 6 | * \package This file is part of the ReactOS PSDK package. 7 | * 8 | * \author 9 | * Timo Kreuzer (timo.kreuzer@reactos.org) 10 | * 11 | * \copyright THIS SOFTWARE IS NOT COPYRIGHTED 12 | * 13 | * This source code is offered for use in the public domain. You may 14 | * use, modify or distribute it freely. 15 | * 16 | * This code is distributed in the hope that it will be useful but 17 | * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY 18 | * DISCLAIMED. This includes but is not limited to warranties of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 20 | * 21 | * \todo 22 | * - missing conversion functions 23 | * - multiplication functions 24 | * - signed add, sub and multiply functions 25 | */ 26 | #pragma once 27 | 28 | #ifndef _INTSAFE_H_INCLUDED_ 29 | #define _INTSAFE_H_INCLUDED_ 30 | 31 | #include 32 | 33 | /* Handle ntintsafe here too */ 34 | 35 | typedef long NTSTATUS; 36 | 37 | typedef wchar_t WCHAR; // wc, 16-bit UNICODE character 38 | 39 | #define NTAPI __stdcall 40 | #define DECLSPEC_ALIGN(x) __declspec(align(x)) 41 | #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) 42 | #define STATUS_SUCCESS ((NTSTATUS)0x00000000) 43 | #define STATUS_INTEGER_OVERFLOW ((NTSTATUS)0xC0000095) 44 | #define INTSAFE_RESULT NTSTATUS 45 | #define INTSAFE_SUCCESS STATUS_SUCCESS 46 | #define INTSAFE_E_ARITHMETIC_OVERFLOW STATUS_INTEGER_OVERFLOW 47 | #define INTSAFE_NAME(name) Rtl##name 48 | #else // _NTINTSAFE_H_INCLUDED_ 49 | #ifndef _HRESULT_DEFINED 50 | typedef _Return_type_success_(return >= 0) long HRESULT; 51 | #endif 52 | #ifndef SUCCEEDED 53 | #define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0) 54 | #define FAILED(hr) (((HRESULT)(hr)) < 0) 55 | #define S_OK ((HRESULT)0L) 56 | #endif 57 | #define INTSAFE_RESULT HRESULT 58 | #define INTSAFE_SUCCESS S_OK 59 | #define INTSAFE_E_ARITHMETIC_OVERFLOW ((HRESULT)0x80070216L) 60 | #define INTSAFE_NAME(name) name 61 | #endif // _NTINTSAFE_H_INCLUDED_ 62 | 63 | 64 | #define FORCEINLINE __inline 65 | 66 | 67 | /* min/max helper macros */ 68 | 69 | # ifndef min 70 | # define min(a,b) (((a) < (b)) ? (a) : (b)) 71 | # endif 72 | # ifndef max 73 | # define max(a,b) (((a) > (b)) ? (a) : (b)) 74 | # endif 75 | 76 | 77 | #ifndef FlagOn 78 | #define FlagOn(_F,_SF) ((_F) & (_SF)) 79 | #endif 80 | 81 | #ifndef BooleanFlagOn 82 | #define BooleanFlagOn(F,SF) ((BOOLEAN)(((F) & (SF)) != 0)) 83 | #endif 84 | 85 | #ifndef SetFlag 86 | #define SetFlag(_F,_SF) ((_F) |= (_SF)) 87 | #endif 88 | 89 | #ifndef ClearFlag 90 | #define ClearFlag(_F,_SF) ((_F) &= ~(_SF)) 91 | #endif 92 | 93 | #if !defined(_W64) 94 | #if defined(_MSC_VER) && !defined(__midl) && (defined(_M_IX86) || defined(_M_ARM)) 95 | #define _W64 __w64 96 | #else 97 | #define _W64 98 | #endif 99 | #endif 100 | #define ANSI_NULL 0 101 | /* Static assert */ 102 | #ifndef C_ASSERT 103 | #ifdef _MSC_VER 104 | # define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1] 105 | #else 106 | # define C_ASSERT(e) extern void __C_ASSERT__(int [(e)?1:-1]) 107 | #endif 108 | #endif /* C_ASSERT */ 109 | 110 | /* Computed page size */ 111 | #define VSM_PAGE_SIZE 0x1000 112 | #define VSM_PAGE_SIZE_DOUBLE 0x2000 113 | 114 | /* Typedefs */ 115 | #ifndef _WINNT_ 116 | #ifndef _NTDEF_ 117 | typedef char CHAR; 118 | typedef unsigned char UCHAR, UINT8; 119 | typedef signed char INT8; 120 | typedef short SHORT; 121 | typedef signed short INT16; 122 | typedef unsigned short USHORT, UINT16; 123 | typedef int INT; 124 | typedef unsigned int UINT32; 125 | typedef signed int INT32; 126 | typedef long LONG; 127 | typedef unsigned long ULONG; 128 | typedef long long LONGLONG, LONG64; 129 | typedef signed long long INT64; 130 | typedef unsigned long long ULONGLONG, DWORDLONG, ULONG64, DWORD64, UINT64; 131 | #ifdef _WIN64 132 | typedef long long INT_PTR, LONG_PTR, SSIZE_T, ptrdiff_t; 133 | typedef unsigned long long UINT_PTR, ULONG_PTR, DWORD_PTR, SIZE_T, size_t; 134 | #else // _WIN64 135 | typedef _W64 int INT_PTR, ptrdiff_t; 136 | typedef _W64 unsigned int UINT_PTR, size_t; 137 | typedef _W64 long LONG_PTR, SSIZE_T; 138 | typedef _W64 unsigned long ULONG_PTR, DWORD_PTR, SIZE_T; 139 | #endif // _WIN64 140 | #endif 141 | typedef unsigned char BYTE; 142 | typedef unsigned short WORD; 143 | typedef unsigned int UINT; 144 | typedef unsigned long DWORD; 145 | #endif // _WINNT_ 146 | typedef DWORD* PDWORD; 147 | typedef void* PVOID; 148 | typedef void* LPVOID; 149 | typedef BYTE* PUCHAR; 150 | typedef char* PCHAR; 151 | typedef char* PCSTR; 152 | typedef ULONG* PULONG; 153 | typedef USHORT * PUSHORT; 154 | typedef unsigned __int64 ULONG_PTR, * PULONG_PTR; 155 | 156 | typedef BOOLEAN *PBOOLEAN; 157 | 158 | typedef struct _STRING 159 | { 160 | volatile USHORT Length; 161 | volatile USHORT MaximumLength; 162 | volatile PCHAR Buffer; 163 | } STRING, * PSTRING; 164 | 165 | typedef struct LIST_ENTRY32 { 166 | ULONG Flink; 167 | ULONG Blink; 168 | } LIST_ENTRY32; 169 | typedef LIST_ENTRY32* PLIST_ENTRY32; 170 | 171 | typedef struct LIST_ENTRY64 { 172 | ULONGLONG Flink; 173 | ULONGLONG Blink; 174 | } LIST_ENTRY64; 175 | typedef LIST_ENTRY64* PLIST_ENTRY64; 176 | 177 | /* Singly Linked Lists */ 178 | typedef struct _SINGLE_LIST_ENTRY { 179 | struct _SINGLE_LIST_ENTRY* Next; 180 | } SINGLE_LIST_ENTRY, * PSINGLE_LIST_ENTRY; 181 | 182 | typedef struct _UINT128 { 183 | 184 | UINT64 Low64; 185 | UINT64 High64; 186 | 187 | } UINT128, *PUINT128; 188 | 189 | typedef UINT128 M128A; 190 | 191 | typedef struct _UINT256 { 192 | 193 | UINT128 Low128; 194 | UINT128 High128; 195 | 196 | } UINT256, *PUINT256; 197 | 198 | typedef union _ULARGE_INTEGER { 199 | 200 | struct 201 | { 202 | DWORD LowPart; 203 | DWORD HighPart; 204 | } u; 205 | ULONGLONG QuadPart; 206 | } ULARGE_INTEGER, *PULARGE_INTEGER; 207 | 208 | 209 | typedef union _LARGE_INTEGER { 210 | 211 | struct 212 | { 213 | DWORD LowPart; 214 | DWORD HighPart; 215 | } u; 216 | ULONGLONG QuadPart; 217 | } LARGE_INTEGER, *PLARGE_INTEGER; 218 | 219 | 220 | 221 | /* Linked Lists */ 222 | typedef struct _LIST_ENTRY_UEFI { 223 | struct _LIST_ENTRY_UEFI* Flink; 224 | struct _LIST_ENTRY_UEFI* Blink; 225 | } LIST_ENTRY_UEFI, *PLIST_ENTRY_UEFI; 226 | 227 | static int PAGE_SIZE = VSM_PAGE_SIZE; 228 | 229 | size_t inline ALIGN_UP(size_t x) 230 | { 231 | return ((PAGE_SIZE - 1) & x) ? ((x + PAGE_SIZE) & ~(PAGE_SIZE - 1)) : x; 232 | } 233 | 234 | size_t inline ALIGN_UP_FIX(size_t x, size_t y) 235 | { 236 | return ((y - 1) & x) ? ((x + y) & ~(y - 1)) : x; 237 | } -------------------------------------------------------------------------------- /windbg/utils.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __PI_UTILS_H__ 3 | #define __PI_UTILS_H__ 4 | 5 | #include "uefiintsafe.h" 6 | typedef enum 7 | { 8 | KDP_PACKET_RECEIVED = 0, 9 | KDP_PACKET_TIMEOUT = 1, 10 | KDP_PACKET_RESEND = 2, 11 | KDP_PACKET_RECHECK = 3, 12 | KDP_PACKET_CONTINUE = 4 13 | } KDP_STATUS; 14 | void 15 | hvresetmemory( 16 | void* dest, 17 | UINT32 count 18 | ); 19 | void* 20 | hvcomparememory( 21 | void* dest, 22 | void* src, 23 | UINT32 count 24 | ); 25 | void 26 | hvwcscpy( 27 | WCHAR* dest, 28 | WCHAR* src 29 | ); 30 | void* 31 | hvcopymemory( 32 | void* dest, 33 | void* src, 34 | UINT32 count); 35 | void stall(int multi); 36 | //void * 37 | //CopyMem( 38 | // void* Destination, 39 | // const void* Source, 40 | // UINT32 Length 41 | //); 42 | void dumpbuf(void* buf, int len); 43 | 44 | WCHAR* GetPDBInfo(UINT8* m_pBuffer, UINT32* m_pCheckSum, UINT32* m_pSizeOfImage); 45 | WCHAR* GetModuleName(UINT8* m_pBuffer, UINT32* m_pCheckSum, UINT32* m_pSizeOfImage); 46 | int w2s(wchar_t* src, char* dest); 47 | VOID 48 | EFIAPI 49 | DisableInterrupts( 50 | VOID 51 | ); 52 | VOID 53 | EFIAPI 54 | EnableInterrupts( 55 | VOID 56 | ); 57 | 58 | 59 | VOID 60 | NTAPI 61 | KdpDprintf( 62 | _In_ CHAR16* FormatString, 63 | ...); 64 | 65 | 66 | #define HYPERVISOR_CALLBACK_VECTOR 0x27 67 | 68 | #endif -------------------------------------------------------------------------------- /windbg/windbg.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbwang505/windbg-uefi/2f90de0c0c00edf24cce963e51f77d08b4b0694f/windbg/windbg.h --------------------------------------------------------------------------------