mastercodeon314 / KsDumper-11

A revival of the classic and legendary KsDumper
409 stars 77 forks source link

Could dump drivers? #5

Open gamous opened 1 year ago

mastercodeon314 commented 1 year ago

I legitimately don't even know where to start, not very strong with kernel drivers. So on this one I asked ChatGPT by prompting it with all of the Driver.c code, then asking it if it could modify it to dump a driver. It looks like a really good place to start, so I'm posting that here and then will be experimenting with this..

Sure, to modify this driver to dump the memory of another driver given some kind of identifier of that driver, you could follow these general steps:

Define a new IOCTL control code that your driver will use to receive the identifier of the driver whose memory needs to be dumped.

Implement a function that takes the identifier received through the IOCTL and finds the corresponding driver object.

Use the driver object obtained in step 2 to read its memory and write it to a file.

Here's an example implementation of these steps: Define a new IOCTL control code that takes the identifier of the target driver:

#define IOCTL_DUMP_DRIVER_MEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef struct _DUMP_DRIVER_MEMORY_REQUEST {
    WCHAR DriverName[MAX_PATH];
    WCHAR FilePath[MAX_PATH];
} DUMP_DRIVER_MEMORY_REQUEST, *PDUMP_DRIVER_MEMORY_REQUEST;

Implement a function that searches for the driver object corresponding to the given name:

PDRIVER_OBJECT GetDriverObjectByName(WCHAR* driverName)
{
    PDRIVER_OBJECT driverObject = NULL;
    UNICODE_STRING uDriverName;
    RtlInitUnicodeString(&uDriverName, driverName);

    // Enumerate loaded drivers
    ULONG bytesNeeded;
    ZwQuerySystemInformation(SystemModuleInformation, NULL, 0, &bytesNeeded);

    PVOID systemInfoBuffer = ExAllocatePoolWithTag(NonPagedPool, bytesNeeded, 'sm01');
    if (systemInfoBuffer == NULL)
    {
        return NULL;
    }

    if (!NT_SUCCESS(ZwQuerySystemInformation(SystemModuleInformation, systemInfoBuffer, bytesNeeded, NULL)))
    {
        ExFreePool(systemInfoBuffer);
        return NULL;
    }

    PSYSTEM_MODULE_INFORMATION pModuleInfo = (PSYSTEM_MODULE_INFORMATION)systemInfoBuffer;

    for (ULONG i = 0; i < pModuleInfo->NumberOfModules; i++)
    {
        if (wcsstr(pModuleInfo->Modules[i].ImageName, uDriverName.Buffer) != NULL)
        {
            UNICODE_STRING uFullPath;
            RtlInitUnicodeString(&uFullPath, pModuleInfo->Modules[i].FullPathName);

            // Get driver object from the driver file path
            PDRIVER_OBJECT tmpDriverObject = NULL;
            if (NT_SUCCESS(OsGetDriverObject(&uFullPath, &tmpDriverObject)))
            {
                if (tmpDriverObject->DriverSection == pModuleInfo->Modules[i].Section)
                {
                    driverObject = tmpDriverObject;
                }
                else
                {
                    // This is not the correct driver object, dereference it
                    ObDereferenceObject(tmpDriverObject);
                }
            }

            RtlFreeUnicodeString(&uFullPath);
            break;
        }
    }

    ExFreePool(systemInfoBuffer);
    return driverObject;
}

Modify the IoControl function to handle the new IOCTL control code, find the driver object using GetDriverObjectByName, and dump its memory to a file:

case IOCTL_DUMP_DRIVER_MEMORY:
{
    PDUMP_DRIVER_MEMORY_REQUEST request = (PDUMP_DRIVER_MEMORY_REQUEST)Irp->AssociatedIrp.SystemBuffer;
    PDRIVER_OBJECT driverObject = GetDriverObjectByName(request->DriverName);

    if (driverObject == NULL)
    {
        status = STATUS_NOT_FOUND;
        bytesIO = 0;
        break;
    }

    // Dump driver memory to file
    HANDLE fileHandle;
    OBJECT_ATTRIBUTES fileAttributes;
    UNICODE_STRING uFilePath;
    RtlInitUnicodeString(&uFilePath, request->FilePath);
    InitializeObjectAttributes(&fileAttributes, &uFilePath, OBJ_KERNEL_HANDLE |