- What is a debugger?
- tracing the execution of a program
- interact with it
- Why os independent - ring0 ?
- userland debugger cannot debug kernel land so ring0 debugger
- userland debugger need to use os procedures to debug, so being ring0 allow being os independant
- Which x86 feature should be handled?
- interruptions/exceptions (faults, bp, ...), and erf... some input/output: keyboard/screen :)
- Nowadays os are in protected mode-> ring* (not real mode) pagination
- Core debugger
- inserting sw bp
- trap flag
- hw breakpoint
What is a debugger?
The best sentence that fits to programming: "errare humanum est" A debugger is there to correct those errors (note: a debugger can be buggy).
There are 2 debugger families: - debugger with source code - debugger *without* source code
We dont discuss of the first category here: too easy :)
The second one is often used to do reverse engineering, i.e. learning the behaviour of a program without its source.
Examples: Softice, Ollydbg, twr2000, ...
Difference between a debugger and a disassembler?
A debugger can show the behaviour of a program during its run time. This allows dynamic study. Disassembler allows the static study of the whole asm code of the target.
RR0D is a debugger.
Why os independent / why ring0 ?
The goal of rr0d was to do a generik debugger for x86.
Quick overview of the x86 mode:
- real mode: one processus that can control the whole processor and the whole memory.
- protected mode: (today's os mode)
- 4 level of segregation: ring 0 to 4
- the rule: a ring can only interfers with a ring less or egal as itself.
- a processus can only interfer in its memory mapping (in a perfect word by the way)
- only ring 0 can execute privilegied instructions
So, ring 0 rulez
This is why rr0d is in ring 0: in theory, it can debug everything.
A ring 3 debugger needs the help of he OS in order to reveive debug messages of the target. But what about ring 0 debugger ?
As we are on x86, we know how those messages are triggered: interruption & exceptions. This is os independant :)
So how to be perfectly OS independant ?
Which x86 feature should be handled ?
basics things we need to hook:
- int 3 for software breakpoint
- int 1 for step by step and hardware debugger
this should be enought to do a light debugger.
but if the program does div/0 or general protection fault?
optionnal interruptions we monitor (but not least):
- int 0: if the app does null division
- int 6: invalid opcode . the app exec non existing mnemonics
- int 13: general protection fault
- int 14 (semi) page fault
but some other should be monitored; for example:
- int 8: double fault
- int 12: stack exception
But rr0d is not finished yet! :)
What's next? - Mecanism of software breakpoint:
Why software breakpoints? - easy: only 4 HW breakpoints are not enought. did you already try to play piano with only 3 fingers? did you ever try to edit a text with vi?
How do they work? - installing a software breakpoint is just replacing an instruction we want a break on, by another insterrution that will trigger the debugger if its executed (and replace back the instruction).
- little automatum of software breakpoints*
But replacing instructions means replacing target memory We have to managed pagination to test properties of the page code (present, ...)
breakpiont remanent: mapping exec rdtsc