By: chpie
2007. 2 - http://chpie.org/ (korean only)
source-code & test-binary is on my vault : 0x60_hook.zip
I love keyboard hook and this article shows you
the most fundamental level keyboard hook.
Everyone knows this
0x60 : keyboard scancode port
0x64 : keyboard status port
If you can monitoring 0x60 port's I/O,
the lowest level hooking is available.
Using processor debug facility, we can monitoring
system's I/O Address space.
pseudo code
DR(0 - 3) = specific I/O Address. (ex 0x60)
DR7.RWn = 10b ( I/O Address space trap )
DR7.LENn = 01b ( one-byte )
DR7.Gn = DR7.Ln = 01b ( DRn Break-point Enable)
But there are some problem.
When context-switching occurs, Windows have it's own
context structure which is different from processor architecture,
all debug-registers are modified immediately.
to prevent our debug register modified,
General-detect (debug facility) needed.
DR7.GD = 01b ( general-detect enable)
general-detect detects any attempt to modify debug registers
and when detect it, raise exception #DB.
general-detect is [ fault-class ] exception,
saved CS and EIP points to instruction caused exception.
mov dr0, eax -- exception occurs and EIP points to it.
to skip instruction, you just modify EIP on the stack.
when exception raised, processor saves some data like CALL instruction.
[ stack (not priviled switch) ]
EFLAGS
CS
EIP ---- we just added 0x3 to this
was saved on the stack.
- dispatch -
I/O address space trap is [ trap-class ] exception.
[code-stream]
nop
in 0x60, al
nop ------ Trap occurs next to the IN instruction.
IN instruction always communicate with device using EAX register,
and exception is trap-class,
you just take a EAX value to get the result of IN 0x60, AL instruction.
It is done, immortal I/O breakpoint was installed on your system!
On multi-processor environment, each processor have it's own Debug registers and IDT.
Multi-processor support code is available on the .http://rootkit.com/.
To call dpc's on the each processor, you can modify each debug registers easily.
Final keyboard hook
2007. 2 - http://chpie.org/ (korean only)
source-code & test-binary is on my vault : 0x60_hook.zip
I love keyboard hook and this article shows you
the most fundamental level keyboard hook.
Everyone knows this
0x60 : keyboard scancode port
0x64 : keyboard status port
If you can monitoring 0x60 port's I/O,
the lowest level hooking is available.
Using processor debug facility, we can monitoring
system's I/O Address space.
pseudo code
DR(0 - 3) = specific I/O Address. (ex 0x60)
DR7.RWn = 10b ( I/O Address space trap )
DR7.LENn = 01b ( one-byte )
DR7.Gn = DR7.Ln = 01b ( DRn Break-point Enable)
But there are some problem.
When context-switching occurs, Windows have it's own
context structure which is different from processor architecture,
all debug-registers are modified immediately.
to prevent our debug register modified,
General-detect (debug facility) needed.
DR7.GD = 01b ( general-detect enable)
general-detect detects any attempt to modify debug registers
and when detect it, raise exception #DB.
general-detect is [ fault-class ] exception,
saved CS and EIP points to instruction caused exception.
mov dr0, eax -- exception occurs and EIP points to it.
to skip instruction, you just modify EIP on the stack.
when exception raised, processor saves some data like CALL instruction.
[ stack (not priviled switch) ]
EFLAGS
CS
EIP ---- we just added 0x3 to this
was saved on the stack.
- dispatch -
I/O address space trap is [ trap-class ] exception.
[code-stream]
nop
in 0x60, al
nop ------ Trap occurs next to the IN instruction.
IN instruction always communicate with device using EAX register,
and exception is trap-class,
you just take a EAX value to get the result of IN 0x60, AL instruction.
It is done, immortal I/O breakpoint was installed on your system!
On multi-processor environment, each processor have it's own Debug registers and IDT.
Multi-processor support code is available on the .http://rootkit.com/.
To call dpc's on the each processor, you can modify each debug registers easily.