forked from Peribunt/Exception-Ret-Spoofing
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Source.cpp
110 lines (88 loc) · 2.74 KB
/
Source.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include <windows.h>
#include <cstdio>
#define MAGIC_SPOOF_RETADDR_NUMBER 0xDEADBEEF00000001
#define CONSOLE_LOG( Fmt, ... ) \
printf( "[!] " __FUNCTION__ ": " Fmt "\n", ##__VA_ARGS__ )
namespace ReturnSpoofer
{
LPVOID FunctionToCall;
LPVOID FakeReturnAddress;
LPVOID ReturnAddressBackup;
__forceinline
VOID WINAPI SetupSpoofCall(
IN LPVOID Function,
IN LPVOID FakeRet )
noexcept
{
FunctionToCall = Function;
FakeReturnAddress = FakeRet;
}
extern "C"
ULONG_PTR SpoofCall(
IN ... );
}
LONG WINAPI VectoredHandler( IN LPEXCEPTION_POINTERS ExceptionPointers )
{
const PCONTEXT ContextRecord = ExceptionPointers->ContextRecord;
const LPEXCEPTION_RECORD ExceptionRecord = ExceptionPointers->ExceptionRecord;
//
// Hit an access violation
//
if ( ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION )
{
//
// Did the exception deliberately occur inside our SpoofCall ASM proc?
//
if ( ContextRecord->Rax == MAGIC_SPOOF_RETADDR_NUMBER )
{
ReturnSpoofer::ReturnAddressBackup = *(LPVOID*)( ContextRecord->Rsp );
*( LPVOID* )( ContextRecord->Rsp ) = ReturnSpoofer::FakeReturnAddress;
CONSOLE_LOG( "Old return address: %p", ReturnSpoofer::ReturnAddressBackup );
CONSOLE_LOG( "New return address: %p", ReturnSpoofer::FakeReturnAddress );
ContextRecord->Rip = (ULONG64)ReturnSpoofer::FunctionToCall;
}
return EXCEPTION_CONTINUE_EXECUTION;
}
//
// Hit a trap instruction
//
if ( ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT )
{
if ( ExceptionRecord->ExceptionAddress == ReturnSpoofer::FakeReturnAddress )
{
CONSOLE_LOG( "Returning back to %p...", ReturnSpoofer::ReturnAddressBackup );
ContextRecord->Rip = (ULONG64)ReturnSpoofer::ReturnAddressBackup;
}
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
}
LONG main( VOID )
{
//
// Add a vectored handler ( Of course you can also use KiUserExceptionDispatcher )
//
LPVOID ExceptionHandler =
AddVectoredExceptionHandler( TRUE, VectoredHandler );
//
// Set up the spoof call for MessageBoxA
// Make the return address a 0xCC anywhere in the executable region of the module I suppose
//
ReturnSpoofer::SetupSpoofCall(
MessageBoxA, ( LPVOID )( ( ULONG64 )MessageBoxA - 1 ) );
//
// Call the MessageBoxA function with a spoofed return address
//
DWORD Result =
ReturnSpoofer::SpoofCall( NULL, "Hello World", "Spoofed call", NULL );
//
// Log to prove both execution flow lands here and the value returned properly
//
CONSOLE_LOG( "MessageBoxA Result: %i", Result );
//
// Remove the vectored handler
//
RemoveVectoredExceptionHandler( ExceptionHandler );
system( "pause" );
return NULL;
}