Interrupt Debug Service (0×2D), Boot loader, Vista 64bits (On the fly)

 DebugPrint      proc near
                 mov     r9d, r8d
                 mov     r8d, edx
                 mov     dx, [rcx]
                 mov     rcx, [rcx+8]
                 mov     eax, 1
                 int     2Dh             ; Internal routine for MSDOS (IRET)
                 int     3               ; Trap to Debugger
                 retn
 DebugPrint      endp

 DebugPrompt     proc near
                 mov     r9w, [rdx+2]
                 mov     r8, [rdx+8]
                 mov     dx, [rcx]
                 mov     rcx, [rcx+8]
                 mov     eax, 2
                 int     2Dh             ; Internal routine for MSDOS (IRET)
                 int     3               ; Trap to Debugger
                 retn
 DebugPrompt     endp

 DebugService2   proc near
                 mov     eax, r8d
                 int     2Dh             ; Internal routine for MSDOS (IRET)
                 int     3               ; Trap to Debugger
                 retn
 DebugService2   endp

 BlBdStart+11C:
                 lea     rdx, [rsp+78h+var_28]
                 lea     rcx, [rsp+78h+var_58]
                 mov     r8d, 3
                 call    DebugService2

BlBdStop        proc near
                 lea     rdx, [rax-28h]
                 mov     r8d, 4
                 xor     ecx, ecx
		[...]
                 call    DebugService2

typedef enum _STATUS_DEBUG_SERVICE {
STATUS_PRINT = 1,
STATUS_PROMPT = 2,
STATUS_START = 3,
STATUS_STOP = 4
} STATUS_DEBUG_SERVICE;

Interrupts, Boot Loader, Vista 64bits (On the fly)

I’ve to do something to save me from idling while a software is rescuing my HDD.

That’s why I’m gonna write short post about the boot loader and the interrupts initialization.
By the way, I add a new category called “On the fly” for post like that which are more or less RCE Memento (interessting or not ::)).
If I had to explain it I’d answer “no blabla just code. don’t read but analyse.”

This article covers where the interrupts 0×1, 0×3, 0×6, 0xD, 0xE, 0×2C, 0×2D are initialized inside the bootloader.

For reminding, I’ve rewritten some things :

//
// 63                             32            16               0
// +------------------------------+------------------------------+
// +           OffsetLow          +   HighLow    +   HighHigh    +
// +------------------------------+------------------------------+
//

typedef struct _KIDT_ENTRY {     // (sizeof=0x10)
	unsigned short wOffsetHighHigh;  // +0x00
	unsigned short Reserved02;       // +0x02
	unsigned short Reserved04;       // +0x04
	unsigned short wOffsetHighLow;   // +0x06
	unsigned long dwOffsetLow;       // +0x08
	unsigned long Reserved0C;        // +0x0C
} KIDT_ENTRY;

typedef enum _INTERRUPT_ID{
    NONE=-1,
   DIVIDE_ERROR=0,			// 0x00
   SINGLE_STEP,				// 0x01
   NMI_INTERRUPT,				// 0x02
   BREAKPOINT,				// 0x03
   OVERFLOW,				// 0x04
   BOUND,					// 0x05
   INVALID_OPCODE,			// 0x6
   NPX_NOT_AVAILABLE,			// 0x07
   DOUBLE_FAULT,				// 0x08
   NPX_SEGMENT_OVERRUN,			// 0x09
   INVALID_TSS,				// 0x0A
   SEGMENT_NOT_PRESENT,			// 0x0B
   STACK,					// 0x0C
   GENERAL_PROTECTION,			// 0x0D
   PAGE,					// 0x0E
   RESERVED,				// 0x0F
   FLOATING_ERROR,			// 0x10
   ALIGNMENT,				// 0x11
   MACHINE_CHECK,				// 0x12
   XMM_EXCEPTION,				// 0x13
   //
   // Other Critical Interrupts
   //
   APC=0x1F,				// 0x1F
   RAISE_ASSERTION=0x2C,		// 0x2C
   DEBUG_SERVICE=0x2D,			// 0x2D
   DPC=0x2F,				// 0x2F
   IPI=0xE1					// 0xE1
} INTERRUPT_ID;

Firstly, we have to know these to function inside the “.text” section.


Function : ArchGetIdtRegister
XREF: BdInstallTrapVectors, BlpArchInitialize

ArchGetIdtRegister proc near
                 sidt    qword ptr [rcx]
                 retn
ArchGetIdtRegister endp

Function : ArchSetIdtRegister
XREF: BdInstallTrapVectors, BlpArchInitialize

ArchSetIdtRegister proc near
                 lidt    qword ptr [rcx]
                 retn
ArchGetIdtRegister endp

Let’s look at the XREF’s functions.

BdInstallTrapVectors

