Skip to content

Instantly share code, notes, and snippets.

@olliencc
Created December 27, 2021 21:11
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save olliencc/881ea27b1fd0765fd44dbf75095bd183 to your computer and use it in GitHub Desktop.
Save olliencc/881ea27b1fd0765fd44dbf75095bd183 to your computer and use it in GitHub Desktop.
//
// MEMGUARD.cpp : Simulate a process we want to dump
//
// Dump early with MEMGUARDDump then
// - strings.exe memguard.dmp | findstr HiLo
// HiLo - %d
//
// Dump later with MEMGUARDDump then
// -
// HiLo - %d
// HiLo - 41 <- from the page that was guarded
//
#include <iostream>
#include <stdio.h>
#include <Windows.h>
#include <tchar.h>
#include <stdlib.h>
unsigned long MyUnhandledExceptionFilter(EXCEPTION_POINTERS* pExceptionInfo)
{
if (pExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_GUARD_PAGE_VIOLATION) // This is going to return true whenever any of our PAGE_GUARD'ed memory page is accessed.
{
_tprintf(TEXT("[i] Guard page fault\n"));
return EXCEPTION_CONTINUE_EXECUTION; // When we return to the page, it will no longer be PAGE_GUARD'ed, so we rely on single stepping to re-apply it. (If we re-applied it here, we'd never move forward.)
}
return EXCEPTION_CONTINUE_EXECUTION;
}
int main(int argc, char** argv)
{
LPVOID ptrGuard = NULL;
LPVOID ptrRead = NULL;
DWORD oldProt;
DWORD dwPageSize; // amount of memory to allocate.
BOOL bLocked; // address of the guarded memory
SYSTEM_INFO sSysInfo; // useful information about the system
MEMORY_BASIC_INFORMATION lpBuffer;
DWORD dwRet = 0;
DWORD dwRand = rand();
char strFoo[100];
GetSystemInfo(&sSysInfo); // initialize the structure
_tprintf(TEXT("[i] This computer has page size %d.\n"), sSysInfo.dwPageSize);
dwPageSize = sSysInfo.dwPageSize;
ptrGuard = VirtualAlloc(NULL, dwPageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
_tprintf(TEXT("[i] Allocated guard page\n"));
memset(strFoo, 0x00, 100);
sprintf_s(strFoo, "HiLo - %d\n", dwRand);
memcpy(ptrGuard, strFoo, strlen(strFoo));
memset(strFoo, 0x00, 100);
_tprintf(TEXT("[i] %d\n"), dwRand);
if (VirtualProtect(ptrGuard, 10, PAGE_READWRITE | PAGE_GUARD, &oldProt) == FALSE) {
_tprintf(TEXT("[i] Error %u\n"), GetLastError());
}
ptrRead = VirtualAlloc(NULL, dwPageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
_tprintf(TEXT("[i] Allocated other page\n"));
AddVectoredExceptionHandler(true, (PVECTORED_EXCEPTION_HANDLER)MyUnhandledExceptionFilter);
_tprintf(TEXT("[i] Registered exception handler\n"));
DWORD dwCount = 0;
while (1) {
Sleep(1000);
dwRet= VirtualQuery(ptrGuard, &lpBuffer, sizeof(lpBuffer));
if (dwRet == 0) {
_tprintf(TEXT("[i] Error %u\n"), GetLastError());
}
_tprintf(TEXT("[i] Range - "));
if(lpBuffer.AllocationProtect & PAGE_GUARD) _tprintf(TEXT("[i] GUARD on alloc "));
else _tprintf(TEXT("[i] NOT GUARD on alloc "));
if (lpBuffer.Protect & PAGE_GUARD) _tprintf(TEXT("[i] GUARD now\n"));
else _tprintf(TEXT("[i] NOT GUARD now\n"));
if (dwCount == 10) {
if (VirtualProtect(ptrGuard, 10, PAGE_READWRITE, &oldProt) == FALSE) {
_tprintf(TEXT("[i] Error %u\n"), GetLastError());
}
else {
_tprintf(TEXT("[i] NOT GUARD now\n"));
}
}
/*
if (dwCount == 10) {
_tprintf(TEXT("[i] Doing read\n"));
memcpy(ptrRead, ptrGuard, 10);
}
if (dwCount == 12) {
_tprintf(TEXT("[i] Doing write\n"));
memcpy(ptrGuard, ptrRead, 10);
}
*/
dwCount++;
}
}
//
// MEMGUARDDump.cpp : Dump MEMGUARD with MiniDumpWriteDump
//
#include <iostream>
#include <stdio.h>
#include <Windows.h>
#include <tchar.h>
#include <stdlib.h>
#include <DbgHelp.h>
#include <TlHelp32.h>
using namespace std;
#pragma comment (lib, "Dbghelp.lib")
int main()
{
DWORD lsassPID = 0;
HANDLE lsassHandle = NULL;
HANDLE outFile = CreateFile(L"memguard.dmp", GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
// Find lsass PID
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 processEntry = {};
processEntry.dwSize = sizeof(PROCESSENTRY32);
LPCWSTR processName = L"";
if (Process32First(snapshot, &processEntry)) {
while (_wcsicmp(processName, L"memguard.exe") != 0) {
Process32Next(snapshot, &processEntry);
processName = processEntry.szExeFile;
lsassPID = processEntry.th32ProcessID;
}
wcout << "[+] Got memguard.exe PID: " << lsassPID << endl;
}
// Open handle to lsass.exe process
lsassHandle = OpenProcess(PROCESS_ALL_ACCESS, 0, lsassPID);
// Create minidump
BOOL isDumped = MiniDumpWriteDump(lsassHandle, lsassPID, outFile, MiniDumpWithFullMemory, NULL, NULL, NULL);
if (isDumped) {
cout << "[+] memguard dumped successfully!" << endl;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment