How to handle this exception? (zero esp) - c++

How to handle this exception?
__asm
{
mov esp, 0
mov eax, 0
div eax
}
This is not handled with try/except or SetUnhandledExceptionFilter().

Assuming this is running in an operating system, the operating system will catch the divide by zero, and then ATTEMPT to form an exception/signal stackframe for the application code. However, since the user-mode stack is "bad", it can't.
There is really no way for the operating system to deal with this, other than kill the application. [Theoretically, the could make up a new stack from some dynamically allocated memory, but it's pretty pointless, as there is no (always working) way for the application itself to recover to a sane state].
Don't set the stack pointer to something that isn't the stack - or if you do store "random" data in the stack pointer register, do not have exceptions. It's the same as "don't aim a gun at your foot and pull the trigger, unless you want to be without your foot".
Edit:
If the code is running in "kernel mode" rather than "usermode", it's even more "game over", since it will "double-fault" - the processor hits a divide by zero exception handler, which tries to write to the stack, and when it does so, it faults. This is now a "fault within a fault handler", aka a "double-fault". The typical setup of the double-fault handler is to have a separate stack, which then recovers the fault handler. But it's still game over - we don't know how to return to the original fault handler [or how to find out what the original fault handler was].
If there is no "new stack" with the double fault handler, it will triple fault a x86 processor - typically, a triple fault will make the processor restart [technically, it halts the processor with a special combination of bits signalled on the address bus to indicate that it's a "triple fault". The typical PC northbridge then resets the processor in recognition that the triple fault is an unrecoverable situation - this is why sometimes your PC simply reboots when you have poor quality drivers].

It's not a good idea to try to interact with a higher-level language's exception mechanism from embedded assembly. The compiler can do "magic" that you cannot match, and there's no (portable) way to tell the compiler that "this assembly code might throw an exception".

Related

When and how exactly is a segmentation fault of a C/C++ application reported and handled by the OS?

I'm failing to understand a specific scenario in which my C++ multi-threaded application (running on a Linux machine, Wind River 6.x) is facing a segmentation fault.
I know the concept of segmentation fault and even went over this post and also this one but failed to encounter a scenario similar to mine and/or an answer to my question, so I'm posting this question.
My code that generates the segmentation fault is as follows (abbreviated and simplified):
// MyStruct* pMyStruct is a function argument that arrives to the function and at some point of time
// being set to NULL
ASSERT_PTR_NE(pMyStruct, NULL); <--- this assertion is logged to my application log (meaning, at this line, pMyStruct is NULL)
int someInt = pMyStruct->someIntOfMyStruct; <--- this line does NOT create the segmentation fault
double someDouble = pMyStruct->someDoubleOfMyStruct; <--- this line ALSO does NOT create the segmentation fault
ASSERT_NUM_EQ(pMyStruct->someIntOfMyStruct, SOME_INT_VALUE_TO_CHECK); <--- this line DOES create the segmentation fault
As mentioned in the last code line, the 4th line of code is the "last line" that my application is executing (I guess) --> when examining the core file with GDB, frame 0 of the core file indicates that this line is the line that causes the crash.
My questions are if so:
How come the 2nd and 3rd lines of code of my application did not cause segmentation fault?
What exactly takes place, system wise, i.e. - in the OS and the application from the moment the NULL was accessed (in the first line) until the application is being terminated by the OS?
Meaning, is it possible that indeed the actual segmentation fault was raised due to the 1st line, YET, for some reason, until the OS actually took the decision and action to terminate the application, also lines 2-4 were executed and when arriving to the 4th line the application "again" raised segmentation fault?
Or, perhaps, is it possible that what actually took place here is an overrun of the pMyStruct variable - meaning, after the first line that does the assert (and prints info to the log file of the application) another thread set the pMyStruct to NON NULL value, thus "allowing" lines 2-3 to run WITHOUT causing a crash and then JUST before line 4 was executed the pMyStruct was "overrun" by another thread and was set to NULL thus, this time causing line 4 to crash?
Typically, an OS creates a segmentation fault after the CPU faults on an address. The CPU doesn't know why the fault happened. It might be that the memory is paged out to disk, but for this question we're assuming a bad pointer. The OS knows it's a bad pointer because the address doesn't correspond to any paged-out memory. Hence, the OS tells the CPU it is handling the situation, and tells the CPU to continue execution in the signal handler.
The C++ null pointer isn't special to the CPU. It just so happens that the OS by convention does not allocate RAM at this address.
By C++ standards, your code has Undefined Behavior, and that allows "time travel". More accurately, to allow optimizations, compilers may shuffle around code in the assumption that Undefined Behavior does not happen. It would seem that lines 2 & 3 are shuffled after line 4. You can't detect this in a correct C++ program.
This is not how a typical CPU sees it. Modern CPU's also shuffle around instructions internally, like compilers do, but when the CPU reports the fault to the OS it will pretend that all instructions happened in the right order.

Custom debugger based on windows api - debugging multithreaded process

In my debugger i set particular memory address to 0xCC (int3) and while execution one of the threads reaches this address. Exception is thrown. While handling exception i subtract IP register to point one instruction before 0xCC and replace 0xCC with original byte. I also set flag in thread context to throw exception after execute one instruction - I need to set back 0xCC byte.
Problem:
Code executes correctly but I realized that there possibly is a bug. After receiving exception I set back original byte and set flag in thread to back to the debugger just right after it executes one instruction (it lets me to set back int3). It sounds good but I have detected that after original byte is executing another thread also executes this instruction without throwing exception (I think it can be related to threads switching).

Is Hardware Breakpoint able to write memory?

I have this ASM Code which i would like to do a Hardware breakpoint on it, however I'm wonder if I could use Hardware Breakpoint to write the memory. Can anyone advice?
[ASM]
41A8BA - 68 12345678 [PUSH 78563412]
Is there anyway I can write it on Hardware Breakpoint that makes it to "68 00000000" for example on C++?
[C++ Code]
LONG WINAPI ExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo)
{
if(ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP)
{
if((DWORD)ExceptionInfo->ExceptionRecord->ExceptionAddress == 0x41A8BA)
{
//What do i write here?
return EXCEPTION_CONTINUE_EXECUTION;
}
}
return EXCEPTION_CONTINUE_SEARCH;
}
I'm very familiar with how x86's implementation of hardware breakpoints work (from "what it does to the processor" - not how it's actually designed internally), and have read the descriptions for several others.
Hardware breakpoints do not DO anything to the code in question - it is a set of special registers, that can be given a pattern ("Address X, trigger on write", "Address Y, trigger on execute"), which are checked against during the execution of the code, and if there is a match (e.g. "Address X is being written to" or "Address Y is being executed"), then the processor will stop executing and enter an exception handler - at which point the software in the exception handler takes over, typically by handing over to the debugger to say "Your code did a write to address X, here's where you are at" or "Your code executed address Y, here's where we stopped".
The hardware brekapoints can't directly be used to read, write or execute anything - it's just a "match + exception" mechanism. Technically, one could make the exception handler do something like writing to the address being executed, but that would not be "the hardware breakpoint", and it would still be treated just like any other code executing on the processor, meaning the memory has to be mapped in a way that it can be written (code, typically, isn't writeable in modern OS's such as Windows and Linux).
You can of course, in the exception handler for the debug break, map the memory as writeable (if needed), and write a different value to the part of code you care about (if it's in another process, you need to use OpenProcess and WriteProcessMemory) - again, this is nothing directly to do with hardware breakpoints, but about the code executed as a consequence, and will still follow the usual rules of the OS with regards to what memory you can read and write.
I'm wondering what this has to do with hardware breakpoints.
Is far as I understand you want to modify a Windows program when it is stopped?
To do this you should use the "WriteProcessMemory()" API function.

Unhandled exception

I am getting unhandled exception at some functionality due to enabling one of control and i am unable to find the exact reason.It gives me error at assembly instruction
00451901 add dword ptr [eax],eax but i can't figure out the basic reason of unhandled exception.Please suggest some software or any other thing to know the impact of enabling and disabling the control.
You get exception, because most certainly, eax contains value that is not an address to writable memory area.
So, the question is why this instruction was executed. Here's the hint:
Machine code for instructions add dword ptr[eax], eax is 01 00.
That is, unexpected executing of this instructions usually means that you happen to execute some data (e.g. 32-bit constant '1').
This usually happens because of buffer or stack overflow in your code or calling function by pointer that wasn't properly assigned.
Check your array access and function pointers calls.

trap invalid opcode rip rsp

We see a couple of below mentioned messages in /var/log/messages for one of our application:
Sep 18 03:24:23 <machine_name> kernel: application_name[14682] trap invalid opcode rip:f6c6e3ce rsp:ffc366bc error:0
...
Sep 18 03:19:35 <machine_name> kernel: application_name[4434] general protection rip:f6cd43a2 rsp:ffdfab0c error:7b2
I am not able to make what’s these output means and how we can track the function / code that is causing the issue. Further what is 'trap invalid opcode' and 'general protection' means?
Usually that means that your program's instruction pointer points to data or garbage. That's commonly caused by writing to stray pointers and such.
One scenario would be that your code writes (through a stray pointer) over some class' virtual table, replacing the member function addresses with nonsense. The next time you call one of the class' virtual functions, your program will interpret the garbage as an address and jump to that address. If whatever data lies at this address happens to not to be a valid machine code instruction for your processor, you would see this error.
There is another possibility that can cause 'invalid' op codes, that would be hardware not supporting newer opcode/instruction sets(SSE 4/5) or it not being from the right manufacturer(both AMD and Intel have some specific opcodes that work only on their processors) or just not having permission to exectute certain ops(though this would probably show up as something else).
From the above I would take RIP to be 'register(?) instruction pointer' and RSP to be 'register stack pointer', in which case you could use a debugger and set an execution hardware breakpoint on the specified address(RIP) and trace back what is calling it.(it seems your using linux or unix, so this is quite vague). if you are on windows, try using a custom exception filter to capture the EXCEPTION_ILLEGAL_INSTRUCTION event to get a little more information