BdInstallTrapVectors proc near          ; CODE XREF: BlBdInitialize+20D

 var_18          = qword ptr -18h

                 sub     rsp, 38h
                 lea     rcx, [rsp+38h+var_18]
                 call    ArchGetIdtRegister
                 mov     r11, [rsp+38h+var_18+2]
                 mov     r9w, 10h
                 mov     [r11+12h], r9w
                 mov     r8w, 8E00h
                 lea     rax, BdTrap01
                 mov     [r11+10h], ax   ; 0x10/(16 = sizeof(_KIDT_ENTRY)) = 0x1
                 mov     [r11+14h], r8w
                 mov     rcx, rax
                 shr     rcx, 10h
                 shr     rax, 20h
                 mov     [r11+16h], cx
                 mov     [r11+18h], eax
                 mov     rdx, [rsp+38h+var_18+2]
                 mov     [rdx+32h], r9w
                 mov     [rdx+34h], r8w
                 lea     rax, BdTrap03
                 mov     [rdx+30h], ax   ; 0x30/(16 = sizeof(_KIDT_ENTRY)) = 0x3
                 mov     rcx, rax
                 shr     rax, 20h
                 mov     [rdx+38h], eax
                 shr     rcx, 10h
                 lea     rax, BdTrap0d
                 mov     [rdx+36h], cx
                 mov     rdx, [rsp+38h+var_18+2]
                 mov     rcx, rax
                 mov     [rdx+0D0h], ax  ; 0x0D/(16 = sizeof(_KIDT_ENTRY)) = 0x0D
                 mov     [rdx+0D2h], r9w
                 mov     [rdx+0D4h], r8w
                 shr     rcx, 10h
                 shr     rax, 20h
                 mov     [rdx+0D6h], cx
                 mov     [rdx+0D8h], eax
                 mov     rdx, [rsp+38h+var_18+2]
                 mov     [rdx+0E2h], r9w
                 mov     [rdx+0E4h], r8w
                 lea     rax, BdTrap0e
                 mov     [rdx+0E0h], ax  ; 0xE0/(16 = sizeof(_KIDT_ENTRY)) = 0x0E
                 mov     rcx, rax
                 shr     rax, 20h
                 mov     [rdx+0E8h], eax
                 shr     rcx, 10h
                 lea     rax, BdTrap2c
                 mov     [rdx+0E6h], cx
                 mov     rdx, [rsp+38h+var_18+2]
                 mov     rcx, rax
                 mov     [rdx+2C0h], ax  ; 0x2C0/(16 = sizeof(_KIDT_ENTRY)) = 0x2C
                 mov     [rdx+2C2h], r9w
                 mov     [rdx+2C4h], r8w
                 shr     rcx, 10h
                 shr     rax, 20h
                 mov     [rdx+2C6h], cx
                 mov     [rdx+2C8h], eax
                 mov     rdx, [rsp+38h+var_18+2]
                 lea     rax, BdTrap2d
                 mov     [rdx+2D2h], r9w
                 mov     [rdx+2D4h], r8w
                 mov     rcx, rax
                 mov     [rdx+2D0h], ax  ; 0x2D0/(16 = sizeof(_KIDT_ENTRY)) = 0x2D
                 shr     rax, 20h
                 shr     rcx, 10h
                 mov     [rdx+2D8h], eax
                 mov     [rdx+2D6h], cx
                 lea     rcx, [rsp+38h+var_18]
                 call    ArchSetIdtRegister
                 add     rsp, 38h
                 retn
BdInstallTrapVectors endp

InitializeLibrary

BlpArchInitialize proc near             ; CODE XREF: InitializeLibrary+12A

 IdtEntry        = qword ptr -18h

                 sub     rsp, 38h

                 cmp     ecx, 1
                 jnz     _exit

                 lea     rcx, [rsp+38h+IdtEntry]
                 call    ArchGetIdtRegister
                 mov     r11, [rsp+38h+IdtEntry+2]
                 lea     rax, ArchTrapNoProcess
                 mov     [r11+30h], ax   ; 0x30/(16 = sizeof(_KIDT_ENTRY)) = 0x3
                 mov     word ptr [r11+32h], 10h
                 mov     word ptr [r11+34h], 8E00h
                 mov     r8, rax
                 mov     rdx, rax
                 shr     r8, 10h
                 shr     rdx, 20h
                 mov     [r11+36h], r8w
                 mov     [r11+38h], edx
                 mov     rcx, [rsp+38h+IdtEntry+2]
                 mov     [rcx+2C0h], ax  ; 0x2C0/(16 = sizeof(_KIDT_ENTRY)) = 0x2C
                 mov     [rcx+2C6h], r8w
                 mov     [rcx+2C8h], edx
                 mov     word ptr [rcx+2C2h], 10h
                 mov     word ptr [rcx+2C4h], 8E00h
                 mov     rcx, [rsp+38h+IdtEntry+2]
                 mov     [rcx+2D0h], ax  ; 0x2D0/(16 = sizeof(_KIDT_ENTRY)) = 0x2D
                 mov     [rcx+2D6h], r8w
                 mov     [rcx+2D8h], edx
                 mov     word ptr [rcx+2D2h], 10h
                 mov     word ptr [rcx+2D4h], 8E00h
                 lea     rcx, [rsp+38h+IdtEntry]
                 call    ArchSetIdtRegister

 _exit:
                 xor     eax, eax
                 add     rsp, 38h
                 retn

BlpArchInitialize endp