├── .gitignore ├── COPYING ├── Driver ├── Driver.vcxproj ├── Driver.vcxproj.filters ├── LICENSE ├── driver.cpp ├── ioctl.h ├── x64.asm └── x86.asm ├── DriverBins ├── Driver_x64.sys ├── Driver_x86.sys └── LICENSE ├── LICENSE ├── NtdllCrt ├── NtdllCrt.vcxproj ├── NtdllCrt.vcxproj.filters └── ntdll.def ├── README.md ├── SaferIO.h ├── SaferIO.sln ├── SaferIO ├── LICENSE ├── SaferIO.vcxproj ├── SaferIO.vcxproj.filters ├── dllmain.cpp ├── global.h ├── ioctl.cpp ├── ioctl.h ├── ntos.h ├── resource.h ├── resource.rc ├── sup.cpp └── sup.h └── TestApp ├── TestApp.vcxproj ├── TestApp.vcxproj.filters └── main.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | bld/ 19 | [Bb]in/ 20 | [Oo]bj/ 21 | [Ll]og/ 22 | 23 | # Visual Studio 2015 cache/options directory 24 | .vs/ 25 | # Uncomment if you have tasks that create the project's static files in wwwroot 26 | #wwwroot/ 27 | 28 | # MSTest test Results 29 | [Tt]est[Rr]esult*/ 30 | [Bb]uild[Ll]og.* 31 | 32 | # NUNIT 33 | *.VisualState.xml 34 | TestResult.xml 35 | 36 | # Build Results of an ATL Project 37 | [Dd]ebugPS/ 38 | [Rr]eleasePS/ 39 | dlldata.c 40 | 41 | # DNX 42 | project.lock.json 43 | project.fragment.lock.json 44 | artifacts/ 45 | 46 | *_i.c 47 | *_p.c 48 | *_i.h 49 | *.ilk 50 | *.meta 51 | *.obj 52 | *.pch 53 | *.pdb 54 | *.pgc 55 | *.pgd 56 | *.rsp 57 | *.sbr 58 | *.tlb 59 | *.tli 60 | *.tlh 61 | *.tmp 62 | *.tmp_proj 63 | *.log 64 | *.vspscc 65 | *.vssscc 66 | .builds 67 | *.pidb 68 | *.svclog 69 | *.scc 70 | 71 | # Chutzpah Test files 72 | _Chutzpah* 73 | 74 | # Visual C++ cache files 75 | ipch/ 76 | *.aps 77 | *.ncb 78 | *.opendb 79 | *.opensdf 80 | *.sdf 81 | *.cachefile 82 | *.VC.db 83 | *.VC.VC.opendb 84 | 85 | # Visual Studio profiler 86 | *.psess 87 | *.vsp 88 | *.vspx 89 | *.sap 90 | 91 | # TFS 2012 Local Workspace 92 | $tf/ 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | *.DotSettings.user 101 | 102 | # JustCode is a .NET coding add-in 103 | .JustCode 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | _NCrunch_* 113 | .*crunch*.local.xml 114 | nCrunchTemp_* 115 | 116 | # MightyMoose 117 | *.mm.* 118 | AutoTest.Net/ 119 | 120 | # Web workbench (sass) 121 | .sass-cache/ 122 | 123 | # Installshield output folder 124 | [Ee]xpress/ 125 | 126 | # DocProject is a documentation generator add-in 127 | DocProject/buildhelp/ 128 | DocProject/Help/*.HxT 129 | DocProject/Help/*.HxC 130 | DocProject/Help/*.hhc 131 | DocProject/Help/*.hhk 132 | DocProject/Help/*.hhp 133 | DocProject/Help/Html2 134 | DocProject/Help/html 135 | 136 | # Click-Once directory 137 | publish/ 138 | 139 | # Publish Web Output 140 | *.[Pp]ublish.xml 141 | *.azurePubxml 142 | # TODO: Comment the next line if you want to checkin your web deploy settings 143 | # but database connection strings (with potential passwords) will be unencrypted 144 | #*.pubxml 145 | *.publishproj 146 | 147 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 148 | # checkin your Azure Web App publish settings, but sensitive information contained 149 | # in these scripts will be unencrypted 150 | PublishScripts/ 151 | 152 | # NuGet Packages 153 | *.nupkg 154 | # The packages folder can be ignored because of Package Restore 155 | **/packages/* 156 | # except build/, which is used as an MSBuild target. 157 | !**/packages/build/ 158 | # Uncomment if necessary however generally it will be regenerated when needed 159 | #!**/packages/repositories.config 160 | # NuGet v3's project.json files produces more ignoreable files 161 | *.nuget.props 162 | *.nuget.targets 163 | 164 | # Microsoft Azure Build Output 165 | csx/ 166 | *.build.csdef 167 | 168 | # Microsoft Azure Emulator 169 | ecf/ 170 | rcf/ 171 | 172 | # Windows Store app package directories and files 173 | AppPackages/ 174 | BundleArtifacts/ 175 | Package.StoreAssociation.xml 176 | _pkginfo.txt 177 | 178 | # Visual Studio cache files 179 | # files ending in .cache can be ignored 180 | *.[Cc]ache 181 | # but keep track of directories ending in .cache 182 | !*.[Cc]ache/ 183 | 184 | # Others 185 | ClientBin/ 186 | ~$* 187 | *~ 188 | *.dbmdl 189 | *.dbproj.schemaview 190 | *.jfm 191 | *.pfx 192 | *.publishsettings 193 | node_modules/ 194 | orleans.codegen.cs 195 | 196 | # Since there are multiple workflows, uncomment next line to ignore bower_components 197 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 198 | #bower_components/ 199 | 200 | # RIA/Silverlight projects 201 | Generated_Code/ 202 | 203 | # Backup & report files from converting an old project file 204 | # to a newer Visual Studio version. Backup files are not needed, 205 | # because we have git ;-) 206 | _UpgradeReport_Files/ 207 | Backup*/ 208 | UpgradeLog*.XML 209 | UpgradeLog*.htm 210 | 211 | # SQL Server files 212 | *.mdf 213 | *.ldf 214 | 215 | # Business Intelligence projects 216 | *.rdl.data 217 | *.bim.layout 218 | *.bim_*.settings 219 | 220 | # Microsoft Fakes 221 | FakesAssemblies/ 222 | 223 | # GhostDoc plugin setting file 224 | *.GhostDoc.xml 225 | 226 | # Node.js Tools for Visual Studio 227 | .ntvs_analysis.dat 228 | 229 | # Visual Studio 6 build log 230 | *.plg 231 | 232 | # Visual Studio 6 workspace options file 233 | *.opt 234 | 235 | # Visual Studio LightSwitch build output 236 | **/*.HTMLClient/GeneratedArtifacts 237 | **/*.DesktopClient/GeneratedArtifacts 238 | **/*.DesktopClient/ModelManifest.xml 239 | **/*.Server/GeneratedArtifacts 240 | **/*.Server/ModelManifest.xml 241 | _Pvt_Extensions 242 | 243 | # Paket dependency manager 244 | .paket/paket.exe 245 | paket-files/ 246 | 247 | # FAKE - F# Make 248 | .fake/ 249 | 250 | # JetBrains Rider 251 | .idea/ 252 | *.sln.iml 253 | 254 | # CodeRush 255 | .cr/ 256 | 257 | # Python Tools for Visual Studio (PTVS) 258 | __pycache__/ 259 | *.pyc -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 2.1, February 1999 3 | 4 | Copyright (C) 1991, 1999 Free Software Foundation, Inc. 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | [This is the first released version of the Lesser GPL. It also counts 10 | as the successor of the GNU Library Public License, version 2, hence 11 | the version number 2.1.] 12 | 13 | Preamble 14 | 15 | The licenses for most software are designed to take away your 16 | freedom to share and change it. By contrast, the GNU General Public 17 | Licenses are intended to guarantee your freedom to share and change 18 | free software--to make sure the software is free for all its users. 19 | 20 | This license, the Lesser General Public License, applies to some 21 | specially designated software packages--typically libraries--of the 22 | Free Software Foundation and other authors who decide to use it. You 23 | can use it too, but we suggest you first think carefully about whether 24 | this license or the ordinary General Public License is the better 25 | strategy to use in any particular case, based on the explanations below. 26 | 27 | When we speak of free software, we are referring to freedom of use, 28 | not price. Our General Public Licenses are designed to make sure that 29 | you have the freedom to distribute copies of free software (and charge 30 | for this service if you wish); that you receive source code or can get 31 | it if you want it; that you can change the software and use pieces of 32 | it in new free programs; and that you are informed that you can do 33 | these things. 34 | 35 | To protect your rights, we need to make restrictions that forbid 36 | distributors to deny you these rights or to ask you to surrender these 37 | rights. These restrictions translate to certain responsibilities for 38 | you if you distribute copies of the library or if you modify it. 39 | 40 | For example, if you distribute copies of the library, whether gratis 41 | or for a fee, you must give the recipients all the rights that we gave 42 | you. You must make sure that they, too, receive or can get the source 43 | code. If you link other code with the library, you must provide 44 | complete object files to the recipients, so that they can relink them 45 | with the library after making changes to the library and recompiling 46 | it. And you must show them these terms so they know their rights. 47 | 48 | We protect your rights with a two-step method: (1) we copyright the 49 | library, and (2) we offer you this license, which gives you legal 50 | permission to copy, distribute and/or modify the library. 51 | 52 | To protect each distributor, we want to make it very clear that 53 | there is no warranty for the free library. Also, if the library is 54 | modified by someone else and passed on, the recipients should know 55 | that what they have is not the original version, so that the original 56 | author's reputation will not be affected by problems that might be 57 | introduced by others. 58 | 59 | Finally, software patents pose a constant threat to the existence of 60 | any free program. We wish to make sure that a company cannot 61 | effectively restrict the users of a free program by obtaining a 62 | restrictive license from a patent holder. Therefore, we insist that 63 | any patent license obtained for a version of the library must be 64 | consistent with the full freedom of use specified in this license. 65 | 66 | Most GNU software, including some libraries, is covered by the 67 | ordinary GNU General Public License. This license, the GNU Lesser 68 | General Public License, applies to certain designated libraries, and 69 | is quite different from the ordinary General Public License. We use 70 | this license for certain libraries in order to permit linking those 71 | libraries into non-free programs. 72 | 73 | When a program is linked with a library, whether statically or using 74 | a shared library, the combination of the two is legally speaking a 75 | combined work, a derivative of the original library. The ordinary 76 | General Public License therefore permits such linking only if the 77 | entire combination fits its criteria of freedom. The Lesser General 78 | Public License permits more lax criteria for linking other code with 79 | the library. 80 | 81 | We call this license the "Lesser" General Public License because it 82 | does Less to protect the user's freedom than the ordinary General 83 | Public License. It also provides other free software developers Less 84 | of an advantage over competing non-free programs. These disadvantages 85 | are the reason we use the ordinary General Public License for many 86 | libraries. However, the Lesser license provides advantages in certain 87 | special circumstances. 88 | 89 | For example, on rare occasions, there may be a special need to 90 | encourage the widest possible use of a certain library, so that it becomes 91 | a de-facto standard. To achieve this, non-free programs must be 92 | allowed to use the library. A more frequent case is that a free 93 | library does the same job as widely used non-free libraries. In this 94 | case, there is little to gain by limiting the free library to free 95 | software only, so we use the Lesser General Public License. 96 | 97 | In other cases, permission to use a particular library in non-free 98 | programs enables a greater number of people to use a large body of 99 | free software. For example, permission to use the GNU C Library in 100 | non-free programs enables many more people to use the whole GNU 101 | operating system, as well as its variant, the GNU/Linux operating 102 | system. 103 | 104 | Although the Lesser General Public License is Less protective of the 105 | users' freedom, it does ensure that the user of a program that is 106 | linked with the Library has the freedom and the wherewithal to run 107 | that program using a modified version of the Library. 108 | 109 | The precise terms and conditions for copying, distribution and 110 | modification follow. Pay close attention to the difference between a 111 | "work based on the library" and a "work that uses the library". The 112 | former contains code derived from the library, whereas the latter must 113 | be combined with the library in order to run. 114 | 115 | GNU LESSER GENERAL PUBLIC LICENSE 116 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 117 | 118 | 0. This License Agreement applies to any software library or other 119 | program which contains a notice placed by the copyright holder or 120 | other authorized party saying it may be distributed under the terms of 121 | this Lesser General Public License (also called "this License"). 122 | Each licensee is addressed as "you". 123 | 124 | A "library" means a collection of software functions and/or data 125 | prepared so as to be conveniently linked with application programs 126 | (which use some of those functions and data) to form executables. 127 | 128 | The "Library", below, refers to any such software library or work 129 | which has been distributed under these terms. A "work based on the 130 | Library" means either the Library or any derivative work under 131 | copyright law: that is to say, a work containing the Library or a 132 | portion of it, either verbatim or with modifications and/or translated 133 | straightforwardly into another language. (Hereinafter, translation is 134 | included without limitation in the term "modification".) 135 | 136 | "Source code" for a work means the preferred form of the work for 137 | making modifications to it. For a library, complete source code means 138 | all the source code for all modules it contains, plus any associated 139 | interface definition files, plus the scripts used to control compilation 140 | and installation of the library. 141 | 142 | Activities other than copying, distribution and modification are not 143 | covered by this License; they are outside its scope. The act of 144 | running a program using the Library is not restricted, and output from 145 | such a program is covered only if its contents constitute a work based 146 | on the Library (independent of the use of the Library in a tool for 147 | writing it). Whether that is true depends on what the Library does 148 | and what the program that uses the Library does. 149 | 150 | 1. You may copy and distribute verbatim copies of the Library's 151 | complete source code as you receive it, in any medium, provided that 152 | you conspicuously and appropriately publish on each copy an 153 | appropriate copyright notice and disclaimer of warranty; keep intact 154 | all the notices that refer to this License and to the absence of any 155 | warranty; and distribute a copy of this License along with the 156 | Library. 157 | 158 | You may charge a fee for the physical act of transferring a copy, 159 | and you may at your option offer warranty protection in exchange for a 160 | fee. 161 | 162 | 2. You may modify your copy or copies of the Library or any portion 163 | of it, thus forming a work based on the Library, and copy and 164 | distribute such modifications or work under the terms of Section 1 165 | above, provided that you also meet all of these conditions: 166 | 167 | a) The modified work must itself be a software library. 168 | 169 | b) You must cause the files modified to carry prominent notices 170 | stating that you changed the files and the date of any change. 171 | 172 | c) You must cause the whole of the work to be licensed at no 173 | charge to all third parties under the terms of this License. 174 | 175 | d) If a facility in the modified Library refers to a function or a 176 | table of data to be supplied by an application program that uses 177 | the facility, other than as an argument passed when the facility 178 | is invoked, then you must make a good faith effort to ensure that, 179 | in the event an application does not supply such function or 180 | table, the facility still operates, and performs whatever part of 181 | its purpose remains meaningful. 182 | 183 | (For example, a function in a library to compute square roots has 184 | a purpose that is entirely well-defined independent of the 185 | application. Therefore, Subsection 2d requires that any 186 | application-supplied function or table used by this function must 187 | be optional: if the application does not supply it, the square 188 | root function must still compute square roots.) 189 | 190 | These requirements apply to the modified work as a whole. If 191 | identifiable sections of that work are not derived from the Library, 192 | and can be reasonably considered independent and separate works in 193 | themselves, then this License, and its terms, do not apply to those 194 | sections when you distribute them as separate works. But when you 195 | distribute the same sections as part of a whole which is a work based 196 | on the Library, the distribution of the whole must be on the terms of 197 | this License, whose permissions for other licensees extend to the 198 | entire whole, and thus to each and every part regardless of who wrote 199 | it. 200 | 201 | Thus, it is not the intent of this section to claim rights or contest 202 | your rights to work written entirely by you; rather, the intent is to 203 | exercise the right to control the distribution of derivative or 204 | collective works based on the Library. 205 | 206 | In addition, mere aggregation of another work not based on the Library 207 | with the Library (or with a work based on the Library) on a volume of 208 | a storage or distribution medium does not bring the other work under 209 | the scope of this License. 210 | 211 | 3. You may opt to apply the terms of the ordinary GNU General Public 212 | License instead of this License to a given copy of the Library. To do 213 | this, you must alter all the notices that refer to this License, so 214 | that they refer to the ordinary GNU General Public License, version 2, 215 | instead of to this License. (If a newer version than version 2 of the 216 | ordinary GNU General Public License has appeared, then you can specify 217 | that version instead if you wish.) Do not make any other change in 218 | these notices. 219 | 220 | Once this change is made in a given copy, it is irreversible for 221 | that copy, so the ordinary GNU General Public License applies to all 222 | subsequent copies and derivative works made from that copy. 223 | 224 | This option is useful when you wish to copy part of the code of 225 | the Library into a program that is not a library. 226 | 227 | 4. You may copy and distribute the Library (or a portion or 228 | derivative of it, under Section 2) in object code or executable form 229 | under the terms of Sections 1 and 2 above provided that you accompany 230 | it with the complete corresponding machine-readable source code, which 231 | must be distributed under the terms of Sections 1 and 2 above on a 232 | medium customarily used for software interchange. 233 | 234 | If distribution of object code is made by offering access to copy 235 | from a designated place, then offering equivalent access to copy the 236 | source code from the same place satisfies the requirement to 237 | distribute the source code, even though third parties are not 238 | compelled to copy the source along with the object code. 239 | 240 | 5. A program that contains no derivative of any portion of the 241 | Library, but is designed to work with the Library by being compiled or 242 | linked with it, is called a "work that uses the Library". Such a 243 | work, in isolation, is not a derivative work of the Library, and 244 | therefore falls outside the scope of this License. 245 | 246 | However, linking a "work that uses the Library" with the Library 247 | creates an executable that is a derivative of the Library (because it 248 | contains portions of the Library), rather than a "work that uses the 249 | library". The executable is therefore covered by this License. 250 | Section 6 states terms for distribution of such executables. 251 | 252 | When a "work that uses the Library" uses material from a header file 253 | that is part of the Library, the object code for the work may be a 254 | derivative work of the Library even though the source code is not. 255 | Whether this is true is especially significant if the work can be 256 | linked without the Library, or if the work is itself a library. The 257 | threshold for this to be true is not precisely defined by law. 258 | 259 | If such an object file uses only numerical parameters, data 260 | structure layouts and accessors, and small macros and small inline 261 | functions (ten lines or less in length), then the use of the object 262 | file is unrestricted, regardless of whether it is legally a derivative 263 | work. (Executables containing this object code plus portions of the 264 | Library will still fall under Section 6.) 265 | 266 | Otherwise, if the work is a derivative of the Library, you may 267 | distribute the object code for the work under the terms of Section 6. 268 | Any executables containing that work also fall under Section 6, 269 | whether or not they are linked directly with the Library itself. 270 | 271 | 6. As an exception to the Sections above, you may also combine or 272 | link a "work that uses the Library" with the Library to produce a 273 | work containing portions of the Library, and distribute that work 274 | under terms of your choice, provided that the terms permit 275 | modification of the work for the customer's own use and reverse 276 | engineering for debugging such modifications. 277 | 278 | You must give prominent notice with each copy of the work that the 279 | Library is used in it and that the Library and its use are covered by 280 | this License. You must supply a copy of this License. If the work 281 | during execution displays copyright notices, you must include the 282 | copyright notice for the Library among them, as well as a reference 283 | directing the user to the copy of this License. Also, you must do one 284 | of these things: 285 | 286 | a) Accompany the work with the complete corresponding 287 | machine-readable source code for the Library including whatever 288 | changes were used in the work (which must be distributed under 289 | Sections 1 and 2 above); and, if the work is an executable linked 290 | with the Library, with the complete machine-readable "work that 291 | uses the Library", as object code and/or source code, so that the 292 | user can modify the Library and then relink to produce a modified 293 | executable containing the modified Library. (It is understood 294 | that the user who changes the contents of definitions files in the 295 | Library will not necessarily be able to recompile the application 296 | to use the modified definitions.) 297 | 298 | b) Use a suitable shared library mechanism for linking with the 299 | Library. A suitable mechanism is one that (1) uses at run time a 300 | copy of the library already present on the user's computer system, 301 | rather than copying library functions into the executable, and (2) 302 | will operate properly with a modified version of the library, if 303 | the user installs one, as long as the modified version is 304 | interface-compatible with the version that the work was made with. 305 | 306 | c) Accompany the work with a written offer, valid for at 307 | least three years, to give the same user the materials 308 | specified in Subsection 6a, above, for a charge no more 309 | than the cost of performing this distribution. 310 | 311 | d) If distribution of the work is made by offering access to copy 312 | from a designated place, offer equivalent access to copy the above 313 | specified materials from the same place. 314 | 315 | e) Verify that the user has already received a copy of these 316 | materials or that you have already sent this user a copy. 317 | 318 | For an executable, the required form of the "work that uses the 319 | Library" must include any data and utility programs needed for 320 | reproducing the executable from it. However, as a special exception, 321 | the materials to be distributed need not include anything that is 322 | normally distributed (in either source or binary form) with the major 323 | components (compiler, kernel, and so on) of the operating system on 324 | which the executable runs, unless that component itself accompanies 325 | the executable. 326 | 327 | It may happen that this requirement contradicts the license 328 | restrictions of other proprietary libraries that do not normally 329 | accompany the operating system. Such a contradiction means you cannot 330 | use both them and the Library together in an executable that you 331 | distribute. 332 | 333 | 7. You may place library facilities that are a work based on the 334 | Library side-by-side in a single library together with other library 335 | facilities not covered by this License, and distribute such a combined 336 | library, provided that the separate distribution of the work based on 337 | the Library and of the other library facilities is otherwise 338 | permitted, and provided that you do these two things: 339 | 340 | a) Accompany the combined library with a copy of the same work 341 | based on the Library, uncombined with any other library 342 | facilities. This must be distributed under the terms of the 343 | Sections above. 344 | 345 | b) Give prominent notice with the combined library of the fact 346 | that part of it is a work based on the Library, and explaining 347 | where to find the accompanying uncombined form of the same work. 348 | 349 | 8. You may not copy, modify, sublicense, link with, or distribute 350 | the Library except as expressly provided under this License. Any 351 | attempt otherwise to copy, modify, sublicense, link with, or 352 | distribute the Library is void, and will automatically terminate your 353 | rights under this License. However, parties who have received copies, 354 | or rights, from you under this License will not have their licenses 355 | terminated so long as such parties remain in full compliance. 356 | 357 | 9. You are not required to accept this License, since you have not 358 | signed it. However, nothing else grants you permission to modify or 359 | distribute the Library or its derivative works. These actions are 360 | prohibited by law if you do not accept this License. Therefore, by 361 | modifying or distributing the Library (or any work based on the 362 | Library), you indicate your acceptance of this License to do so, and 363 | all its terms and conditions for copying, distributing or modifying 364 | the Library or works based on it. 365 | 366 | 10. Each time you redistribute the Library (or any work based on the 367 | Library), the recipient automatically receives a license from the 368 | original licensor to copy, distribute, link with or modify the Library 369 | subject to these terms and conditions. You may not impose any further 370 | restrictions on the recipients' exercise of the rights granted herein. 371 | You are not responsible for enforcing compliance by third parties with 372 | this License. 373 | 374 | 11. If, as a consequence of a court judgment or allegation of patent 375 | infringement or for any other reason (not limited to patent issues), 376 | conditions are imposed on you (whether by court order, agreement or 377 | otherwise) that contradict the conditions of this License, they do not 378 | excuse you from the conditions of this License. If you cannot 379 | distribute so as to satisfy simultaneously your obligations under this 380 | License and any other pertinent obligations, then as a consequence you 381 | may not distribute the Library at all. For example, if a patent 382 | license would not permit royalty-free redistribution of the Library by 383 | all those who receive copies directly or indirectly through you, then 384 | the only way you could satisfy both it and this License would be to 385 | refrain entirely from distribution of the Library. 386 | 387 | If any portion of this section is held invalid or unenforceable under any 388 | particular circumstance, the balance of the section is intended to apply, 389 | and the section as a whole is intended to apply in other circumstances. 390 | 391 | It is not the purpose of this section to induce you to infringe any 392 | patents or other property right claims or to contest validity of any 393 | such claims; this section has the sole purpose of protecting the 394 | integrity of the free software distribution system which is 395 | implemented by public license practices. Many people have made 396 | generous contributions to the wide range of software distributed 397 | through that system in reliance on consistent application of that 398 | system; it is up to the author/donor to decide if he or she is willing 399 | to distribute software through any other system and a licensee cannot 400 | impose that choice. 401 | 402 | This section is intended to make thoroughly clear what is believed to 403 | be a consequence of the rest of this License. 404 | 405 | 12. If the distribution and/or use of the Library is restricted in 406 | certain countries either by patents or by copyrighted interfaces, the 407 | original copyright holder who places the Library under this License may add 408 | an explicit geographical distribution limitation excluding those countries, 409 | so that distribution is permitted only in or among countries not thus 410 | excluded. In such case, this License incorporates the limitation as if 411 | written in the body of this License. 412 | 413 | 13. The Free Software Foundation may publish revised and/or new 414 | versions of the Lesser General Public License from time to time. 415 | Such new versions will be similar in spirit to the present version, 416 | but may differ in detail to address new problems or concerns. 417 | 418 | Each version is given a distinguishing version number. If the Library 419 | specifies a version number of this License which applies to it and 420 | "any later version", you have the option of following the terms and 421 | conditions either of that version or of any later version published by 422 | the Free Software Foundation. If the Library does not specify a 423 | license version number, you may choose any version ever published by 424 | the Free Software Foundation. 425 | 426 | 14. If you wish to incorporate parts of the Library into other free 427 | programs whose distribution conditions are incompatible with these, 428 | write to the author to ask for permission. For software which is 429 | copyrighted by the Free Software Foundation, write to the Free 430 | Software Foundation; we sometimes make exceptions for this. Our 431 | decision will be guided by the two goals of preserving the free status 432 | of all derivatives of our free software and of promoting the sharing 433 | and reuse of software generally. 434 | 435 | NO WARRANTY 436 | 437 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 438 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 439 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 440 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY 441 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 442 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 443 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE 444 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME 445 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 446 | 447 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 448 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 449 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU 450 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR 451 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 452 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 453 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 454 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF 455 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 456 | DAMAGES. 457 | 458 | END OF TERMS AND CONDITIONS 459 | 460 | How to Apply These Terms to Your New Libraries 461 | 462 | If you develop a new library, and you want it to be of the greatest 463 | possible use to the public, we recommend making it free software that 464 | everyone can redistribute and change. You can do so by permitting 465 | redistribution under these terms (or, alternatively, under the terms of the 466 | ordinary General Public License). 467 | 468 | To apply these terms, attach the following notices to the library. It is 469 | safest to attach them to the start of each source file to most effectively 470 | convey the exclusion of warranty; and each file should have at least the 471 | "copyright" line and a pointer to where the full notice is found. 472 | 473 | 474 | Copyright (C) 475 | 476 | This library is free software; you can redistribute it and/or 477 | modify it under the terms of the GNU Lesser General Public 478 | License as published by the Free Software Foundation; either 479 | version 2.1 of the License, or (at your option) any later version. 480 | 481 | This library is distributed in the hope that it will be useful, 482 | but WITHOUT ANY WARRANTY; without even the implied warranty of 483 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 484 | Lesser General Public License for more details. 485 | 486 | You should have received a copy of the GNU Lesser General Public 487 | License along with this library; if not, write to the Free Software 488 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 489 | 490 | Also add information on how to contact you by electronic and paper mail. 491 | 492 | You should also get your employer (if you work as a programmer) or your 493 | school, if any, to sign a "copyright disclaimer" for the library, if 494 | necessary. Here is a sample; alter the names: 495 | 496 | Yoyodyne, Inc., hereby disclaims all copyright interest in the 497 | library `Frob' (a library for tweaking knobs) written by James Random Hacker. 498 | 499 | , 1 April 1990 500 | Ty Coon, President of Vice 501 | 502 | That's all there is to it! 503 | -------------------------------------------------------------------------------- /Driver/Driver.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {C81DE704-2CD2-4416-8F7D-9F5069C51A3C} 23 | {dd38f7fc-d7bd-488b-9242-7d8754cde80d} 24 | v4.5 25 | 12.0 26 | Debug 27 | Win32 28 | Driver 29 | 30 | 31 | 32 | Windows10 33 | true 34 | WindowsKernelModeDriver10.0 35 | Driver 36 | WDM 37 | 38 | 39 | Windows10 40 | false 41 | WindowsKernelModeDriver10.0 42 | Driver 43 | WDM 44 | 45 | 46 | Windows10 47 | true 48 | WindowsKernelModeDriver10.0 49 | Driver 50 | WDM 51 | 52 | 53 | Windows10 54 | false 55 | WindowsKernelModeDriver10.0 56 | Driver 57 | WDM 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | DbgengKernelDebugger 69 | false 70 | 71 | 72 | DbgengKernelDebugger 73 | false 74 | 75 | 76 | DbgengKernelDebugger 77 | false 78 | 79 | 80 | DbgengKernelDebugger 81 | false 82 | 83 | 84 | 85 | $(DDK_LIB_PATH)\Wdmsec.lib;%(AdditionalDependencies) 86 | 87 | 88 | MinSpace 89 | 90 | 91 | true 92 | 93 | 94 | 95 | 96 | $(DDK_LIB_PATH)\Wdmsec.lib;%(AdditionalDependencies) 97 | 98 | 99 | true 100 | 101 | 102 | 103 | 104 | $(DDK_LIB_PATH)\Wdmsec.lib;%(AdditionalDependencies) 105 | 106 | 107 | MinSpace 108 | 109 | 110 | true 111 | 112 | 113 | 114 | 115 | $(DDK_LIB_PATH)\Wdmsec.lib;%(AdditionalDependencies) 116 | 117 | 118 | true 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | true 133 | true 134 | 135 | 136 | true 137 | true 138 | 139 | 140 | 141 | 142 | 143 | -------------------------------------------------------------------------------- /Driver/Driver.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 | Source Files 24 | 25 | 26 | 27 | 28 | Header Files 29 | 30 | 31 | 32 | 33 | Source Files 34 | 35 | 36 | Source Files 37 | 38 | 39 | -------------------------------------------------------------------------------- /Driver/LICENSE: -------------------------------------------------------------------------------- 1 | SPDX-License-Identifier: LGPL-2.1-or-later 2 | 3 | We use LGPL 2.1 here since it lacks anti-tivoization clause which would 4 | prevent Microsoft from WHQL signing it. 5 | 6 | SaferIO Driver - Simple giveio-style driver with secure access 7 | Copyright (C) 2021 namazso 8 | 9 | This library is free software; you can redistribute it and/or 10 | modify it under the terms of the GNU Lesser General Public 11 | License as published by the Free Software Foundation; either 12 | version 2.1 of the License, or (at your option) any later version. 13 | 14 | This library is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | Lesser General Public License for more details. 18 | 19 | You should have received a copy of the GNU Lesser General Public 20 | License along with this library; if not, write to the Free Software 21 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | -------------------------------------------------------------------------------- /Driver/driver.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-2.1-or-later 2 | // 3 | // We use LGPL 2.1 here since it lacks anti-tivoization clause which would 4 | // prevent Microsoft from WHQL signing it. 5 | // 6 | // SaferIO Driver - Simple giveio-style driver with secure access 7 | // Copyright (C) 2021 namazso 8 | // 9 | // This library is free software; you can redistribute it and/or 10 | // modify it under the terms of the GNU Lesser General Public 11 | // License as published by the Free Software Foundation; either 12 | // version 2.1 of the License, or (at your option) any later version. 13 | // 14 | // This library is distributed in the hope that it will be useful, 15 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | // Lesser General Public License for more details. 18 | // 19 | // You should have received a copy of the GNU Lesser General Public 20 | // License along with this library; if not, write to the Free Software 21 | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "ioctl.h" 28 | 29 | #define NT_DEVICE_BASE_PATH L"\\Device\\" 30 | #define DOS_DEVICE_BASE_PATH L"\\DosDevices\\" 31 | 32 | #define ALLOC_TAG 'dOIS' 33 | 34 | const UNICODE_STRING PHYSICAL_MEMORY = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory"); 35 | 36 | EXTERN_C DRIVER_INITIALIZE DriverEntry; 37 | 38 | _Dispatch_type_(IRP_MJ_CREATE) 39 | DRIVER_DISPATCH IrpCreate; 40 | 41 | _Dispatch_type_(IRP_MJ_CLOSE) 42 | DRIVER_DISPATCH IrpClose; 43 | 44 | _Dispatch_type_(IRP_MJ_DEVICE_CONTROL) 45 | DRIVER_DISPATCH IrpDeviceControl; 46 | 47 | DRIVER_UNLOAD DriverUnload; 48 | 49 | UNICODE_STRING g_NtDevicePath{}; 50 | UNICODE_STRING g_DosDevicePath{}; 51 | PDEVICE_OBJECT g_DeviceObject{}; 52 | LONG g_RefCount{}; 53 | 54 | NTSTATUS DriverEntry( 55 | _In_ PDRIVER_OBJECT DriverObject, 56 | _In_ PUNICODE_STRING RegistryPath 57 | ) 58 | { 59 | UNREFERENCED_PARAMETER(RegistryPath); 60 | 61 | NTSTATUS Status = STATUS_SUCCESS; 62 | 63 | const auto& DriverName = DriverObject->DriverName; 64 | 65 | const auto NtDevicePathSize = DriverName.Length + sizeof(NT_DEVICE_BASE_PATH) + sizeof(WCHAR); 66 | const auto NtDevicePathBuffer = (PWSTR)ExAllocatePoolZero(NonPagedPool, NtDevicePathSize, ALLOC_TAG); 67 | 68 | if (NtDevicePathBuffer) 69 | { 70 | const auto DosDevicePathSize = DriverName.Length + sizeof(DOS_DEVICE_BASE_PATH) + sizeof(WCHAR); 71 | const auto DosDevicePathBuffer = (PWSTR)ExAllocatePoolZero(NonPagedPool, NtDevicePathSize, ALLOC_TAG); 72 | 73 | if (DosDevicePathBuffer) 74 | { 75 | wcscpy(NtDevicePathBuffer, NT_DEVICE_BASE_PATH); 76 | wcscpy(DosDevicePathBuffer, DOS_DEVICE_BASE_PATH); 77 | 78 | g_NtDevicePath = { 79 | sizeof(NT_DEVICE_BASE_PATH) - sizeof(WCHAR), 80 | (USHORT)NtDevicePathSize, 81 | NtDevicePathBuffer 82 | }; 83 | g_DosDevicePath = { 84 | sizeof(DOS_DEVICE_BASE_PATH) - sizeof(WCHAR), 85 | (USHORT)DosDevicePathSize, 86 | DosDevicePathBuffer 87 | }; 88 | 89 | RtlAppendUnicodeStringToString(&g_NtDevicePath, &DriverName); 90 | RtlAppendUnicodeStringToString(&g_DosDevicePath, &DriverName); 91 | 92 | Status = WdmlibIoCreateDeviceSecure( 93 | DriverObject, 94 | 0, 95 | &g_NtDevicePath, 96 | FILE_DEVICE_UNKNOWN, 97 | FILE_DEVICE_SECURE_OPEN, 98 | FALSE, 99 | &SDDL_DEVOBJ_SYS_ALL_ADM_ALL, 100 | nullptr, 101 | &g_DeviceObject 102 | ); 103 | 104 | if (NT_SUCCESS(Status)) 105 | { 106 | Status = IoCreateSymbolicLink(&g_DosDevicePath, &g_NtDevicePath); 107 | 108 | if (NT_SUCCESS(Status)) 109 | { 110 | DriverObject->MajorFunction[IRP_MJ_CREATE] = IrpCreate; 111 | DriverObject->MajorFunction[IRP_MJ_CLOSE] = IrpClose; 112 | DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IrpDeviceControl; 113 | 114 | DriverObject->DriverUnload = DriverUnload; 115 | 116 | DriverObject->Flags &= ~DO_DEVICE_INITIALIZING; 117 | 118 | return Status; 119 | } 120 | 121 | IoDeleteDevice(g_DeviceObject); 122 | } 123 | 124 | ExFreePool(DosDevicePathBuffer); 125 | } 126 | else 127 | { 128 | Status = STATUS_NO_MEMORY; 129 | } 130 | 131 | ExFreePool(NtDevicePathBuffer); 132 | } 133 | else 134 | { 135 | Status = STATUS_NO_MEMORY; 136 | } 137 | 138 | return Status; 139 | } 140 | 141 | VOID DriverUnload( 142 | _In_ PDRIVER_OBJECT DriverObject 143 | ) 144 | { 145 | UNREFERENCED_PARAMETER(DriverObject); 146 | 147 | IoDeleteSymbolicLink(&g_DosDevicePath); 148 | IoDeleteDevice(g_DeviceObject); 149 | RtlFreeUnicodeString(&g_NtDevicePath); 150 | RtlFreeUnicodeString(&g_DosDevicePath); 151 | } 152 | 153 | NTSTATUS IrpCreate( 154 | PDEVICE_OBJECT DeviceObject, 155 | PIRP Irp 156 | ) 157 | { 158 | UNREFERENCED_PARAMETER(DeviceObject); 159 | 160 | OBJECT_ATTRIBUTES ObjectAttributes; 161 | InitializeObjectAttributes( 162 | &ObjectAttributes, 163 | const_cast(&PHYSICAL_MEMORY), 164 | OBJ_CASE_INSENSITIVE, 165 | (HANDLE)nullptr, 166 | (PSECURITY_DESCRIPTOR)nullptr 167 | ); 168 | 169 | HANDLE PhysicalMemory{}; 170 | const auto Status = ZwOpenSection( 171 | &PhysicalMemory, 172 | SECTION_ALL_ACCESS, 173 | &ObjectAttributes 174 | ); 175 | 176 | if (NT_SUCCESS(Status)) 177 | { 178 | const auto Stack = IoGetCurrentIrpStackLocation(Irp); 179 | Stack->FileObject->FsContext = (PVOID)PhysicalMemory; 180 | 181 | InterlockedIncrement(&g_RefCount); 182 | } 183 | 184 | Irp->IoStatus.Status = Status; 185 | Irp->IoStatus.Information = 0; 186 | 187 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 188 | 189 | return Status; 190 | } 191 | 192 | NTSTATUS IrpClose( 193 | PDEVICE_OBJECT DeviceObject, 194 | PIRP Irp 195 | ) 196 | { 197 | UNREFERENCED_PARAMETER(DeviceObject); 198 | 199 | const auto Stack = IoGetCurrentIrpStackLocation(Irp); 200 | auto& Context = Stack->FileObject->FsContext; 201 | const auto PhysicalMemory = (HANDLE)Context; 202 | 203 | if (PhysicalMemory) 204 | { 205 | ZwClose(PhysicalMemory); 206 | Context = nullptr; 207 | } 208 | 209 | InterlockedDecrement(&g_RefCount); 210 | 211 | Irp->IoStatus.Status = STATUS_SUCCESS; 212 | Irp->IoStatus.Information = 0; 213 | 214 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 215 | 216 | return STATUS_SUCCESS; 217 | } 218 | 219 | using IOCTL_HANDLER_FN = NTSTATUS(*)(PVOID Context, ULONG Code, PVOID Buffer, ULONG InSize, ULONG OutSize); 220 | 221 | struct IOCTL_HANDLER 222 | { 223 | ULONG Code; 224 | ULONG InSize; 225 | ULONG OutSize; 226 | 227 | ULONG InChecked : 1; 228 | ULONG OutChecked : 1; 229 | ULONG Reserved : 30; 230 | 231 | IOCTL_HANDLER_FN Handler; 232 | }; 233 | 234 | template 235 | NTSTATUS IoCtlPhysicalMemoryRead(PVOID, ULONG, PVOID Buffer, ULONG, ULONG) 236 | { 237 | const auto Virtual = MmGetVirtualForPhysical(*(PPHYSICAL_ADDRESS)Buffer); 238 | if (!Virtual) 239 | return STATUS_INVALID_PARAMETER; 240 | *(T*)Buffer = *(T*)Virtual; 241 | return STATUS_SUCCESS; 242 | } 243 | 244 | template 245 | NTSTATUS IoCtlPhysicalMemoryWrite(PVOID, ULONG, PVOID Buffer, ULONG, ULONG) 246 | { 247 | const auto Virtual = MmGetVirtualForPhysical(*(PPHYSICAL_ADDRESS)Buffer); 248 | if (!Virtual) 249 | return STATUS_INVALID_PARAMETER; 250 | *(T*)Virtual = *(T*)(((PPHYSICAL_ADDRESS)Buffer) + 1); 251 | return STATUS_SUCCESS; 252 | } 253 | 254 | #pragma warning(push) 255 | #pragma warning(disable: 4996) 256 | 257 | NTSTATUS PCIConfigRead(const IOCTL_PCI_CONFIG_CMD* Cmd, PVOID Buffer, ULONG Length) 258 | { 259 | if (Length == 0) 260 | return STATUS_INVALID_PARAMETER; 261 | 262 | PCI_SLOT_NUMBER Slot{}; 263 | Slot.u.bits.DeviceNumber = Cmd->DeviceNumber; 264 | Slot.u.bits.FunctionNumber = Cmd->FunctionNumber; 265 | 266 | USHORT VendorId{}; 267 | auto Result = HalGetBusDataByOffset( 268 | PCIConfiguration, 269 | Cmd->BusNumber, 270 | Slot.u.AsULONG, 271 | &VendorId, 272 | 0, 273 | sizeof(VendorId) 274 | ); 275 | 276 | if (Result == 0) 277 | return STATUS_NOT_FOUND; 278 | 279 | if (Result == 2 && VendorId == PCI_INVALID_VENDORID) 280 | return STATUS_DEVICE_DOES_NOT_EXIST; 281 | 282 | Result = HalGetBusDataByOffset( 283 | PCIConfiguration, 284 | Cmd->BusNumber, 285 | Slot.u.AsULONG, 286 | Buffer, 287 | Cmd->Offset, 288 | Length 289 | ); 290 | 291 | if (Result == 0) 292 | return STATUS_NOT_FOUND; 293 | 294 | if (Result == 2 && Length != 2) 295 | return STATUS_DEVICE_DOES_NOT_EXIST; 296 | 297 | if (Result != Length) 298 | return STATUS_UNSUCCESSFUL; 299 | 300 | return STATUS_SUCCESS; 301 | } 302 | 303 | NTSTATUS PCIConfigWrite(const IOCTL_PCI_CONFIG_CMD* Cmd, PVOID Buffer, ULONG Length) 304 | { 305 | if (Length == 0) 306 | return STATUS_INVALID_PARAMETER; 307 | 308 | PCI_SLOT_NUMBER Slot{}; 309 | Slot.u.bits.DeviceNumber = Cmd->DeviceNumber; 310 | Slot.u.bits.FunctionNumber = Cmd->FunctionNumber; 311 | 312 | USHORT VendorId{}; 313 | auto Result = HalGetBusDataByOffset( 314 | PCIConfiguration, 315 | Cmd->BusNumber, 316 | Slot.u.AsULONG, 317 | &VendorId, 318 | 0, 319 | sizeof(VendorId) 320 | ); 321 | 322 | if (Result == 0) 323 | return STATUS_NOT_FOUND; 324 | 325 | if (Result == 2 && VendorId == PCI_INVALID_VENDORID) 326 | return STATUS_DEVICE_DOES_NOT_EXIST; 327 | 328 | Result = HalSetBusDataByOffset( 329 | PCIConfiguration, 330 | Cmd->BusNumber, 331 | Slot.u.AsULONG, 332 | Buffer, 333 | Cmd->Offset, 334 | Length 335 | ); 336 | 337 | if (Result != Length) 338 | return STATUS_UNSUCCESSFUL; 339 | 340 | return STATUS_SUCCESS; 341 | } 342 | 343 | #pragma warning(pop) 344 | 345 | extern "C" ULONG __fastcall _dell(IOCTL_DELL_SMM_REGS* Registers); 346 | 347 | NTSTATUS QueryDellSMM(IOCTL_DELL_SMM_REGS In, IOCTL_DELL_SMM_REGS* Out) 348 | { 349 | *Out = In; 350 | const auto Result = _dell(Out); 351 | return (Result != 0 || (Out->Eax & 0xFFFF) == 0xFFFF || Out->Eax == In.Eax) ? STATUS_UNSUCCESSFUL : STATUS_SUCCESS; 352 | } 353 | 354 | NTSTATUS MsrRead(ULONG Index, ULONG64* Value) 355 | { 356 | NTSTATUS Status = STATUS_SUCCESS; 357 | __try 358 | { 359 | *Value = __readmsr(Index); 360 | } 361 | __except (EXCEPTION_EXECUTE_HANDLER) 362 | { 363 | Status = GetExceptionCode(); 364 | } 365 | return Status; 366 | } 367 | 368 | NTSTATUS MsrWrite(ULONG Index, ULONG64 Value) 369 | { 370 | NTSTATUS Status = STATUS_SUCCESS; 371 | __try 372 | { 373 | __writemsr(Index, Value); 374 | } 375 | __except (EXCEPTION_EXECUTE_HANDLER) 376 | { 377 | Status = GetExceptionCode(); 378 | } 379 | return Status; 380 | } 381 | 382 | const static IOCTL_HANDLER IOCTL_HANDLERS[] = { 383 | { 384 | IOCTL_IO_PORT_READ, 385 | 2, 386 | 1, 387 | 1, 388 | 1, 389 | 0, 390 | (IOCTL_HANDLER_FN)[] (PVOID, ULONG, PVOID Buffer, ULONG, ULONG) 391 | { 392 | *(PUCHAR)Buffer = __inbyte(*(PUSHORT)Buffer); 393 | return STATUS_SUCCESS; 394 | } 395 | }, 396 | { 397 | IOCTL_IO_PORT_READ, 398 | 2, 399 | 2, 400 | 1, 401 | 1, 402 | 0, 403 | (IOCTL_HANDLER_FN)[](PVOID, ULONG, PVOID Buffer, ULONG, ULONG) 404 | { 405 | *(PUSHORT)Buffer = __inword(*(PUSHORT)Buffer); 406 | return STATUS_SUCCESS; 407 | } 408 | }, 409 | { 410 | IOCTL_IO_PORT_READ, 411 | 2, 412 | 4, 413 | 1, 414 | 1, 415 | 0, 416 | (IOCTL_HANDLER_FN)[](PVOID, ULONG, PVOID Buffer, ULONG, ULONG) 417 | { 418 | *(PULONG)Buffer = __indword(*(PUSHORT)Buffer); 419 | return STATUS_SUCCESS; 420 | } 421 | }, 422 | { 423 | IOCTL_IO_PORT_WRITE, 424 | 5, 425 | 0, 426 | 1, 427 | 1, 428 | 0, 429 | (IOCTL_HANDLER_FN)[](PVOID, ULONG, PVOID Buffer, ULONG, ULONG) 430 | { 431 | __outbyte(*(PUSHORT)Buffer, *(PUCHAR)(((char*)Buffer) + 4)); 432 | return STATUS_SUCCESS; 433 | } 434 | }, 435 | { 436 | IOCTL_IO_PORT_WRITE, 437 | 6, 438 | 0, 439 | 1, 440 | 1, 441 | 0, 442 | (IOCTL_HANDLER_FN)[](PVOID, ULONG, PVOID Buffer, ULONG, ULONG) 443 | { 444 | __outword(*(PUSHORT)Buffer, *(PUSHORT)(((char*)Buffer) + 4)); 445 | return STATUS_SUCCESS; 446 | } 447 | }, 448 | { 449 | IOCTL_IO_PORT_WRITE, 450 | 8, 451 | 0, 452 | 1, 453 | 1, 454 | 0, 455 | (IOCTL_HANDLER_FN)[](PVOID, ULONG, PVOID Buffer, ULONG, ULONG) 456 | { 457 | __outdword(*(PUSHORT)Buffer, *(PULONG)(((char*)Buffer) + 4)); 458 | return STATUS_SUCCESS; 459 | } 460 | }, 461 | { 462 | IOCTL_MSR_READ, 463 | 4, 464 | 8, 465 | 1, 466 | 1, 467 | 0, 468 | (IOCTL_HANDLER_FN)[](PVOID, ULONG, PVOID Buffer, ULONG, ULONG) 469 | { 470 | ULONG64 Value = 0; 471 | const auto Status = MsrRead(*(PULONG)Buffer, &Value); 472 | *(PULONG64)Buffer = Value; 473 | return Status; 474 | } 475 | }, 476 | { 477 | IOCTL_MSR_WRITE, 478 | 12, 479 | 0, 480 | 1, 481 | 1, 482 | 0, 483 | (IOCTL_HANDLER_FN)[](PVOID, ULONG, PVOID Buffer, ULONG, ULONG) 484 | { 485 | const ULONG Index = *(PULONG)Buffer; 486 | const ULONG64 Value = *(PULONG64)(((char*)Buffer) + 4); 487 | return MsrWrite(Index, Value); 488 | } 489 | }, 490 | { 491 | IOCTL_PHYSMEM_MAP, 492 | 12, 493 | 0, 494 | 1, 495 | 0, 496 | 0, 497 | (IOCTL_HANDLER_FN)[](PVOID Context, ULONG, PVOID Buffer, ULONG, ULONG OutSize) 498 | { 499 | if (OutSize != 4 && OutSize != 8) 500 | return STATUS_INVALID_BUFFER_SIZE; 501 | 502 | if (!Context) 503 | return STATUS_UNSUCCESSFUL; 504 | 505 | PVOID MappedAddress{}; 506 | LARGE_INTEGER PhysicalAddress{}; 507 | PhysicalAddress.QuadPart = *(PULONG64)Buffer; 508 | const auto Length = *(PULONG)(((char*)Buffer) + 8); 509 | SIZE_T ViewSize = Length; 510 | 511 | const auto Status = ZwMapViewOfSection( 512 | Context, 513 | NtCurrentProcess(), 514 | &MappedAddress, 515 | 0L, 516 | Length, 517 | &PhysicalAddress, 518 | &ViewSize, 519 | ViewShare, 520 | 0, 521 | PAGE_READWRITE | PAGE_NOCACHE 522 | ); 523 | 524 | if (OutSize == 4) 525 | *(PULONG)Buffer = (ULONG)(ULONG_PTR)MappedAddress; 526 | else 527 | *(PULONG64)Buffer = (ULONG64)(ULONG_PTR)MappedAddress; 528 | 529 | return Status; 530 | } 531 | }, 532 | { 533 | IOCTL_PHYSMEM_UNMAP, 534 | 0, 535 | 0, 536 | 0, 537 | 1, 538 | 0, 539 | (IOCTL_HANDLER_FN)[](PVOID, ULONG, PVOID Buffer, ULONG InSize, ULONG) 540 | { 541 | if (InSize != 4 && InSize != 8) 542 | return STATUS_INVALID_BUFFER_SIZE; 543 | 544 | const auto MappedAddress = InSize == 4 545 | ? ((PVOID)(ULONG_PTR)*(PULONG)Buffer) 546 | : ((PVOID)(ULONG_PTR)*(PULONG64)Buffer); 547 | 548 | if ((ULONG_PTR)MM_HIGHEST_USER_ADDRESS < (ULONG_PTR)MappedAddress) 549 | return STATUS_INVALID_PARAMETER; 550 | 551 | return ZwUnmapViewOfSection( 552 | NtCurrentProcess(), 553 | MappedAddress 554 | ); 555 | } 556 | }, 557 | { 558 | IOCTL_GET_REFCOUNT, 559 | 0, 560 | 4, 561 | 1, 562 | 1, 563 | 0, 564 | (IOCTL_HANDLER_FN)[](PVOID, ULONG, PVOID Buffer, ULONG, ULONG) 565 | { 566 | *(PLONG)Buffer = g_RefCount; 567 | return STATUS_SUCCESS; 568 | } 569 | }, 570 | { IOCTL_PHYSMEM_READ, 8, 1, 1, 1, 0, &IoCtlPhysicalMemoryRead }, 571 | { IOCTL_PHYSMEM_READ, 8, 2, 1, 1, 0, &IoCtlPhysicalMemoryRead }, 572 | { IOCTL_PHYSMEM_READ, 8, 4, 1, 1, 0, &IoCtlPhysicalMemoryRead }, 573 | { IOCTL_PHYSMEM_READ, 8, 8, 1, 1, 0, &IoCtlPhysicalMemoryRead }, 574 | 575 | { IOCTL_PHYSMEM_WRITE, 9, 1, 1, 1, 0, &IoCtlPhysicalMemoryWrite }, 576 | { IOCTL_PHYSMEM_WRITE, 10, 2, 1, 1, 0, &IoCtlPhysicalMemoryWrite }, 577 | { IOCTL_PHYSMEM_WRITE, 12, 4, 1, 1, 0, &IoCtlPhysicalMemoryWrite }, 578 | { IOCTL_PHYSMEM_WRITE, 16, 8, 1, 1, 0, &IoCtlPhysicalMemoryWrite }, 579 | 580 | { 581 | IOCTL_PCI_CONFIG_READ, 582 | sizeof(IOCTL_PCI_CONFIG_CMD), 583 | 0, 584 | 1, 585 | 0, 586 | 0, 587 | (IOCTL_HANDLER_FN)[](PVOID, ULONG, PVOID Buffer, ULONG, ULONG OutSize) 588 | { 589 | return PCIConfigRead((IOCTL_PCI_CONFIG_CMD*)Buffer, Buffer, OutSize); 590 | } 591 | }, 592 | { 593 | IOCTL_PCI_CONFIG_WRITE, 594 | 0, 595 | 0, 596 | 0, 597 | 1, 598 | 0, 599 | (IOCTL_HANDLER_FN)[](PVOID, ULONG, PVOID Buffer, ULONG InSize, ULONG) 600 | { 601 | if (InSize < sizeof(IOCTL_PCI_CONFIG_CMD) + 1) 602 | return STATUS_INVALID_BUFFER_SIZE; 603 | 604 | const auto Cmd = (IOCTL_PCI_CONFIG_CMD*)Buffer; 605 | return PCIConfigWrite(Cmd, Cmd + 1, InSize - sizeof(IOCTL_PCI_CONFIG_CMD)); 606 | } 607 | }, 608 | { 609 | IOCTL_DELL_SMM, 610 | sizeof(IOCTL_DELL_SMM_REGS), 611 | sizeof(IOCTL_DELL_SMM_REGS), 612 | 1, 613 | 1, 614 | 0, 615 | (IOCTL_HANDLER_FN)[](PVOID, ULONG, PVOID Buffer, ULONG, ULONG) 616 | { 617 | return QueryDellSMM(*(IOCTL_DELL_SMM_REGS*)Buffer, (IOCTL_DELL_SMM_REGS*)Buffer); 618 | } 619 | }, 620 | }; 621 | 622 | NTSTATUS IrpDeviceControl( 623 | PDEVICE_OBJECT DeviceObject, 624 | PIRP Irp 625 | ) 626 | { 627 | UNREFERENCED_PARAMETER(DeviceObject); 628 | 629 | auto Status = STATUS_NOT_IMPLEMENTED; 630 | 631 | const auto Stack = IoGetCurrentIrpStackLocation(Irp); 632 | auto& Context = Stack->FileObject->FsContext; 633 | auto& Params = Stack->Parameters.DeviceIoControl; 634 | 635 | const auto Code = Params.IoControlCode; 636 | const auto Buffer = Irp->AssociatedIrp.SystemBuffer; 637 | const auto InSize = Params.InputBufferLength; 638 | const auto OutSize = Params.OutputBufferLength; 639 | 640 | for (const auto& Handler : IOCTL_HANDLERS) 641 | { 642 | if (Handler.Code != Code) 643 | continue; 644 | 645 | // If we find at least one with matching code assume the sizes are invalid 646 | Status = STATUS_INVALID_BUFFER_SIZE; 647 | 648 | if (Handler.InChecked && Handler.InSize != InSize) 649 | continue; 650 | 651 | if (Handler.OutChecked && Handler.OutSize != OutSize) 652 | continue; 653 | 654 | // Found first matching handler 655 | Status = Handler.Handler(Context, Code, Buffer, InSize, OutSize); 656 | break; 657 | } 658 | 659 | Irp->IoStatus.Status = Status; 660 | Irp->IoStatus.Information = NT_SUCCESS(Status) ? OutSize : 0; 661 | 662 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 663 | 664 | return Status; 665 | } 666 | -------------------------------------------------------------------------------- /Driver/ioctl.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-2.1-or-later 2 | // 3 | // We use LGPL 2.1 here since it lacks anti-tivoization clause which would 4 | // prevent Microsoft from WHQL signing it. 5 | // 6 | // SaferIO Driver - Simple giveio-style driver with secure access 7 | // Copyright (C) 2021 namazso 8 | // 9 | // This library is free software; you can redistribute it and/or 10 | // modify it under the terms of the GNU Lesser General Public 11 | // License as published by the Free Software Foundation; either 12 | // version 2.1 of the License, or (at your option) any later version. 13 | // 14 | // This library is distributed in the hope that it will be useful, 15 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | // Lesser General Public License for more details. 18 | // 19 | // You should have received a copy of the GNU Lesser General Public 20 | // License along with this library; if not, write to the Free Software 21 | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | #pragma once 23 | 24 | #define SAFEIO_DEVICE_TYPE (0x8000) 25 | 26 | enum IOCTL_CODES : ULONG 27 | { 28 | // in: USHORT Port; 29 | // out: UCHAR Value; 30 | // out: USHORT Value; 31 | // out: ULONG Value; 32 | IOCTL_IO_PORT_READ = (ULONG)CTL_CODE(SAFEIO_DEVICE_TYPE, 0x90C, METHOD_BUFFERED, FILE_READ_ACCESS), 33 | 34 | // in: USHORT Port; USHORT Reserved; UCHAR Value; 35 | // in: USHORT Port; USHORT Reserved; USHORT Value; 36 | // in: USHORT Port; USHORT Reserved; ULONG Value; 37 | // out: VOID; 38 | IOCTL_IO_PORT_WRITE = (ULONG)CTL_CODE(SAFEIO_DEVICE_TYPE, 0x90D, METHOD_BUFFERED, FILE_READ_ACCESS), 39 | 40 | // in: ULONG Index; 41 | // out: ULONG64 Value; 42 | IOCTL_MSR_READ = (ULONG)CTL_CODE(SAFEIO_DEVICE_TYPE, 0x912, METHOD_BUFFERED, FILE_READ_ACCESS), 43 | 44 | // in: ULONG Index; ULONG64 Value; 45 | // out: VOID; 46 | IOCTL_MSR_WRITE = (ULONG)CTL_CODE(SAFEIO_DEVICE_TYPE, 0x913, METHOD_BUFFERED, FILE_READ_ACCESS), 47 | 48 | // in: ULONG64 PhysicalAddress; ULONG Size; 49 | // out: PVOID MappedAddress; 50 | IOCTL_PHYSMEM_MAP = (ULONG)CTL_CODE(SAFEIO_DEVICE_TYPE, 0x917, METHOD_BUFFERED, FILE_READ_ACCESS), 51 | 52 | // in: PVOID MappedAddress; 53 | // out: VOID; 54 | IOCTL_PHYSMEM_UNMAP = (ULONG)CTL_CODE(SAFEIO_DEVICE_TYPE, 0x918, METHOD_BUFFERED, FILE_READ_ACCESS), 55 | 56 | // in: VOID; 57 | // out: ULONG RefCount; 58 | IOCTL_GET_REFCOUNT = (ULONG)CTL_CODE(SAFEIO_DEVICE_TYPE, 0x925, METHOD_BUFFERED, FILE_READ_ACCESS), 59 | 60 | // in: ULONG64 PhysicalAddress; 61 | // out: UCHAR Value; 62 | // out: USHORT Value; 63 | // out: ULONG Value; 64 | // out: ULONG64 Value; 65 | IOCTL_PHYSMEM_READ = (ULONG)CTL_CODE(SAFEIO_DEVICE_TYPE, 0x926, METHOD_BUFFERED, FILE_READ_ACCESS), 66 | 67 | // in: ULONG64 PhysicalAddress; UCHAR Value; 68 | // in: ULONG64 PhysicalAddress; USHORT Value; 69 | // in: ULONG64 PhysicalAddress; ULONG Value; 70 | // in: ULONG64 PhysicalAddress; ULONG64 Value; 71 | // out: VOID; 72 | IOCTL_PHYSMEM_WRITE = (ULONG)CTL_CODE(SAFEIO_DEVICE_TYPE, 0x927, METHOD_BUFFERED, FILE_READ_ACCESS), 73 | 74 | // in: IOCTL_PCI_CONFIG_CMD Cmd; 75 | // out: UCHAR[] but at most 255 76 | IOCTL_PCI_CONFIG_READ = (ULONG)CTL_CODE(SAFEIO_DEVICE_TYPE, 0x907, METHOD_BUFFERED, FILE_READ_ACCESS), 77 | 78 | // in: IOCTL_PCI_CONFIG_CMD Cmd; UCHAR Value; 79 | // in: IOCTL_PCI_CONFIG_CMD Cmd; USHORT Value; 80 | // in: IOCTL_PCI_CONFIG_CMD Cmd; ULONG Value; 81 | // out: VOID; 82 | IOCTL_PCI_CONFIG_WRITE = (ULONG)CTL_CODE(SAFEIO_DEVICE_TYPE, 0x908, METHOD_BUFFERED, FILE_READ_ACCESS), 83 | 84 | // in: IOCTL_PCI_CONFIG_CMD Regs; 85 | // out: IOCTL_PCI_CONFIG_CMD Regs; 86 | IOCTL_DELL_SMM = (ULONG)CTL_CODE(SAFEIO_DEVICE_TYPE, 0x8FF, METHOD_BUFFERED, FILE_READ_ACCESS), 87 | }; 88 | 89 | struct IOCTL_PCI_CONFIG_CMD 90 | { 91 | UCHAR BusNumber; 92 | UCHAR DeviceNumber; 93 | UCHAR FunctionNumber; 94 | UCHAR Reserved; 95 | ULONG Offset; 96 | }; 97 | 98 | struct IOCTL_DELL_SMM_REGS 99 | { 100 | ULONG Eax; 101 | ULONG Ecx; 102 | ULONG Edx; 103 | ULONG Ebx; 104 | ULONG Esi; 105 | ULONG Edi; 106 | }; 107 | -------------------------------------------------------------------------------- /Driver/x64.asm: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: LGPL-2.1-or-later 2 | ; 3 | ; We use LGPL 2.1 here since it lacks anti-tivoization clause which would 4 | ; prevent Microsoft from WHQL signing it. 5 | ; 6 | ; SaferIO Driver - Simple giveio-style driver with secure access 7 | ; Copyright (C) 2021 namazso 8 | ; 9 | ; This library is free software; you can redistribute it and/or 10 | ; modify it under the terms of the GNU Lesser General Public 11 | ; License as published by the Free Software Foundation; either 12 | ; version 2.1 of the License, or (at your option) any later version. 13 | ; 14 | ; This library is distributed in the hope that it will be useful, 15 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | ; Lesser General Public License for more details. 18 | ; 19 | ; You should have received a copy of the GNU Lesser General Public 20 | ; License along with this library; if not, write to the Free Software 21 | ; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | 23 | .code 24 | 25 | PUBLIC _dell 26 | 27 | _dell PROC FRAME 28 | push rbx 29 | .pushreg rbx 30 | push rsi 31 | .pushreg rsi 32 | push rdi 33 | .pushreg rdi 34 | .endprolog 35 | 36 | mov r8, rcx 37 | 38 | mov eax, [r8] 39 | mov ecx, [r8+4] 40 | mov edx, [r8+8] 41 | mov ebx, [r8+12] 42 | mov esi, [r8+16] 43 | mov edi, [r8+20] 44 | 45 | out 0b2h, al 46 | out 084h, al 47 | 48 | mov [r8], eax 49 | mov [r8+4], ecx 50 | mov [r8+8], edx 51 | mov [r8+12], ebx 52 | mov [r8+16], esi 53 | mov [r8+20], edi 54 | 55 | pop rdi 56 | pop rsi 57 | pop rbx 58 | 59 | setb al 60 | movzx eax, al 61 | 62 | ret 63 | _dell ENDP 64 | 65 | END -------------------------------------------------------------------------------- /Driver/x86.asm: -------------------------------------------------------------------------------- 1 | ; SPDX-License-Identifier: LGPL-2.1-or-later 2 | ; 3 | ; We use LGPL 2.1 here since it lacks anti-tivoization clause which would 4 | ; prevent Microsoft from WHQL signing it. 5 | ; 6 | ; SaferIO Driver - Simple giveio-style driver with secure access 7 | ; Copyright (C) 2021 namazso 8 | ; 9 | ; This library is free software; you can redistribute it and/or 10 | ; modify it under the terms of the GNU Lesser General Public 11 | ; License as published by the Free Software Foundation; either 12 | ; version 2.1 of the License, or (at your option) any later version. 13 | ; 14 | ; This library is distributed in the hope that it will be useful, 15 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | ; Lesser General Public License for more details. 18 | ; 19 | ; You should have received a copy of the GNU Lesser General Public 20 | ; License along with this library; if not, write to the Free Software 21 | ; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | 23 | .386 24 | .model flat 25 | .code 26 | 27 | PUBLIC @_dell@4 28 | 29 | @_dell@4 PROC 30 | push ebx 31 | push esi 32 | push edi 33 | push ebp 34 | 35 | mov ebp, ecx 36 | 37 | mov eax, [ebp] 38 | mov ecx, [ebp+4] 39 | mov edx, [ebp+8] 40 | mov ebx, [ebp+12] 41 | mov esi, [ebp+16] 42 | mov edi, [ebp+20] 43 | 44 | out 0b2h, al 45 | out 084h, al 46 | 47 | mov [ebp], eax 48 | mov [ebp+4], ecx 49 | mov [ebp+8], edx 50 | mov [ebp+12], ebx 51 | mov [ebp+16], esi 52 | mov [ebp+20], edi 53 | 54 | pop ebp 55 | pop edi 56 | pop esi 57 | pop ebx 58 | 59 | setb al 60 | movzx eax, al 61 | 62 | ret 63 | @_dell@4 ENDP 64 | 65 | END -------------------------------------------------------------------------------- /DriverBins/Driver_x64.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/namazso/SaferIO/4666892eb80f3057202ad00708acfce522721696/DriverBins/Driver_x64.sys -------------------------------------------------------------------------------- /DriverBins/Driver_x86.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/namazso/SaferIO/4666892eb80f3057202ad00708acfce522721696/DriverBins/Driver_x86.sys -------------------------------------------------------------------------------- /DriverBins/LICENSE: -------------------------------------------------------------------------------- 1 | These signed driver files are from GPU-Z v2.41.0 distributed under this license: 2 | 3 | GPU-Z is free to use for personal and commercial usage. However, you may not 4 | redistribute GPU-Z as part of a commercial package. We also offer a GPU-Z SDK, 5 | which is provided as simple-to-use DLL with full feature set. Commercial support 6 | and customization options are available, please contact us for details. 7 | 8 | An alternative compatible driver (without signed binaries) licensed under LGPL 9 | is provided in the Driver folder. 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | All original code is licensed under LGPL 2.1, the text of which is included 2 | in the COPYING file. See the file headers and LICENSE files in folders for 3 | licensing details of each component or file. 4 | 5 | The signed driver binaries in the DriverBins folder are part of GPU-Z, and can 6 | only be redistributed non-commercially. An alternative compatible driver 7 | (without signed binaries) licensed under LGPL 2.1 is provided in the Driver 8 | folder. For details see DriverBins\LICENSE and Driver\LICENSE 9 | 10 | Some code is from the KDU project, originally licensed under the MIT license: 11 | 12 | Copyright (c) 2020 - 2021 KDU Project 13 | 14 | Permission is hereby granted, free of charge, to any person obtaining a copy 15 | of this software and associated documentation files (the "Software"), to deal 16 | in the Software without restriction, including without limitation the rights 17 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 18 | copies of the Software, and to permit persons to whom the Software is 19 | furnished to do so, subject to the following conditions: 20 | 21 | The above copyright notice and this permission notice shall be included in all 22 | copies or substantial portions of the Software. 23 | -------------------------------------------------------------------------------- /NtdllCrt/NtdllCrt.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Release 6 | ARM64 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Release 14 | x64 15 | 16 | 17 | 18 | 15.0 19 | {9EF2EA5B-B660-4F8A-8ECB-F2DBD19B8435} 20 | NtdllCrt 21 | 10.0 22 | 23 | 24 | 25 | Utility 26 | false 27 | v142 28 | true 29 | MultiByte 30 | 31 | 32 | Utility 33 | false 34 | v142 35 | true 36 | MultiByte 37 | 38 | 39 | Utility 40 | false 41 | v142 42 | true 43 | MultiByte 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | Level3 64 | MaxSpeed 65 | true 66 | true 67 | true 68 | true 69 | 70 | 71 | true 72 | true 73 | 74 | 75 | 76 | 77 | Level3 78 | MaxSpeed 79 | true 80 | true 81 | true 82 | true 83 | 84 | 85 | true 86 | true 87 | 88 | 89 | 90 | 91 | Level3 92 | MaxSpeed 93 | true 94 | true 95 | true 96 | true 97 | 98 | 99 | true 100 | true 101 | 102 | 103 | 104 | 105 | lib /DEF:ntdll.def /OUT:"$(SolutionDir)obj\$(Platform)\ntdll.lib" /MACHINE:$(PlatformTarget) 106 | $(SolutionDir)obj\$(Platform)\ntdll.lib;%(Outputs) 107 | 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /NtdllCrt/NtdllCrt.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;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /NtdllCrt/ntdll.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | _CIcos 3 | _CIlog 4 | _CIpow 5 | _CIsin 6 | _CIsqrt 7 | __isascii 8 | __iscsym 9 | __iscsymf 10 | __toascii 11 | _alldiv 12 | _alldvrm 13 | _allmul 14 | _alloca_probe 15 | _alloca_probe_16 16 | _alloca_probe_8 17 | _allrem 18 | _allshl 19 | _allshr 20 | _atoi64 21 | _aulldiv 22 | _aulldvrm 23 | _aullrem 24 | _aullshr 25 | _chkstk 26 | _errno 27 | _except_handler4_common 28 | _fltused 29 | _ftol 30 | _ftol2 31 | _ftol2_sse 32 | _i64toa 33 | _i64toa_s 34 | _i64tow 35 | _i64tow_s 36 | _itoa 37 | _itoa_s 38 | _itow 39 | _itow_s 40 | _lfind 41 | _local_unwind4 42 | _ltoa 43 | _ltoa_s 44 | _ltow 45 | _ltow_s 46 | _makepath_s 47 | _memccpy 48 | _memicmp 49 | _snprintf 50 | _snprintf_s 51 | _snscanf_s 52 | _snwprintf 53 | _snwprintf_s 54 | _snwscanf_s 55 | _splitpath 56 | _splitpath_s 57 | _strcmpi 58 | _stricmp 59 | _strlwr 60 | _strlwr_s 61 | _strnicmp 62 | _strnset_s 63 | _strset_s 64 | _strupr 65 | _strupr_s 66 | _swprintf 67 | _ui64toa 68 | _ui64toa_s 69 | _ui64tow 70 | _ui64tow_s 71 | _ultoa 72 | _ultoa_s 73 | _ultow 74 | _ultow_s 75 | _vscprintf 76 | _vscwprintf 77 | _vsnprintf 78 | _vsnprintf_s 79 | _vsnwprintf 80 | _vsnwprintf_s 81 | _vswprintf 82 | _wcsicmp 83 | _wcslwr 84 | _wcslwr_s 85 | _wcsnicmp 86 | _wcsnset_s 87 | _wcsset_s 88 | _wcstoi64 89 | _wcstoui64 90 | _wcsupr 91 | _wcsupr_s 92 | _wmakepath_s 93 | _wsplitpath_s 94 | _wtoi 95 | _wtoi64 96 | _wtol 97 | abs 98 | atan 99 | atan2 100 | atoi 101 | atol 102 | bsearch 103 | bsearch_s 104 | ceil 105 | cos 106 | fabs 107 | floor 108 | isalnum 109 | isalpha 110 | iscntrl 111 | isdigit 112 | isgraph 113 | islower 114 | isprint 115 | ispunct 116 | isspace 117 | isupper 118 | iswalnum 119 | iswalpha 120 | iswascii 121 | iswctype 122 | iswdigit 123 | iswgraph 124 | iswlower 125 | iswprint 126 | iswspace 127 | iswxdigit 128 | isxdigit 129 | labs 130 | log 131 | mbstowcs 132 | memchr 133 | memcmp 134 | memcpy 135 | memcpy_s 136 | memmove 137 | memmove_s 138 | memset 139 | pow 140 | qsort 141 | qsort_s 142 | sin 143 | sprintf 144 | sprintf_s 145 | sqrt 146 | sscanf 147 | sscanf_s 148 | strcat 149 | strcat_s 150 | strchr 151 | strcmp 152 | strcpy 153 | strcpy_s 154 | strcspn 155 | strlen 156 | strncat 157 | strncat_s 158 | strncmp 159 | strncpy 160 | strncpy_s 161 | strnlen 162 | strpbrk 163 | strrchr 164 | strspn 165 | strstr 166 | strtok_s 167 | strtol 168 | strtoul 169 | swprintf 170 | swprintf_s 171 | swscanf_s 172 | tan 173 | tolower 174 | toupper 175 | towlower 176 | towupper 177 | vDbgPrintEx 178 | vDbgPrintExWithPrefix 179 | vsprintf 180 | vsprintf_s 181 | vswprintf_s 182 | wcscat 183 | wcscat_s 184 | wcschr 185 | wcscmp 186 | wcscpy 187 | wcscpy_s 188 | wcscspn 189 | wcslen 190 | wcsncat 191 | wcsncat_s 192 | wcsncmp 193 | wcsncpy 194 | wcsncpy_s 195 | wcsnlen 196 | wcspbrk 197 | wcsrchr 198 | wcsspn 199 | wcsstr 200 | wcstok_s 201 | wcstol 202 | wcstombs 203 | wcstoul -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SaferIO 2 | 3 | ## About 4 | 5 | SaferIO is an easy to use slightly more safe IO access library. 6 | 7 | ## Features 8 | 9 | * Access IO ports, MSRs, physical memory, and PCI configuration space 10 | * Simple to use API 11 | * x86 and x64 supported 12 | 13 | ## Driver 14 | 15 | There is an original but no signed binary provided driver licensed under LGPL 2.1 in the Driver folder. In DriverBins folder there is a WHQL signed driver from GPU-Z. See [LICENSE](LICENSE), [Driver/LICENSE](Driver/LICENSE) and [DriverBins/LICENSE](DriverBins/LICENSE) for more details. Both drivers restrict device object access to Administrators to prevent exploitation. 16 | -------------------------------------------------------------------------------- /SaferIO.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-2.1-or-later 2 | // 3 | // SaferIO Library - Simple library for IO access 4 | // Copyright (C) 2021 namazso 5 | // 6 | // This library is free software; you can redistribute it and/or 7 | // modify it under the terms of the GNU Lesser General Public 8 | // License as published by the Free Software Foundation; either 9 | // version 2.1 of the License, or (at your option) any later version. 10 | // 11 | // This library is distributed in the hope that it will be useful, 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | // Lesser General Public License for more details. 15 | // 16 | // You should have received a copy of the GNU Lesser General Public 17 | // License along with this library; if not, write to the Free Software 18 | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | #pragma once 20 | 21 | #define SAFERIO_CALLCONV __stdcall 22 | 23 | #ifdef SAFERIO_EXPORTS 24 | #define SAFERIO_DLLEXPORT __declspec(dllexport) 25 | #else 26 | #define SAFERIO_DLLEXPORT __declspec(dllimport) 27 | #endif 28 | 29 | #define SAFERIO_EXPORT(...) SAFERIO_DLLEXPORT __VA_ARGS__ SAFERIO_CALLCONV 30 | 31 | #ifdef __cplusplus 32 | #define SAFERIO_REF & 33 | #else 34 | #define SAFERIO_REF * 35 | #endif 36 | 37 | EXTERN_C_START 38 | 39 | SAFERIO_EXPORT(NTSTATUS) DrvInitialize(PCWSTR Name); 40 | SAFERIO_EXPORT(NTSTATUS) DrvUninitialize(PCWSTR Name); 41 | 42 | SAFERIO_EXPORT(NTSTATUS) DrvGetRefCount(ULONG SAFERIO_REF RefCount); 43 | 44 | SAFERIO_EXPORT(NTSTATUS) DrvIoPortReadByte(USHORT Port, UCHAR SAFERIO_REF Value); 45 | SAFERIO_EXPORT(NTSTATUS) DrvIoPortReadWord(USHORT Port, USHORT SAFERIO_REF Value); 46 | SAFERIO_EXPORT(NTSTATUS) DrvIoPortReadDword(USHORT Port, ULONG SAFERIO_REF Value); 47 | 48 | SAFERIO_EXPORT(NTSTATUS) DrvIoPortWriteByte(USHORT Port, UCHAR Value); 49 | SAFERIO_EXPORT(NTSTATUS) DrvIoPortWriteWord(USHORT Port, USHORT Value); 50 | SAFERIO_EXPORT(NTSTATUS) DrvIoPortWriteDword(USHORT Port, ULONG Value); 51 | 52 | SAFERIO_EXPORT(NTSTATUS) DrvMsrRead(ULONG Index, ULONG64 SAFERIO_REF Value); 53 | 54 | SAFERIO_EXPORT(NTSTATUS) DrvMsrWrite(ULONG Index, ULONG64 Value); 55 | 56 | SAFERIO_EXPORT(NTSTATUS) DrvPhysMap(ULONG64 Addr, ULONG Length, PVOID SAFERIO_REF MappedAddress); 57 | SAFERIO_EXPORT(NTSTATUS) DrvPhysUnmap(PVOID MappedAddress); 58 | 59 | SAFERIO_EXPORT(NTSTATUS) DrvPhysReadByte(ULONG64 Addr, UCHAR SAFERIO_REF Value); 60 | SAFERIO_EXPORT(NTSTATUS) DrvPhysReadWord(ULONG64 Addr, USHORT SAFERIO_REF Value); 61 | SAFERIO_EXPORT(NTSTATUS) DrvPhysReadDword(ULONG64 Addr, ULONG SAFERIO_REF Value); 62 | SAFERIO_EXPORT(NTSTATUS) DrvPhysReadQword(ULONG64 Addr, ULONG64 SAFERIO_REF Value); 63 | 64 | SAFERIO_EXPORT(NTSTATUS) DrvPhysWriteByte(ULONG64 Addr, UCHAR Value); 65 | SAFERIO_EXPORT(NTSTATUS) DrvPhysWriteWord(ULONG64 Addr, USHORT Value); 66 | SAFERIO_EXPORT(NTSTATUS) DrvPhysWriteDword(ULONG64 Addr, ULONG Value); 67 | SAFERIO_EXPORT(NTSTATUS) DrvPhysWriteQword(ULONG64 Addr, ULONG64 Value); 68 | 69 | SAFERIO_EXPORT(NTSTATUS) DrvPciConfigRead(UCHAR Bus, UCHAR Device, UCHAR Function, ULONG Offset, PVOID OutBuffer, UCHAR OutSize); 70 | 71 | SAFERIO_EXPORT(NTSTATUS) DrvPciConfigWriteByte(UCHAR Bus, UCHAR Device, UCHAR Function, ULONG Offset, UCHAR Value); 72 | SAFERIO_EXPORT(NTSTATUS) DrvPciConfigWriteWord(UCHAR Bus, UCHAR Device, UCHAR Function, ULONG Offset, USHORT Value); 73 | SAFERIO_EXPORT(NTSTATUS) DrvPciConfigWriteDword(UCHAR Bus, UCHAR Device, UCHAR Function, ULONG Offset, ULONG Value); 74 | 75 | EXTERN_C_END 76 | -------------------------------------------------------------------------------- /SaferIO.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31515.178 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SaferIO", "SaferIO\SaferIO.vcxproj", "{75E82EF2-FF7B-4C85-B7F5-4367B51C1630}" 7 | ProjectSection(ProjectDependencies) = postProject 8 | {9EF2EA5B-B660-4F8A-8ECB-F2DBD19B8435} = {9EF2EA5B-B660-4F8A-8ECB-F2DBD19B8435} 9 | EndProjectSection 10 | EndProject 11 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NtdllCrt", "NtdllCrt\NtdllCrt.vcxproj", "{9EF2EA5B-B660-4F8A-8ECB-F2DBD19B8435}" 12 | EndProject 13 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestApp", "TestApp\TestApp.vcxproj", "{89CA6409-F0BB-4F46-9C86-DD57A0F909D9}" 14 | ProjectSection(ProjectDependencies) = postProject 15 | {75E82EF2-FF7B-4C85-B7F5-4367B51C1630} = {75E82EF2-FF7B-4C85-B7F5-4367B51C1630} 16 | EndProjectSection 17 | EndProject 18 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Driver", "Driver\Driver.vcxproj", "{C81DE704-2CD2-4416-8F7D-9F5069C51A3C}" 19 | EndProject 20 | Global 21 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 22 | Debug|x64 = Debug|x64 23 | Debug|x86 = Debug|x86 24 | Release|x64 = Release|x64 25 | Release|x86 = Release|x86 26 | EndGlobalSection 27 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 28 | {75E82EF2-FF7B-4C85-B7F5-4367B51C1630}.Debug|x64.ActiveCfg = Debug|x64 29 | {75E82EF2-FF7B-4C85-B7F5-4367B51C1630}.Debug|x64.Build.0 = Debug|x64 30 | {75E82EF2-FF7B-4C85-B7F5-4367B51C1630}.Debug|x86.ActiveCfg = Debug|Win32 31 | {75E82EF2-FF7B-4C85-B7F5-4367B51C1630}.Debug|x86.Build.0 = Debug|Win32 32 | {75E82EF2-FF7B-4C85-B7F5-4367B51C1630}.Release|x64.ActiveCfg = Release|x64 33 | {75E82EF2-FF7B-4C85-B7F5-4367B51C1630}.Release|x64.Build.0 = Release|x64 34 | {75E82EF2-FF7B-4C85-B7F5-4367B51C1630}.Release|x86.ActiveCfg = Release|Win32 35 | {75E82EF2-FF7B-4C85-B7F5-4367B51C1630}.Release|x86.Build.0 = Release|Win32 36 | {9EF2EA5B-B660-4F8A-8ECB-F2DBD19B8435}.Debug|x64.ActiveCfg = Release|x64 37 | {9EF2EA5B-B660-4F8A-8ECB-F2DBD19B8435}.Debug|x64.Build.0 = Release|x64 38 | {9EF2EA5B-B660-4F8A-8ECB-F2DBD19B8435}.Debug|x86.ActiveCfg = Release|Win32 39 | {9EF2EA5B-B660-4F8A-8ECB-F2DBD19B8435}.Debug|x86.Build.0 = Release|Win32 40 | {9EF2EA5B-B660-4F8A-8ECB-F2DBD19B8435}.Release|x64.ActiveCfg = Release|x64 41 | {9EF2EA5B-B660-4F8A-8ECB-F2DBD19B8435}.Release|x64.Build.0 = Release|x64 42 | {9EF2EA5B-B660-4F8A-8ECB-F2DBD19B8435}.Release|x86.ActiveCfg = Release|Win32 43 | {9EF2EA5B-B660-4F8A-8ECB-F2DBD19B8435}.Release|x86.Build.0 = Release|Win32 44 | {89CA6409-F0BB-4F46-9C86-DD57A0F909D9}.Debug|x64.ActiveCfg = Debug|x64 45 | {89CA6409-F0BB-4F46-9C86-DD57A0F909D9}.Debug|x64.Build.0 = Debug|x64 46 | {89CA6409-F0BB-4F46-9C86-DD57A0F909D9}.Debug|x86.ActiveCfg = Debug|Win32 47 | {89CA6409-F0BB-4F46-9C86-DD57A0F909D9}.Debug|x86.Build.0 = Debug|Win32 48 | {89CA6409-F0BB-4F46-9C86-DD57A0F909D9}.Release|x64.ActiveCfg = Release|x64 49 | {89CA6409-F0BB-4F46-9C86-DD57A0F909D9}.Release|x64.Build.0 = Release|x64 50 | {89CA6409-F0BB-4F46-9C86-DD57A0F909D9}.Release|x86.ActiveCfg = Release|Win32 51 | {89CA6409-F0BB-4F46-9C86-DD57A0F909D9}.Release|x86.Build.0 = Release|Win32 52 | {C81DE704-2CD2-4416-8F7D-9F5069C51A3C}.Debug|x64.ActiveCfg = Debug|x64 53 | {C81DE704-2CD2-4416-8F7D-9F5069C51A3C}.Debug|x64.Build.0 = Debug|x64 54 | {C81DE704-2CD2-4416-8F7D-9F5069C51A3C}.Debug|x64.Deploy.0 = Debug|x64 55 | {C81DE704-2CD2-4416-8F7D-9F5069C51A3C}.Debug|x86.ActiveCfg = Debug|Win32 56 | {C81DE704-2CD2-4416-8F7D-9F5069C51A3C}.Debug|x86.Build.0 = Debug|Win32 57 | {C81DE704-2CD2-4416-8F7D-9F5069C51A3C}.Debug|x86.Deploy.0 = Debug|Win32 58 | {C81DE704-2CD2-4416-8F7D-9F5069C51A3C}.Release|x64.ActiveCfg = Release|x64 59 | {C81DE704-2CD2-4416-8F7D-9F5069C51A3C}.Release|x64.Build.0 = Release|x64 60 | {C81DE704-2CD2-4416-8F7D-9F5069C51A3C}.Release|x64.Deploy.0 = Release|x64 61 | {C81DE704-2CD2-4416-8F7D-9F5069C51A3C}.Release|x86.ActiveCfg = Release|Win32 62 | {C81DE704-2CD2-4416-8F7D-9F5069C51A3C}.Release|x86.Build.0 = Release|Win32 63 | {C81DE704-2CD2-4416-8F7D-9F5069C51A3C}.Release|x86.Deploy.0 = Release|Win32 64 | EndGlobalSection 65 | GlobalSection(SolutionProperties) = preSolution 66 | HideSolutionNode = FALSE 67 | EndGlobalSection 68 | GlobalSection(ExtensibilityGlobals) = postSolution 69 | SolutionGuid = {DA492E9A-1024-4C7F-9BCB-A29DAB04D92B} 70 | EndGlobalSection 71 | EndGlobal 72 | -------------------------------------------------------------------------------- /SaferIO/LICENSE: -------------------------------------------------------------------------------- 1 | SPDX-License-Identifier: LGPL-2.1-or-later 2 | 3 | SaferIO Library - Simple library for IO access 4 | Copyright (C) 2021 namazso 5 | 6 | This library is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU Lesser General Public 8 | License as published by the Free Software Foundation; either 9 | version 2.1 of the License, or (at your option) any later version. 10 | 11 | This library is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with this library; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -------------------------------------------------------------------------------- /SaferIO/SaferIO.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {75e82ef2-ff7b-4c85-b7f5-4367b51c1630} 25 | SaferIO 26 | 10.0 27 | 28 | 29 | 30 | DynamicLibrary 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | DynamicLibrary 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | DynamicLibrary 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | DynamicLibrary 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | false 78 | 79 | 80 | true 81 | 82 | 83 | false 84 | 85 | 86 | 87 | Level3 88 | true 89 | WIN32;_DEBUG;SAFERIO_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 90 | true 91 | NotUsing 92 | pch.h 93 | stdcpp17 94 | /d2FH4- /Brepro %(AdditionalOptions) 95 | 96 | 97 | Windows 98 | true 99 | false 100 | ntdll.lib;$(SolutionDir)obj\$(Platform)\ntdll.lib;%(AdditionalDependencies) 101 | /Brepro /PDBALTPATH:%_PDB% %(AdditionalOptions) 102 | 103 | 104 | 105 | 106 | Level3 107 | true 108 | true 109 | true 110 | WIN32;NDEBUG;SAFERIO_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 111 | true 112 | NotUsing 113 | pch.h 114 | stdcpp17 115 | /d2FH4- /Brepro %(AdditionalOptions) 116 | false 117 | 118 | 119 | Windows 120 | true 121 | true 122 | true 123 | false 124 | DllEntry 125 | ntdll.lib;$(SolutionDir)obj\$(Platform)\ntdll.lib;%(AdditionalDependencies) 126 | /Brepro /PDBALTPATH:%_PDB% %(AdditionalOptions) 127 | 128 | 129 | 130 | 131 | Level3 132 | true 133 | _DEBUG;SAFERIO_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 134 | true 135 | NotUsing 136 | pch.h 137 | stdcpp17 138 | /d2FH4- /Brepro %(AdditionalOptions) 139 | 140 | 141 | Windows 142 | true 143 | false 144 | ntdll.lib;$(SolutionDir)obj\$(Platform)\ntdll.lib;%(AdditionalDependencies) 145 | /Brepro /PDBALTPATH:%_PDB% %(AdditionalOptions) 146 | 147 | 148 | 149 | 150 | Level3 151 | true 152 | true 153 | true 154 | NDEBUG;SAFERIO_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 155 | true 156 | NotUsing 157 | pch.h 158 | stdcpp17 159 | /d2FH4- /Brepro %(AdditionalOptions) 160 | false 161 | 162 | 163 | Windows 164 | true 165 | true 166 | true 167 | false 168 | DllEntry 169 | ntdll.lib;$(SolutionDir)obj\$(Platform)\ntdll.lib;%(AdditionalDependencies) 170 | /Brepro /PDBALTPATH:%_PDB% %(AdditionalOptions) 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | -------------------------------------------------------------------------------- /SaferIO/SaferIO.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | 29 | 30 | Header Files 31 | 32 | 33 | Header Files 34 | 35 | 36 | Header Files 37 | 38 | 39 | Header Files 40 | 41 | 42 | Header Files 43 | 44 | 45 | Header Files 46 | 47 | 48 | 49 | 50 | Resource Files 51 | 52 | 53 | -------------------------------------------------------------------------------- /SaferIO/dllmain.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-2.1-or-later 2 | // 3 | // SaferIO Library - Simple library for IO access 4 | // Copyright (C) 2021 namazso 5 | // 6 | // This library is free software; you can redistribute it and/or 7 | // modify it under the terms of the GNU Lesser General Public 8 | // License as published by the Free Software Foundation; either 9 | // version 2.1 of the License, or (at your option) any later version. 10 | // 11 | // This library is distributed in the hope that it will be useful, 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | // Lesser General Public License for more details. 15 | // 16 | // You should have received a copy of the GNU Lesser General Public 17 | // License along with this library; if not, write to the Free Software 18 | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | #include "global.h" 20 | #include "sup.h" 21 | #include "resource.h" 22 | 23 | EXTERN_C IMAGE_DOS_HEADER __ImageBase; 24 | #define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase) 25 | 26 | HANDLE g_DeviceHandle{}; 27 | 28 | WCHAR g_AppName[MAX_PATH]{}; 29 | WCHAR g_TempFileName[MAX_PATH + 1]{}; 30 | 31 | extern "C" BOOL APIENTRY DllEntry( 32 | HMODULE Module, 33 | DWORD Reason, 34 | LPVOID Reserved 35 | ) 36 | { 37 | switch (Reason) 38 | { 39 | case DLL_PROCESS_ATTACH: 40 | case DLL_THREAD_ATTACH: 41 | case DLL_THREAD_DETACH: 42 | break; 43 | 44 | case DLL_PROCESS_DETACH: 45 | DrvUninitialize(g_AppName); 46 | break; 47 | } 48 | return TRUE; 49 | } 50 | 51 | BOOL APIENTRY DllMain( 52 | HMODULE Module, 53 | DWORD Reason, 54 | LPVOID Reserved 55 | ) 56 | { 57 | return DllEntry(Module, Reason, Reserved); 58 | } 59 | 60 | USHORT GetNativeArchitecture() 61 | { 62 | using LPFN_ISWOW64PROCESS2 = BOOL(WINAPI*)(HANDLE, PUSHORT, PUSHORT); 63 | 64 | const auto Kernel32 = GetModuleHandleW(L"kernel32"); 65 | const auto FnIsWow64Process2 = Kernel32 ? (LPFN_ISWOW64PROCESS2)GetProcAddress(Kernel32, "IsWow64Process2") : nullptr; 66 | USHORT ProcessMachine = 0; 67 | USHORT NativeMachine = 0; 68 | 69 | // Apparently IsWow64Process2 can fail somehow 70 | if (FnIsWow64Process2 && FnIsWow64Process2(GetCurrentProcess(), &ProcessMachine, &NativeMachine)) 71 | return NativeMachine; 72 | 73 | SYSTEM_INFO SystemInfo; 74 | // On 64 bit processors that aren't x64 or IA64, GetNativeSystemInfo behaves as GetSystemInfo 75 | GetNativeSystemInfo(&SystemInfo); 76 | switch (SystemInfo.wProcessorArchitecture) 77 | { 78 | case PROCESSOR_ARCHITECTURE_AMD64: 79 | return (USHORT)IMAGE_FILE_MACHINE_AMD64; 80 | case PROCESSOR_ARCHITECTURE_ARM: 81 | return (USHORT)IMAGE_FILE_MACHINE_ARM; 82 | case PROCESSOR_ARCHITECTURE_ARM64: // according to docs this could never happen 83 | return (USHORT)IMAGE_FILE_MACHINE_ARM64; 84 | case PROCESSOR_ARCHITECTURE_IA64: 85 | return (USHORT)IMAGE_FILE_MACHINE_IA64; 86 | case PROCESSOR_ARCHITECTURE_INTEL: 87 | return (USHORT)IMAGE_FILE_MACHINE_I386; 88 | default: 89 | break; 90 | } 91 | 92 | // I wonder why does IsWow64Process exist when GetNativeSystemInfo can provide same and more, plus it cannot fail 93 | // either unlike IsWow64Process which apparently can do so. 94 | 95 | return (USHORT)IMAGE_FILE_MACHINE_UNKNOWN; 96 | } 97 | 98 | NTSTATUS GetDriverData(PVOID* Buffer, ULONG* Size) 99 | { 100 | *Buffer = nullptr; 101 | *Size = 0; 102 | 103 | const auto Architecture = GetNativeArchitecture(); 104 | 105 | ULONG ResourceId = 0; 106 | 107 | if (Architecture == IMAGE_FILE_MACHINE_I386) 108 | ResourceId = IDR_DRIVER_X86; 109 | else if (Architecture == IMAGE_FILE_MACHINE_AMD64) 110 | ResourceId = IDR_DRIVER_X64; 111 | else 112 | return STATUS_NOT_SUPPORTED; 113 | 114 | return supQueryResourceData(ResourceId, HINST_THISCOMPONENT, Buffer, Size); 115 | } 116 | 117 | NTSTATUS DrvpLoadDriver(PCWSTR Name) 118 | { 119 | NTSTATUS Status = STATUS_SUCCESS; 120 | HANDLE File{}; 121 | PSECURITY_DESCRIPTOR AdminSD{}; 122 | PACL DefaultACL{}; 123 | PVOID DriverBuffer{}; 124 | ULONG DriverSize{}; 125 | 126 | Status = GetDriverData(&DriverBuffer, &DriverSize); 127 | if (!NT_SUCCESS(Status)) 128 | return Status; 129 | 130 | WCHAR TempPath[MAX_PATH + 1]{}; 131 | GetTempPathW((DWORD)std::size(TempPath), TempPath); 132 | 133 | WCHAR TempFileName[MAX_PATH + 1]{}; 134 | GetTempFileNameW(TempPath, L"SIO", 0, TempFileName); 135 | 136 | supWriteBufferToFile( 137 | TempFileName, 138 | DriverBuffer, 139 | DriverSize, 140 | TRUE, 141 | &Status, 142 | WRITE_DAC, 143 | &File 144 | ); 145 | 146 | if (NT_SUCCESS(Status)) 147 | { 148 | Status = supCreateSystemAdminAccessSD(&AdminSD, &DefaultACL); 149 | if (NT_SUCCESS(Status)) 150 | { 151 | Status = NtSetSecurityObject( 152 | File, 153 | DACL_SECURITY_INFORMATION, 154 | AdminSD 155 | ); 156 | 157 | if (NT_SUCCESS(Status)) 158 | { 159 | wcscpy_s(g_TempFileName, TempFileName); 160 | 161 | NtClose(File); 162 | File = nullptr; 163 | 164 | Status = supEnablePrivilege(SE_LOAD_DRIVER_PRIVILEGE, TRUE); 165 | if (NT_SUCCESS(Status)) 166 | { 167 | Status = supLoadDriver(Name, TempFileName, FALSE); 168 | supMarkForDelete(TempFileName); 169 | } 170 | } 171 | } 172 | } 173 | 174 | if (File) 175 | NtClose(File); 176 | 177 | if (g_TempFileName[0]) 178 | supMarkForDelete(g_TempFileName); 179 | 180 | if (DefaultACL) 181 | supHeapFree(DefaultACL); 182 | 183 | if (AdminSD) 184 | supHeapFree(AdminSD); 185 | 186 | return Status; 187 | } 188 | 189 | SAFERIO_EXPORT(NTSTATUS) DrvInitialize(PCWSTR Name) 190 | { 191 | NTSTATUS Status = STATUS_SUCCESS; 192 | 193 | if (!Name || !*Name) 194 | return STATUS_INVALID_PARAMETER; 195 | 196 | if (g_DeviceHandle) 197 | return STATUS_ALREADY_INITIALIZED; 198 | 199 | wcscpy_s(g_AppName, Name); 200 | 201 | Status = supOpenDriver(Name, GENERIC_WRITE | GENERIC_READ, &g_DeviceHandle); 202 | 203 | if (Status == STATUS_OBJECT_NAME_NOT_FOUND) 204 | { 205 | Status = DrvpLoadDriver(Name); 206 | if (NT_SUCCESS(Status)) 207 | { 208 | Status = supOpenDriver(Name, GENERIC_WRITE | GENERIC_READ, &g_DeviceHandle); 209 | } 210 | } 211 | 212 | return Status; 213 | } 214 | 215 | SAFERIO_EXPORT(NTSTATUS) DrvUninitialize(PCWSTR Name) 216 | { 217 | NTSTATUS Status = STATUS_SUCCESS; 218 | 219 | if (!Name || !*Name) 220 | return STATUS_INVALID_PARAMETER; 221 | 222 | if (0 != wcscmp(Name, g_AppName)) 223 | return STATUS_INVALID_PARAMETER; 224 | 225 | if (!g_DeviceHandle) 226 | return STATUS_SUCCESS; 227 | 228 | ULONG RefCount{}; 229 | Status = DrvGetRefCount(RefCount); 230 | if (!NT_SUCCESS(Status)) 231 | return Status; 232 | 233 | NtClose(g_DeviceHandle); 234 | g_DeviceHandle = nullptr; 235 | 236 | if (RefCount > 1) 237 | return STATUS_SUCCESS; 238 | 239 | Status = supEnablePrivilege(SE_LOAD_DRIVER_PRIVILEGE, TRUE); 240 | if (!NT_SUCCESS(Status)) 241 | return Status; 242 | 243 | Status = supUnloadDriver(Name, TRUE); 244 | 245 | if (g_TempFileName[0]) 246 | supMarkForDelete(g_TempFileName); 247 | 248 | return Status; 249 | } 250 | 251 | NTSTATUS IoCtl(ULONG Code, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength) 252 | { 253 | return supCallDriver( 254 | g_DeviceHandle, 255 | Code, 256 | InputBuffer, 257 | InputBufferLength, 258 | OutputBuffer, 259 | OutputBufferLength 260 | ); 261 | } -------------------------------------------------------------------------------- /SaferIO/global.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-2.1-or-later 2 | // 3 | // SaferIO Library - Simple library for IO access 4 | // Copyright (C) 2021 namazso 5 | // 6 | // This library is free software; you can redistribute it and/or 7 | // modify it under the terms of the GNU Lesser General Public 8 | // License as published by the Free Software Foundation; either 9 | // version 2.1 of the License, or (at your option) any later version. 10 | // 11 | // This library is distributed in the hope that it will be useful, 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | // Lesser General Public License for more details. 15 | // 16 | // You should have received a copy of the GNU Lesser General Public 17 | // License along with this library; if not, write to the Free Software 18 | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | #pragma once 20 | #define _NO_CRT_STDIO_INLINE 21 | #define _CRT_SECURE_NO_WARNINGS 22 | #include 23 | #define WIN32_NO_STATUS 24 | #include 25 | #include 26 | #include 27 | #include "ntos.h" 28 | 29 | #include 30 | #include 31 | 32 | #include "../SaferIO.h" 33 | -------------------------------------------------------------------------------- /SaferIO/ioctl.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-2.1-or-later 2 | // 3 | // SaferIO Library - Simple library for IO access 4 | // Copyright (C) 2021 namazso 5 | // 6 | // This library is free software; you can redistribute it and/or 7 | // modify it under the terms of the GNU Lesser General Public 8 | // License as published by the Free Software Foundation; either 9 | // version 2.1 of the License, or (at your option) any later version. 10 | // 11 | // This library is distributed in the hope that it will be useful, 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | // Lesser General Public License for more details. 15 | // 16 | // You should have received a copy of the GNU Lesser General Public 17 | // License along with this library; if not, write to the Free Software 18 | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | #include "global.h" 20 | #include "ioctl.h" 21 | 22 | template 23 | __forceinline std::array AsBytes(const T& Value) 24 | { 25 | const auto Address = (const uint8_t*)std::addressof(Value); 26 | std::array Array{}; 27 | std::copy(Address, Address + sizeof(T), Array.begin()); 28 | return Array; 29 | } 30 | 31 | template 32 | __forceinline constexpr auto Sum() -> std::size_t 33 | { 34 | return (Args + ... + 0); 35 | } 36 | 37 | template 38 | __forceinline constexpr auto FlattenArray(std::array... Arrays) 39 | { 40 | constexpr std::size_t NbArray = sizeof...(Arrays); 41 | 42 | T* Data[NbArray] = { &Arrays[0]... }; 43 | constexpr std::size_t Lengths[NbArray] = { Arrays.size()... }; 44 | 45 | constexpr std::size_t FlatLength = Sum(); 46 | 47 | std::array FlatArray = { 0 }; 48 | 49 | size_t Index = 0; 50 | for (size_t i = 0; i < NbArray; i++) 51 | { 52 | for (size_t j = 0; j < Lengths[i]; j++) 53 | { 54 | FlatArray[Index] = Data[i][j]; 55 | Index++; 56 | } 57 | } 58 | 59 | return FlatArray; 60 | } 61 | 62 | constexpr std::array FlattenArray() { return {}; } 63 | 64 | template 65 | __forceinline auto MakeArray(const Args&... Args_) 66 | { 67 | return FlattenArray(AsBytes(Args_)...); 68 | } 69 | 70 | NTSTATUS IoCtl(ULONG Code, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength); 71 | 72 | template 73 | BOOL DoIoCtl(ULONG Code, Out&& OutVar, const In&... InVars) 74 | { 75 | auto InPacked = MakeArray(InVars...); 76 | constexpr auto OutSize = std::is_same_v, std::monostate> ? 0 : sizeof(OutVar); 77 | return IoCtl( 78 | Code, 79 | (PVOID)InPacked.data(), 80 | (ULONG)InPacked.size(), 81 | (PVOID)&OutVar, 82 | (ULONG)OutSize 83 | ); 84 | } 85 | 86 | SAFERIO_EXPORT(NTSTATUS) DrvGetRefCount(ULONG& RefCount) { return DoIoCtl(IOCTL_GET_REFCOUNT, RefCount); } 87 | 88 | SAFERIO_EXPORT(NTSTATUS) DrvIoPortReadByte(USHORT Port, UCHAR& Value) { return DoIoCtl(IOCTL_IO_PORT_READ, Value, Port); } 89 | SAFERIO_EXPORT(NTSTATUS) DrvIoPortReadWord(USHORT Port, USHORT& Value) { return DoIoCtl(IOCTL_IO_PORT_READ, Value, Port); } 90 | SAFERIO_EXPORT(NTSTATUS) DrvIoPortReadDword(USHORT Port, ULONG& Value) { return DoIoCtl(IOCTL_IO_PORT_READ, Value, Port); } 91 | 92 | SAFERIO_EXPORT(NTSTATUS) DrvIoPortWriteByte(USHORT Port, UCHAR Value) { return DoIoCtl(IOCTL_IO_PORT_WRITE, std::monostate{}, Port, (USHORT)0, Value); } 93 | SAFERIO_EXPORT(NTSTATUS) DrvIoPortWriteWord(USHORT Port, USHORT Value) { return DoIoCtl(IOCTL_IO_PORT_WRITE, std::monostate{}, Port, (USHORT)0, Value); } 94 | SAFERIO_EXPORT(NTSTATUS) DrvIoPortWriteDword(USHORT Port, ULONG Value) { return DoIoCtl(IOCTL_IO_PORT_WRITE, std::monostate{}, Port, (USHORT)0, Value); } 95 | 96 | SAFERIO_EXPORT(NTSTATUS) DrvMsrRead(ULONG Index, ULONG64& Value) { return DoIoCtl(IOCTL_MSR_READ, Value, Index); } 97 | 98 | SAFERIO_EXPORT(NTSTATUS) DrvMsrWrite(ULONG Index, ULONG64 Value) { return DoIoCtl(IOCTL_MSR_WRITE, std::monostate{}, Index, Value); } 99 | 100 | SAFERIO_EXPORT(NTSTATUS) DrvPhysReadByte(ULONG64 Addr, UCHAR& Value) { return DoIoCtl(IOCTL_PHYSMEM_READ, Value, Addr); } 101 | SAFERIO_EXPORT(NTSTATUS) DrvPhysReadWord(ULONG64 Addr, USHORT& Value) { return DoIoCtl(IOCTL_PHYSMEM_READ, Value, Addr); } 102 | SAFERIO_EXPORT(NTSTATUS) DrvPhysReadDword(ULONG64 Addr, ULONG& Value) { return DoIoCtl(IOCTL_PHYSMEM_READ, Value, Addr); } 103 | SAFERIO_EXPORT(NTSTATUS) DrvPhysReadQword(ULONG64 Addr, ULONG64& Value) { return DoIoCtl(IOCTL_PHYSMEM_READ, Value, Addr); } 104 | 105 | SAFERIO_EXPORT(NTSTATUS) DrvPhysWriteByte(ULONG64 Addr, UCHAR Value) { return DoIoCtl(IOCTL_PHYSMEM_WRITE, std::monostate{}, Addr, Value); } 106 | SAFERIO_EXPORT(NTSTATUS) DrvPhysWriteWord(ULONG64 Addr, USHORT Value) { return DoIoCtl(IOCTL_PHYSMEM_WRITE, std::monostate{}, Addr, Value); } 107 | SAFERIO_EXPORT(NTSTATUS) DrvPhysWriteDword(ULONG64 Addr, ULONG Value) { return DoIoCtl(IOCTL_PHYSMEM_WRITE, std::monostate{}, Addr, Value); } 108 | SAFERIO_EXPORT(NTSTATUS) DrvPhysWriteQword(ULONG64 Addr, ULONG64 Value) { return DoIoCtl(IOCTL_PHYSMEM_WRITE, std::monostate{}, Addr, Value); } 109 | 110 | SAFERIO_EXPORT(NTSTATUS) DrvPciConfigRead(UCHAR Bus, UCHAR Device, UCHAR Function, ULONG Offset, PVOID OutBuffer, UCHAR OutSize) 111 | { 112 | IOCTL_PCI_CONFIG_CMD Cmd{}; 113 | Cmd.BusNumber = Bus; 114 | Cmd.DeviceNumber = Device; 115 | Cmd.FunctionNumber = Function; 116 | Cmd.Offset = Offset; 117 | return IoCtl( 118 | IOCTL_PCI_CONFIG_READ, 119 | &Cmd, 120 | (ULONG)sizeof(Cmd), 121 | OutBuffer, 122 | (ULONG)OutSize 123 | ); 124 | } 125 | 126 | SAFERIO_EXPORT(NTSTATUS) DrvPciConfigWriteByte(UCHAR Bus, UCHAR Device, UCHAR Function, ULONG Offset, UCHAR Value) 127 | { 128 | IOCTL_PCI_CONFIG_CMD Cmd{}; 129 | Cmd.BusNumber = Bus; 130 | Cmd.DeviceNumber = Device; 131 | Cmd.FunctionNumber = Function; 132 | Cmd.Offset = Offset; 133 | return DoIoCtl(IOCTL_PCI_CONFIG_WRITE, std::monostate{}, Cmd, Value); 134 | } 135 | 136 | SAFERIO_EXPORT(NTSTATUS) DrvPciConfigWriteWord(UCHAR Bus, UCHAR Device, UCHAR Function, ULONG Offset, USHORT Value) 137 | { 138 | IOCTL_PCI_CONFIG_CMD Cmd{}; 139 | Cmd.BusNumber = Bus; 140 | Cmd.DeviceNumber = Device; 141 | Cmd.FunctionNumber = Function; 142 | Cmd.Offset = Offset; 143 | return DoIoCtl(IOCTL_PCI_CONFIG_WRITE, std::monostate{}, Cmd, Value); 144 | } 145 | 146 | SAFERIO_EXPORT(NTSTATUS) DrvPciConfigWriteDword(UCHAR Bus, UCHAR Device, UCHAR Function, ULONG Offset, ULONG Value) 147 | { 148 | IOCTL_PCI_CONFIG_CMD Cmd{}; 149 | Cmd.BusNumber = Bus; 150 | Cmd.DeviceNumber = Device; 151 | Cmd.FunctionNumber = Function; 152 | Cmd.Offset = Offset; 153 | return DoIoCtl(IOCTL_PCI_CONFIG_WRITE, std::monostate{}, Cmd, Value); 154 | } 155 | 156 | SAFERIO_EXPORT(NTSTATUS) DrvPhysMap(ULONG64 Addr, ULONG Length, PVOID& MappedAddress) 157 | { 158 | return DoIoCtl(IOCTL_PHYSMEM_MAP, MappedAddress, Addr, Length); 159 | } 160 | 161 | SAFERIO_EXPORT(NTSTATUS) DrvPhysUnmap(PVOID MappedAddress) 162 | { 163 | return DoIoCtl(IOCTL_PHYSMEM_UNMAP, std::monostate{}, MappedAddress); 164 | } 165 | -------------------------------------------------------------------------------- /SaferIO/ioctl.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-2.1-or-later 2 | // 3 | // SaferIO Library - Simple library for IO access 4 | // Copyright (C) 2021 namazso 5 | // 6 | // This library is free software; you can redistribute it and/or 7 | // modify it under the terms of the GNU Lesser General Public 8 | // License as published by the Free Software Foundation; either 9 | // version 2.1 of the License, or (at your option) any later version. 10 | // 11 | // This library is distributed in the hope that it will be useful, 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | // Lesser General Public License for more details. 15 | // 16 | // You should have received a copy of the GNU Lesser General Public 17 | // License along with this library; if not, write to the Free Software 18 | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | #pragma once 20 | 21 | #define SAFEIO_DEVICE_TYPE (0x8000) 22 | 23 | enum IOCTL_CODES : ULONG 24 | { 25 | // in: USHORT Port; 26 | // out: UCHAR Value; 27 | // out: USHORT Value; 28 | // out: ULONG Value; 29 | IOCTL_IO_PORT_READ = (ULONG)CTL_CODE(SAFEIO_DEVICE_TYPE, 0x90C, METHOD_BUFFERED, FILE_READ_ACCESS), 30 | 31 | // in: USHORT Port; USHORT Reserved; UCHAR Value; 32 | // in: USHORT Port; USHORT Reserved; USHORT Value; 33 | // in: USHORT Port; USHORT Reserved; ULONG Value; 34 | // out: VOID; 35 | IOCTL_IO_PORT_WRITE = (ULONG)CTL_CODE(SAFEIO_DEVICE_TYPE, 0x90D, METHOD_BUFFERED, FILE_READ_ACCESS), 36 | 37 | // in: ULONG Index; 38 | // out: ULONG64 Value; 39 | IOCTL_MSR_READ = (ULONG)CTL_CODE(SAFEIO_DEVICE_TYPE, 0x912, METHOD_BUFFERED, FILE_READ_ACCESS), 40 | 41 | // in: ULONG Index; ULONG64 Value; 42 | // out: VOID; 43 | IOCTL_MSR_WRITE = (ULONG)CTL_CODE(SAFEIO_DEVICE_TYPE, 0x913, METHOD_BUFFERED, FILE_READ_ACCESS), 44 | 45 | // in: ULONG64 PhysicalAddress; ULONG Size; 46 | // out: PVOID MappedAddress; 47 | IOCTL_PHYSMEM_MAP = (ULONG)CTL_CODE(SAFEIO_DEVICE_TYPE, 0x917, METHOD_BUFFERED, FILE_READ_ACCESS), 48 | 49 | // in: PVOID MappedAddress; 50 | // out: VOID; 51 | IOCTL_PHYSMEM_UNMAP = (ULONG)CTL_CODE(SAFEIO_DEVICE_TYPE, 0x918, METHOD_BUFFERED, FILE_READ_ACCESS), 52 | 53 | // in: VOID; 54 | // out: ULONG RefCount; 55 | IOCTL_GET_REFCOUNT = (ULONG)CTL_CODE(SAFEIO_DEVICE_TYPE, 0x925, METHOD_BUFFERED, FILE_READ_ACCESS), 56 | 57 | // in: ULONG64 PhysicalAddress; 58 | // out: UCHAR Value; 59 | // out: USHORT Value; 60 | // out: ULONG Value; 61 | // out: ULONG64 Value; 62 | IOCTL_PHYSMEM_READ = (ULONG)CTL_CODE(SAFEIO_DEVICE_TYPE, 0x926, METHOD_BUFFERED, FILE_READ_ACCESS), 63 | 64 | // in: ULONG64 PhysicalAddress; UCHAR Value; 65 | // in: ULONG64 PhysicalAddress; USHORT Value; 66 | // in: ULONG64 PhysicalAddress; ULONG Value; 67 | // in: ULONG64 PhysicalAddress; ULONG64 Value; 68 | // out: VOID; 69 | IOCTL_PHYSMEM_WRITE = (ULONG)CTL_CODE(SAFEIO_DEVICE_TYPE, 0x927, METHOD_BUFFERED, FILE_READ_ACCESS), 70 | 71 | // in: IOCTL_PCI_CONFIG_CMD Cmd; 72 | // out: UCHAR[] but at most 255 73 | IOCTL_PCI_CONFIG_READ = (ULONG)CTL_CODE(SAFEIO_DEVICE_TYPE, 0x907, METHOD_BUFFERED, FILE_READ_ACCESS), 74 | 75 | // in: IOCTL_PCI_CONFIG_CMD Cmd; UCHAR Value; 76 | // in: IOCTL_PCI_CONFIG_CMD Cmd; USHORT Value; 77 | // in: IOCTL_PCI_CONFIG_CMD Cmd; ULONG Value; 78 | // out: VOID; 79 | IOCTL_PCI_CONFIG_WRITE = (ULONG)CTL_CODE(SAFEIO_DEVICE_TYPE, 0x908, METHOD_BUFFERED, FILE_READ_ACCESS), 80 | 81 | }; 82 | 83 | struct IOCTL_PCI_CONFIG_CMD 84 | { 85 | UCHAR BusNumber; 86 | UCHAR DeviceNumber; 87 | UCHAR FunctionNumber; 88 | UCHAR Reserved; 89 | ULONG Offset; 90 | }; 91 | -------------------------------------------------------------------------------- /SaferIO/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by resource.rc 4 | // 5 | #define IDR_DRIVER_X86 101 6 | #define IDR_DRIVER_X64 102 7 | 8 | // Next default values for new objects 9 | // 10 | #ifdef APSTUDIO_INVOKED 11 | #ifndef APSTUDIO_READONLY_SYMBOLS 12 | #define _APS_NEXT_RESOURCE_VALUE 102 13 | #define _APS_NEXT_COMMAND_VALUE 40001 14 | #define _APS_NEXT_CONTROL_VALUE 1001 15 | #define _APS_NEXT_SYMED_VALUE 101 16 | #endif 17 | #endif 18 | -------------------------------------------------------------------------------- /SaferIO/resource.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #include "resource.h" 4 | 5 | #define APSTUDIO_READONLY_SYMBOLS 6 | ///////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Generated from the TEXTINCLUDE 2 resource. 9 | // 10 | #include "winres.h" 11 | 12 | ///////////////////////////////////////////////////////////////////////////// 13 | #undef APSTUDIO_READONLY_SYMBOLS 14 | 15 | ///////////////////////////////////////////////////////////////////////////// 16 | // English (United States) resources 17 | 18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 19 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 20 | #pragma code_page(1252) 21 | 22 | ///////////////////////////////////////////////////////////////////////////// 23 | // 24 | // 256 25 | // 26 | 27 | IDR_DRIVER_X86 RCDATA "..\DriverBins\Driver_x86.sys" 28 | 29 | IDR_DRIVER_X64 RCDATA "..\DriverBins\Driver_x64.sys" 30 | 31 | 32 | #ifdef APSTUDIO_INVOKED 33 | ///////////////////////////////////////////////////////////////////////////// 34 | // 35 | // TEXTINCLUDE 36 | // 37 | 38 | 1 TEXTINCLUDE 39 | BEGIN 40 | "resource.h\0" 41 | END 42 | 43 | 2 TEXTINCLUDE 44 | BEGIN 45 | "#include ""winres.h""\r\n" 46 | "\0" 47 | END 48 | 49 | 3 TEXTINCLUDE 50 | BEGIN 51 | "\r\n" 52 | "\0" 53 | END 54 | 55 | #endif // APSTUDIO_INVOKED 56 | 57 | 58 | ///////////////////////////////////////////////////////////////////////////// 59 | // 60 | // 256 61 | // 62 | 63 | #endif // English (United States) resources 64 | ///////////////////////////////////////////////////////////////////////////// 65 | 66 | 67 | 68 | #ifndef APSTUDIO_INVOKED 69 | ///////////////////////////////////////////////////////////////////////////// 70 | // 71 | // Generated from the TEXTINCLUDE 3 resource. 72 | // 73 | 74 | 75 | ///////////////////////////////////////////////////////////////////////////// 76 | #endif // not APSTUDIO_INVOKED 77 | 78 | -------------------------------------------------------------------------------- /SaferIO/sup.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-2.1-or-later 2 | // 3 | // SaferIO Library - Simple library for IO access 4 | // Copyright (C) 2021 namazso 5 | // 6 | // This library is free software; you can redistribute it and/or 7 | // modify it under the terms of the GNU Lesser General Public 8 | // License as published by the Free Software Foundation; either 9 | // version 2.1 of the License, or (at your option) any later version. 10 | // 11 | // This library is distributed in the hope that it will be useful, 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | // Lesser General Public License for more details. 15 | // 16 | // You should have received a copy of the GNU Lesser General Public 17 | // License along with this library; if not, write to the Free Software 18 | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | // 20 | // Notice for original file from KDU Project: 21 | // 22 | // Copyright (c) 2020 - 2021 KDU Project 23 | // 24 | // Permission is hereby granted, free of charge, to any person obtaining a copy 25 | // of this software and associated documentation files (the "Software"), to deal 26 | // in the Software without restriction, including without limitation the rights 27 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 28 | // copies of the Software, and to permit persons to whom the Software is 29 | // furnished to do so, subject to the following conditions: 30 | // 31 | // The above copyright notice and this permission notice shall be included in all 32 | // copies or substantial portions of the Software. 33 | // 34 | // TITLE: SUP.CPP 35 | // 36 | // VERSION: 1.11 37 | // 38 | // DATE: 14 May 2021 39 | // 40 | // Program global support routines. 41 | 42 | #include "global.h" 43 | #include "sup.h" 44 | 45 | #define NT_REG_PREP L"\\Registry\\Machine" 46 | #define DRIVER_REGKEY L"%wS\\System\\CurrentControlSet\\Services\\%wS" 47 | 48 | /* 49 | * supHeapAlloc 50 | * 51 | * Purpose: 52 | * 53 | * Wrapper for RtlAllocateHeap. 54 | * 55 | */ 56 | PVOID FORCEINLINE supHeapAlloc( 57 | _In_ SIZE_T Size 58 | ) 59 | { 60 | return RtlAllocateHeap(NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, Size); 61 | } 62 | 63 | /* 64 | * supHeapFree 65 | * 66 | * Purpose: 67 | * 68 | * Wrapper for RtlFreeHeap. 69 | * 70 | */ 71 | BOOL FORCEINLINE supHeapFree( 72 | _In_ PVOID Memory 73 | ) 74 | { 75 | return RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, Memory); 76 | } 77 | 78 | /* 79 | * supCallDriver 80 | * 81 | * Purpose: 82 | * 83 | * Call driver. 84 | * 85 | */ 86 | NTSTATUS supCallDriver( 87 | _In_ HANDLE DeviceHandle, 88 | _In_ ULONG IoControlCode, 89 | _In_opt_ PVOID InputBuffer, 90 | _In_opt_ ULONG InputBufferLength, 91 | _In_opt_ PVOID OutputBuffer, 92 | _In_opt_ ULONG OutputBufferLength 93 | ) 94 | { 95 | IO_STATUS_BLOCK IoStatus; 96 | 97 | return NtDeviceIoControlFile( 98 | DeviceHandle, 99 | nullptr, 100 | nullptr, 101 | nullptr, 102 | &IoStatus, 103 | IoControlCode, 104 | InputBuffer, 105 | InputBufferLength, 106 | OutputBuffer, 107 | OutputBufferLength 108 | ); 109 | } 110 | 111 | /* 112 | * supxDeleteKeyRecursive 113 | * 114 | * Purpose: 115 | * 116 | * Delete key and all it subkeys/values. 117 | * 118 | */ 119 | BOOL supxDeleteKeyRecursive( 120 | _In_ HKEY KeyRoot, 121 | _In_ LPWSTR SubKey 122 | ) 123 | { 124 | LPWSTR End; 125 | LONG Result; 126 | DWORD Size; 127 | WCHAR Name[MAX_PATH + 1]; 128 | HKEY Key; 129 | FILETIME WriteTime; 130 | 131 | // 132 | // Attempt to delete key as is. 133 | // 134 | Result = RegDeleteKey(KeyRoot, SubKey); 135 | if (Result == ERROR_SUCCESS) 136 | return TRUE; 137 | 138 | // 139 | // Try to open key to check if it exist. 140 | // 141 | Result = RegOpenKeyEx(KeyRoot, SubKey, 0, KEY_READ, &Key); 142 | if (Result != ERROR_SUCCESS) 143 | { 144 | if (Result == ERROR_FILE_NOT_FOUND) 145 | return TRUE; 146 | else 147 | return FALSE; 148 | } 149 | 150 | // 151 | // Add slash to the key path if not present. 152 | // 153 | End = SubKey + wcslen(SubKey); 154 | if (*(End - 1) != TEXT('\\')) 155 | { 156 | *End = TEXT('\\'); 157 | End++; 158 | *End = TEXT('\0'); 159 | } 160 | 161 | // 162 | // Enumerate subkeys and call this func for each. 163 | // 164 | Size = MAX_PATH; 165 | Result = RegEnumKeyEx( 166 | Key, 167 | 0, 168 | Name, 169 | &Size, 170 | nullptr, 171 | nullptr, 172 | nullptr, 173 | &WriteTime 174 | ); 175 | 176 | if (Result == ERROR_SUCCESS) 177 | { 178 | do 179 | { 180 | wcsncpy(End, Name, MAX_PATH); 181 | 182 | if (!supxDeleteKeyRecursive(KeyRoot, SubKey)) 183 | break; 184 | 185 | Size = MAX_PATH; 186 | 187 | Result = RegEnumKeyEx( 188 | Key, 189 | 0, 190 | Name, 191 | &Size, 192 | nullptr, 193 | nullptr, 194 | nullptr, 195 | &WriteTime 196 | ); 197 | } 198 | while (Result == ERROR_SUCCESS); 199 | } 200 | 201 | End--; 202 | *End = TEXT('\0'); 203 | 204 | RegCloseKey(Key); 205 | 206 | // 207 | // Delete current key, all it subkeys should be already removed. 208 | // 209 | Result = RegDeleteKey(KeyRoot, SubKey); 210 | if (Result == ERROR_SUCCESS) 211 | return TRUE; 212 | 213 | return FALSE; 214 | } 215 | 216 | /* 217 | * supRegDeleteKeyRecursive 218 | * 219 | * Purpose: 220 | * 221 | * Delete key and all it subkeys/values. 222 | * 223 | * Remark: 224 | * 225 | * SubKey should not be longer than 260 chars. 226 | * 227 | */ 228 | BOOL supRegDeleteKeyRecursive( 229 | _In_ HKEY hKeyRoot, 230 | _In_ LPWSTR lpSubKey 231 | ) 232 | { 233 | WCHAR KeyName[MAX_PATH + 1]; 234 | RtlSecureZeroMemory(KeyName, sizeof(KeyName)); 235 | wcsncpy(KeyName, lpSubKey, MAX_PATH); 236 | KeyName[MAX_PATH] = 0; 237 | return supxDeleteKeyRecursive(hKeyRoot, KeyName); 238 | } 239 | 240 | /* 241 | * supEnablePrivilege 242 | * 243 | * Purpose: 244 | * 245 | * Enable/Disable given privilege. 246 | * 247 | * Return NTSTATUS value. 248 | * 249 | */ 250 | NTSTATUS supEnablePrivilege( 251 | _In_ DWORD Privilege, 252 | _In_ BOOL Enable 253 | ) 254 | { 255 | ULONG Length; 256 | NTSTATUS Status; 257 | HANDLE TokenHandle; 258 | LUID LuidPrivilege; 259 | 260 | PTOKEN_PRIVILEGES NewState; 261 | UCHAR Buffer[sizeof(TOKEN_PRIVILEGES) + sizeof(LUID_AND_ATTRIBUTES)]; 262 | 263 | Status = NtOpenProcessToken( 264 | NtCurrentProcess(), 265 | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, 266 | &TokenHandle 267 | ); 268 | 269 | if (!NT_SUCCESS(Status)) 270 | { 271 | return Status; 272 | } 273 | 274 | NewState = (PTOKEN_PRIVILEGES)Buffer; 275 | 276 | LuidPrivilege = RtlConvertUlongToLuid(Privilege); 277 | 278 | NewState->PrivilegeCount = 1; 279 | NewState->Privileges[0].Luid = LuidPrivilege; 280 | NewState->Privileges[0].Attributes = Enable ? SE_PRIVILEGE_ENABLED : 0; 281 | 282 | Status = NtAdjustPrivilegesToken( 283 | TokenHandle, 284 | FALSE, 285 | NewState, 286 | sizeof(Buffer), 287 | nullptr, 288 | &Length 289 | ); 290 | 291 | if (Status == STATUS_NOT_ALL_ASSIGNED) 292 | { 293 | Status = STATUS_PRIVILEGE_NOT_HELD; 294 | } 295 | 296 | NtClose(TokenHandle); 297 | return Status; 298 | } 299 | 300 | /* 301 | * supxCreateDriverEntry 302 | * 303 | * Purpose: 304 | * 305 | * Creating registry entry for driver. 306 | * 307 | */ 308 | NTSTATUS supxCreateDriverEntry( 309 | _In_opt_ LPCWSTR DriverPath, 310 | _In_ LPCWSTR KeyName 311 | ) 312 | { 313 | NTSTATUS Status = STATUS_UNSUCCESSFUL; 314 | DWORD Data, Result; 315 | HKEY Handle = nullptr; 316 | UNICODE_STRING DriverImagePath; 317 | 318 | RtlInitEmptyUnicodeString(&DriverImagePath, NULL, 0); 319 | 320 | if (DriverPath) 321 | { 322 | if (!RtlDosPathNameToNtPathName_U( 323 | DriverPath, 324 | &DriverImagePath, 325 | nullptr, 326 | nullptr 327 | )) 328 | { 329 | return STATUS_INVALID_PARAMETER_2; 330 | } 331 | } 332 | 333 | if (ERROR_SUCCESS != RegCreateKeyEx( 334 | HKEY_LOCAL_MACHINE, 335 | KeyName, 336 | 0, 337 | nullptr, 338 | REG_OPTION_NON_VOLATILE, 339 | KEY_ALL_ACCESS, 340 | nullptr, 341 | &Handle, 342 | nullptr 343 | )) 344 | { 345 | Status = STATUS_ACCESS_DENIED; 346 | goto Cleanup; 347 | } 348 | 349 | Result = ERROR_SUCCESS; 350 | 351 | do 352 | { 353 | Data = SERVICE_ERROR_NORMAL; 354 | Result = RegSetValueEx( 355 | Handle, 356 | TEXT("ErrorControl"), 357 | 0, 358 | REG_DWORD, 359 | (BYTE*)&Data, 360 | sizeof(Data) 361 | ); 362 | if (Result != ERROR_SUCCESS) 363 | break; 364 | 365 | Data = SERVICE_KERNEL_DRIVER; 366 | Result = RegSetValueEx( 367 | Handle, 368 | TEXT("Type"), 369 | 0, 370 | REG_DWORD, 371 | (BYTE*)&Data, 372 | sizeof(Data) 373 | ); 374 | if (Result != ERROR_SUCCESS) 375 | break; 376 | 377 | Data = SERVICE_DEMAND_START; 378 | Result = RegSetValueEx( 379 | Handle, 380 | TEXT("Start"), 381 | 0, 382 | REG_DWORD, 383 | (BYTE*)&Data, 384 | sizeof(Data) 385 | ); 386 | 387 | if (Result != ERROR_SUCCESS) 388 | break; 389 | 390 | if (DriverPath) 391 | { 392 | Result = RegSetValueEx( 393 | Handle, 394 | TEXT("ImagePath"), 395 | 0, 396 | REG_EXPAND_SZ, 397 | (BYTE*)DriverImagePath.Buffer, 398 | (DWORD)DriverImagePath.Length + sizeof(UNICODE_NULL) 399 | ); 400 | } 401 | } 402 | while (FALSE); 403 | 404 | RegCloseKey(Handle); 405 | 406 | if (Result != ERROR_SUCCESS) 407 | { 408 | Status = STATUS_ACCESS_DENIED; 409 | } 410 | else 411 | { 412 | Status = STATUS_SUCCESS; 413 | } 414 | 415 | Cleanup: 416 | if (DriverPath) 417 | { 418 | if (DriverImagePath.Buffer) 419 | { 420 | RtlFreeUnicodeString(&DriverImagePath); 421 | } 422 | } 423 | return Status; 424 | } 425 | 426 | /* 427 | * supLoadDriver 428 | * 429 | * Purpose: 430 | * 431 | * Install driver and load it. 432 | * 433 | * N.B. 434 | * SE_LOAD_DRIVER_PRIVILEGE is required to be assigned and enabled. 435 | * 436 | */ 437 | NTSTATUS supLoadDriver( 438 | _In_ LPCWSTR DriverName, 439 | _In_ LPCWSTR DriverPath, 440 | _In_ BOOLEAN UnloadPreviousInstance 441 | ) 442 | { 443 | SIZE_T KeyOffset; 444 | NTSTATUS Status; 445 | UNICODE_STRING DriverServiceName; 446 | 447 | WCHAR Buffer[MAX_PATH + 1]; 448 | 449 | if (DriverName == nullptr) 450 | return STATUS_INVALID_PARAMETER_1; 451 | if (DriverPath == nullptr) 452 | return STATUS_INVALID_PARAMETER_2; 453 | 454 | RtlSecureZeroMemory(Buffer, sizeof(Buffer)); 455 | 456 | KeyOffset = RTL_NUMBER_OF(NT_REG_PREP); 457 | 458 | if (FAILED( 459 | StringCchPrintf(Buffer, MAX_PATH, 460 | DRIVER_REGKEY, 461 | NT_REG_PREP, 462 | DriverName) 463 | )) 464 | { 465 | return STATUS_INVALID_PARAMETER_1; 466 | } 467 | 468 | Status = supxCreateDriverEntry( 469 | DriverPath, 470 | &Buffer[KeyOffset] 471 | ); 472 | 473 | if (!NT_SUCCESS(Status)) 474 | return Status; 475 | 476 | RtlInitUnicodeString(&DriverServiceName, Buffer); 477 | Status = NtLoadDriver(&DriverServiceName); 478 | 479 | if (UnloadPreviousInstance) 480 | { 481 | if ((Status == STATUS_IMAGE_ALREADY_LOADED) || 482 | (Status == STATUS_OBJECT_NAME_COLLISION) || 483 | (Status == STATUS_OBJECT_NAME_EXISTS)) 484 | { 485 | Status = NtUnloadDriver(&DriverServiceName); 486 | if (NT_SUCCESS(Status)) 487 | { 488 | Status = NtLoadDriver(&DriverServiceName); 489 | } 490 | } 491 | } 492 | else 493 | { 494 | if (Status == STATUS_OBJECT_NAME_EXISTS) 495 | Status = STATUS_SUCCESS; 496 | } 497 | 498 | return Status; 499 | } 500 | 501 | /* 502 | * supUnloadDriver 503 | * 504 | * Purpose: 505 | * 506 | * Call driver unload and remove corresponding registry key. 507 | * 508 | * N.B. 509 | * SE_LOAD_DRIVER_PRIVILEGE is required to be assigned and enabled. 510 | * 511 | */ 512 | NTSTATUS supUnloadDriver( 513 | _In_ LPCWSTR DriverName, 514 | _In_ BOOLEAN Remove 515 | ) 516 | { 517 | NTSTATUS Status; 518 | SIZE_T KeyOffset; 519 | UNICODE_STRING DriverServiceName; 520 | 521 | WCHAR Buffer[MAX_PATH + 1]; 522 | 523 | RtlSecureZeroMemory(Buffer, sizeof(Buffer)); 524 | 525 | if (FAILED( 526 | StringCchPrintf(Buffer, MAX_PATH, 527 | DRIVER_REGKEY, 528 | NT_REG_PREP, 529 | DriverName) 530 | )) 531 | { 532 | return STATUS_INVALID_PARAMETER_1; 533 | } 534 | 535 | KeyOffset = RTL_NUMBER_OF(NT_REG_PREP); 536 | 537 | Status = supxCreateDriverEntry( 538 | nullptr, 539 | &Buffer[KeyOffset] 540 | ); 541 | 542 | if (!NT_SUCCESS(Status)) 543 | return Status; 544 | 545 | RtlInitUnicodeString(&DriverServiceName, Buffer); 546 | Status = NtUnloadDriver(&DriverServiceName); 547 | 548 | if (NT_SUCCESS(Status)) 549 | { 550 | if (Remove) 551 | supRegDeleteKeyRecursive(HKEY_LOCAL_MACHINE, &Buffer[KeyOffset]); 552 | } 553 | 554 | return Status; 555 | } 556 | 557 | /* 558 | * supOpenDriver 559 | * 560 | * Purpose: 561 | * 562 | * Open handle for helper driver. 563 | * 564 | */ 565 | NTSTATUS supOpenDriver( 566 | _In_ LPCWSTR DriverName, 567 | _In_ ACCESS_MASK DesiredAccess, 568 | _Out_ PHANDLE DeviceHandle 569 | ) 570 | { 571 | NTSTATUS Status = STATUS_UNSUCCESSFUL; 572 | 573 | UNICODE_STRING DeviceLink; 574 | OBJECT_ATTRIBUTES ObjectAttributes; 575 | IO_STATUS_BLOCK IoStatus; 576 | 577 | WCHAR DeviceLinkBuffer[MAX_PATH + 1]; 578 | 579 | // assume failure 580 | if (DeviceHandle) 581 | *DeviceHandle = nullptr; 582 | else 583 | return STATUS_INVALID_PARAMETER_2; 584 | 585 | if (DriverName) 586 | { 587 | RtlSecureZeroMemory(DeviceLinkBuffer, sizeof(DeviceLinkBuffer)); 588 | 589 | if (FAILED( 590 | StringCchPrintf(DeviceLinkBuffer, 591 | MAX_PATH, 592 | TEXT("\\DosDevices\\%wS"), 593 | DriverName) 594 | )) 595 | { 596 | return STATUS_INVALID_PARAMETER_1; 597 | } 598 | 599 | RtlInitUnicodeString(&DeviceLink, DeviceLinkBuffer); 600 | InitializeObjectAttributes(&ObjectAttributes, &DeviceLink, OBJ_CASE_INSENSITIVE, NULL, NULL); 601 | 602 | Status = NtCreateFile( 603 | DeviceHandle, 604 | DesiredAccess, 605 | &ObjectAttributes, 606 | &IoStatus, 607 | nullptr, 608 | 0, 609 | 0, 610 | FILE_OPEN, 611 | 0, 612 | nullptr, 613 | 0 614 | ); 615 | } 616 | else 617 | { 618 | Status = STATUS_INVALID_PARAMETER_1; 619 | } 620 | 621 | return Status; 622 | } 623 | 624 | /* 625 | * supQueryResourceData 626 | * 627 | * Purpose: 628 | * 629 | * Load resource by given id. 630 | * 631 | * N.B. Use supHeapFree to release memory allocated for the decompressed buffer. 632 | * 633 | */ 634 | NTSTATUS supQueryResourceData( 635 | _In_ ULONG_PTR ResourceId, 636 | _In_ PVOID DllHandle, 637 | _Out_opt_ PVOID* Data, 638 | _Out_opt_ PULONG DataSize 639 | ) 640 | { 641 | NTSTATUS Status = STATUS_UNSUCCESSFUL; 642 | ULONG_PTR IdPath[3]; 643 | IMAGE_RESOURCE_DATA_ENTRY* DataEntry; 644 | PVOID PtrToData = nullptr; 645 | ULONG SizeOfData = 0; 646 | 647 | if (Data) 648 | *Data = nullptr; 649 | if (DataSize) 650 | *DataSize = 0; 651 | 652 | if (DllHandle != nullptr) 653 | { 654 | IdPath[0] = (ULONG_PTR)RT_RCDATA; //type 655 | IdPath[1] = ResourceId; //id 656 | IdPath[2] = 0; //lang 657 | 658 | Status = LdrFindResource_U(DllHandle, IdPath, 3, &DataEntry); 659 | if (NT_SUCCESS(Status)) 660 | { 661 | Status = LdrAccessResource(DllHandle, DataEntry, &PtrToData, &SizeOfData); 662 | if (NT_SUCCESS(Status)) 663 | { 664 | if (Data) 665 | *Data = PtrToData; 666 | if (DataSize) 667 | *DataSize = SizeOfData; 668 | } 669 | } 670 | } 671 | return Status; 672 | } 673 | 674 | /* 675 | * supWriteBufferToFile 676 | * 677 | * Purpose: 678 | * 679 | * Create new file (or open existing) and write (append) buffer to it. 680 | * 681 | */ 682 | SIZE_T supWriteBufferToFile( 683 | _In_ PWSTR FileName, 684 | _In_ PVOID Buffer, 685 | _In_ SIZE_T Size, 686 | _In_ BOOL Flush, 687 | _Out_opt_ NTSTATUS* Result, 688 | _In_opt_ ULONG AdditionalAccessFlags, 689 | _Out_opt_ HANDLE* Handle 690 | ) 691 | { 692 | NTSTATUS Status = STATUS_UNSUCCESSFUL; 693 | HANDLE File = nullptr; 694 | OBJECT_ATTRIBUTES ObjectAttributes; 695 | UNICODE_STRING NtFileName; 696 | IO_STATUS_BLOCK IoStatus; 697 | ULONG_PTR nBlocks, BlockIndex; 698 | ULONG BlockSize, RemainingSize; 699 | PUCHAR BytePtr = (PUCHAR)Buffer; 700 | SIZE_T BytesWritten = 0; 701 | 702 | if (Result) 703 | *Result = STATUS_UNSUCCESSFUL; 704 | if (Handle) 705 | *Handle = nullptr; 706 | 707 | if (RtlDosPathNameToNtPathName_U(FileName, &NtFileName, nullptr, nullptr) == FALSE) 708 | { 709 | if (Result) 710 | *Result = STATUS_INVALID_PARAMETER_1; 711 | return 0; 712 | } 713 | 714 | InitializeObjectAttributes(&ObjectAttributes, &NtFileName, OBJ_CASE_INSENSITIVE, nullptr, NULL); 715 | 716 | Status = NtCreateFile( 717 | &File, 718 | AdditionalAccessFlags | FILE_WRITE_ACCESS | SYNCHRONIZE, 719 | &ObjectAttributes, 720 | &IoStatus, 721 | nullptr, 722 | FILE_ATTRIBUTE_NORMAL, 723 | 0, 724 | FILE_OVERWRITE_IF, 725 | FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, 726 | nullptr, 727 | 0 728 | ); 729 | 730 | if (!NT_SUCCESS(Status)) 731 | goto fail; 732 | 733 | if (Size < 0x80000000) 734 | { 735 | BlockSize = (ULONG)Size; 736 | Status = NtWriteFile(File, nullptr, nullptr, nullptr, &IoStatus, BytePtr, BlockSize, nullptr, nullptr); 737 | if (!NT_SUCCESS(Status)) 738 | goto fail; 739 | 740 | BytesWritten += IoStatus.Information; 741 | } 742 | else 743 | { 744 | BlockSize = 0x7FFFFFFF; 745 | nBlocks = (Size / BlockSize); 746 | for (BlockIndex = 0; BlockIndex < nBlocks; BlockIndex++) 747 | { 748 | Status = NtWriteFile(File, nullptr, nullptr, nullptr, &IoStatus, BytePtr, BlockSize, nullptr, nullptr); 749 | if (!NT_SUCCESS(Status)) 750 | goto fail; 751 | 752 | BytePtr += BlockSize; 753 | BytesWritten += IoStatus.Information; 754 | } 755 | RemainingSize = (ULONG)(Size % BlockSize); 756 | if (RemainingSize != 0) 757 | { 758 | Status = NtWriteFile(File, nullptr, nullptr, nullptr, &IoStatus, BytePtr, RemainingSize, nullptr, nullptr); 759 | if (!NT_SUCCESS(Status)) 760 | goto fail; 761 | BytesWritten += IoStatus.Information; 762 | } 763 | } 764 | 765 | fail: 766 | if (File != nullptr) 767 | { 768 | if (Flush != FALSE) 769 | NtFlushBuffersFile(File, &IoStatus); 770 | if (NT_SUCCESS(Status) && Handle) 771 | *Handle = File; 772 | else 773 | NtClose(File); 774 | } 775 | RtlFreeUnicodeString(&NtFileName); 776 | if (Result) 777 | *Result = Status; 778 | 779 | return BytesWritten; 780 | } 781 | 782 | /* 783 | * supMarkForDelete 784 | * 785 | * Purpose: 786 | * 787 | * Mark a file for deletion when all handles to it close. 788 | * 789 | */ 790 | NTSTATUS supMarkForDelete(PWSTR FileName) 791 | { 792 | NTSTATUS Status = STATUS_UNSUCCESSFUL; 793 | HANDLE File = nullptr; 794 | OBJECT_ATTRIBUTES ObjectAttributes; 795 | UNICODE_STRING NtFileName; 796 | IO_STATUS_BLOCK IoStatus; 797 | 798 | if (RtlDosPathNameToNtPathName_U(FileName, &NtFileName, nullptr, nullptr) == FALSE) 799 | return STATUS_INVALID_PARAMETER_1; 800 | 801 | InitializeObjectAttributes(&ObjectAttributes, &NtFileName, OBJ_CASE_INSENSITIVE, nullptr, NULL); 802 | 803 | Status = NtCreateFile( 804 | &File, 805 | DELETE | SYNCHRONIZE, 806 | &ObjectAttributes, 807 | &IoStatus, 808 | nullptr, 809 | FILE_ATTRIBUTE_NORMAL, 810 | FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 811 | FILE_OPEN, 812 | FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE | FILE_DELETE_ON_CLOSE, 813 | nullptr, 814 | 0 815 | ); 816 | 817 | RtlFreeUnicodeString(&NtFileName); 818 | 819 | if (!NT_SUCCESS(Status)) 820 | return Status; 821 | 822 | NtClose(File); 823 | 824 | return Status; 825 | } 826 | 827 | /* 828 | * supExpandEnvironmentStrings 829 | * 830 | * Purpose: 831 | * 832 | * Reimplemented ExpandEnvironmentStrings. 833 | * 834 | */ 835 | DWORD supExpandEnvironmentStrings( 836 | _In_ LPCWSTR Src, 837 | _Out_writes_to_opt_(Size, return) LPWSTR Dst, 838 | _In_ DWORD Size 839 | ) 840 | { 841 | NTSTATUS Status; 842 | SIZE_T SrcLength = 0; 843 | SIZE_T ReturnLength = 0; 844 | SIZE_T DstLength = (SIZE_T)Size; 845 | 846 | if (Src) 847 | { 848 | SrcLength = wcslen(Src); 849 | } 850 | 851 | Status = RtlExpandEnvironmentStrings( 852 | nullptr, 853 | (PWSTR)Src, 854 | SrcLength, 855 | Dst, 856 | DstLength, 857 | &ReturnLength 858 | ); 859 | 860 | if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_TOO_SMALL)) 861 | { 862 | if (ReturnLength <= MAXDWORD32) 863 | return (DWORD)ReturnLength; 864 | 865 | Status = STATUS_UNSUCCESSFUL; 866 | } 867 | RtlSetLastWin32Error(RtlNtStatusToDosError(Status)); 868 | return 0; 869 | } 870 | 871 | 872 | /* 873 | * supReadFileToBuffer 874 | * 875 | * Purpose: 876 | * 877 | * Read file to buffer. Release memory when it no longer needed. 878 | * 879 | */ 880 | PBYTE supReadFileToBuffer( 881 | _In_ LPWSTR FileName, 882 | _Inout_opt_ LPDWORD BufferSize 883 | ) 884 | { 885 | NTSTATUS Status; 886 | HANDLE File = nullptr; 887 | PBYTE Buffer = nullptr; 888 | SIZE_T Size = 0; 889 | 890 | UNICODE_STRING Name; 891 | OBJECT_ATTRIBUTES ObjectAttributes; 892 | IO_STATUS_BLOCK IoStatus; 893 | FILE_STANDARD_INFORMATION Information; 894 | 895 | if (FileName == nullptr) 896 | return nullptr; 897 | 898 | Name.Buffer = nullptr; 899 | 900 | do 901 | { 902 | if (!RtlDosPathNameToNtPathName_U(FileName, &Name, nullptr, nullptr)) 903 | break; 904 | 905 | InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_CASE_INSENSITIVE, NULL, NULL); 906 | 907 | Status = NtCreateFile( 908 | &File, 909 | FILE_READ_DATA | SYNCHRONIZE, 910 | &ObjectAttributes, 911 | &IoStatus, 912 | nullptr, 913 | FILE_ATTRIBUTE_NORMAL, 914 | FILE_SHARE_READ, 915 | FILE_OPEN, 916 | FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, 917 | nullptr, 918 | 0 919 | ); 920 | 921 | if (!NT_SUCCESS(Status)) 922 | { 923 | break; 924 | } 925 | 926 | RtlSecureZeroMemory(&Information, sizeof(Information)); 927 | 928 | Status = NtQueryInformationFile( 929 | File, 930 | &IoStatus, 931 | &Information, 932 | sizeof(FILE_STANDARD_INFORMATION), 933 | FileStandardInformation 934 | ); 935 | 936 | if (!NT_SUCCESS(Status)) 937 | break; 938 | 939 | Size = (SIZE_T)Information.EndOfFile.LowPart; 940 | 941 | Buffer = (PBYTE)supHeapAlloc(Size); 942 | if (Buffer) 943 | { 944 | Status = NtReadFile( 945 | File, 946 | nullptr, 947 | nullptr, 948 | nullptr, 949 | &IoStatus, 950 | Buffer, 951 | Information.EndOfFile.LowPart, 952 | nullptr, 953 | nullptr 954 | ); 955 | 956 | if (NT_SUCCESS(Status)) 957 | { 958 | if (BufferSize) 959 | *BufferSize = Information.EndOfFile.LowPart; 960 | } 961 | else 962 | { 963 | supHeapFree(Buffer); 964 | Buffer = nullptr; 965 | } 966 | } 967 | } 968 | while (FALSE); 969 | 970 | if (File != nullptr) 971 | { 972 | NtClose(File); 973 | } 974 | 975 | if (Name.Buffer) 976 | RtlFreeUnicodeString(&Name); 977 | 978 | return Buffer; 979 | } 980 | 981 | /* 982 | * supCreateSystemAdminAccessSD 983 | * 984 | * Purpose: 985 | * 986 | * Create security descriptor with Admin/System ACL set. 987 | * 988 | */ 989 | NTSTATUS supCreateSystemAdminAccessSD( 990 | _Out_ PSECURITY_DESCRIPTOR* SecurityDescriptor, 991 | _Out_ PACL* DefaultAcl 992 | ) 993 | { 994 | NTSTATUS Status = STATUS_UNSUCCESSFUL; 995 | ULONG AclSize = 0; 996 | SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; 997 | PACL Acl = nullptr; 998 | PSECURITY_DESCRIPTOR Descriptor = nullptr; 999 | 1000 | UCHAR sidBuffer[2 * sizeof(SID)]; 1001 | 1002 | *SecurityDescriptor = nullptr; 1003 | *DefaultAcl = nullptr; 1004 | 1005 | do 1006 | { 1007 | RtlSecureZeroMemory(sidBuffer, sizeof(sidBuffer)); 1008 | 1009 | Descriptor = supHeapAlloc(sizeof(SECURITY_DESCRIPTOR)); 1010 | if (Descriptor == nullptr) 1011 | { 1012 | Status = STATUS_INSUFFICIENT_RESOURCES; 1013 | break; 1014 | } 1015 | 1016 | AclSize += RtlLengthRequiredSid(1); //LocalSystem sid 1017 | AclSize += RtlLengthRequiredSid(2); //Admin group sid 1018 | AclSize += sizeof(ACL); 1019 | AclSize += 2 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG)); 1020 | 1021 | Acl = (PACL)supHeapAlloc(AclSize); 1022 | if (Acl == nullptr) 1023 | { 1024 | Status = STATUS_INSUFFICIENT_RESOURCES; 1025 | break; 1026 | } 1027 | 1028 | Status = RtlCreateAcl(Acl, AclSize, ACL_REVISION); 1029 | if (!NT_SUCCESS(Status)) 1030 | break; 1031 | 1032 | // 1033 | // Local System - Generic All. 1034 | // 1035 | RtlInitializeSid(sidBuffer, &NtAuthority, 1); 1036 | *(RtlSubAuthoritySid(sidBuffer, 0)) = SECURITY_LOCAL_SYSTEM_RID; 1037 | RtlAddAccessAllowedAce(Acl, ACL_REVISION, GENERIC_ALL, sidBuffer); 1038 | 1039 | // 1040 | // Admins - Generic All. 1041 | // 1042 | RtlInitializeSid(sidBuffer, &NtAuthority, 2); 1043 | *(RtlSubAuthoritySid(sidBuffer, 0)) = SECURITY_BUILTIN_DOMAIN_RID; 1044 | *(RtlSubAuthoritySid(sidBuffer, 1)) = DOMAIN_ALIAS_RID_ADMINS; 1045 | RtlAddAccessAllowedAce(Acl, ACL_REVISION, GENERIC_ALL, sidBuffer); 1046 | 1047 | Status = RtlCreateSecurityDescriptor( 1048 | Descriptor, 1049 | SECURITY_DESCRIPTOR_REVISION1 1050 | ); 1051 | if (!NT_SUCCESS(Status)) 1052 | break; 1053 | 1054 | Status = RtlSetDaclSecurityDescriptor( 1055 | Descriptor, 1056 | TRUE, 1057 | Acl, 1058 | FALSE 1059 | ); 1060 | 1061 | if (!NT_SUCCESS(Status)) 1062 | break; 1063 | 1064 | *SecurityDescriptor = Descriptor; 1065 | *DefaultAcl = Acl; 1066 | } 1067 | while (FALSE); 1068 | 1069 | if (!NT_SUCCESS(Status)) 1070 | { 1071 | if (Acl) 1072 | supHeapFree(Acl); 1073 | 1074 | if (Descriptor) 1075 | { 1076 | supHeapFree(Descriptor); 1077 | } 1078 | 1079 | *SecurityDescriptor = nullptr; 1080 | *DefaultAcl = nullptr; 1081 | } 1082 | 1083 | return Status; 1084 | } 1085 | -------------------------------------------------------------------------------- /SaferIO/sup.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-2.1-or-later 2 | // 3 | // SaferIO Library - Simple library for IO access 4 | // Copyright (C) 2021 namazso 5 | // 6 | // This library is free software; you can redistribute it and/or 7 | // modify it under the terms of the GNU Lesser General Public 8 | // License as published by the Free Software Foundation; either 9 | // version 2.1 of the License, or (at your option) any later version. 10 | // 11 | // This library is distributed in the hope that it will be useful, 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | // Lesser General Public License for more details. 15 | // 16 | // You should have received a copy of the GNU Lesser General Public 17 | // License along with this library; if not, write to the Free Software 18 | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | // 20 | // Notice for original file from KDU Project: 21 | // 22 | // Copyright (c) 2020 - 2021 KDU Project 23 | // 24 | // Permission is hereby granted, free of charge, to any person obtaining a copy 25 | // of this software and associated documentation files (the "Software"), to deal 26 | // in the Software without restriction, including without limitation the rights 27 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 28 | // copies of the Software, and to permit persons to whom the Software is 29 | // furnished to do so, subject to the following conditions: 30 | // 31 | // The above copyright notice and this permission notice shall be included in all 32 | // copies or substantial portions of the Software. 33 | // 34 | // TITLE: SUP.H 35 | // 36 | // VERSION: 1.11 37 | // 38 | // DATE: 14 May 2021 39 | // 40 | // Support routines header file. 41 | #pragma once 42 | 43 | PVOID FORCEINLINE supHeapAlloc( 44 | _In_ SIZE_T Size 45 | ); 46 | 47 | BOOL FORCEINLINE supHeapFree( 48 | _In_ PVOID Memory 49 | ); 50 | 51 | NTSTATUS supCallDriver( 52 | _In_ HANDLE DeviceHandle, 53 | _In_ ULONG IoControlCode, 54 | _In_opt_ PVOID InputBuffer, 55 | _In_opt_ ULONG InputBufferLength, 56 | _In_opt_ PVOID OutputBuffer, 57 | _In_opt_ ULONG OutputBufferLength 58 | ); 59 | 60 | NTSTATUS supEnablePrivilege( 61 | _In_ DWORD Privilege, 62 | _In_ BOOL Enable 63 | ); 64 | 65 | NTSTATUS supLoadDriver( 66 | _In_ LPCWSTR DriverName, 67 | _In_ LPCWSTR DriverPath, 68 | _In_ BOOLEAN UnloadPreviousInstance 69 | ); 70 | 71 | NTSTATUS supUnloadDriver( 72 | _In_ LPCWSTR DriverName, 73 | _In_ BOOLEAN Remove 74 | ); 75 | 76 | NTSTATUS supOpenDriver( 77 | _In_ LPCWSTR DriverName, 78 | _In_ ACCESS_MASK DesiredAccess, 79 | _Out_ PHANDLE DeviceHandle 80 | ); 81 | 82 | NTSTATUS supQueryResourceData( 83 | _In_ ULONG_PTR ResourceId, 84 | _In_ PVOID DllHandle, 85 | _Out_opt_ PVOID* Data, 86 | _Out_opt_ PULONG DataSize 87 | ); 88 | 89 | PBYTE supReadFileToBuffer( 90 | _In_ LPWSTR FileName, 91 | _Inout_opt_ LPDWORD BufferSize 92 | ); 93 | 94 | SIZE_T supWriteBufferToFile( 95 | _In_ PWSTR FileName, 96 | _In_ PVOID Buffer, 97 | _In_ SIZE_T Size, 98 | _In_ BOOL Flush, 99 | _Out_opt_ NTSTATUS* Result, 100 | _In_opt_ ULONG AdditionalAccessFlags, 101 | _Out_opt_ HANDLE* Handle 102 | ); 103 | 104 | NTSTATUS supMarkForDelete( 105 | _In_ PWSTR FileName 106 | ); 107 | 108 | DWORD supExpandEnvironmentStrings( 109 | _In_ LPCWSTR Src, 110 | _Out_writes_to_opt_(Size, return) LPWSTR Dst, 111 | _In_ DWORD Size 112 | ); 113 | 114 | NTSTATUS supCreateSystemAdminAccessSD( 115 | _Out_ PSECURITY_DESCRIPTOR* SecurityDescriptor, 116 | _Out_ PACL* DefaultAcl 117 | ); 118 | -------------------------------------------------------------------------------- /TestApp/TestApp.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {89ca6409-f0bb-4f46-9c86-dd57a0f909d9} 25 | TestApp 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | false 78 | 79 | 80 | true 81 | 82 | 83 | false 84 | 85 | 86 | 87 | Level3 88 | true 89 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 90 | true 91 | 92 | 93 | Console 94 | true 95 | $(OutDir)SaferIO.lib;%(AdditionalDependencies) 96 | 97 | 98 | 99 | 100 | Level3 101 | true 102 | true 103 | true 104 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 105 | true 106 | 107 | 108 | Console 109 | true 110 | true 111 | true 112 | $(OutDir)SaferIO.lib;%(AdditionalDependencies) 113 | 114 | 115 | 116 | 117 | Level3 118 | true 119 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 120 | true 121 | 122 | 123 | Console 124 | true 125 | $(OutDir)SaferIO.lib;%(AdditionalDependencies) 126 | 127 | 128 | 129 | 130 | Level3 131 | true 132 | true 133 | true 134 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 135 | true 136 | 137 | 138 | Console 139 | true 140 | true 141 | true 142 | $(OutDir)SaferIO.lib;%(AdditionalDependencies) 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /TestApp/TestApp.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /TestApp/main.cpp: -------------------------------------------------------------------------------- 1 | // public domain 2 | #include 3 | #include 4 | #include "../SaferIO.h" 5 | 6 | constexpr static auto APP_NAME = L"TestApp"; 7 | 8 | int main() 9 | { 10 | enum : ULONG { IA32_KERNEL_GS_BASE = 0xC0000102 }; 11 | 12 | NTSTATUS Status = DrvInitialize(APP_NAME); 13 | printf("DrvInitialize returned: %08X\n", Status); 14 | ULONG64 GsBase{}; 15 | ULONG64 Teb = (ULONG64)NtCurrentTeb(); 16 | Status = DrvMsrRead(IA32_KERNEL_GS_BASE, GsBase); 17 | printf("DrvMsrRead returned: %08X, GsBase = %016llX, TEB = %016llX\n", Status, GsBase, Teb); 18 | Status = DrvUninitialize(APP_NAME); 19 | printf("DrvUninitialize returned: %08X\n", Status); 20 | return 0; 21 | } 22 | --------------------------------------------------------------------------------