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

KbTriggerCopyOnWrite BSOD immediately sample #29

Open
Tai7sy opened this issue Sep 21, 2020 · 2 comments
Open

KbTriggerCopyOnWrite BSOD immediately sample #29

Tai7sy opened this issue Sep 21, 2020 · 2 comments

Comments

@Tai7sy
Copy link
Contributor

Tai7sy commented Sep 21, 2020

debug_me.exe is a simple application which call MessageBoxA when button clicked.

Now we use KbWriteProcessMemory with TriggleCoW to user32.MessageBoxA like this:

VOID BSOD_Test() {

    WdkTypes::PEPROCESS Process;
    DWORD ProcessId = GetProcessIdByName(TEXT("debug_me.exe")); // A wow64 process
    PVOID Address = (PVOID)0x76311F70; // user32.MessageBoxA

    Processes::Descriptors::KbGetEprocess(ProcessId, &Process);
    printf("MessageBoxA: VA:%p, PA:0x%I64X\n", Address, GetPhysAddr(Process, Address));
    {
        BYTE Buffer[1] = { 0 };
        BOOL Status = Processes::MemoryManagement::KbReadProcessMemory(ProcessId, (WdkTypes::PVOID)Address, Buffer, 1);
        printf("MessageBoxA: KbReadProcessMemory:  0x%02X\n", Buffer[0]);
    }

    {
        BYTE* NewBuffer = new BYTE[1];
        NewBuffer[0] = 0xC3;
        BOOL Status = Processes::MemoryManagement::KbWriteProcessMemory(ProcessId, (WdkTypes::PVOID)Address, NewBuffer, 1, TRUE);
        delete[] NewBuffer;
        printf("MessageBoxA: KbWriteProcessMemory: %d\n", Status);
        printf("MessageBoxA: PA:0x%I64X\n", GetPhysAddr(Process, Address));
    }

    Processes::Descriptors::KbDereferenceObject(Process);
}

The debug_me.exe will crash obviously because the user32.MessageBoxA is changed to 0xC3 and caused some stack error.

Then it will cause immediately BSOD.

QUOTA_UNDERFLOW (21)
This bugcheck occurs if a kernel component mishandles quota charges and
returns more quota than was previously charged to a particular quota block.
Arguments:
Arg1: ffffc9872b1ee080, The process (if any) that was initially charged.
Arg2: 0000000000000002, The quota type in question (paged pool, nonpaged pool, etc.)
Arg3: ffffffffffffffff, The initial charge amount to return.
Arg4: fffffffffffae8bd, The remaining (unreturned) charge.
------------------
os: 
Windows 10 1809

stack:
[0x4]   nt!PspReturnQuota + 0x180085   
[0x5]   nt!PsReturnProcessPageFileQuota + 0x25   
[0x6]   nt!MiReturnFullProcessCharges + 0x4b   
[0x7]   nt!MiRemoveVadCharges + 0xab   
[0x8]   nt!MiFinishVadDeletion + 0xf1   
[0x9]   nt!MiDeleteVad + 0x15f2   
[0xa]   nt!MiUnmapVad + 0x49   
[0xb]   nt!MiCleanVad + 0x30   
[0xc]   nt!MmCleanProcessAddressSpace + 0x113   
[0xd]   nt!PspRundownSingleProcess + 0x129   
[0xe]   nt!PspProcessRundownWorkerSingle + 0x32   
[0xf]   nt!ExpWorkerThread + 0x16a   
[0x10]   nt!PspSystemThreadStartup + 0x55   
[0x11]   nt!KiStartSystemThread + 0x1c   

Since the KbTriggerCopyOnWrite will still take some minnutes/hours to cause a BSOD, which meen it difficult to debug.
This maybe helpful to find the problem.

@HoShiMin
Copy link
Owner

Thanx a lot for this sample! I'm in developing of the Kernel-Bridge 2 - a fully rewritten implementation. And I'll check your code there a bit later. But it seems that the best solution is to use ZwProtectVirtualMemory.

@Tai7sy
Copy link
Contributor Author

Tai7sy commented Sep 21, 2020

I thought the SEC_NOCHANGE would cause the ZwProtectVirtualMemory to failed, which is used by some game or game protector to map ntdll to avoid being hooked.

But in fact, there should be no impact.
If some memory reagion was created with SEC_NOCHANGE, then the COW flag in the pte will be meaningless, (At least it's not a memory created/shared by the system, and it won't cause a system crash. )
So we don't need to trigger cow on this kind of memory region.

@Tai7sy Tai7sy changed the title KbTriggerCopyOnWrite BSOD immediately POC KbTriggerCopyOnWrite BSOD immediately sample Sep 21, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants