13 |
|
|
14 |
#define TEST_CMOV 0 |
#define TEST_CMOV 0 |
15 |
#define TEST_FCOMI 0 |
#define TEST_FCOMI 0 |
16 |
|
//#define LINUX_VM86_IOPL_FIX |
17 |
|
|
18 |
#define xglue(x, y) x ## y |
#define xglue(x, y) x ## y |
19 |
#define glue(x, y) xglue(x, y) |
#define glue(x, y) xglue(x, y) |
1107 |
switch(VM86_TYPE(ret)) { |
switch(VM86_TYPE(ret)) { |
1108 |
case VM86_INTx: |
case VM86_INTx: |
1109 |
{ |
{ |
1110 |
int int_num, ah; |
int int_num, ah, v; |
1111 |
|
|
1112 |
int_num = VM86_ARG(ret); |
int_num = VM86_ARG(ret); |
1113 |
if (int_num != 0x21) |
if (int_num != 0x21) |
1135 |
r->eax = (r->eax & ~0xff) | '$'; |
r->eax = (r->eax & ~0xff) | '$'; |
1136 |
} |
} |
1137 |
break; |
break; |
1138 |
case 0xff: /* extension: write hex number in edx */ |
case 0xff: /* extension: write eflags number in edx */ |
1139 |
printf("%08x\n", (int)r->edx); |
v = (int)r->edx; |
1140 |
|
#ifndef LINUX_VM86_IOPL_FIX |
1141 |
|
v &= ~0x3000; |
1142 |
|
#endif |
1143 |
|
printf("%08x\n", v); |
1144 |
break; |
break; |
1145 |
default: |
default: |
1146 |
unknown_int: |
unknown_int: |
1361 |
printf("val=0x%x\n", val); |
printf("val=0x%x\n", val); |
1362 |
} |
} |
1363 |
|
|
1364 |
|
/* specific precise single step test */ |
1365 |
|
void sig_trap_handler(int sig, siginfo_t *info, void *puc) |
1366 |
|
{ |
1367 |
|
struct ucontext *uc = puc; |
1368 |
|
printf("EIP=0x%08x\n", uc->uc_mcontext.gregs[REG_EIP]); |
1369 |
|
} |
1370 |
|
|
1371 |
|
const uint8_t sstep_buf1[4] = { 1, 2, 3, 4}; |
1372 |
|
uint8_t sstep_buf2[4]; |
1373 |
|
|
1374 |
|
void test_single_step(void) |
1375 |
|
{ |
1376 |
|
struct sigaction act; |
1377 |
|
volatile int val; |
1378 |
|
int i; |
1379 |
|
|
1380 |
|
val = 0; |
1381 |
|
act.sa_sigaction = sig_trap_handler; |
1382 |
|
sigemptyset(&act.sa_mask); |
1383 |
|
act.sa_flags = SA_SIGINFO; |
1384 |
|
sigaction(SIGTRAP, &act, NULL); |
1385 |
|
asm volatile ("pushf\n" |
1386 |
|
"orl $0x00100, (%%esp)\n" |
1387 |
|
"popf\n" |
1388 |
|
"movl $0xabcd, %0\n" |
1389 |
|
|
1390 |
|
/* jmp test */ |
1391 |
|
"movl $3, %%ecx\n" |
1392 |
|
"1:\n" |
1393 |
|
"addl $1, %0\n" |
1394 |
|
"decl %%ecx\n" |
1395 |
|
"jnz 1b\n" |
1396 |
|
|
1397 |
|
/* movsb: the single step should stop at each movsb iteration */ |
1398 |
|
"movl $sstep_buf1, %%esi\n" |
1399 |
|
"movl $sstep_buf2, %%edi\n" |
1400 |
|
"movl $0, %%ecx\n" |
1401 |
|
"rep movsb\n" |
1402 |
|
"movl $3, %%ecx\n" |
1403 |
|
"rep movsb\n" |
1404 |
|
"movl $1, %%ecx\n" |
1405 |
|
"rep movsb\n" |
1406 |
|
|
1407 |
|
/* cmpsb: the single step should stop at each cmpsb iteration */ |
1408 |
|
"movl $sstep_buf1, %%esi\n" |
1409 |
|
"movl $sstep_buf2, %%edi\n" |
1410 |
|
"movl $0, %%ecx\n" |
1411 |
|
"rep cmpsb\n" |
1412 |
|
"movl $4, %%ecx\n" |
1413 |
|
"rep cmpsb\n" |
1414 |
|
|
1415 |
|
/* getpid() syscall: single step should skip one |
1416 |
|
instruction */ |
1417 |
|
"movl $20, %%eax\n" |
1418 |
|
"int $0x80\n" |
1419 |
|
"movl $0, %%eax\n" |
1420 |
|
|
1421 |
|
/* when modifying SS, trace is not done on the next |
1422 |
|
instruction */ |
1423 |
|
"movl %%ss, %%ecx\n" |
1424 |
|
"movl %%ecx, %%ss\n" |
1425 |
|
"addl $1, %0\n" |
1426 |
|
"movl $1, %%eax\n" |
1427 |
|
"movl %%ecx, %%ss\n" |
1428 |
|
"jmp 1f\n" |
1429 |
|
"addl $1, %0\n" |
1430 |
|
"1:\n" |
1431 |
|
"movl $1, %%eax\n" |
1432 |
|
"pushl %%ecx\n" |
1433 |
|
"popl %%ss\n" |
1434 |
|
"addl $1, %0\n" |
1435 |
|
"movl $1, %%eax\n" |
1436 |
|
|
1437 |
|
"pushf\n" |
1438 |
|
"andl $~0x00100, (%%esp)\n" |
1439 |
|
"popf\n" |
1440 |
|
: "=m" (val) |
1441 |
|
: |
1442 |
|
: "cc", "memory", "eax", "ecx", "esi", "edi"); |
1443 |
|
printf("val=%d\n", val); |
1444 |
|
for(i = 0; i < 4; i++) |
1445 |
|
printf("sstep_buf2[%d] = %d\n", i, sstep_buf2[i]); |
1446 |
|
} |
1447 |
|
|
1448 |
/* self modifying code test */ |
/* self modifying code test */ |
1449 |
uint8_t code[] = { |
uint8_t code[] = { |
1450 |
0xb8, 0x1, 0x00, 0x00, 0x00, /* movl $1, %eax */ |
0xb8, 0x1, 0x00, 0x00, 0x00, /* movl $1, %eax */ |
1491 |
test_vm86(); |
test_vm86(); |
1492 |
test_exceptions(); |
test_exceptions(); |
1493 |
test_self_modifying_code(); |
test_self_modifying_code(); |
1494 |
|
test_single_step(); |
1495 |
return 0; |
return 0; |
1496 |
} |
} |