Setting pool as read-only?

Is there a way? I’d prefer something simple, but even if using MDLs to
set ExAllocated Pool would be fine for this purpose.

I cannot set data access breakpoints in that many locations.

I don’t know of an API to change the page protection directly. If you hide your allocations behind an API you can double map the buffer and return a read only version to yourself. Here’s a very sloppy example with any and all error handling removed:

    PVOID pool;
    PUCHAR mappedAddress;
    PMDL mdl;

    pool = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, 'xxxx');

    mdl = IoAllocateMdl(pool, PAGE_SIZE, FALSE, FALSE, NULL);

    MmProbeAndLockPages(mdl, KernelMode, IoWriteAccess);
        
    mappedAddress = (PUCHAR)MmGetSystemAddressForMdlSafe(mdl, NormalPagePriority);

    status = MmProtectMdlSystemAddress(mdl, PAGE_READONLY);

    // Generates ATTEMPTED_WRITE_TO_READONLY_MEMORY
    *mappedAddress = 'Y';

You wouldn’t want to do this all the time of course, but if you’re desperate it works.

KInda what I needed, apart from having to allocate PAGE_SIZEd chunks :frowning:
Luckily, I randomly found the culprit! Thanks.

PAGE_SIZE was by way of example but not limitation, it would work with smaller buffers. Glad to hear you fixed it.

Hmm, I never ran MDLs without PAGE_SIZE aligned buffers (for
completely different reasons), I did not realize it was possible to
set only small areas as read-only.
E.g. 8 bytes writable, 4 bytes read-only, 4 bytes writable, etc.?

That is awesome, thanks.

PAGE_SIZE was by way of example but not limitation, it would work with
smaller buffers. Glad to hear you fixed it.

You would need to create MDLs for each of the small areas and use different virtual addresses to access them. I suspect that would probably get out of hand very quickly.

Quite probable, but it is nice to have sometimes.
The structures in question were “set up and never write to”,
therefore, it is only a matter of writing wrappers for
allocation/deallocation.

Thank you for confirming this!

You would need to create MDLs for each of the small areas and use different
virtual addresses to access them. I suspect that would probably get out of
hand very quickly.