Skip to content

Instantly share code, notes, and snippets.

@nmulasmajic
Created September 1, 2017 00:06
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save nmulasmajic/f459b7146a1371d70c890ee45ec54084 to your computer and use it in GitHub Desktop.
Save nmulasmajic/f459b7146a1371d70c890ee45ec54084 to your computer and use it in GitHub Desktop.
/*
* Module Name:
* int3.cpp
*
* Abstract:
* Examines the difference in operation between a
* multi-byte int 3 (0xCD 0x03) and a single-byte
* int 3 (0xCC).
*
* Author:
* Nemanja (Nemi) Mulasmajic <nm@triplefault.io>
* http://triplefault.io
*/
#pragma warning(disable: 4710)
#pragma warning(push, 0)
#include <Windows.h>
#include <stdio.h>
#pragma warning(pop)
// The size of an architecture page on x86/x64.
#define PAGE_SIZE 0x1000
// Single-byte int 3 stub.
BYTE _Int3[] =
{
0xCC, /* int 3*/
0xC3 /* ret */
};
// Multi-byte int 3 stub.
BYTE _LongInt3[] =
{
0xCD, 0x03, /* int 3 */
0xC3 /* ret */
};
/*
* Handles exception processing for our int 3s.
*/
DWORD WINAPI ExceptionFilter(_In_ PEXCEPTION_POINTERS ExceptionInformation)
{
// Malformed exception information.
if (!ExceptionInformation || !ExceptionInformation->ExceptionRecord || !ExceptionInformation->ContextRecord)
return EXCEPTION_EXECUTE_HANDLER;
// This is the only type of exception we should see...
if (ExceptionInformation->ExceptionRecord->ExceptionCode != EXCEPTION_BREAKPOINT)
return EXCEPTION_EXECUTE_HANDLER;
printf("[+] ExceptionRecord->ExceptionAddress: 0x%p.\n", ExceptionInformation->ExceptionRecord->ExceptionAddress);
#if defined(_M_AMD64)
#define IP Rip
#elif defined(_M_IX86)
#define IP Eip
#else
#error "Compiling for unhandled architecture."
#endif
const BYTE* InstructionPointer = (const BYTE*)ExceptionInformation->ContextRecord->IP;
printf("[+] ContextRecord->IP: 0x%p.\n", InstructionPointer);
printf("\t@ [0: 0x%X...]\n", InstructionPointer[0]);
#undef IP
return EXCEPTION_EXECUTE_HANDLER;
}
/*
* The entry point.
*/
int main(void)
{
int status = -1;
// Allocate executable memory.
PBYTE Memory = (PBYTE)VirtualAlloc(NULL, PAGE_SIZE, (MEM_COMMIT | MEM_RESERVE), PAGE_EXECUTE_READWRITE);
if (!Memory)
{
fprintf(stderr, "[-] ERROR: Failed to allocate memory.\n");
goto Cleanup;
}
typedef void(*Function)();
// Place our simple breakpoint stubs in executable memory.
// Our single-byte int 3 will be at the start of this region.
Function Int3 = (Function)&Memory[0];
size_t BufferSize = sizeof(_Int3);
memcpy(Int3, _Int3, BufferSize);
printf("[+] Single-byte 'int 3' buffer: 0x%p.\n", Int3);
// Our multi-byte int 3 will be immediately after.
Function LongInt3 = (Function)&Memory[BufferSize];
BufferSize = sizeof(_LongInt3);
memcpy(LongInt3, _LongInt3, BufferSize);
printf("[+] Multi-byte 'int 3' buffer: 0x%p.\n", LongInt3);
// Execute both variants of int 3.
printf("\n[+] Executing single-byte variant.\n");
__try
{
Int3();
}
__except (ExceptionFilter(GetExceptionInformation())) { }
printf("\n[+] Executing multi-byte variant.\n");
__try
{
LongInt3();
}
__except (ExceptionFilter(GetExceptionInformation())) {}
status = 0;
Cleanup:
// Free allocated memory.
if (Memory)
{
VirtualFree(Memory, 0, MEM_FREE);
Memory = NULL;
}
// Wait for [ENTER] key press to terminate the program.
getchar();
return status;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment