First of all, read this:
That's pretty much how all this started.
A SEH buffer overflow is a specific stack overflow that targets the EXCEPTION_REGISTRATION_RECORD sitting some arbitrary distance down the stack.
Why does this not happen for every program then since there should ...
No, the Windows loader doesn't care about the name of the .pdata section. It doesn't find the RUNTIME_FUNCTION structs based on the section name, but rather based on the content of NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].
Furthermore, the RUNTIME_FUNCTION structs don't need to be in "a separate COFF section".
Regarding your original question: Upon ntdll.dll loading each PE image, the list of exception handler addresses in the PE image is parsed and each address is inserted into a sorted list that ntdll.dll internally uses. When an exception hits, ntdll.dll!KiUserExceptionDispatcher will try to figure out which exception in the SEH chain to use. In turn, each ...
the __ehstate_t type is defined as int. toState is the index of the next handler in the array that needs to be unwind.
Action is the operation that needs to be done in order to reach the next state (the value of toState). This happens until toState reaches -1, which is the "blank" state that ends the unwinding process.
The state is incremented by one every ...
In case of the compiler-level SEH, the callback invoked by the OS is the compiler-provided function, usually __except_handler3 or similar. Once called, it inspects the stack, retrieves the trylevel, looks up the corresponding scopetable entry and calls the exception filter (lpfnFilter). If the filter returns non-zero, the handler (lpfnHandler) is invoked - ...
I post my own answer based on my own research. I am not sure about correctness of the parts in bold. Comments correcting my answer or fuller and better answers are welcome. I will edit out the boldness after I receive comments confirming or refuting my assumptions.
Assume that your malicious buffer overwrote the _EXCEPTION_REGISTRATION_RECORD and you found ...
A more flexible solution using x64dbg
In addition to ollydbg2's built-in experimental support, it's relatively easy to achieve something similar in x64dbg, although some manual scripting is required. Using x64dbg's SetExceptionBPX function, you can define any exception to be treated as a breakpoint by x64dbg instead of being treated by regular exception ...
So, EHFlags bits are defined as follows (see ehdata_values.h):
#define FI_EHS_FLAG 0x00000001
#define FI_DYNSTKALIGN_FLAG 0x00000002
#define FI_EHNOEXCEPT_FLAG 0x00000004
i.e. 5 is FI_EHS_FLAG|FI_EHNOEXCEPT_FLAG
In crt\src\vcruntime\frame.cpp we can find this snippet:
auto tryBlockMap = T::TryBlockMap(pFuncInfo, pDC);
just modified your source a bit to print Rip prior and post in handler
added another exception and eliminated a warning (empty handler block)
and tested with +1,+2,+3 +4 +5 on the handler Hardware breaks doesn't get hit
I haven't checked by single stepping inside RtlpExecuteHandlerForxxx calls
here is a modified src
I think this is a great moment to introduce you to this great article written back in 1997, but which still holds up. I really recommend that you read it because it will explain to you everything about SEH. To answer your question about continuing execution, I will quote one paragraph from the article:
When the operating system sees that ...
First, your platform is very important ( mine is Windows )
In Windows WinDbg + !exploitable is one of fast analyze options.
it is here
Additionally I use WinDbg + !analyze to determine standard name of bug...
it is default WinDbg extension.
Finally, as the nature of bugs is unknown (in your case) it is not an easy way to detect root cause.
Standard exploitation of SEH based BoF will try to point the SE Handler to a POP/POP/RET instruction. This is not always the case depending on enabled memory protections. (use Mona plugin for Immunity to check this using the command !mona mod, or simply inspect the vulnerable binary characteristics)
If your SE Handler is pointing to 0x384c5c36, you should ...
38 4c 5c 36 is the value of the EIP when dbg cannot continue.
Based on your comment above, in response to your questions:
The exploit's payload.
It's the location in memory where the exploit's payload is loaded.
If you're only looking to analyze the payload (and not the exploit/trigger), set a breakpoint on that address and debug from there.
Exception handling can cause memory leaks. Your C++ compiler is smart enough to realize the possibility of memory leaks surrounding exception handling and is automatically inserting exception handlers where necessary to prevent memory leaks. This means that there really is a try/catch block where you observed an exception handler, except it is ...
fs: points to ETHREAD
whose first is member NtTib which again is a structure
whose first member is _EXCEPTION_REGISTRATION_RECORD
0:000> dt ntdll!_TEB NtTib.* @$thread
+0x000 NtTib :
+0x000 ExceptionList : 0x0010f76c _EXCEPTION_REGISTRATION_RECORD
+0x004 StackBase : 0x00110000 Void
+0x008 StackLimit : 0x0010d000 Void
Well the comment: "Install new handler" is a bit misleading. What you are installing is EXCEPTION_REGISTRATION_RECORD and if you would check how this structure looks like it would be more obvious that this is the way:
typedef struct _EXCEPTION_REGISTRATION_RECORD
from your second screen shot [ebp+10] will point to _CONTEXT
ebx = [ebp+10] ->
ebx == CONTEXT->FirstMember ==ContextFlags
ebx+4 == CONTEXT->SecondMember == Dr0 (Debug Register 0)
ebx+a0 == Register Esi
ebx + b8 == Eip (this is where the execution will continue )
ebx+b0 == Eax
if you have a hardware breakpoint you will get a different esi (see ...
There are two things you must check:
You overwritten exception handler but, is there any exception occurs?
Are there any protection mechanism active for exception handlers?
For first one, most easy exception which you can trigger and not caught until your handler is obviously access violation. You can try to trigger an exception with overwrite a value ...
The SEH overwrite attack requires that the function has registered an SEH handler. The SEH handler address exists below the stack cookie and return address. If you've overwritten the return address then you've written too many data.
The chain's integrity will be checked, and there must be executable memory at the handler address (i.e. 0x41414141) for the ...