DivideError: (ISR)

push ebp
mov ebp,esp
mov eax,dword ptr ss:;EFLAGS zeroed out
mov Startflags,eax
mov eax,dword ptr ss: ; got address here
add eax,02h
mov dword ptr ss:,eax
pop ebp
mov eax, dword ptr ss: ;good EIP
mov GoodEIP,eax
pop edx ;flags
pop ecx ;CS
pop eax ;EIP changed here
mov eax,GoodEIP
jmp eax

In this sub routine we understand that the data segment and the stack segment are the same selector, selector 10h in a driver. Selector 10h is the operating systems global data selector with a base address of 0h and full limit of FFFFFFh. Also the stack grow upwards because it is also the data segment. Being that the handler is in the same code segment as the process, we cannot do a far return as is necessary to pop the Eflags/CS/EIP off the stack. So it must be done manually as shown above. The scheduler triggered by timer interrupt will attempt to alter the EIP which is why you must get it early and store it.

push ecx ; save selector, ecx value of 10h(the data selector)
push ebp ; A way of storing information
push esp ; on the stack
pop ebp
xor ecx,ecx
xor edx,edx
push ecx
push edx
SIDT ss: ; Store IDT address and seg. limit on stack
pop edx ; high word
pop ecx ; low word
pop ebp
mov eax,edx
shr eax,010h
shl ecx,010h
or eax,ecx ; IDT address now in "eax"
mov IDTbase,eax
pop ecx

Now we have interrupt vecter table address

mov edi,IDTbase
push ds
mov ds,cx
mov eax, dword ptr ds: ;High word of 8 bytes
mov HwordDiv,eax
mov eax, dword ptr ds: ;IDT base + 00=
mov LwordDiv,eax ;Divide Error Exception
push ebx
xor ebx,ebx
push cs
pop ebx ;*
ror eax,010h
cmp bx,ax ; See if same CS selector
jnz NoGo
mov eax,DivideError ; location of new ISR
push ecx
mov ecx,LwordDiv
mov cx,ax
mov dword ptr ds:,ecx
mov ecx,HwordDiv
ror ecx,010h
shr eax,010h
mov cx,ax
rol ecx,010h
mov dword ptr ds:,ecx
pop ecx
pop ebx
pop ds

Here we replaced the Divide by zero interrupt vector with a pointer to the ISR which resides in current code segment. The divide by zero interrupt or exception is offset zero in the IDT with each entry being two dwords or 64 bits (8 bytes)

push ebx
xor edx,edx
mov eax,00000002h
mov ebx,00000000h ; divide by zero
div ebx
nop
nop
nop
nop
PopEBX:
pop ebx

Lastely we try it out
Posted on 2003-09-20 07:23:56 by mrgone