Created
February 8, 2016 20:07
-
-
Save andreiw/54fe5acdebe1330d0ca7 to your computer and use it in GitHub Desktop.
x64 override idt handlers in existing system (useful for UEFI)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void c_gate_entry(uint64_t *regs) | |
{ | |
uint64_t gate = regs[15]; | |
unsigned ix = 0; | |
uint64_t pc; | |
uint64_t sp; | |
uint64_t cr2; | |
warn("Gate = 0x%lx", gate); | |
warn("----------------------"); | |
warn("rax = 0x%lx", regs[ix++]); | |
warn("rcx = 0x%lx", regs[ix++]); | |
warn("rdx = 0x%lx", regs[ix++]); | |
warn("rbx = 0x%lx", regs[ix++]); | |
warn("rbp = 0x%lx", regs[ix++]); | |
warn("rsi = 0x%lx", regs[ix++]); | |
warn("rdi = 0x%lx", regs[ix++]); | |
warn("r8 = 0x%lx", regs[ix++]); | |
warn("r9 = 0x%lx", regs[ix++]); | |
warn("r10 = 0x%lx", regs[ix++]); | |
warn("r11 = 0x%lx", regs[ix++]); | |
warn("r12 = 0x%lx", regs[ix++]); | |
warn("r13 = 0x%lx", regs[ix++]); | |
warn("r14 = 0x%lx", regs[ix++]); | |
warn("r15 = 0x%lx", regs[ix++]); | |
/* skip over gate */ | |
ix++; | |
switch (gate) { | |
case 8: | |
case 10: | |
case 11: | |
case 12: | |
case 13: | |
case 14: | |
case 17: | |
warn("error code = 0x%lx", regs[ix++]); | |
} | |
pc = regs[ix++]; | |
warn("RIP = 0x%lx", pc); | |
warn("CS = 0x%lx", regs[ix++]); | |
warn("RFLAGS = 0x%lx", regs[ix++]); | |
sp = regs[ix++]; | |
warn("RSP = 0x%lx", sp); | |
warn("SS = 0x%lx", regs[ix++]); | |
__asm__ __volatile__("mov %%cr2, %0" | |
: "=r" (cr2)); | |
warn("CR2 = 0x%lx", cr2); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
typedef struct { | |
uint16_t limit; | |
uint64_t offset; | |
} desc __attribute__((packed)); | |
typedef struct { | |
uint64_t off_0_15 : 16; | |
uint64_t seg : 16; | |
uint64_t ist : 3; | |
uint64_t rsvd_0 : 5; | |
uint64_t type : 5; | |
uint64_t dpl : 2; | |
uint64_t p : 1; | |
uint64_t off_16_31 : 16; | |
uint64_t off_32_63 : 32; | |
uint64_t rsvd_1 : 32; | |
} gate; | |
extern void *idt_gate3; | |
void override_exc(void) | |
{ | |
desc d; | |
gate *idt; | |
uint64_t addr; | |
__asm__ __volatile__("sidt %0" : "=m" (d)); | |
warn("IDT is 0x%x at 0x%lx", d.limit, d.offset); | |
idt = (gate *) d.offset; | |
// inherit the rest from running system | |
addr = (uint64_t) &idt_gate3; | |
idt[3].off_0_15 = addr & 0xffff; | |
idt[3].off_16_31 = (addr >> 16) & 0xffff; | |
idt[3].off_32_63 = addr >> 32; | |
// enter our trap handler c_gate_entry | |
__asm__ __volatile__ ("int $3"); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
EXTERN c_gate_entry | |
gate_entry: | |
push r15 | |
push r14 | |
push r13 | |
push r12 | |
push r11 | |
push r10 | |
push r9 | |
push r8 | |
push rdi | |
push rsi | |
push rbp | |
push rbx | |
push rdx | |
push rcx | |
push rax | |
mov rdi, rsp | |
call c_gate_entry | |
jmp $ | |
%macro gen_gate 2 ; label gate | |
GLOBAL %1 | |
%1: | |
push qword %2 | |
jmp gate_entry | |
%endmacro | |
GLOBAL IdtStart | |
GLOBAL IdtEnd | |
ALIGN 4096 | |
IdtStart: | |
gen_gate idt_gate0, 0 | |
gen_gate idt_gate1, 1 | |
gen_gate idt_gate2, 2 | |
gen_gate idt_gate3, 3 | |
gen_gate idt_gate4, 4 | |
gen_gate idt_gate5, 5 | |
gen_gate idt_gate6, 6 | |
gen_gate idt_gate7, 7 | |
gen_gate idt_gate8, 8 | |
gen_gate idt_gate9, 9 | |
gen_gate idt_gate10,10 | |
gen_gate idt_gate11,11 | |
gen_gate idt_gate12,12 | |
gen_gate idt_gate13,13 | |
gen_gate idt_gate14,14 | |
gen_gate idt_gate15,15 | |
gen_gate idt_gate16,16 | |
gen_gate idt_gate17,17 | |
gen_gate idt_gate18,18 | |
gen_gate idt_gate19,19 | |
gen_gate idt_gate20,20 | |
gen_gate idt_gate21,21 | |
IdtEnd: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment