mirror of
https://github.com/gmh5225/awesome-game-security
synced 2026-06-21 13:56:22 +00:00
archive: add 5 repo prompt(s) [skip ci]
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,912 @@
|
||||
Project Path: arc_btbd_wpp_bsfm1me0
|
||||
|
||||
Source Tree:
|
||||
|
||||
```txt
|
||||
arc_btbd_wpp_bsfm1me0
|
||||
├── README.md
|
||||
└── wpp
|
||||
├── disk.c
|
||||
├── disk.h
|
||||
├── main.c
|
||||
├── mount.c
|
||||
├── mount.h
|
||||
├── stdafx.h
|
||||
├── util.c
|
||||
├── util.h
|
||||
├── wpp.c
|
||||
├── wpp.h
|
||||
├── wpp.inf
|
||||
├── wpp.vcxproj
|
||||
└── wpp.vcxproj.filters
|
||||
|
||||
```
|
||||
|
||||
`README.md`:
|
||||
|
||||
```md
|
||||
# WPP
|
||||
|
||||
A proof-of-concept for intercepting drivers' DeviceControl via WPP.
|
||||
|
||||
## Explanation
|
||||
|
||||
Windows drivers like `disk.sys` and `mountmgr.sys` support WPP tracing for debugging purposes within their `DeviceControl` (and other functions). Since the drivers' pointer to the global WPP control and pointer to the WPP trace function both reside in `.data` sections, its WPP can be easily hijacked.
|
||||
|
||||
After changing the WPP trace function and enabling the driver's WPP via changing the flags, we must determine if our trace function was actually called by `DeviceControl` via a return address check.
|
||||
|
||||
Finally, we want to intercept the `DeviceControl` by grabbing the pointer to the IRP. This can either be done by walking the stack backwards or using a register that still has the IRP pointer. In this PoC, a stack walk is used for `disk.sys` and a register is used for `mountmgr.sys`.
|
||||
|
||||
Obviously, this method only works on drivers that actually have WPP tracing inside their `DeviceControl`.
|
||||
|
||||
## Note
|
||||
|
||||
This PoC was only tested on Windows 10 1507, 1803, 1809, and 1903.
|
||||
```
|
||||
|
||||
`wpp/disk.c`:
|
||||
|
||||
```c
|
||||
#include "stdafx.h"
|
||||
|
||||
static CHAR *SERIAL = "123456789";
|
||||
|
||||
NTSTATUS StorageQueryIoc(PDEVICE_OBJECT device, PIRP irp, PVOID context) {
|
||||
if (context) {
|
||||
IOC_REQUEST request = *(PIOC_REQUEST)context;
|
||||
ExFreePool(context);
|
||||
|
||||
if (request.BufferLength >= sizeof(STORAGE_DEVICE_DESCRIPTOR)) {
|
||||
PSTORAGE_DEVICE_DESCRIPTOR desc = (PSTORAGE_DEVICE_DESCRIPTOR)request.Buffer;
|
||||
ULONG offset = desc->SerialNumberOffset;
|
||||
if (offset && offset < request.BufferLength) {
|
||||
strcpy((PCHAR)desc + offset, SERIAL);
|
||||
}
|
||||
}
|
||||
|
||||
if (request.OldRoutine && irp->StackCount > 1) {
|
||||
return request.OldRoutine(device, irp, request.OldContext);
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS AtaPassIoc(PDEVICE_OBJECT device, PIRP irp, PVOID context) {
|
||||
if (context) {
|
||||
IOC_REQUEST request = *(PIOC_REQUEST)context;
|
||||
ExFreePool(context);
|
||||
|
||||
if (request.BufferLength >= sizeof(ATA_PASS_THROUGH_EX) + sizeof(PIDENTIFY_DEVICE_DATA)) {
|
||||
PATA_PASS_THROUGH_EX pte = (PATA_PASS_THROUGH_EX)request.Buffer;
|
||||
ULONG offset = (ULONG)pte->DataBufferOffset;
|
||||
if (offset && offset < request.BufferLength) {
|
||||
PCHAR serial = (PCHAR)((PIDENTIFY_DEVICE_DATA)((PBYTE)request.Buffer + offset))->SerialNumber;
|
||||
SwapEndianess(serial, SERIAL);
|
||||
}
|
||||
}
|
||||
|
||||
if (request.OldRoutine && irp->StackCount > 1) {
|
||||
return request.OldRoutine(device, irp, request.OldContext);
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS SmartDataIoc(PDEVICE_OBJECT device, PIRP irp, PVOID context) {
|
||||
if (context) {
|
||||
IOC_REQUEST request = *(PIOC_REQUEST)context;
|
||||
ExFreePool(context);
|
||||
|
||||
if (request.BufferLength >= sizeof(SENDCMDOUTPARAMS)) {
|
||||
PCHAR serial = ((PIDSECTOR)((PSENDCMDOUTPARAMS)request.Buffer)->bBuffer)->sSerialNumber;
|
||||
SwapEndianess(serial, SERIAL);
|
||||
}
|
||||
|
||||
if (request.OldRoutine && irp->StackCount > 1) {
|
||||
return request.OldRoutine(device, irp, request.OldContext);
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID DiskFilter(PCONTEXT context, PVOID returnAddress, PVOID *frame, PVOID *base) {
|
||||
UNREFERENCED_PARAMETER(context);
|
||||
|
||||
for (; *frame != returnAddress; ++frame) {
|
||||
if (frame >= base) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
PIRP irp = *(frame + 6);
|
||||
if (!irp) {
|
||||
return;
|
||||
}
|
||||
|
||||
PIO_STACK_LOCATION ioc = IoGetCurrentIrpStackLocation(irp);
|
||||
switch (ioc->Parameters.DeviceIoControl.IoControlCode) {
|
||||
case IOCTL_STORAGE_QUERY_PROPERTY:
|
||||
if (((PSTORAGE_PROPERTY_QUERY)irp->AssociatedIrp.SystemBuffer)->PropertyId == StorageDeviceProperty) {
|
||||
ChangeIoc(ioc, irp, StorageQueryIoc);
|
||||
}
|
||||
break;
|
||||
case IOCTL_ATA_PASS_THROUGH:
|
||||
ChangeIoc(ioc, irp, AtaPassIoc);
|
||||
break;
|
||||
case SMART_RCV_DRIVE_DATA:
|
||||
ChangeIoc(ioc, irp, SmartDataIoc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS SetDiskWpp() {
|
||||
UNICODE_STRING diskStr = RTL_CONSTANT_STRING(L"\\Driver\\Disk");
|
||||
PDRIVER_OBJECT diskObject = 0;
|
||||
|
||||
NTSTATUS status = ObReferenceObjectByName(&diskStr, OBJ_CASE_INSENSITIVE, 0, 0, *IoDriverObjectType, KernelMode, 0, &diskObject);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
printf("! failed to get %wZ driver object: %x !\n", &diskStr, status);
|
||||
return status;
|
||||
}
|
||||
|
||||
PVOID wppGlobal = FindPatternImage(diskObject->DriverStart, "\x48\x89\x3D", "xxx");
|
||||
if (!wppGlobal) {
|
||||
printf("! failed to find %wZ WppGlobal !\n", &diskStr);
|
||||
|
||||
ObDereferenceObject(diskObject);
|
||||
return STATUS_FAILED_DRIVER_ENTRY;
|
||||
}
|
||||
|
||||
PVOID wppTraceMessage = FindPatternImage(diskObject->DriverStart, "\x48\x8B\x05\x00\x00\x00\x00\x48\x83", "xxx????xx");
|
||||
if (!wppTraceMessage) {
|
||||
printf("! failed to find %wZ WppTraceMessage !\n", &diskStr);
|
||||
|
||||
ObDereferenceObject(diskObject);
|
||||
return STATUS_FAILED_DRIVER_ENTRY;
|
||||
}
|
||||
|
||||
PVOID returnAddress = FindPatternImage(diskObject->DriverStart, "\x90\xE9\x00\x00\x00\x00\x48\x8D\x54", "xx????xxx");
|
||||
if (!returnAddress) {
|
||||
printf("! failed to find %wZ return address !\n", &diskStr);
|
||||
|
||||
ObDereferenceObject(diskObject);
|
||||
return STATUS_FAILED_DRIVER_ENTRY;
|
||||
}
|
||||
|
||||
WppSet(returnAddress, DiskFilter, RELATIVE_ADDR(wppGlobal, 7), RELATIVE_ADDR(wppTraceMessage, 7));
|
||||
|
||||
printf("success for %wZ\n", &diskStr);
|
||||
ObDereferenceObject(diskObject);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
```
|
||||
|
||||
`wpp/disk.h`:
|
||||
|
||||
```h
|
||||
#pragma once
|
||||
|
||||
NTSTATUS SetDiskWpp();
|
||||
```
|
||||
|
||||
`wpp/main.c`:
|
||||
|
||||
```c
|
||||
#include "stdafx.h"
|
||||
|
||||
VOID DriverUnload(PDRIVER_OBJECT driver) {
|
||||
UNREFERENCED_PARAMETER(driver);
|
||||
|
||||
WppUndo();
|
||||
}
|
||||
|
||||
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING registryPath) {
|
||||
UNREFERENCED_PARAMETER(registryPath);
|
||||
|
||||
driver->DriverUnload = DriverUnload;
|
||||
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
if (!NT_SUCCESS(status = SetDiskWpp())) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(status = SetMountWpp())) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
```
|
||||
|
||||
`wpp/mount.c`:
|
||||
|
||||
```c
|
||||
#include "stdafx.h"
|
||||
|
||||
NTSTATUS MountPointsIoc(PDEVICE_OBJECT device, PIRP irp, PVOID context) {
|
||||
if (context) {
|
||||
IOC_REQUEST request = *(PIOC_REQUEST)context;
|
||||
ExFreePool(context);
|
||||
|
||||
if (request.BufferLength >= sizeof(MOUNTMGR_MOUNT_POINTS)) {
|
||||
PMOUNTMGR_MOUNT_POINTS points = (PMOUNTMGR_MOUNT_POINTS)request.Buffer;
|
||||
for (DWORD i = 0; i < points->NumberOfMountPoints; ++i) {
|
||||
PMOUNTMGR_MOUNT_POINT point = &points->MountPoints[i];
|
||||
if (point->UniqueIdOffset) {
|
||||
point->UniqueIdLength = 0;
|
||||
}
|
||||
|
||||
if (point->SymbolicLinkNameOffset) {
|
||||
point->SymbolicLinkNameLength = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (request.OldRoutine && irp->StackCount > 1) {
|
||||
return request.OldRoutine(device, irp, request.OldContext);
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS MountUniqueIoc(PDEVICE_OBJECT device, PIRP irp, PVOID context) {
|
||||
if (context) {
|
||||
IOC_REQUEST request = *(PIOC_REQUEST)context;
|
||||
ExFreePool(context);
|
||||
|
||||
if (request.BufferLength >= sizeof(MOUNTDEV_UNIQUE_ID)) {
|
||||
((PMOUNTDEV_UNIQUE_ID)request.Buffer)->UniqueIdLength = 0;
|
||||
}
|
||||
|
||||
if (request.OldRoutine && irp->StackCount > 1) {
|
||||
return request.OldRoutine(device, irp, request.OldContext);
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID MountFilter(PCONTEXT context, PVOID returnAddress, PVOID *frame, PVOID *base) {
|
||||
UNREFERENCED_PARAMETER(returnAddress);
|
||||
UNREFERENCED_PARAMETER(frame);
|
||||
UNREFERENCED_PARAMETER(base);
|
||||
|
||||
PIRP irp = (PIRP)context->Rdi;
|
||||
if (!irp) {
|
||||
return;
|
||||
}
|
||||
|
||||
PIO_STACK_LOCATION ioc = IoGetCurrentIrpStackLocation(irp);
|
||||
switch (ioc->Parameters.DeviceIoControl.IoControlCode) {
|
||||
case IOCTL_MOUNTMGR_QUERY_POINTS:
|
||||
ChangeIoc(ioc, irp, MountPointsIoc);
|
||||
break;
|
||||
case IOCTL_MOUNTDEV_QUERY_UNIQUE_ID:
|
||||
ChangeIoc(ioc, irp, MountUniqueIoc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS SetMountWpp() {
|
||||
UNICODE_STRING mountStr = RTL_CONSTANT_STRING(L"\\Driver\\mountmgr");
|
||||
PDRIVER_OBJECT mountObject = 0;
|
||||
|
||||
NTSTATUS status = ObReferenceObjectByName(&mountStr, OBJ_CASE_INSENSITIVE, 0, 0, *IoDriverObjectType, KernelMode, 0, &mountObject);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
printf("! failed to get %wZ driver object: %x !\n", &mountStr, status);
|
||||
return status;
|
||||
}
|
||||
|
||||
PVOID wppGlobal = FindPatternImage(mountObject->DriverStart, "\x48\x89\x3D", "xxx");
|
||||
if (!wppGlobal) {
|
||||
printf("! failed to find %wZ WppGlobal !\n", &mountStr);
|
||||
|
||||
ObDereferenceObject(mountObject);
|
||||
return STATUS_FAILED_DRIVER_ENTRY;
|
||||
}
|
||||
|
||||
PVOID wppTraceMessage = FindPatternImage(mountObject->DriverStart, "\x48\x8B\x05\x00\x00\x00\x00\x4C\x8D\x05", "xxx????xxx");
|
||||
if (!wppTraceMessage) {
|
||||
printf("! failed to find %wZ WppTraceMessage !\n", &mountStr);
|
||||
|
||||
ObDereferenceObject(mountObject);
|
||||
return STATUS_FAILED_DRIVER_ENTRY;
|
||||
}
|
||||
|
||||
PVOID returnAddress = FindPatternImage(mountObject->DriverStart, "\x45\x8B\xCE\xE8\x00\x00\x00\x00\x90\xE9", "xxxx????xx");
|
||||
if (!returnAddress) {
|
||||
printf("! failed to find %wZ return address !\n", &mountStr);
|
||||
|
||||
ObDereferenceObject(mountObject);
|
||||
return STATUS_FAILED_DRIVER_ENTRY;
|
||||
}
|
||||
|
||||
WppSet((PBYTE)returnAddress + 8, MountFilter, RELATIVE_ADDR(wppGlobal, 7), RELATIVE_ADDR(wppTraceMessage, 7));
|
||||
|
||||
printf("success for %wZ\n", &mountStr);
|
||||
ObDereferenceObject(mountObject);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
```
|
||||
|
||||
`wpp/mount.h`:
|
||||
|
||||
```h
|
||||
#pragma once
|
||||
|
||||
NTSTATUS SetMountWpp();
|
||||
```
|
||||
|
||||
`wpp/stdafx.h`:
|
||||
|
||||
```h
|
||||
#pragma once
|
||||
|
||||
#define printf(fmt, ...) DbgPrint("[dbg] "fmt, ##__VA_ARGS__)
|
||||
|
||||
#include <intrin.h>
|
||||
#include <fltKernel.h>
|
||||
#include <ntddk.h>
|
||||
#include <windef.h>
|
||||
#include <ntimage.h>
|
||||
#include <ntdddisk.h>
|
||||
#include <ntddscsi.h>
|
||||
#include <ata.h>
|
||||
#include <mountmgr.h>
|
||||
#include <mountdev.h>
|
||||
|
||||
extern POBJECT_TYPE *IoDriverObjectType;
|
||||
|
||||
NTKERNELAPI PVOID PsGetCurrentThreadStackBase();
|
||||
NTKERNELAPI NTSTATUS ObReferenceObjectByName(PUNICODE_STRING ObjectName, ULONG Attributes, PACCESS_STATE PassedAccessState, ACCESS_MASK DesiredAccess, POBJECT_TYPE ObjectType, KPROCESSOR_MODE AccessMode, PVOID ParseContext, PVOID *Object);
|
||||
|
||||
typedef struct _IDSECTOR {
|
||||
USHORT wGenConfig;
|
||||
USHORT wNumCyls;
|
||||
USHORT wReserved;
|
||||
USHORT wNumHeads;
|
||||
USHORT wBytesPerTrack;
|
||||
USHORT wBytesPerSector;
|
||||
USHORT wSectorsPerTrack;
|
||||
USHORT wVendorUnique[3];
|
||||
CHAR sSerialNumber[20];
|
||||
USHORT wBufferType;
|
||||
USHORT wBufferSize;
|
||||
USHORT wECCSize;
|
||||
CHAR sFirmwareRev[8];
|
||||
CHAR sModelNumber[40];
|
||||
USHORT wMoreVendorUnique;
|
||||
USHORT wDoubleWordIO;
|
||||
USHORT wCapabilities;
|
||||
USHORT wReserved1;
|
||||
USHORT wPIOTiming;
|
||||
USHORT wDMATiming;
|
||||
USHORT wBS;
|
||||
USHORT wNumCurrentCyls;
|
||||
USHORT wNumCurrentHeads;
|
||||
USHORT wNumCurrentSectorsPerTrack;
|
||||
ULONG ulCurrentSectorCapacity;
|
||||
USHORT wMultSectorStuff;
|
||||
ULONG ulTotalAddressableSectors;
|
||||
USHORT wSingleWordDMA;
|
||||
USHORT wMultiWordDMA;
|
||||
BYTE bReserved[128];
|
||||
} IDSECTOR, *PIDSECTOR;
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#include "wpp.h"
|
||||
#include "disk.h"
|
||||
#include "mount.h"
|
||||
```
|
||||
|
||||
`wpp/util.c`:
|
||||
|
||||
```c
|
||||
#include "stdafx.h"
|
||||
|
||||
VOID SwapEndianess(PCHAR dest, PCHAR src) {
|
||||
for (size_t i = 0, l = strlen(src); i < l; i += 2) {
|
||||
dest[i] = src[i + 1];
|
||||
dest[i + 1] = src[i];
|
||||
}
|
||||
}
|
||||
|
||||
VOID ChangeIoc(PIO_STACK_LOCATION ioc, PIRP irp, PIO_COMPLETION_ROUTINE routine) {
|
||||
PIOC_REQUEST request = (PIOC_REQUEST)ExAllocatePool(NonPagedPool, sizeof(IOC_REQUEST));
|
||||
if (!request) {
|
||||
printf("! failed to allocate IOC_REQUEST !\n");
|
||||
return;
|
||||
}
|
||||
|
||||
request->Buffer = irp->AssociatedIrp.SystemBuffer;
|
||||
request->BufferLength = ioc->Parameters.DeviceIoControl.OutputBufferLength;
|
||||
request->OldContext = ioc->Context;
|
||||
request->OldRoutine = ioc->CompletionRoutine;
|
||||
|
||||
ioc->Control = SL_INVOKE_ON_SUCCESS;
|
||||
ioc->Context = request;
|
||||
ioc->CompletionRoutine = routine;
|
||||
}
|
||||
|
||||
BOOL CheckMask(PCHAR base, PCHAR pattern, PCHAR mask) {
|
||||
for (; *mask; ++base, ++pattern, ++mask) {
|
||||
if (*mask == 'x' && *base != *pattern) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PVOID FindPattern(PCHAR base, DWORD length, PCHAR pattern, PCHAR mask) {
|
||||
length -= (DWORD)strlen(mask);
|
||||
for (DWORD i = 0; i <= length; ++i) {
|
||||
PVOID addr = &base[i];
|
||||
if (CheckMask(addr, pattern, mask)) {
|
||||
return addr;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PVOID FindPatternImage(PCHAR base, PCHAR pattern, PCHAR mask) {
|
||||
PVOID match = 0;
|
||||
|
||||
PIMAGE_NT_HEADERS headers = (PIMAGE_NT_HEADERS)(base + ((PIMAGE_DOS_HEADER)base)->e_lfanew);
|
||||
PIMAGE_SECTION_HEADER sections = IMAGE_FIRST_SECTION(headers);
|
||||
for (DWORD i = 0; i < headers->FileHeader.NumberOfSections; ++i) {
|
||||
PIMAGE_SECTION_HEADER section = §ions[i];
|
||||
if (*(PINT)section->Name == 'EGAP' || memcmp(section->Name, ".text", 5) == 0) {
|
||||
match = FindPattern(base + section->VirtualAddress, section->Misc.VirtualSize, pattern, mask);
|
||||
if (match) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
```
|
||||
|
||||
`wpp/util.h`:
|
||||
|
||||
```h
|
||||
#pragma once
|
||||
|
||||
#define LENGTH(a) (sizeof(a) / sizeof(a[0]))
|
||||
#define RELATIVE_ADDR(addr, size) ((PVOID)((PBYTE)addr + *(PINT)((PBYTE)addr + (size - (INT)sizeof(INT))) + size))
|
||||
|
||||
typedef struct _IOC_REQUEST {
|
||||
PVOID Buffer;
|
||||
ULONG BufferLength;
|
||||
PVOID OldContext;
|
||||
PIO_COMPLETION_ROUTINE OldRoutine;
|
||||
} IOC_REQUEST, *PIOC_REQUEST;
|
||||
|
||||
VOID SwapEndianess(PCHAR dest, PCHAR src);
|
||||
VOID ChangeIoc(PIO_STACK_LOCATION ioc, PIRP irp, PIO_COMPLETION_ROUTINE routine);
|
||||
PVOID FindPattern(PCHAR base, DWORD length, PCHAR pattern, PCHAR mask);
|
||||
PVOID FindPatternImage(PCHAR base, PCHAR pattern, PCHAR mask);
|
||||
```
|
||||
|
||||
`wpp/wpp.c`:
|
||||
|
||||
```c
|
||||
#include "stdafx.h"
|
||||
|
||||
DEVICE_OBJECT fakeWppGlobal = {
|
||||
.Timer = (PIO_TIMER)WPP_FLAG_ALL,
|
||||
};
|
||||
|
||||
struct {
|
||||
WPP Buffer[0x100];
|
||||
ULONG Length;
|
||||
} wpps = { 0 };
|
||||
|
||||
VOID WppSet(PVOID returnAddress, WPP_FILTER filter, PDEVICE_OBJECT *wppGlobal, PVOID *wppTraceMessage) {
|
||||
PWPP wpp = &wpps.Buffer[wpps.Length++];
|
||||
|
||||
wpp->ReturnAddress = returnAddress;
|
||||
wpp->Filter = filter;
|
||||
|
||||
wpp->WppGlobal = wppGlobal;
|
||||
wpp->WppTraceMessage = wppTraceMessage;
|
||||
|
||||
wpp->WppGlobalOriginal = InterlockedExchangePointer(wppGlobal, &fakeWppGlobal);
|
||||
wpp->WppTraceMessageOriginal = InterlockedExchangePointer(wppTraceMessage, (PVOID)WppTraceMessage);
|
||||
}
|
||||
|
||||
VOID WppUndo() {
|
||||
for (ULONG i = 0; i < wpps.Length; ++i) {
|
||||
PWPP wpp = &wpps.Buffer[i];
|
||||
|
||||
InterlockedExchangePointer(wpp->WppGlobal, wpp->WppGlobalOriginal);
|
||||
InterlockedExchangePointer(wpp->WppTraceMessage, wpp->WppTraceMessageOriginal);
|
||||
}
|
||||
}
|
||||
|
||||
ULONG WppTraceMessage(VOID *loggerHandle, ULONG messageFlags, LPCGUID messageGuid, USHORT messageNumber, ...) {
|
||||
UNREFERENCED_PARAMETER(loggerHandle);
|
||||
UNREFERENCED_PARAMETER(messageFlags);
|
||||
UNREFERENCED_PARAMETER(messageGuid);
|
||||
UNREFERENCED_PARAMETER(messageNumber);
|
||||
|
||||
CONTEXT context;
|
||||
RtlCaptureContext(&context);
|
||||
|
||||
PVOID returnAddress = 0;
|
||||
if (!RtlCaptureStackBackTrace(2, 1, &returnAddress, 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (ULONG i = 0; i < wpps.Length; ++i) {
|
||||
PWPP wpp = &wpps.Buffer[i];
|
||||
if (wpp->ReturnAddress == returnAddress) {
|
||||
wpp->Filter(&context, returnAddress, (PVOID *)_AddressOfReturnAddress(), ((PVOID *)PsGetCurrentThreadStackBase()) - 1);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
`wpp/wpp.h`:
|
||||
|
||||
```h
|
||||
#pragma once
|
||||
|
||||
#define WPP_FLAG_ALL (0xFFFFFFFFFFFFFFFF)
|
||||
|
||||
typedef VOID(*WPP_FILTER)(PCONTEXT, PVOID, PVOID, PVOID);
|
||||
|
||||
typedef struct _WPP {
|
||||
PVOID ReturnAddress;
|
||||
WPP_FILTER Filter;
|
||||
|
||||
PDEVICE_OBJECT *WppGlobal;
|
||||
PDEVICE_OBJECT WppGlobalOriginal;
|
||||
|
||||
PVOID *WppTraceMessage;
|
||||
PVOID WppTraceMessageOriginal;
|
||||
} WPP, *PWPP;
|
||||
|
||||
VOID WppSet(PVOID returnAddress, WPP_FILTER filter, PDEVICE_OBJECT *wppGlobal, PVOID *wppTraceMessage);
|
||||
VOID WppUndo();
|
||||
ULONG WppTraceMessage(VOID *LoggerHandle, ULONG MessageFlags, LPCGUID MessageGuid, USHORT MessageNumber, ...);
|
||||
```
|
||||
|
||||
`wpp/wpp.inf`:
|
||||
|
||||
```inf
|
||||
;
|
||||
; wpp.inf
|
||||
;
|
||||
|
||||
[Version]
|
||||
Signature="$WINDOWS NT$"
|
||||
Class=Sample ; TODO: edit Class
|
||||
ClassGuid={78A1C341-4539-11d3-B88D-00C04FAD5171} ; TODO: edit ClassGuid
|
||||
Provider=%ManufacturerName%
|
||||
CatalogFile=wpp.cat
|
||||
DriverVer= ; TODO: set DriverVer in stampinf property pages
|
||||
|
||||
[DestinationDirs]
|
||||
DefaultDestDir = 12
|
||||
wpp_Device_CoInstaller_CopyFiles = 11
|
||||
|
||||
; ================= Class section =====================
|
||||
|
||||
[ClassInstall32]
|
||||
Addreg=SampleClassReg
|
||||
|
||||
[SampleClassReg]
|
||||
HKR,,,0,%ClassName%
|
||||
HKR,,Icon,,-5
|
||||
|
||||
[SourceDisksNames]
|
||||
1 = %DiskName%,,,""
|
||||
|
||||
[SourceDisksFiles]
|
||||
wpp.sys = 1,,
|
||||
WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames
|
||||
|
||||
;*****************************************
|
||||
; Install Section
|
||||
;*****************************************
|
||||
|
||||
[Manufacturer]
|
||||
%ManufacturerName%=Standard,NT$ARCH$
|
||||
|
||||
[Standard.NT$ARCH$]
|
||||
%wpp.DeviceDesc%=wpp_Device, Root\wpp ; TODO: edit hw-id
|
||||
|
||||
[wpp_Device.NT]
|
||||
CopyFiles=Drivers_Dir
|
||||
|
||||
[Drivers_Dir]
|
||||
wpp.sys
|
||||
|
||||
;-------------- Service installation
|
||||
[wpp_Device.NT.Services]
|
||||
AddService = wpp,%SPSVCINST_ASSOCSERVICE%, wpp_Service_Inst
|
||||
|
||||
; -------------- wpp driver install sections
|
||||
[wpp_Service_Inst]
|
||||
DisplayName = %wpp.SVCDESC%
|
||||
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
|
||||
StartType = 3 ; SERVICE_DEMAND_START
|
||||
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
|
||||
ServiceBinary = %12%\wpp.sys
|
||||
|
||||
;
|
||||
;--- wpp_Device Coinstaller installation ------
|
||||
;
|
||||
|
||||
[wpp_Device.NT.CoInstallers]
|
||||
AddReg=wpp_Device_CoInstaller_AddReg
|
||||
CopyFiles=wpp_Device_CoInstaller_CopyFiles
|
||||
|
||||
[wpp_Device_CoInstaller_AddReg]
|
||||
HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller"
|
||||
|
||||
[wpp_Device_CoInstaller_CopyFiles]
|
||||
WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll
|
||||
|
||||
[wpp_Device.NT.Wdf]
|
||||
KmdfService = wpp, wpp_wdfsect
|
||||
[wpp_wdfsect]
|
||||
KmdfLibraryVersion = $KMDFVERSION$
|
||||
|
||||
[Strings]
|
||||
SPSVCINST_ASSOCSERVICE= 0x00000002
|
||||
ManufacturerName="<Your manufacturer name>" ;TODO: Replace with your manufacturer name
|
||||
ClassName="Samples" ; TODO: edit ClassName
|
||||
DiskName = "wpp Installation Disk"
|
||||
wpp.DeviceDesc = "wpp Device"
|
||||
wpp.SVCDESC = "wpp Service"
|
||||
|
||||
```
|
||||
|
||||
`wpp/wpp.vcxproj`:
|
||||
|
||||
```vcxproj
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|ARM">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|ARM64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{D1B4239E-E6CF-49D0-AB30-E5F7CEA1E6BE}</ProjectGuid>
|
||||
<TemplateGuid>{1bc93793-694f-48fe-9372-81e2b05556fd}</TemplateGuid>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
|
||||
<RootNamespace>wpp</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>Driver</ConfigurationType>
|
||||
<DriverType>KMDF</DriverType>
|
||||
<DriverTargetPlatform>Universal</DriverTargetPlatform>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>Driver</ConfigurationType>
|
||||
<DriverType>KMDF</DriverType>
|
||||
<DriverTargetPlatform>Universal</DriverTargetPlatform>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>Driver</ConfigurationType>
|
||||
<DriverType>KMDF</DriverType>
|
||||
<DriverTargetPlatform>Universal</DriverTargetPlatform>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>Driver</ConfigurationType>
|
||||
<DriverType>KMDF</DriverType>
|
||||
<DriverTargetPlatform>Universal</DriverTargetPlatform>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>Driver</ConfigurationType>
|
||||
<DriverType>KMDF</DriverType>
|
||||
<DriverTargetPlatform>Universal</DriverTargetPlatform>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>Driver</ConfigurationType>
|
||||
<DriverType>KMDF</DriverType>
|
||||
<DriverTargetPlatform>Universal</DriverTargetPlatform>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>Driver</ConfigurationType>
|
||||
<DriverType>KMDF</DriverType>
|
||||
<DriverTargetPlatform>Universal</DriverTargetPlatform>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>Driver</ConfigurationType>
|
||||
<DriverType>KMDF</DriverType>
|
||||
<DriverTargetPlatform>Universal</DriverTargetPlatform>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Inf Include="wpp.inf" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<FilesToPackage Include="$(TargetPath)" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="disk.c" />
|
||||
<ClCompile Include="main.c" />
|
||||
<ClCompile Include="mount.c" />
|
||||
<ClCompile Include="util.c" />
|
||||
<ClCompile Include="wpp.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="disk.h" />
|
||||
<ClInclude Include="mount.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="util.h" />
|
||||
<ClInclude Include="wpp.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
```
|
||||
|
||||
`wpp/wpp.vcxproj.filters`:
|
||||
|
||||
```filters
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Driver Files">
|
||||
<UniqueIdentifier>{8E41214B-6785-4CFE-B992-037D68949A14}</UniqueIdentifier>
|
||||
<Extensions>inf;inv;inx;mof;mc;</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Inf Include="wpp.inf">
|
||||
<Filter>Driver Files</Filter>
|
||||
</Inf>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="util.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="wpp.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="disk.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mount.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="util.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="wpp.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="disk.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="mount.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
```
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user