Skip to content

Commit

Permalink
Pass through access mask to ALPC transport.
Browse files Browse the repository at this point in the history
  • Loading branch information
tyranid committed Mar 21, 2024
1 parent ed01978 commit 53b6587
Show file tree
Hide file tree
Showing 9 changed files with 80 additions and 14 deletions.
16 changes: 16 additions & 0 deletions NtApiDotNet/AlpcMessageAttributes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,22 @@ public AlpcHandleMessageAttributeEntry(NtObject obj)
{
Flags = AlpcHandleAttrFlags.SameAccess | AlpcHandleAttrFlags.SameAttributes;
Handle = obj.Handle.DangerousGetHandle().ToInt32();
}

/// <summary>
/// Constructor.
/// </summary>
/// <param name="obj">The object to construct the entry from.</param>
/// <param name="desired_access">The desired access for the attribute. If 0 then just copies the access.</param>
public AlpcHandleMessageAttributeEntry(NtObject obj, AccessMask desired_access)
{
Flags = AlpcHandleAttrFlags.SameAttributes;
DesiredAccess = desired_access;
if (DesiredAccess.IsEmpty)
{
Flags |= AlpcHandleAttrFlags.SameAccess;
}
Handle = obj.Handle.DangerousGetHandle().ToInt32();
}
}

