Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class __attribute__((packed)) interrupt_wrapper
- {
- using function_ptr = void(*)(unsigned);
- unsigned int_vector; // [eax-0x1C]
- selector ds; // [eax-0x18]
- selector es; // [eax-0x16]
- selector fs; // [eax-0x14]
- selector gs; // [eax-0x12]
- function_ptr entry_point; // [eax-0x10]
- std::array<byte, 0x40> code; // [eax-0x0C]
- public:
- interrupt_wrapper(unsigned vec, function_ptr f) : int_vector(vec), entry_point(f)
- {
- byte* start;
- std::size_t size;
- asm volatile (
- ".intel_syntax noprefix;"
- "jmp interrupt_wrapper_end%=;"
- // --- \/\/\/\/\/\/ --- //
- "interrupt_wrapper_begin%=:;" // On entry, the only known register is CS.
- "push ds; push es; push fs; push gs; pusha;" // 7 bytes
- "call get_eip%=;" // call near/relative (E8) // 5 bytes
- "get_eip%=: pop eax;" // Pop EIP into EAX and use it to find our vars
- "mov ds, cs:[eax-0x18];" // Restore segment registers
- "mov es, cs:[eax-0x16];"
- "mov fs, cs:[eax-0x14];"
- "mov gs, cs:[eax-0x12];"
- "push cs:[eax-0x1C];" // Pass our interrupt vector along
- "call cs:[eax-0x10];" // Call the entry point
- "add esp, 4;"
- "popa; pop gs; pop fs; pop es; pop ds;"
- "sti;" // IRET may or may not reset the interrupt flag.
- "iret;"
- "interrupt_wrapper_end%=:;"
- // --- /\/\/\/\/\/\ --- //
- "mov %0, offset interrupt_wrapper_begin%=;"
- "mov %1, offset interrupt_wrapper_end%=;"
- "sub %1, %0;"
- ".att_syntax prefix"
- : "=r" (start)
- , "=r" (size));
- assert(size <= code.size());
- auto* ptr = memory_descriptor(get_cs(), start).get_ptr<byte>();
- std::copy_n(ptr, size, code.data());
- asm volatile (
- ".intel_syntax noprefix;"
- "mov ax, ds;"
- "mov bx, es;"
- "mov cx, fs;"
- "mov dx, gs;"
- ".att_syntax prefix"
- : "=a" (ds)
- , "=b" (es)
- , "=c" (fs)
- , "=d" (gs));
- }
- auto get_ptr(selector cs) { return far_ptr32 { cs, reinterpret_cast<std::size_t>(code.data()) }; }
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement