⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test-i386.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 5 页
字号:
{    r->esp = (r->esp & ~0xffff) | ((r->esp - 2) & 0xffff);    *(uint16_t *)seg_to_linear(r->ss, r->esp) = val;}#undef __syscall_return#define __syscall_return(type, res) \do { \	return (type) (res); \} while (0)_syscall2(int, vm86, int, func, struct vm86plus_struct *, v86)extern char vm86_code_start;extern char vm86_code_end;#define VM86_CODE_CS 0x100#define VM86_CODE_IP 0x100void test_vm86(void){    struct vm86plus_struct ctx;    struct vm86_regs *r;    uint8_t *vm86_mem;    int seg, ret;    vm86_mem = mmap((void *)0x00000000, 0x110000,                     PROT_WRITE | PROT_READ | PROT_EXEC,                     MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);    if (vm86_mem == MAP_FAILED) {        printf("ERROR: could not map vm86 memory");        return;    }    memset(&ctx, 0, sizeof(ctx));    /* init basic registers */    r = &ctx.regs;    r->eip = VM86_CODE_IP;    r->esp = 0xfffe;    seg = VM86_CODE_CS;    r->cs = seg;    r->ss = seg;    r->ds = seg;    r->es = seg;    r->fs = seg;    r->gs = seg;    r->eflags = VIF_MASK;    /* move code to proper address. We use the same layout as a .com       dos program. */    memcpy(vm86_mem + (VM86_CODE_CS << 4) + VM86_CODE_IP,            &vm86_code_start, &vm86_code_end - &vm86_code_start);    /* mark int 0x21 as being emulated */    set_bit((uint8_t *)&ctx.int_revectored, 0x21);    for(;;) {        ret = vm86(VM86_ENTER, &ctx);        switch(VM86_TYPE(ret)) {        case VM86_INTx:            {                int int_num, ah, v;                                int_num = VM86_ARG(ret);                if (int_num != 0x21)                    goto unknown_int;                ah = (r->eax >> 8) & 0xff;                switch(ah) {                case 0x00: /* exit */                    goto the_end;                case 0x02: /* write char */                    {                        uint8_t c = r->edx;                        putchar(c);                    }                    break;                case 0x09: /* write string */                    {                        uint8_t c, *ptr;                        ptr = seg_to_linear(r->ds, r->edx);                        for(;;) {                            c = *ptr++;                            if (c == '$')                                break;                            putchar(c);                        }                        r->eax = (r->eax & ~0xff) | '$';                    }                    break;                case 0xff: /* extension: write eflags number in edx */                    v = (int)r->edx;#ifndef LINUX_VM86_IOPL_FIX                    v &= ~0x3000;#endif                    printf("%08x\n", v);                    break;                default:                unknown_int:                    printf("unsupported int 0x%02x\n", int_num);                    goto the_end;                }            }            break;        case VM86_SIGNAL:            /* a signal came, we just ignore that */            break;        case VM86_STI:            break;        default:            printf("ERROR: unhandled vm86 return code (0x%x)\n", ret);            goto the_end;        }    } the_end:    printf("VM86 end\n");    munmap(vm86_mem, 0x110000);}#endif/* exception tests */#if defined(__i386__) && !defined(REG_EAX)#define REG_EAX EAX#define REG_EBX EBX#define REG_ECX ECX#define REG_EDX EDX#define REG_ESI ESI#define REG_EDI EDI#define REG_EBP EBP#define REG_ESP ESP#define REG_EIP EIP#define REG_EFL EFL#define REG_TRAPNO TRAPNO#define REG_ERR ERR#endif#if defined(__x86_64__)#define REG_EIP REG_RIP#endifjmp_buf jmp_env;int v1;int tab[2];void sig_handler(int sig, siginfo_t *info, void *puc){    struct ucontext *uc = puc;    printf("si_signo=%d si_errno=%d si_code=%d",           info->si_signo, info->si_errno, info->si_code);    printf(" si_addr=0x%08lx",           (unsigned long)info->si_addr);    printf("\n");    printf("trapno=" FMTLX " err=" FMTLX,           (long)uc->uc_mcontext.gregs[REG_TRAPNO],           (long)uc->uc_mcontext.gregs[REG_ERR]);    printf(" EIP=" FMTLX, (long)uc->uc_mcontext.gregs[REG_EIP]);    printf("\n");    longjmp(jmp_env, 1);}void test_exceptions(void){    struct sigaction act;    volatile int val;        act.sa_sigaction = sig_handler;    sigemptyset(&act.sa_mask);    act.sa_flags = SA_SIGINFO | SA_NODEFER;    sigaction(SIGFPE, &act, NULL);    sigaction(SIGILL, &act, NULL);    sigaction(SIGSEGV, &act, NULL);    sigaction(SIGBUS, &act, NULL);    sigaction(SIGTRAP, &act, NULL);    /* test division by zero reporting */    printf("DIVZ exception:\n");    if (setjmp(jmp_env) == 0) {        /* now divide by zero */        v1 = 0;        v1 = 2 / v1;    }#if !defined(__x86_64__)    printf("BOUND exception:\n");    if (setjmp(jmp_env) == 0) {        /* bound exception */        tab[0] = 1;        tab[1] = 10;        asm volatile ("bound %0, %1" : : "r" (11), "m" (tab[0]));    }#endif#ifdef TEST_SEGS    printf("segment exceptions:\n");    if (setjmp(jmp_env) == 0) {        /* load an invalid segment */        asm volatile ("movl %0, %%fs" : : "r" ((0x1234 << 3) | 1));    }    if (setjmp(jmp_env) == 0) {        /* null data segment is valid */        asm volatile ("movl %0, %%fs" : : "r" (3));        /* null stack segment */        asm volatile ("movl %0, %%ss" : : "r" (3));    }    {        struct modify_ldt_ldt_s ldt;        ldt.entry_number = 1;        ldt.base_addr = (unsigned long)&seg_data1;        ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12;        ldt.seg_32bit = 1;        ldt.contents = MODIFY_LDT_CONTENTS_DATA;        ldt.read_exec_only = 0;        ldt.limit_in_pages = 1;        ldt.seg_not_present = 1;        ldt.useable = 1;        modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */                if (setjmp(jmp_env) == 0) {            /* segment not present */            asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1)));        }    }#endif    /* test SEGV reporting */    printf("PF exception:\n");    if (setjmp(jmp_env) == 0) {        val = 1;        /* we add a nop to test a weird PC retrieval case */        asm volatile ("nop");        /* now store in an invalid address */        *(char *)0x1234 = 1;    }    /* test SEGV reporting */    printf("PF exception:\n");    if (setjmp(jmp_env) == 0) {        val = 1;        /* read from an invalid address */        v1 = *(char *)0x1234;    }        /* test illegal instruction reporting */    printf("UD2 exception:\n");    if (setjmp(jmp_env) == 0) {        /* now execute an invalid instruction */        asm volatile("ud2");    }    printf("lock nop exception:\n");    if (setjmp(jmp_env) == 0) {        /* now execute an invalid instruction */        asm volatile("lock nop");    }        printf("INT exception:\n");    if (setjmp(jmp_env) == 0) {        asm volatile ("int $0xfd");    }    if (setjmp(jmp_env) == 0) {        asm volatile ("int $0x01");    }    if (setjmp(jmp_env) == 0) {        asm volatile (".byte 0xcd, 0x03");    }    if (setjmp(jmp_env) == 0) {        asm volatile ("int $0x04");    }    if (setjmp(jmp_env) == 0) {        asm volatile ("int $0x05");    }    printf("INT3 exception:\n");    if (setjmp(jmp_env) == 0) {        asm volatile ("int3");    }    printf("CLI exception:\n");    if (setjmp(jmp_env) == 0) {        asm volatile ("cli");    }    printf("STI exception:\n");    if (setjmp(jmp_env) == 0) {        asm volatile ("cli");    }#if !defined(__x86_64__)    printf("INTO exception:\n");    if (setjmp(jmp_env) == 0) {        /* overflow exception */        asm volatile ("addl $1, %0 ; into" : : "r" (0x7fffffff));    }#endif    printf("OUTB exception:\n");    if (setjmp(jmp_env) == 0) {        asm volatile ("outb %%al, %%dx" : : "d" (0x4321), "a" (0));    }    printf("INB exception:\n");    if (setjmp(jmp_env) == 0) {        asm volatile ("inb %%dx, %%al" : "=a" (val) : "d" (0x4321));    }    printf("REP OUTSB exception:\n");    if (setjmp(jmp_env) == 0) {        asm volatile ("rep outsb" : : "d" (0x4321), "S" (tab), "c" (1));    }    printf("REP INSB exception:\n");    if (setjmp(jmp_env) == 0) {        asm volatile ("rep insb" : : "d" (0x4321), "D" (tab), "c" (1));    }    printf("HLT exception:\n");    if (setjmp(jmp_env) == 0) {        asm volatile ("hlt");    }    printf("single step exception:\n");    val = 0;    if (setjmp(jmp_env) == 0) {        asm volatile ("pushf\n"                      "orl $0x00100, (%%esp)\n"                      "popf\n"                      "movl $0xabcd, %0\n"                       "movl $0x0, %0\n" : "=m" (val) : : "cc", "memory");    }    printf("val=0x%x\n", val);}#if !defined(__x86_64__)/* specific precise single step test */void sig_trap_handler(int sig, siginfo_t *info, void *puc){    struct ucontext *uc = puc;    printf("EIP=" FMTLX "\n", (long)uc->uc_mcontext.gregs[REG_EIP]);}const uint8_t sstep_buf1[4] = { 1, 2, 3, 4};uint8_t sstep_buf2[4];void test_single_step(void){    struct sigaction act;    volatile int val;    int i;    val = 0;    act.sa_sigaction = sig_trap_handler;    sigemptyset(&act.sa_mask);    act.sa_flags = SA_SIGINFO;    sigaction(SIGTRAP, &act, NULL);    asm volatile ("pushf\n"                  "orl $0x00100, (%%esp)\n"                  "popf\n"                  "movl $0xabcd, %0\n"                   /* jmp test */                  "movl $3, %%ecx\n"                  "1:\n"                  "addl $1, %0\n"                  "decl %%ecx\n"                  "jnz 1b\n"                  /* movsb: the single step should stop at each movsb iteration */                  "movl $sstep_buf1, %%esi\n"                  "movl $sstep_buf2, %%edi\n"                  "movl $0, %%ecx\n"                  "rep movsb\n"                  "movl $3, %%ecx\n"                  "rep movsb\n"                  "movl $1, %%ecx\n"                  "rep movsb\n"                  /* cmpsb: the single step should stop at each cmpsb iteration */                  "movl $sstep_buf1, %%esi\n"                  "movl $sstep_buf2, %%edi\n"                  "movl $0, %%ecx\n"                  "rep cmpsb\n"                  "movl $4, %%ecx\n"                  "rep cmpsb\n"                                    /* getpid() syscall: single step should skip one                     instruction */                  "movl $20, %%eax\n"                  "int $0x80\n"                  "movl $0, %%eax\n"                                    /* when modifying SS, trace is not done on the next                     instruction */                  "movl %%ss, %%ecx\n"                  "movl %%ecx, %%ss\n"                  "addl $1, %0\n"                  "movl $1, %%eax\n"                  "movl %%ecx, %%ss\n"                  "jmp 1f\n"                  "addl $1, %0\n"                  "1:\n"                  "movl $1, %%eax\n"                  "pushl %%ecx\n"                  "popl %%ss\n"                  "addl $1, %0\n"                  "movl $1, %%eax\n"                                    "pushf\n"                  "andl $~0x00100, (%%esp)\n"                  "popf\n"                  : "=m" (val)                   :                   : "cc", "memory", "eax", "ecx", "esi", "edi");    printf("val=%d\n", val);    for(i = 0; i < 4; i++)        printf("sstep_buf2[%d] = %d\n", i, sstep_buf2[i]);}/* self modifying code test */uint8_t code[] = {    0xb8, 0x1, 0x00, 0x00, 0x00, /* movl $1, %eax */    0xc3, /* ret */};asm("smc_code2:\n"    "movl 4(%esp), %eax\n"    "movl %eax, smc_patch_addr2 + 1\n"    "nop\n"    "nop\n"    "nop\n"    "nop\n"    "nop\n"    "nop\n"    "nop\n"    "nop\n"    "smc_patch_addr2:\n"    "movl $1, %eax\n"    "ret\n");typedef int FuncType(void);extern int smc_code2(int);void test_self_modifying_code(void){    int i;    printf("self modifying code:\n");    printf("func1 = 0x%x\n", ((FuncType *)code)());    for(i = 2; i <= 4; i++) {        code[1] = i;        printf("func%d = 0x%x\n", i, ((FuncType *)code)());    }    /* more difficult test : the modified code is just after the       modifying instruction. It is forbidden in Intel specs, but it       is used by old DOS programs */    for(i = 2; i <= 4; i++) {        printf("smc_code2(%d) = %d\n", i, smc_code2(i));    }}#endiflong enter_stack[4096];#if defined(__x86_64__)#define RSP "%%rsp"#define RBP "%%rbp"#else#define RSP "%%esp"#define RBP "%%ebp"#endif#define TEST_ENTER(size, stack_type, level)\{\    long esp_save, esp_val, ebp_val, ebp_save, i;\    stack_type *ptr, *stack_end, *stack_ptr;\    memset(enter_stack, 0, sizeof(enter_stack));\    stack_end = stack_ptr = (stack_type *)(enter_stack + 4096);\    ebp_val = (long)stack_ptr;\    for(i=1;i<=32;i++)\       *--stack_ptr = i;\    esp_val = (long)stack_ptr;\    asm("mov " RSP ", %[esp_save]\n"\        "mov " RBP ", %[ebp_save]\n"\        "mov %[esp_val], " RSP "\n"\        "mov %[ebp_val], " RBP "\n"\        "enter" size " $8, $" #level "\n"\        "mov " RSP ", %[esp_val]\n"\        "mov " RBP ", %[ebp_val]\n"\        "mov %[esp_save], " RSP "\n"\        "mov %[ebp_save], " RBP "\n"\        : [esp_save] "=r" (esp_save),\        [ebp_save] "=r" (ebp_save),\        [esp_val] "=r" (esp_val),\        [ebp_val] "=r" (ebp_val)\        :  "[esp_val]" (esp_val),\        "[ebp_val]" (ebp_val));\    printf("level=%d:\n", level);\

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -