Skip to content

Commit 4049ce3

Browse files
committed
Added NtLoadKey3.
1 parent 9e966ab commit 4049ce3

3 files changed

Lines changed: 163 additions & 7 deletions

File tree

NtApiDotNet/NtKey.cs

Lines changed: 119 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,21 +97,25 @@ public static NtKey LoadKey(ObjectAttributes key_obj_attr, ObjectAttributes file
9797
/// <param name="file_obj_attr">Object attributes for the path to the hive file</param>
9898
/// <param name="flags">Load flags</param>
9999
/// <param name="desired_access">Desired access for the root key</param>
100+
/// <param name="trust_key">Key that this hive will be trusted for.</param>
101+
/// <param name="key_event">Event handle for key load.</param>
100102
/// <param name="throw_on_error">True to throw an exception on error.</param>
101103
/// <returns>The NT status code and object result.</returns>
102104
public static NtResult<NtKey> LoadKey(ObjectAttributes key_obj_attr, ObjectAttributes file_obj_attr,
103-
LoadKeyFlags flags, KeyAccessRights desired_access, bool throw_on_error)
105+
LoadKeyFlags flags, KeyAccessRights desired_access, NtKey trust_key, NtEvent key_event, bool throw_on_error)
104106
{
105107
if ((flags & LoadKeyFlags.AppKey) != 0)
106108
{
107109
return NtSystemCalls.NtLoadKeyEx(key_obj_attr, file_obj_attr, flags,
108-
IntPtr.Zero, IntPtr.Zero, desired_access, out SafeKernelObjectHandle key_handle, 0)
110+
trust_key.GetHandle().DangerousGetHandle(), key_event.GetHandle().DangerousGetHandle(),
111+
desired_access, out SafeKernelObjectHandle key_handle, 0)
109112
.CreateResult(throw_on_error, () => new NtKey(key_handle, KeyDisposition.OpenedExistingKey, false));
110113
}
111114
else
112115
{
113-
var result = NtSystemCalls.NtLoadKeyExNoHandle(key_obj_attr, file_obj_attr, flags,
114-
IntPtr.Zero, IntPtr.Zero, 0, IntPtr.Zero, 0).CreateResult<NtKey>(throw_on_error, () => null);
116+
var result = NtSystemCalls.NtLoadKeyEx(key_obj_attr, file_obj_attr, flags,
117+
trust_key.GetHandle().DangerousGetHandle(), key_event.GetHandle().DangerousGetHandle(),
118+
0, IntPtr.Zero, 0).CreateResult<NtKey>(throw_on_error, () => null);
115119
if (!result.IsSuccess)
116120
{
117121
return result;
@@ -121,6 +125,117 @@ public static NtResult<NtKey> LoadKey(ObjectAttributes key_obj_attr, ObjectAttri
121125
}
122126
}
123127

128+
/// <summary>
129+
/// Load a new hive
130+
/// </summary>
131+
/// <param name="key_obj_attr">Object attributes for the key name</param>
132+
/// <param name="file_obj_attr">Object attributes for the path to the hive file</param>
133+
/// <param name="flags">Load flags</param>
134+
/// <param name="desired_access">Desired access for the root key</param>
135+
/// <param name="trust_key">Key that this hive will be trusted for.</param>
136+
/// <param name="key_event">Event handle for key load.</param>
137+
/// <returns>The opened key.</returns>
138+
public static NtKey LoadKey(ObjectAttributes key_obj_attr, ObjectAttributes file_obj_attr,
139+
LoadKeyFlags flags, KeyAccessRights desired_access, NtKey trust_key, NtEvent key_event)
140+
{
141+
return LoadKey(key_obj_attr, file_obj_attr, flags, desired_access, trust_key, key_event, true).Result;
142+
}
143+
144+
/// <summary>
145+
/// Load a new hive
146+
/// </summary>
147+
/// <param name="key_obj_attr">Object attributes for the key name</param>
148+
/// <param name="file_obj_attr">Object attributes for the path to the hive file</param>
149+
/// <param name="flags">Load flags</param>
150+
/// <param name="desired_access">Desired access for the root key</param>
151+
/// <param name="throw_on_error">True to throw an exception on error.</param>
152+
/// <returns>The NT status code and object result.</returns>
153+
public static NtResult<NtKey> LoadKey(ObjectAttributes key_obj_attr, ObjectAttributes file_obj_attr,
154+
LoadKeyFlags flags, KeyAccessRights desired_access, bool throw_on_error)
155+
{
156+
return LoadKey(key_obj_attr, file_obj_attr, flags, desired_access, null, null, throw_on_error);
157+
}
158+
159+
/// <summary>
160+
/// Load a new hive
161+
/// </summary>
162+
/// <param name="key_obj_attr">Object attributes for the key name</param>
163+
/// <param name="file_obj_attr">Object attributes for the path to the hive file</param>
164+
/// <param name="flags">Load flags</param>
165+
/// <param name="desired_access">Desired access for the root key</param>
166+
/// <param name="token">Token to open the hive files under.</param>
167+
/// <param name="trust_key">Key that this hive will be trusted for.</param>
168+
/// <param name="key_event">Event handle for key load.</param>
169+
/// <param name="throw_on_error">True to throw an exception on error.</param>
170+
/// <returns>The NT status code and object result.</returns>
171+
public static NtResult<NtKey> LoadKey(ObjectAttributes key_obj_attr, ObjectAttributes file_obj_attr,
172+
LoadKeyFlags flags, KeyAccessRights desired_access, NtKey trust_key, NtEvent key_event, NtToken token, bool throw_on_error)
173+
{
174+
if (token == null)
175+
{
176+
return LoadKey(key_obj_attr, file_obj_attr, flags, desired_access, trust_key, key_event, throw_on_error);
177+
}
178+
179+
List<KeyLoadArgument> args = new List<KeyLoadArgument>();
180+
if (trust_key != null)
181+
{
182+
args.Add(new KeyLoadArgument()
183+
{
184+
ArgumentType = KeyLoadArgumentType.TrustKeyHandle,
185+
Argument = trust_key.Handle.DangerousGetHandle()
186+
});
187+
}
188+
189+
if (key_event != null)
190+
{
191+
args.Add(new KeyLoadArgument()
192+
{
193+
ArgumentType = KeyLoadArgumentType.EventHandle,
194+
Argument = key_event.Handle.DangerousGetHandle()
195+
});
196+
}
197+
args.Add(new KeyLoadArgument()
198+
{
199+
ArgumentType = KeyLoadArgumentType.TokenHandle,
200+
Argument = token.Handle.DangerousGetHandle()
201+
});
202+
203+
if ((flags & LoadKeyFlags.AppKey) != 0)
204+
{
205+
return NtSystemCalls.NtLoadKey3(key_obj_attr, file_obj_attr, flags,
206+
args.ToArray(), args.Count, desired_access, out SafeKernelObjectHandle key_handle, 0)
207+
.CreateResult(throw_on_error, () => new NtKey(key_handle, KeyDisposition.OpenedExistingKey, false));
208+
}
209+
else
210+
{
211+
var result = NtSystemCalls.NtLoadKey3(key_obj_attr, file_obj_attr, flags,
212+
args.ToArray(), args.Count, 0, IntPtr.Zero, 0).CreateResult<NtKey>(throw_on_error, () => null);
213+
if (!result.IsSuccess)
214+
{
215+
return result;
216+
}
217+
218+
return Open(key_obj_attr, desired_access, KeyCreateOptions.NonVolatile, throw_on_error);
219+
}
220+
}
221+
222+
/// <summary>
223+
/// Load a new hive
224+
/// </summary>
225+
/// <param name="key_obj_attr">Object attributes for the key name</param>
226+
/// <param name="file_obj_attr">Object attributes for the path to the hive file</param>
227+
/// <param name="flags">Load flags</param>
228+
/// <param name="desired_access">Desired access for the root key</param>
229+
/// <param name="token">Token to open the hive files under.</param>
230+
/// <param name="trust_key">Key that this hive will be trusted for.</param>
231+
/// <param name="key_event">Event handle for key load.</param>
232+
/// <returns>The loaded key.</returns>
233+
public static NtKey LoadKey(ObjectAttributes key_obj_attr, ObjectAttributes file_obj_attr,
234+
LoadKeyFlags flags, KeyAccessRights desired_access, NtKey trust_key, NtEvent key_event, NtToken token)
235+
{
236+
return LoadKey(key_obj_attr, file_obj_attr, flags, desired_access, trust_key, key_event, token, true).Result;
237+
}
238+
124239
/// <summary>
125240
/// Unload an existing hive.
126241
/// </summary>

NtApiDotNet/NtKeyNative.cs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public enum LoadKeyFlags
2626
Exclusive = 0x20,
2727
Unknown800 = 0x800,
2828
ReadOnly = 0x2000,
29+
DontCheckAccess = 0x8000,
2930
}
3031