Expand Down
10 changes: 5 additions & 5 deletions NtApiDotNet/Ndr/Marshal/NdrMarshalBuffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public class NdrMarshalBuffer
#region Private Members
private readonly MemoryStream _stm;
private readonly BinaryWriter _writer;
private readonly List<NtObject> _handles;
private readonly List<NdrSystemHandle> _handles;
private NdrDeferralStack _deferred_writes;
private int _referent;
private long? _conformance_position;
Expand Down Expand Up @@ -190,7 +190,7 @@ public NdrMarshalBuffer(NdrDataRepresentation data_representation)
{
_stm = new MemoryStream();
_writer = new BinaryWriter(_stm, Encoding.Unicode);
_handles = new List<NtObject>();
_handles = new List<NdrSystemHandle>();
_referent = 0x20000;
_deferred_writes = new NdrDeferralStack();
NdrUnmarshalBuffer.CheckDataRepresentation(data_representation);
Expand All @@ -200,11 +200,11 @@ public NdrMarshalBuffer(NdrDataRepresentation data_representation)
#endregion

#region Misc Methods
public void WriteSystemHandle<T>(T handle) where T : NtObject
public void WriteSystemHandle<T>(T handle, uint desired_access = 0) where T : NtObject
{
if (handle != null)
{
_handles.Add(handle);
_handles.Add(new NdrSystemHandle(handle, desired_access));
WriteInt32(_handles.Count);
}
else
Expand Down Expand Up @@ -1224,7 +1224,7 @@ public void WriteConformantVaryingArray<T>(T[] array, long conformance, long var

#region Public Properties

public List<NtObject> Handles => _handles;
public List<NdrSystemHandle> Handles => _handles;

public NdrDataRepresentation DataRepresentation { get; }

Expand Down
48 changes: 48 additions & 0 deletions NtApiDotNet/Ndr/Marshal/NdrSystemHandle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2019 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// NOTE: This file is a modified version of NdrParser.cs from OleViewDotNet
// https://github.com/tyranid/oleviewdotnet. It's been relicensed from GPLv3 by
// the original author James Forshaw to be used under the Apache License for this
// project.

namespace NtApiDotNet.Ndr.Marshal
{
/// <summary>
/// Structure to hold an NDR system handle.
/// </summary>
public readonly struct NdrSystemHandle
{
/// <summary>
/// The object handle.
/// </summary>
public NtObject Handle { get; }

/// <summary>
/// The desired access mask.
/// </summary>
public uint DesiredAccess { get; }

/// <summary>
/// Constructor.
/// </summary>
/// <param name="handle">The object handle.</param>
/// <param name="desired_access">The desired access mask.</param>
public NdrSystemHandle(NtObject handle, uint desired_access)
{
Handle = handle;
DesiredAccess = desired_access;
}
}
}
1 change: 1 addition & 0 deletions NtApiDotNet/NtApiDotNet.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
<Compile Include="Ndr\IdlNdrFormatterInternal.cs" />
<Compile Include="Ndr\Marshal\FLAGGED_WORD_BLOB.cs" />
<Compile Include="Ndr\Marshal\NdrUserMarshal.cs" />
<Compile Include="Ndr\Marshal\NdrSystemHandle.cs" />
<Compile Include="Ndr\NdrUtils.cs" />
<Compile Include="Net\Dns\DnsClient.cs" />
<Compile Include="Net\Dns\DnsAddressRecord.cs" />
Expand Down
2 changes: 1 addition & 1 deletion NtApiDotNet/Win32/Rpc/RpcClientBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ protected RpcClientBase(string interface_id, int major, int minor)
/// <param name="handles">List of handles marshaled into the buffer.</param>
/// <returns>Unmarshal NDR buffer for the result.</returns>
protected RpcClientResponse SendReceive(int proc_num, NdrDataRepresentation data_representation,
byte[] ndr_buffer, IReadOnlyCollection<NtObject> handles)
byte[] ndr_buffer, IReadOnlyCollection<NdrSystemHandle> handles)
{
if (!Connected)
{
Expand Down
2 changes: 1 addition & 1 deletion NtApiDotNet/Win32/Rpc/RpcClientBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ private RpcTypeDescriptor GetSystemHandleTypeDescriptor(NdrSystemHandleTypeRefer
{
return new RpcTypeDescriptor(system_handle_type.GetSystemHandleType(),
nameof(NdrUnmarshalBuffer.ReadSystemHandle), marshal_helper, nameof(NdrMarshalBuffer.WriteSystemHandle), system_handle_type, null, null,
new AdditionalArguments(true), new AdditionalArguments(true));
new AdditionalArguments(true, CodeGenUtils.GetPrimitive(system_handle_type.AccessMask)), new AdditionalArguments(true));
}

private RpcTypeDescriptor GetHandleTypeDescriptor(NdrHandleTypeReference handle_type, MarshalHelperBuilder marshal_helper)
Expand Down
2 changes: 1 addition & 1 deletion NtApiDotNet/Win32/Rpc/Transport/IRpcClientTransport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public interface IRpcClientTransport : IDisposable
/// <param name="handles">List of handles marshaled into the buffer.</param>
/// <returns>Client response from the send.</returns>
RpcClientResponse SendReceive(int proc_num, Guid objuuid, NdrDataRepresentation data_representation,
byte[] ndr_buffer, IReadOnlyCollection<NtObject> handles);
byte[] ndr_buffer, IReadOnlyCollection<NdrSystemHandle> handles);

/// <summary>
/// Add and authenticate a new security context.
Expand Down
11 changes: 6 additions & 5 deletions NtApiDotNet/Win32/Rpc/Transport/RpcAlpcClientTransport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using NtApiDotNet.Ndr.Marshal;
using System;
using System.Collections.Generic;
using System.Linq;

namespace NtApiDotNet.Win32.Rpc.Transport
{
Expand Down Expand Up @@ -153,7 +154,7 @@ private void ClearAttributes(AlpcMessage msg, AlpcReceiveMessageAttributes attri
_client.Send(AlpcMessageFlags.None, msg, attributes.ToContinuationAttributes(flags), NtWaitTimeout.Infinite);
}

private RpcClientResponse SendAndReceiveLarge(int proc_num, Guid objuuid, byte[] ndr_buffer, IReadOnlyCollection<NtObject> handles)
private RpcClientResponse SendAndReceiveLarge(int proc_num, Guid objuuid, byte[] ndr_buffer, IReadOnlyCollection<NdrSystemHandle> handles)
{
LRPC_LARGE_REQUEST_MESSAGE req_msg = new LRPC_LARGE_REQUEST_MESSAGE()
{
Expand All @@ -177,7 +178,7 @@ private RpcClientResponse SendAndReceiveLarge(int proc_num, Guid objuuid, byte[]

if (handles.Count > 0)
{
send_attr.AddHandles(handles);
send_attr.AddHandles(handles.Select(h => new AlpcHandleMessageAttributeEntry(h.Handle, h.DesiredAccess)));
}

using (var port_section = _client.CreatePortSection(AlpcCreatePortSectionFlags.Secure, ndr_buffer.Length))
Expand All @@ -199,7 +200,7 @@ private RpcClientResponse SendAndReceiveLarge(int proc_num, Guid objuuid, byte[]
}
}

private RpcClientResponse SendAndReceiveImmediate(int proc_num, Guid objuuid, byte[] ndr_buffer, IReadOnlyCollection<NtObject> handles)
private RpcClientResponse SendAndReceiveImmediate(int proc_num, Guid objuuid, byte[] ndr_buffer, IReadOnlyCollection<NdrSystemHandle> handles)
{
LRPC_IMMEDIATE_REQUEST_MESSAGE req_msg = new LRPC_IMMEDIATE_REQUEST_MESSAGE()
{
Expand All @@ -221,7 +222,7 @@ private RpcClientResponse SendAndReceiveImmediate(int proc_num, Guid objuuid, by

if (handles.Count > 0)
{
send_attr.AddHandles(handles);
send_attr.AddHandles(handles.Select(h => new AlpcHandleMessageAttributeEntry(h.Handle, h.DesiredAccess)));
}

using (AlpcReceiveMessageAttributes recv_attr = new AlpcReceiveMessageAttributes())
Expand Down Expand Up @@ -329,7 +330,7 @@ public void Bind(Guid interface_id, Version interface_version, Guid transfer_syn
/// <param name="handles">List of handles marshaled into the buffer.</param>
/// <returns>Client response from the send.</returns>
public RpcClientResponse SendReceive(int proc_num, Guid objuuid, NdrDataRepresentation data_representation,
byte[] ndr_buffer, IReadOnlyCollection<NtObject> handles)
byte[] ndr_buffer, IReadOnlyCollection<NdrSystemHandle> handles)
{
if (ndr_buffer.Length > 0xF00)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,7 @@ public RpcTransportSecurityContext AddSecurityContext(RpcTransportSecurity trans
/// <param name="handles">List of handles marshaled into the buffer.</param>
/// <returns>Client response from the send.</returns>
public RpcClientResponse SendReceive(int proc_num, Guid objuuid, NdrDataRepresentation data_representation,
byte[] ndr_buffer, IReadOnlyCollection<NtObject> handles)
byte[] ndr_buffer, IReadOnlyCollection<NdrSystemHandle> handles)
{
NdrUnmarshalBuffer.CheckDataRepresentation(data_representation);
return new RpcClientResponse(SendReceiveRequestPDU(proc_num, objuuid,
Expand Down

0 comments on commit 53b6587

Please sign in to comment.