Custom debugger based on windows api - debugging multithreaded process - c++

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).

Related

Are exceptions stacked by the Cortex-M hardware in thread-mode or handler mode?

On Cortex-M processors with MPUs (let's use Cortex-M4 to be specific, but I bet the answer is the same for e.g. M3), what privilege mode is does the hardware exception entry stacking run in w.r.t the MPU?
Suppose I'm running in unprivileged thread mode using the process stack (PSP), with the MPU set to only accept writes within a particular region (e.g. a user-mode process is running). When an exception occurs, before the handler executes (in handler mode), the hardware stacks registers r0-r3,lr,pc etc onto the PSP. Does this also occur in unprivileged thread mode?
Specifically, suppose the process sets it's SP to some arbitrary point in memory it should not be allowed to write to, will the exception stacking result in a memory fault?
Coming back to this a year later after having dealt with this, the answer is that stacking occurs with whatever privilege was previously running.
So, if in unprivileged mode an interrupt occurs, the hardware will stack registers on the PSP using the existing MPU settings as though unprivileged code is performing the stacking. If stacking would violate MPU rules, a MemManage Fault occurs, and the MemManage Fault Status Register's MSTKERR field will be set (page 4-25 of the Cortex-M4 user guide)
About MPU rule violation & MSTKERR / MUNSKERR, when exception occurs in unprivileged software, and MPU is enabled:
On the exception entry, if the base address of allocated stack memory for the unprivileged software is NOT aligned to its stack size, then Cortex-M4 generates MemManage fault and MSTKERR field is set.
On the exception return, similarly if the base address of allocated stack memory is NOT aligned to its stack size, then Cortex-M4 generates MemManage fault and MUNSKERR field is set.
For example MPU_RASR.SIZE = 0x7 means the MPU region for the stack has size 2^(7+1) = 256 bytes , then MPU_RBAR.ADDR must be like 0x00000100 , 0x00000200 ... etc., otherwise Cortex-M4 generates corresponding MemManage fault immediately on exception entry/return.
For more information please read section 4.5.4 MPU Region Base Address Register in DUI0553 - Cortex ™ -M4 Devices Generic User Guide .

How does GDB restore instruction after breakpoint

I have read that GDB puts a int 3 (opcode CC) at the wanted adress in the target program memory.
Si this operation is erasing a piece of instruction (1 byte) in the program memory.
My question is: How and When GDB replaces the original opcode when the program continues ?
When i type disassemble in GDB, i do not see CC opcode. Is this because GDB knows it is him that puts the CC ?
Is there a way to do a raw disassemble, in order to see exactly what opcodes are loaded in memory at this instant ?
How and When GDB replaces the original opcode when the program continues ?
I use this as an interview question ;-)
On Linux, to continue past the breakpoint, 0xCC is replaced with the original instruction, and ptrace(PTRACE_SINGLESTEP, ...) is done. When the thread stops on the next instruction, original code is again replaced by the 0xCC opcode (to restore the breakpoint), and the thread continued on its merry way.
On x86 platforms that do not have PTRACE_SINGLESTEP, trap flag is set in EFLAGS via ptrace(PTRACE_SETREGS, ...) and the thread is continued. The trap flag causes the thread to immediately stop again (on the next instruction, just like PTRACE_SINGLESTEP would).
When i type disassemble in GDB, i do not see CC opcode. Is this because GDB knows it is him that puts the CC ?
Correct. A program could examine and print its own instruction stream, and you can observe breakpoint 0xCC opcodes that way.
Is there a way to do a raw disassemble, in order to see exactly what opcodes are loaded in memory at this instant ?
I don't believe there is. You can use (gdb) set debug infrun to observe what GDB is doing to the inferior (being debugged) process.
What i do not understand in fact is the exact role of SIGTRAP. Who is sending/receiving this signal ? The debugger or the target program?
Neither: after PTRACE_ATTACH, the kernel stops the inferior, then notifies the debugger that it has done so, by making debugger's wait return.
I see a wait(NULL) after the ptrace attach. What is the meaning of this wait?
See the explanation above.
Thread specific breakpoints?
For a thread-specific breakpoint, the debugger inserts a process-wide breakpoint (via 0xCC opcode), then simply immediately resumes any thread which hits the breakpoint, unless the thread is the specific one that you wanted to stop.

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.

How to handle this exception? (zero esp)

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".

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