Skip to content

Instantly share code, notes, and snippets.

@tayler-king
Created November 23, 2018 18:02
Show Gist options
  • Save tayler-king/3d6ca9cc94c541bfe5671bdfea168c18 to your computer and use it in GitHub Desktop.
Save tayler-king/3d6ca9cc94c541bfe5671bdfea168c18 to your computer and use it in GitHub Desktop.
#include <ntdef.h>
#include <ntifs.h>
#include "Types.h"
PLOAD_IMAGE_NOTIFY_ROUTINE NotifyImageLoadCallback(PUNICODE_STRING FullImageName, HANDLE ProcessID, PIMAGE_INFO w_ImageInfo)
{
if (wcsstr(FullImageName->Buffer, L"\\Win64\\TslGame.exe"))
{
DbgPrintEx(0, 0, "\n[PUBG]: Hooked to %ls \n", FullImageName->Buffer);
DbgPrintEx(0, 0, "\n[PUBG]: Hooked Process: %d \n", ProcessID);
PUID = ProcessID;
PUBase = GetSectionBaseAddress(ProcessID);
}
}
NTKERNELAPI PVOID PsGetProcessSectionBaseAddress(__in PEPROCESS Process);
// routine to ignore the PE header and get the actual game base address
DWORD64 GetSectionBaseAddress(HANDLE w_pid)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PEPROCESS targetProcess;
PVOID value = 0;
ntStatus = PsLookupProcessByProcessId((HANDLE)w_pid, &targetProcess);
if (ntStatus != STATUS_SUCCESS || !targetProcess)
return 0;
__try
{
KeAttachProcess((PKPROCESS)targetProcess);
value = PsGetProcessSectionBaseAddress(targetProcess);
KeDetachProcess();
}
__except (GetExceptionCode())
{
return 0;
}
return (DWORD64)value;
}
VOID Unload(PDRIVER_OBJECT DriverObject) {
PsRemoveLoadImageNotifyRoutine((PLOAD_IMAGE_NOTIFY_ROUTINE)NotifyImageLoadCallback);
UNICODE_STRING usDosDeviceName;
RtlInitUnicodeString(&usDosDeviceName, L"\\DosDevices\\PUBGMap");
IoDeleteSymbolicLink(&usDosDeviceName);
IoDeleteDevice(DriverObject->DeviceObject);
}
NTSTATUS NTAPI MmCopyVirtualMemory (
PEPROCESS SourceProcess,
PVOID SourceAddress,
PEPROCESS TargetProcess,
PVOID TargetAddress,
SIZE_T BufferSize,
KPROCESSOR_MODE PreviousMode,
PSIZE_T ReturnSize
);
NTSTATUS ReadMemOutputClient(pReadStruct w_poReadStruct) {
PEPROCESS hClient, hGame;
if (PUBase == 0 && w_poReadStruct->ProtocolMsg != PROTO_GET_BASEADDR)
return STATUS_UNSUCCESSFUL;
PsLookupProcessByProcessId(PUID, &hGame);
PsLookupProcessByProcessId((HANDLE)w_poReadStruct->UserPID, &hClient);
if (w_poReadStruct->ProtocolMsg == PROTO_GET_BASEADDR) {
SIZE_T Result;
if (NT_SUCCESS(MmCopyVirtualMemory(hGame, &PUBase, hClient, w_poReadStruct->UserBufferAdress, w_poReadStruct->ReadSize, KernelMode, &Result)))
return STATUS_SUCCESS;
else {
DbgPrint("\n[PUBG]: Failed to read base address\n");
return STATUS_ACCESS_DENIED;
}
}
if (w_poReadStruct->ProtocolMsg == PROTO_NORMAL_READ) {
SIZE_T Result;
if (NT_SUCCESS(MmCopyVirtualMemory(hGame, w_poReadStruct->GameAddressOffset, hClient, w_poReadStruct->UserBufferAdress, w_poReadStruct->ReadSize, KernelMode, &Result)))
return STATUS_SUCCESS;
else {
DbgPrint("\n[PUBG]: Failed to read memory\n");
DbgPrintEx(0, 0, "\n[PUBG]: GameAddressOffset %I64lx\n", w_poReadStruct->GameAddressOffset);
DbgPrintEx(0, 0, "\n[PUBG]: ReadSize %I64ld\n", w_poReadStruct->ReadSize);
return STATUS_ACCESS_DENIED;
}
}
return STATUS_SUCCESS;
}
// basic IOCTL communication routine
NTSTATUS WriteBufferedIO(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
NTSTATUS NtStatus = STATUS_SUCCESS;
PIO_STACK_LOCATION pIoStackIrp = NULL;
pReadStruct readStruct;
pIoStackIrp = IoGetCurrentIrpStackLocation(Irp);
if (pIoStackIrp)
{
// Read the struct from the IRP and store inside readStruct
readStruct = (pReadStruct)Irp->AssociatedIrp.SystemBuffer;
if (readStruct)
{
// do the magic the client (um app) wants to
if (readStruct->ReadSize)
{
ReadMemOutputClient(readStruct);
}
}
}
return NtStatus;
}
// dummy routine
NTSTATUS UnSupportedIrpFunction(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
NTSTATUS NtStatus = STATUS_NOT_SUPPORTED;
DbgPrintEx(0, 0, "[PUBG]: Unsupported Irp Function \r\n");
return NtStatus;
}
// driver entrypoint
NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT pDriverObject, _In_ PUNICODE_STRING RegistryPath)
{
DbgPrintEx(0, 0, "\n[PUBG]:");
DbgPrintEx(0, 0, "\n[PUBG]: Driver Starting");
PUBase = 0;
NTSTATUS status = STATUS_SUCCESS;
RtlInitUnicodeString(&dev, L"\\Device\\PUBGMap");
RtlInitUnicodeString(&dos, L"\\DosDevices\\PUBGMap");
status = IoCreateDevice(pDriverObject, 0, &dev, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDeviceObject);
if (status == STATUS_SUCCESS)
{
for (UINT32 uiIndex = 0; uiIndex < IRP_MJ_MAXIMUM_FUNCTION; uiIndex++)
{
pDriverObject->MajorFunction[uiIndex] = UnSupportedIrpFunction;
}
pDriverObject->MajorFunction[IRP_MJ_WRITE] = WriteBufferedIO;
pDriverObject->DriverUnload = Unload;
pDeviceObject->Flags |= DO_BUFFERED_IO;
pDeviceObject->Flags &= (~DO_DEVICE_INITIALIZING);
IoCreateSymbolicLink(&dos, &dev);
DbgPrintEx(0, 0, "\n[PUBG]: Driver Started Successfully");
}
else
{
return STATUS_UNSUCCESSFUL;
}
PsSetLoadImageNotifyRoutine(NotifyImageLoadCallback);
return STATUS_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment