My goal is to access the IDT from a MacOS kernel module.
I'm running macOS 10.13.2 under VMFusion 10.0.1, and it seems like the sidt
assembly command points to corrupted table structure.
This opcode should return the address to "Interrupt Descriptor Table" which holds the descriptors for each interrupt.
Each interrupt contain pointer for callback function that should be called when a specific interrupt is called.
For example, here are 2 interrupt descriptor that points to valid callbacks from kernel __TEXT section in previous older versions.
- int3 points to idt64_int3
- int80 points to idt64_unix_scall
etc...
For some reason, starting from high Sierra 10.13.2, the sidt
return memory range that doesn't contain valid pointers (all are outside the boundary of the kernel __TEXT
section). perhaps there's another way of getting the table pointer ?
here's my source code for finding the idt pointer:
unsigned char idt_out[10];
__asm__ volatile ("sidt %0": "=m" (idt_out));
// skip the first 2 bytes as they are not part of the address
uint64_t idt_address = *((unsigned long long *)(idt_out+2));
printf("idt address is %llx \n", idt_address);
int80_desc = (struct descriptor_idt*)(idt_address + sizeof(struct idt_desc)*0x80);
int80_address = (mach_vm_address_t)(((unsigned long)int80_desc->offset_high << 32) + ((unsigned int)int80_desc->offset_middle << 16) + int80_descriptor->offset_low); // this should point to idt64_unix_scall