3132
[Flags]
@@ -277,6 +278,20 @@ public struct KeyTrustInformation
277278
public bool TrustedKey => Flags.GetBit(0);
278279
}
279280

281+
public enum KeyLoadArgumentType : byte
282+
{
283+
TrustKeyHandle = 1,
284+
EventHandle,
285+
TokenHandle
286+
}
287+
288+
[StructLayout(LayoutKind.Sequential)]
289+
public struct KeyLoadArgument
290+
{
291+
public KeyLoadArgumentType ArgumentType;
292+
public IntPtr Argument;
293+
}
294+
280295
public static partial class NtSystemCalls
281296
{
282297
[DllImport("ntdll.dll")]
@@ -349,10 +364,18 @@ out KeyDisposition Disposition
349364
public static extern NtStatus NtLoadKeyEx([In] ObjectAttributes DestinationName, [In] ObjectAttributes FileName, LoadKeyFlags Flags,
350365
IntPtr TrustKeyHandle, IntPtr EventHandle, KeyAccessRights DesiredAccess, out SafeKernelObjectHandle KeyHandle, int Unused);
351366

352-
[DllImport("ntdll.dll", EntryPoint = "NtLoadKeyEx")]
353-
public static extern NtStatus NtLoadKeyExNoHandle([In] ObjectAttributes DestinationName, [In] ObjectAttributes FileName, LoadKeyFlags Flags,
367+
[DllImport("ntdll.dll")]
368+
public static extern NtStatus NtLoadKeyEx([In] ObjectAttributes DestinationName, [In] ObjectAttributes FileName, LoadKeyFlags Flags,
354369
IntPtr TrustKeyHandle, IntPtr EventHandle, KeyAccessRights DesiredAccess, IntPtr KeyHandle, int Unused);
355370

371+
[DllImport("ntdll.dll")]
372+
public static extern NtStatus NtLoadKey3([In] ObjectAttributes DestinationName, [In] ObjectAttributes FileName, LoadKeyFlags Flags,
373+
[In, MarshalAs(UnmanagedType.LPArray)] KeyLoadArgument[] LoadArguments, int LoadArgumentCount, KeyAccessRights DesiredAccess, out SafeKernelObjectHandle KeyHandle, int Unused);
374+
375+
[DllImport("ntdll.dll")]
376+
public static extern NtStatus NtLoadKey3([In] ObjectAttributes DestinationName, [In] ObjectAttributes FileName, LoadKeyFlags Flags,
377+
[In, MarshalAs(UnmanagedType.LPArray)] KeyLoadArgument[] LoadArguments, int LoadArgumentCount, KeyAccessRights DesiredAccess, IntPtr KeyHandle, int Unused);
378+
356379
[DllImport("ntdll.dll")]
357380
public static extern NtStatus NtUnloadKey2([In] ObjectAttributes KeyObjectAttributes, UnloadKeyFlags Flags);
358381

NtObjectManager/Cmdlets/Object/AddNtKeyHiveCmdlet.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,24 @@ public sealed class AddNtKeyHiveCmdlet : NtObjectBaseCmdletWithAccess<KeyAccessR
5656
[Parameter]
5757
public LoadKeyFlags LoadFlags { get; set; }
5858

59+
/// <summary>
60+
/// <para type="description">Specifes the token to impersonate for loading the hive.</para>
61+
/// </summary>
62+
[Parameter]
63+
public NtToken Token { get; set; }
64+
65+
/// <summary>
66+
/// <para type="description">Specifes the key that this new hive should trust.</para>
67+
/// </summary>
68+
[Parameter]
69+
public NtKey TrustKey { get; set; }
70+
71+
/// <summary>
72+
/// <para type="description">Specifes an event for the hive load.</para>
73+
/// </summary>
74+
[Parameter]
75+
public NtEvent Event { get; set; }
76+
5977
/// <summary>
6078
/// Virtual method to return the value of the Path variable.
6179
/// </summary>
@@ -102,7 +120,7 @@ protected override object CreateObject(ObjectAttributes obj_attributes)
102120
}
103121
}
104122

105-
return NtKey.LoadKey(name, obj_attributes, LoadFlags, Access);
123+
return NtKey.LoadKey(name, obj_attributes, LoadFlags, Access, TrustKey, Event, Token);
106124
}
107125
}
108126

0 commit comments

Comments
 (0)