Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #ifdef __i386__
- # include <linux/unistd.h>
- # include <asm/ldt.h>
- # include <sys/mman.h>
- # include <unistd.h>
- # include <sys/syscall.h>
- # include <errno.h>
- #else
- # include <asm/prctl.h>
- # include <sys/prctl.h>
- #endif
- int arch_prctl(int code, unsigned long addr);
- int test_func()
- {
- return (42);
- }
- int main()
- {
- #ifdef __i386__
- void *seg = mmap(NULL, getpagesize(), PROT_WRITE | PROT_READ,
- MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
- struct user_desc u_info;
- int val;
- ((void **)seg)[0x10 / sizeof(void *)] = &test_func;
- u_info.entry_number = 6;
- u_info.base_addr = (unsigned long)seg;
- u_info.limit = getpagesize();
- u_info.seg_32bit = 1;
- u_info.contents = MODIFY_LDT_CONTENTS_DATA;
- u_info.read_exec_only = 0;
- u_info.limit_in_pages = 0;
- u_info.seg_not_present = 0;
- u_info.useable = 1;
- val = (6 << 3 | 0 << 2 | 3);
- /* if a 32 bit program run on a 64 bit system, the first free gdt slot is 12
- * instead of 6 for 32 bit system.
- */
- if (syscall(SYS_set_thread_area, &u_info) < 0 && errno == EINVAL) {
- u_info.entry_number = 12;
- val = (12 << 3 | 0 << 2 | 3);
- if (syscall(SYS_set_thread_area, &u_info) < 0)
- puts("Fail");
- }
- __asm__ volatile ("mov %0, %%eax; \n\
- mov %0, %%fs; \n\
- call *%%fs:0x10; \n\
- mov $0x10, %%eax; \n\
- call *%%fs:(%%eax);" \
- : : "m" (val) : "eax");
- #else
- void (*funcs[10])();
- funcs[0x10 / sizeof(void *)] = (void *)&test_func;
- arch_prctl(ARCH_SET_GS, (unsigned long)funcs);
- __asm__ volatile ("call *%gs:0x10; \n\
- mov $0x10, %rax; \n\
- call *%gs:(%rax);");
- #endif
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement