Skip to content

Instantly share code, notes, and snippets.

@andreiw
Created February 8, 2016 20:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save andreiw/54fe5acdebe1330d0ca7 to your computer and use it in GitHub Desktop.
Save andreiw/54fe5acdebe1330d0ca7 to your computer and use it in GitHub Desktop.
x64 override idt handlers in existing system (useful for UEFI)
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);
}
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");
}
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