Created
September 1, 2017 00:06
-
-
Save nmulasmajic/f459b7146a1371d70c890ee45ec54084 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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 <[email protected]> | |
* 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