static void test_sandbox_cti_tgt(void) { protect_mem(sandbox_cti_tgt, 1024, ALLOW_READ|ALLOW_WRITE|ALLOW_EXEC); sandbox_cti_tgt(); print("end selfmod loop test\n"); }
static void do_test(char *buf, size_t len) { int i, j; char *code; protect_mem(buf, len, ALLOW_READ|ALLOW_WRITE); for (i = 0; i < 7; i++) { for (j = 0; j < 7; j++) { code = copy_to_buf(buf, len, NULL, CODE_INC, COPY_NORMAL); protect_mem_check(buf, len, prot_codes[i], ALLOW_READ|ALLOW_WRITE); protect_mem_check(buf, len, prot_codes[j], prot_codes[i]); test_print(code, 5); test_print(code, 2); if (j > 1 && j < 6) { code = copy_to_buf(buf, len, NULL, CODE_DEC, COPY_NORMAL); test_print(code, 3); test_print(code, 1); code = copy_to_buf(buf, len, NULL, CODE_SELF_MOD, COPY_NORMAL); test_print(code, 43981); test_print(code, 4660); } buf++; len--; if (j > 1 && j < 6) { protect_mem_check(buf, len, ALLOW_READ|ALLOW_WRITE, prot_codes[j]); code = copy_to_buf(buf, len, NULL, CODE_SELF_MOD, COPY_NORMAL); protect_mem_check(buf, len, prot_codes[i], ALLOW_READ|ALLOW_WRITE); protect_mem_check(buf, len, prot_codes[j], prot_codes[i]); test_print(code, 4660); test_print(code, 43981); } protect_mem_check(buf, len, ALLOW_READ|ALLOW_WRITE, prot_codes[j]); } } }
static void test_sandbox_fault(void) { int i; print("start fault test\n"); protect_mem(sandbox_fault_no_ilt, 1024, ALLOW_READ|ALLOW_WRITE|ALLOW_EXEC); i = SIGSETJMP(mark); if (i == 0) sandbox_fault(42); /* i#1441: test max writes with illegal instr */ protect_mem(sandbox_illegal_no_ilt, 1024, ALLOW_READ|ALLOW_WRITE|ALLOW_EXEC); i = SIGSETJMP(mark); if (i == 0) sandbox_illegal_instr(42); print("end fault test\n"); }
int main() { INIT(); #ifdef USE_DYNAMO dynamorio_app_init(); dynamorio_app_start(); #endif /* make foo code writable */ protect_mem(code_self_mod, 1024, ALLOW_READ|ALLOW_WRITE|ALLOW_EXEC); // Note that main and the exception handler __except_handler3 are on this page too foo(0xabcd); foo(0x1234); foo(0xef01); #ifdef USE_DYNAMO dynamorio_app_stop(); dynamorio_app_exit(); #endif return 0; }
static void test_code_self_mod(void) { /* Make the code writable. Note that main and the exception handler * __except_handler3 are on this page too. */ protect_mem(code_self_mod, 1024, ALLOW_READ|ALLOW_WRITE|ALLOW_EXEC); print("Executed 0x%x iters\n", code_self_mod(0xabcd)); print("Executed 0x%x iters\n", code_self_mod(0x1234)); print("Executed 0x%x iters\n", code_self_mod(0xef01)); }
static void test_sandbox_cross_page(void) { int i; print("start cross-page test\n"); /* Make sandbox_cross_page code writable */ protect_mem(sandbox_cross_page_no_ilt, 1024, ALLOW_READ|ALLOW_WRITE|ALLOW_EXEC); for (i = 0; i < 50; i++) { sandbox_cross_page(i, global_buf); } print("end cross-page test\n"); }
int main(void) { INIT(); protect_mem(foo, PAGE_SIZE, ALLOW_EXEC|ALLOW_WRITE|ALLOW_READ); print("foo returned %d\n", foo(10)); print("foo returned %d\n", foo(10)); return 0; }
void protect_mem_check(void *start, size_t len, int prot, int expected) { #ifdef UNIX /* FIXME : add check */ protect_mem(start, len, prot); #else DWORD old; if (VirtualProtect(start, len, get_os_prot_word(prot), &old) == 0) { print("Error on VirtualProtect\n"); } if (old != get_os_prot_word(expected)) { print("Unexpected previous permissions\n"); } #endif }
int main() { /* Execute writable code to test i#143. * This opcode sequence is matched in the client. * We can't put this on the stack b/c we need page prot -w on Windows. */ static char buf[] = { 0x90, 0x90, 0x90, 0xc3 /*ret*/ }; void (*func)(void) = (void (*)(void))buf; protect_mem(buf, sizeof(buf), ALLOW_READ | ALLOW_WRITE | ALLOW_EXEC); (*func)(); /* Make a system call to help test i#143c#4 */ print("all done\n"); return 0; }
/* i#993: Test case for a bug where the last byte of a fragment was in a * different vmarea. */ static void test_sandbox_last_byte(void) { int r; byte *last_byte = (byte *)last_byte_jmp_no_ilt + 1; if (!ALIGNED(last_byte, PAGE_SIZE)) { print("laste_byte is not page-aligned: "PFX"\n" "Instruction sizes in sandbox_last_byte must be wrong.\n", last_byte); } print("start last byte test\n"); protect_mem(last_byte, PAGE_SIZE, ALLOW_READ|ALLOW_WRITE|ALLOW_EXEC); /* Execute self-modifying code to create a sandboxed page. */ make_last_byte_selfmod(); r = sandbox_last_byte(); print("sandbox_last_byte: %d\n", r); /* Should be 0. */ /* Make the relative jmp offset zero, so it goes to the next instruction. */ *last_byte = 0; r = sandbox_last_byte(); print("sandbox_last_byte: %d\n", r); /* Should be 1. */ print("end last byte test\n"); }
static void test_alloc_overlap(void) { /* Test i#1175: create some +rx DGC. Then change it to +rw via mmap * instead of mprotect and ensure DR catches a subsequent code modification. * We allocate two pages and put the code one page in so that our * modifying mmap can have its prot match the region base's prot to * make it harder for DR to detect. */ char *buf = allocate_mem(PAGE_SIZE*2, ALLOW_READ|ALLOW_WRITE|ALLOW_EXEC); char *code = copy_to_buf(buf + PAGE_SIZE, PAGE_SIZE, NULL, CODE_INC, COPY_NORMAL); protect_mem(code, PAGE_SIZE, ALLOW_READ|ALLOW_EXEC); test_print(code, 42); #ifdef UNIX code = mmap(buf, PAGE_SIZE*2, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANON|MAP_FIXED, 0, 0); #else code = VirtualAlloc(buf, PAGE_SIZE*2, MEM_COMMIT, PAGE_EXECUTE_READWRITE); #endif code = copy_to_buf(code, PAGE_SIZE, NULL, CODE_DEC, COPY_NORMAL); test_print(code, 42); /* Hmm, there is no free_mem()... */ }
int main(int argc, char *argv[]) { int offs, tid; unsigned long hThread; INIT(); print("testing hook pattern\n"); /* make it executable so that natively it works on NX */ protect_mem(datacode, sizeof(datacode), ALLOW_READ|ALLOW_WRITE|ALLOW_EXEC); protect_mem(datacode2, sizeof(datacode), ALLOW_READ|ALLOW_WRITE|ALLOW_EXEC); /* ensure our same-page test is relevant */ assert((((ptr_int_t)datacode) & ~(PAGE_SIZE -1)) == (((ptr_int_t)&datacode[sizeof(datacode)-1]) & ~(PAGE_SIZE -1))); /****************************************************************************/ /* datacode */ /* we need to set the 1st jmp so we'll match the pattern */ offs = ((ptr_int_t)&image_target + 5/*skip jmp*/) - DATACODE_POST_JMP; /* make direct jmp go to image_target */ *((int *)(&datacode[DATACODE_JMP_OPND_IDX])) = offs; __asm { pusha call offset datacode popa } print("testing non-pattern-match on same page\n"); offs = (ptr_int_t)&maliciousness - DATACODE_POST_2ND_JMP; /* make 2nd direct jmp go to maliciousness */ *((int *)(&datacode[DATACODE_2ND_JMP_OPND_IDX])) = offs; offs = DATACODE_POST_JMP; __asm { pusha call dword ptr offs popa } print("testing non-pattern-match in same region\n"); /* have 2nd instr make direct jmp to maliciousness */ offs = (ptr_int_t)&maliciousness - ((ptr_int_t)datacode + 2/*first instr*/ + 5/*this new jmp*/); datacode[2] = 0xe9; *((int *)(&datacode[3])) = offs; __asm { pusha call offset datacode popa } /* put the code back */ datacode[2] = 0x55; datacode[3] = 0x8b; datacode[4] = 0xec; datacode[5] = 0xe9; offs = ((ptr_int_t)&image_target + 5/*skip jmp*/) - DATACODE_POST_JMP; print("testing hook pattern again\n"); /* make direct jmp go to image_target */ *((int *)(&datacode[DATACODE_JMP_OPND_IDX])) = offs; __asm { pusha call offset datacode popa } print("testing non-pattern-match in same region by another thread\n"); /* now have another thread do the same thing */ hThread = _beginthreadex(NULL, 0, run_func, NULL, 0, &tid); WaitForSingleObject((HANDLE)hThread, INFINITE); print("testing different pattern match in same region\n"); /* now change to have 1st instr make direct jmp to maliciousness */ offs = (ptr_int_t)&maliciousness - ((ptr_int_t)datacode + 5); datacode[0] = 0xe9; *((int *)(&datacode[1])) = offs; __asm { pusha call offset datacode popa } /****************************************************************************/ /* datacode2 */ /* for -detect_mode we may have added datacode2 -- so force removal of it */ protect_mem(datacode2, sizeof(datacode), ALLOW_READ|ALLOW_WRITE); /* but we have to make sure it works on nx */ protect_mem(datacode2, sizeof(datacode), ALLOW_READ|ALLOW_WRITE|ALLOW_EXEC); print("testing pattern match that modifies itself to be a non-match\n"); /* would be allowed w/ last_area 4020 impl but shared->private check deletes * shared area and we end up getting lucky. */ /* MUST be just after change 1st instr of datacode to jmp to maliciousness */ offs = ((ptr_int_t)&image_target2 + 10/*skip length of pre-jmp instrs*/) - ((ptr_int_t)datacode2 + sizeof(datacode2) - 1); /* make direct jmp go to image_target */ *((int *)(&datacode2[sizeof(datacode2)-5])) = offs; /* make the mov modify the jmp to go to the jmp at the start of * datacode (I would put another jmp at end of datacode2 but we'll * just elide and allow!) which will go to maliciousness */ offs = (ptr_int_t)(&datacode) - ((ptr_int_t)datacode2 + sizeof(datacode2) - 1); /* immed comes last */ *((int *)(&datacode2[6])) = offs; /* target of mov comes before immed */ *((int *)(&datacode2[2])) = (ptr_int_t) &datacode2[11]; __asm { pusha call offset datacode2 popa } print("finished\n"); return 0; }