Quote:
Originally posted by binh81
Can someone provide me some links discussing the Interrupt Vector Table structure (aka the format layout) and perhaps some reading about interrupt handling and setting etc... I am getting annoyed by all this anti tracing trick :<<... guess i have to pick it up anyway.... |
Hiya,
I'll have a go at answering your question due to the fact, I've had the need to hook interrupts in the project I've been working on with Kayaker. With this said, I'm really a complete newbie on these topics so I'll appreciate it if anyone with a good grasp of systems level programming sees fit to patch up any holes in my current understanding of these matters.
There are actually 2 internal structures used by the processor for interrupt handling. The first is the Interrupt Vector Table (IVT) which is used in Real Mode. It consists of 4 byte entries containing far pointers to the interrupt handler procedures. The second table, called the Interrupt Descriptor Table, is used for handling interrupts in Protected Mode. In contrast the the IVT, the IDT consists of 8 byte descriptors which contain the segment and offset address of the interrupt service routine. Interestingly, the IDT is relocatable.
The ASM instructions for dealing with the IDT are the LIDT and SIDT commands. The SIDT (store interrupt descriptor table) command loads the size and location of the interrupt descriptor into an fword (6 byte) variable. If hooking an interrupt, you will use this command to get the base location of the interrupt descriptor table. The descriptors for each interrupt are indexed as offsets from this address.
For example, the INT 3 descriptor would be located at:
Base_IDT_Address (obtained from SIDT command) +[ 8 (size of each descriptor) * 3 (interrupt number)]
For the actual strucure of the descriptors, I'll refer you to an excellent doc which I'm attaching to this post... A picture really is worth a thousand words here
Similarly, one might use the LIDT (load interrupt descriptor table) to relocate the interrupt descriptor table or to change it's size. When I was reasearching this, I found it intriguing that one might actually enlarge the interrupt descriptor table to create their own "user defined" interrupts above and beyond the normal 256.
It is also important to note that ones interrupt service routine (ISR) needs to reside in non-pagable memory, in a locked code segment inside a VxD. Heh, hooking the IDT so it calls your handler is the easy part

...It's *inside* the ISR that the real fun begins... LOL, I've been finding this out the hard way recently. First, you have the issue of reentrancy. This can be partially solved by disabling interrupts around critical code sections using the cli instruction and by using dynamcially allocated variables. Beyond reentrancy, synchronization issues rear their ugly heads... For example, its impossible to do file I/O or memory allocation in the context of an interrupt handler. In such cases, it may be necessary to schedule an "event callback" to do this type of processing for you. In a real-time situation this synchronization is a *nightmare*. As far as I can tell, you're not guaranteed the VMM will even execute your event callbacks sequentially and the usage of synchronization structures like Sempahores and Mutexes appear to be questionable in context of an ISR. Indeed, the only safe functions to call are those labled as "asynchronous" in the documentation. Beyond these restrictions, it is desirable to keep your ISR as short and optomized as possilbe. Did I mention how much "fun" debugging an ISR with asynchronous callbacks can be

Sorry, if I got of on a tangent here... Maybe this last stuff is not related to "cracking" per se, but I'm just discovering these "fun" synchronization problems so I thought I'd note them while they're fresh in my mind.
Anyway, here's part of my VxD's ISR routine which you can use as an example to see how an interrupt is hooked.
;================================Begin Hook_INT Proc==================================
BeginProc Hook_INT
;-------------------------------------------------------------------------
; Assume ebx contains the # of the interrupt you want to hook and edx
; contains a pointer to the new interrupt handler procedure you want to
; install.
;-------------------------------------------------------------------------
;INT 1
pushad ; save registers
;--------------------------------------------------
; SIDT stores the Interrupt Descriptor Table (IDT)
; Register into the specified operand
;--------------------------------------------------
sidt IDTR ; IDTR is variable to hold base address of IDT
;------------------------------------------------
; Get index into IDT for the int we want to hook
;------------------------------------------------
push edx ;save handler address
mov eax, 08h ; mov 08 multiplier in eax
mul dword ptr ebx ; mul with interrupt number in ebx
add eax, dword ptr [IDTR+2] ; add to base address of IDT + 2 bytes
; offset of INT x handler in eax
;------------------------------------------------
; Save the original INT handler
;------------------------------------------------
push ebx
mov ebx, Index
pop IntNumber[ebx] ; save interrupt # for lookup of handler later
mov cx,[eax+06h] ; get the low word part of the offset from the IDT
shl ecx,010h ; shift into high word position in register
mov cx,[eax] ; get the high word part of the offset from the IDT
push ecx
pop SaveOldInt[ebx] ; save old INT handler
add Index,4 ;increment index to point to next location in arrays
;-------------------------------------------------
; Replace original INT handler with our new one
;-------------------------------------------------
pop edx
cli ; ignore maskable external interrupts
mov [eax],dx ; modify the high word part of the offset
shr edx,010h ; shift into low word position in register
mov [eax+6],dx ; modify the low word part of the offset
sti ; resume responding to interrupts
clc
popad
mov eax, 1 ; if got here return TRUE
ret
EndProc Hook_INT
;==================================End Hook_INT Proc==================================
Hope this answers part of your question...
Cheers,
Clandestiny
PS. If you email me, I'll be happy to send you my "research" on the IDT, ISR's, reentrancy, and synchronization issues.