15
15
*/
16
16
17
17
#pragma once
18
- #include " ../driver_loader.hpp"
19
- #include < algorithm>
18
+ #include " ../driver.hpp"
20
19
21
20
namespace ntw ::sys {
22
21
23
- NTW_INLINE driver::~driver () noexcept { static_cast <void >(unload ()); }
24
-
25
- NTW_INLINE driver::driver (driver&& other) noexcept
26
- : _service_path(_service_path_buffer, other._service_path.size())
27
- {
28
- auto & sp = other._service_path .get ();
29
- sp.Buffer = nullptr ;
30
- for (auto i = 0 ; i < (sp.Length >> 1 ); ++i)
31
- _service_path_buffer[i] = other._service_path_buffer [i];
32
- }
33
-
34
- NTW_INLINE driver& driver::operator =(driver&& other) noexcept
22
+ status load_driver (unicode_string service_name)
35
23
{
36
- unload ();
37
- _service_path.get ().Length = other._service_path .get ().Length ;
38
- _service_path.get ().MaximumLength = other._service_path .get ().MaximumLength ;
39
- for (auto i = 0 ; i < (other._service_path .get ().Length >> 1 ); ++i)
40
- _service_path_buffer[i] = other._service_path_buffer [i];
41
- return *this ;
24
+ return NTW_SYSCALL (NtLoadDriver)(&service_name.get ());
42
25
}
43
26
44
- NTW_INLINE status driver::_build_service_path (unicode_string file_path) noexcept
27
+ status unload_driver (unicode_string service_name)
45
28
{
46
- // load into service path buffer
47
- // L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"
48
- // obfuscation + speed
49
- auto uptr = reinterpret_cast <std::uint64_t *>(_service_path_buffer);
50
- uptr[0 ] = 28992356398268508 ;
51
- uptr[1 ] = 32088645568757865 ;
52
- uptr[2 ] = 27303403459444857 ;
53
- uptr[3 ] = 30962698416554083 ;
54
- uptr[4 ] = 34058828670304357 ;
55
- uptr[5 ] = 30681206260760691 ;
56
- uptr[6 ] = 32088649860579420 ;
57
- uptr[7 ] = 32651569751457906 ;
58
- uptr[8 ] = 32651569752113219 ;
59
- uptr[9 ] = 23362886930727026 ;
60
- uptr[10 ] = 23362818211577957 ;
61
- uptr[11 ] = 29555379368231013 ;
62
- uptr[12 ] = 25896191785238627 ;
63
-
64
- // find first separator
65
- const auto first = std::find (file_path.rbegin (), file_path.rend (), L' \\ ' );
66
- if (first == file_path.rend ())
67
- STATUS_OBJECT_PATH_SYNTAX_BAD;
68
-
69
- // find file extension
70
- const auto last = std::find (file_path.rbegin (), first, L' .' );
71
-
72
- // check size
73
- const std::size_t size = (first - last) - 1 ;
74
- if (size > 256 - 52 )
75
- return STATUS_NAME_TOO_LONG;
76
-
77
- // copy file name without extension
78
- std::copy_n (first.base (), size, _service_path_buffer + 52 );
79
-
80
- _service_path = { _service_path_buffer, static_cast <std::uint16_t >(size + 52 ) };
81
- return STATUS_SUCCESS;
29
+ return NTW_SYSCALL (NtUnloadDriver)(&service_name.get ());
82
30
}
83
31
84
- NTW_INLINE status driver::_init_service_fields (unicode_string path,
85
- const io::unique_reg_key& reg,
86
- start start_type,
87
- error_control error_control_type,
88
- type driver_type) noexcept
89
- {
90
- alignas (8 ) wchar_t buffer[16 ];
91
- auto uibuffer = reinterpret_cast <std::uint64_t *>(buffer);
92
-
93
- // ImagePath
94
- uibuffer[0 ] = 28992339220168777 ;
95
- uibuffer[1 ] = 32651513915506789 ;
96
- uibuffer[2 ] = 104 ;
97
-
98
- auto status =
99
- reg.set ({ buffer, 9 }, REG_EXPAND_SZ, path.begin (), path.byte_size () + 2 );
100
- if (!status.success ())
101
- return status;
102
-
103
- // Type
104
- uibuffer[0 ] = 28429453692043348 ;
105
-
106
- status = reg.set ({ buffer, 4 }, static_cast <ulong_t >(driver_type));
107
- if (!status.success ())
108
- return status;
109
-
110
- // ErrorControl
111
- uibuffer[0 ] = 31244212048625733 ;
112
- uibuffer[1 ] = 30962724183933042 ;
113
- uibuffer[2 ] = 30399774233591924 ;
114
-
115
- status = reg.set ({ buffer, 12 }, static_cast <ulong_t >(error_control_type));
116
- if (!status.success ())
117
- return status;
118
-
119
- uibuffer[0 ] = 32088563964444755 ;
120
- uibuffer[1 ] = 116 ;
121
-
122
- return reg.set ({ buffer, 5 }, static_cast <ulong_t >(start_type));
123
- }
124
-
125
- NTW_INLINE result<driver> driver::load (unicode_string path,
126
- start start_type,
127
- error_control error_control_type,
128
- type driver_type) noexcept
129
- {
130
- driver d;
131
- auto status = d._build_service_path (path);
132
- if (!status.success ())
133
- return status;
134
-
135
- io::reg_create_options options;
136
- if (start_type == start::manual_with_cleanup) {
137
- start_type = start::manual;
138
- options.non_preserved ();
139
- }
140
-
141
- const auto reg = io::unique_reg_key::create (
142
- d._service_path , io::reg_access{}.write (), options);
143
- if (!reg)
144
- return { reg.status () };
145
-
146
- _init_service_fields (path, *reg, start_type, error_control_type, driver_type);
147
-
148
- status = NTW_SYSCALL (NtLoadDriver)(&d._service_path .get ());
149
- return { status, std::move (d) };
150
- }
151
-
152
- NTW_INLINE status driver::unload () noexcept
153
- {
154
- if (_service_path.begin ()) {
155
- const auto s = NTW_SYSCALL (NtUnloadDriver)(&_service_path.get ());
156
- if (NT_SUCCESS (s))
157
- _service_path.get ().Buffer = nullptr ;
158
- return s;
159
- }
160
- return STATUS_NOT_FOUND;
161
- }
162
-
163
- NTW_INLINE void driver::release () noexcept { _service_path.get ().Buffer = nullptr ; }
164
-
165
32
} // namespace ntw::sys
0 commit comments