diff --git a/mixr/mixr.c b/mixr/mixr.c index b3cca06a7033eb9b56b3fa6ed6bb30bfa03bfbea..ca551b5c256aeb2c6650e28ed55cb89214fa970c 100644 --- a/mixr/mixr.c +++ b/mixr/mixr.c @@ -16,7 +16,7 @@ int syscall(int number, ...); #include <itox.h> #endif -#include <mixr_rw.h> +#include <mixr_structures.h> #define PROT_NONE 0x0 #define PROT_READ 0x1 @@ -30,7 +30,7 @@ static int q_fd; #define SYS_mprotect 10 #endif -#define DT_ENTRY_SIZE (8+2+1) +#define DT_ENTRY_SIZE (8+2+2+1) #define DT_LENGTH_SIZE 8 #define DT_FIXED_SIZE_SIZE 8 #define DT_FIRST_ENTRY_OFFSET (DT_LENGTH_SIZE+DT_FIXED_SIZE_SIZE) @@ -246,6 +246,15 @@ int _mprotect(void *addr, size_t len, int flags) #endif } +uint16_t de_table_entry_count(void *de_table_addr) +{ + uint16_t entry_count = 0; + + _memcpy(&entry_count, (const void*)de_table_addr, sizeof(uint16_t)); + + return entry_count; +} + uint16_t rw_table_entry_count(void *rw_table_addr) { uint16_t entry_count = 0; @@ -255,6 +264,37 @@ uint16_t rw_table_entry_count(void *rw_table_addr) return entry_count; } +struct de_table_entry de_table_read_entry(void *de_table_addr, unsigned int entry) +{ + struct de_table_entry de_entry = {}; + void *entry_address = NULL; + uint16_t entry_count = de_table_entry_count(de_table_addr); + + if (entry_count < entry) + return de_entry; + + entry_address = (void*)(de_table_addr + + entry*DE_TABLE_ENTRY_SIZE + + DE_TABLE_HEADER_SIZE); + _memcpy(&de_entry, entry_address, sizeof(struct de_table_entry)); + + return de_entry; +} + +void de_table_write_entry(void *de_table_addr, unsigned int entry, struct de_table_entry de_entry) +{ + void *entry_address = NULL; + uint16_t entry_count = de_table_entry_count(de_table_addr); + + if (entry_count < entry) + return; + + entry_address = (void*)(de_table_addr + + entry*DE_TABLE_ENTRY_SIZE + + DE_TABLE_HEADER_SIZE); + _memcpy(entry_address, &de_entry, sizeof(struct de_table_entry)); +} + struct rw_table_entry rw_table_read_entry(void *rw_table_addr, unsigned int entry) { struct rw_table_entry rw_entry = {}; @@ -291,6 +331,10 @@ void rw_table_print_entry(struct rw_table_entry rw_entry) { printf("RW Entry: {%hd, 0x%hhx, 0x%hhx, 0x%lx}\n", rw_entry.instruction_offset,rw_entry.rewrite_offset, rw_entry.rewrite_length,rw_entry.absolute_value); } +void de_table_print_entry(struct de_table_entry de_entry) +{ + printf("DE Entry: {%hx, 0x%hhx, 0x%x}\n", de_entry.tag,de_entry.instruction_offset,de_entry.dollop_table_ptr); +} #endif uint64_t dt_table_length(void *dt_table_addr) @@ -356,7 +400,7 @@ uint64_t dt_table_read_entry_address(void *dt_table_addr, unsigned int entry) return entry_address; } -uint16_t dt_table_read_entry_offset(void *dt_table_addr, unsigned int entry) +uint16_t dt_table_read_de_entry_offset(void *dt_table_addr, unsigned int entry) { uint16_t entry_offset; _memcpy(&entry_offset, @@ -365,11 +409,20 @@ uint16_t dt_table_read_entry_offset(void *dt_table_addr, unsigned int entry) return entry_offset; } +uint16_t dt_table_read_rw_entry_offset(void *dt_table_addr, unsigned int entry) +{ + uint16_t entry_offset; + _memcpy(&entry_offset, + (const void*)(dt_table_entry_address(dt_table_addr, entry)+8+2), + sizeof(uint16_t)); + return entry_offset; +} + uint8_t dt_table_read_entry_active(void *dt_table_addr, unsigned int entry) { uint8_t entry_active; _memcpy(&entry_active, - (const void*)(dt_table_entry_address(dt_table_addr, entry)+10), + (const void*)(dt_table_entry_address(dt_table_addr, entry)+12), sizeof(uint8_t)); return entry_active; } @@ -380,9 +433,16 @@ void dt_table_write_entry_address(void *dt_table_addr, unsigned int entry, uint6 sizeof(uint64_t)); } -void dt_table_write_entry_offset(void *dt_table_addr, unsigned int entry, uint16_t entry_offset) +void dt_table_write_de_entry_offset(void *dt_table_addr, unsigned int entry, uint16_t entry_offset) { - _memcpy((void*)(dt_table_entry_address(dt_table_addr, entry)+8), + _memcpy((void*)(dt_table_entry_address(dt_table_addr, entry)+8), + (const void*)&entry_offset, + sizeof(uint16_t)); +} + +void dt_table_write_rw_entry_offset(void *dt_table_addr, unsigned int entry, uint16_t entry_offset) +{ + _memcpy((void*)(dt_table_entry_address(dt_table_addr, entry)+8+2), (const void*)&entry_offset, sizeof(uint16_t)); } @@ -390,7 +450,7 @@ void dt_table_write_entry_offset(void *dt_table_addr, unsigned int entry, uint16 void dt_table_write_entry_active(void *dt_table_addr, unsigned int entry, uint8_t entry_active) { - _memcpy((void*)(dt_table_entry_address(dt_table_addr, entry)+10), + _memcpy((void*)(dt_table_entry_address(dt_table_addr, entry)+12), (const void*)&entry_active, sizeof(uint8_t)); } @@ -481,6 +541,42 @@ void dt_table_swap_entry_contents(void *dt_table_addr, unsigned int a, unsigned PROT_READ|PROT_EXEC); } +void mixr_do_de(uint64_t dollop_start, struct de_table_entry de_entry) +{ + uint64_t next_pc_address = dollop_start + de_entry.instruction_offset; + uint64_t dest = next_pc_address - 0x4; + uint32_t jump_target = 0; + + _memcpy((void*)&jump_target, (uint32_t*)de_entry.dollop_table_ptr, sizeof(uint32_t)); + +#if DEBUG + print_str_debug("DE Table Entry through "); + print_unsigned_long_long_debug(de_entry.dollop_table_ptr); + print_str_debug(" to (0x"); + print_addr_debug((void*)jump_target); + print_str_debug(") written to "); + print_addr_debug((void*)dest); + print_str_debug("\n"); +#endif + + jump_target -= next_pc_address; + +#ifdef DEBUG + if (jump_target == NULL) + jump_target = 0xdead; +#else + assert(jump_target); +#endif + + _mprotect((void*)(((uintptr_t)dest)&PAGE_MASK), + PAGE_SIZE + PAGE_SIZE, + PROT_READ|PROT_EXEC|PROT_WRITE); + _memcpy((void*)dest, &jump_target, sizeof(uint32_t)); + _mprotect((void*)(((uintptr_t)dest)&PAGE_MASK), + PAGE_SIZE + PAGE_SIZE, + PROT_READ|PROT_EXEC); +} + void mixr_do_rw(uint64_t dollop_start, struct rw_table_entry rw_entry) { uint64_t next_pc_address = dollop_start + rw_entry.instruction_offset; @@ -602,6 +698,7 @@ void zipr_mixr(void *table_addr) #endif mixr_active_dollops_mark_from_stack(table_addr); + #ifdef POLICY_RANDOM for (random_iterator=0;random_iterator<random_iterator_max;random_iterator++) #else @@ -614,14 +711,23 @@ void zipr_mixr(void *table_addr) #else uint64_t a = table_iterator, b = a-1; #endif + + /* + * Calculations of addresses/pointers for dollop A + */ uint64_t dt_address_a = dt_table_read_entry_address(table_addr, a); - uint16_t dt_offset_a = dt_table_read_entry_offset(table_addr, a); - uint64_t rw_address_a = dt_address_a + dt_offset_a; + uint16_t dt_rw_offset_a = dt_table_read_rw_entry_offset(table_addr, a); + uint64_t rw_address_a = dt_address_a + dt_rw_offset_a; uint16_t rw_entry_count_a = rw_table_entry_count((void*)rw_address_a); + + /* + * Calculations of addresses/pointers for dollop B + */ uint64_t dt_address_b = dt_table_read_entry_address(table_addr, b); - uint16_t dt_offset_b = dt_table_read_entry_offset(table_addr, b); - uint64_t rw_address_b = dt_address_b + dt_offset_b; + uint16_t dt_rw_offset_b = dt_table_read_rw_entry_offset(table_addr, b); + uint64_t rw_address_b = dt_address_b + dt_rw_offset_b; uint16_t rw_entry_count_b = rw_table_entry_count((void*)rw_address_b); + uint16_t rw_entry_count_iterator = 0; #ifdef DEBUG @@ -630,7 +736,7 @@ void zipr_mixr(void *table_addr) print_str_debug(": ("); print_addr_debug((void*)dt_address_a); print_str_debug(","); - print_int_debug(dt_offset_a); + print_int_debug(dt_rw_offset_a); print_str_debug(" #"); print_int_debug(rw_entry_count_a); print_str_debug(") <-> "); @@ -638,7 +744,7 @@ void zipr_mixr(void *table_addr) print_str_debug(": ("); print_addr_debug((void*)dt_address_b); print_str_debug(","); - print_int_debug(dt_offset_b); + print_int_debug(dt_rw_offset_b); print_str_debug(" #"); print_int_debug(rw_entry_count_b); print_str_debug(")\n"); @@ -665,6 +771,7 @@ void zipr_mixr(void *table_addr) } dt_table_swap_entry_contents(table_addr, a, b); + /* * Rewrite a. */ @@ -678,9 +785,10 @@ void zipr_mixr(void *table_addr) * this looks more confusing. */ mixr_do_rw(dt_address_b, - rw_table_read_entry((void*)(dt_address_b+dt_offset_a), + rw_table_read_entry((void*)(dt_address_b+dt_rw_offset_a), rw_entry_count_iterator)); } + /* * Rewrite b. */ @@ -694,13 +802,61 @@ void zipr_mixr(void *table_addr) * this looks more confusing. */ mixr_do_rw(dt_address_a, - rw_table_read_entry((void*)(dt_address_a+dt_offset_b), + rw_table_read_entry((void*)(dt_address_a+dt_rw_offset_b), rw_entry_count_iterator)); } } +#ifdef DEBUG + print_str_debug("Done with the swapping!\n"); +#endif + for (table_iterator=0;table_iterator<table_length;table_iterator++) + { + uint64_t dt_address=dt_table_read_entry_address(table_addr, table_iterator); + uint16_t dt_de_offset = dt_table_read_de_entry_offset(table_addr, + table_iterator); + uint64_t de_address = dt_address + dt_de_offset; + uint16_t de_entry_count = de_table_entry_count((void*)de_address); + uint16_t de_entry_count_iterator = 0; + + for (de_entry_count_iterator = 0; + de_entry_count_iterator<de_entry_count; + de_entry_count_iterator++) + { + struct de_table_entry entry = de_table_read_entry((void*)de_address, + de_entry_count_iterator); + if (entry.tag != 0x0) + { +#ifdef DEBUG + print_str_debug("Skipping.\n"); +#endif + continue; + } + +#ifdef DEBUG + print_str_debug("Looking at "); + print_addr_debug(de_address); + print_str_debug("'s "); + print_int_debug(de_entry_count_iterator); + print_str_debug(" entry.\n"); +#endif + if (entry.dollop_table_ptr == 0x0) + { +#ifdef DEBUG + print_str_debug("Skipping because it is empty!\n"); +#endif + continue; + } + mixr_do_de(dt_address, entry); + } + } + +#ifdef DEBUG + print_str_debug("Done with the fixing up DE Table entries!\n"); +#endif + mixr_active_dollops_clear(table_addr); #ifdef DEBUG - print_str_debug("Done with the clearing swapping!\n"); + print_str_debug("Done with the clearing!\n"); #endif #ifdef DEBUG @@ -718,7 +874,7 @@ void zipr_mixr(void *table_addr) print_str_debug("Attempting to write to fifo q file handle:"); print_int_debug(q_fd); print_str_debug("\n"); - write(q_fd, (const char *)&q_value, sizeof(uint64_t)); + write(q_fd, (const char *)&q_value, sizeof(uint65_t)); #endif } @@ -764,7 +920,7 @@ void zipr_hook_start(unsigned long long id, void zipr_hook_dynamic_callback(unsigned int id, unsigned long long rax, unsigned long long rsp) { print_str_debug("zipr_hook_dynamic_callback()\n"); - zipr_mixr(global_table_addr); + //zipr_mixr(global_table_addr); } #ifdef TEST @@ -780,8 +936,11 @@ void test_dollop_table(void) int nine = 9; int ten = 10; - uint16_t nine_offset = 0x9; - uint16_t ten_offset = 0xa; + uint16_t nine_de_offset = 0x99; + uint16_t ten_de_offset = 0xaa; + + uint16_t nine_rw_offset = 0x9; + uint16_t ten_rw_offset = 0xa; uint8_t nine_active = 0x9; uint8_t ten_active = 0xa; @@ -797,16 +956,20 @@ void test_dollop_table(void) table_entry_address += 1; table_entry_offset += 1; printf("table_entry_address: (%d): %lx\n", i, table_entry_address); - printf("table_entry_offset: (%d): %hx\n", i, table_entry_offset); + printf("[de|rw]_table_entry_offset: (%d): %hx\n", i, table_entry_offset); dt_table_write_entry_address(table, i, table_entry_address); - dt_table_write_entry_offset(table, i, table_entry_offset); + dt_table_write_de_entry_offset(table, i, table_entry_offset); + dt_table_write_rw_entry_offset(table, i, table_entry_offset); } dt_table_write_entry_address(table, 9, (uint64_t)&nine); - dt_table_write_entry_offset(table, 9, nine_offset); + dt_table_write_de_entry_offset(table, 9, nine_de_offset); + dt_table_write_rw_entry_offset(table, 9, nine_rw_offset); dt_table_write_entry_active(table, 9, nine_active); + dt_table_write_entry_address(table, 10, (uint64_t)&ten); - dt_table_write_entry_offset(table, 10, ten_offset); + dt_table_write_de_entry_offset(table, 10, ten_de_offset); + dt_table_write_rw_entry_offset(table, 10, ten_rw_offset); dt_table_write_entry_active(table, 10, ten_active); printf("dt_table_length: %lu\n", dt_table_length(table)); @@ -814,9 +977,12 @@ void test_dollop_table(void) printf("dt_table_read_entry_address(0): %lx\n", dt_table_read_entry_address(table, 0)); printf("dt_table_read_entry_address(5): %lx\n", dt_table_read_entry_address(table, 5)); printf("dt_table_read_entry_address(8): %lx\n", dt_table_read_entry_address(table, 8)); - printf("dt_table_read_entry_offset(0): %hx\n", dt_table_read_entry_offset(table, 0)); - printf("dt_table_read_entry_offset(5): %hx\n", dt_table_read_entry_offset(table, 5)); - printf("dt_table_read_entry_offset(8): %hx\n", dt_table_read_entry_offset(table, 8)); + printf("dt_table_read_de_entry_offset(0): %hx\n", dt_table_read_de_entry_offset(table, 0)); + printf("dt_table_read_de_entry_offset(5): %hx\n", dt_table_read_de_entry_offset(table, 5)); + printf("dt_table_read_de_entry_offset(8): %hx\n", dt_table_read_de_entry_offset(table, 8)); + printf("dt_table_read_rw_entry_offset(0): %hx\n", dt_table_read_rw_entry_offset(table, 0)); + printf("dt_table_read_rw_entry_offset(5): %hx\n", dt_table_read_rw_entry_offset(table, 5)); + printf("dt_table_read_rw_entry_offset(8): %hx\n", dt_table_read_rw_entry_offset(table, 8)); printf("dt_table_read_entry_active(0): %hx\n", dt_table_read_entry_active(table, 0)); printf("dt_table_read_entry_active(5): %hx\n", dt_table_read_entry_active(table, 5)); printf("dt_table_read_entry_active(8): %hx\n", dt_table_read_entry_active(table, 8)); @@ -825,36 +991,73 @@ void test_dollop_table(void) dt_table_swap_entry_addresses(table, 5, 8); printf("dt_table_read_entry_address(5): %lx\n", dt_table_read_entry_address(table, 5)); - printf("dt_table_read_entry_offset(5): %hx\n", dt_table_read_entry_offset(table, 5)); + printf("dt_table_read_de_entry_offset(5): %hx\n", dt_table_read_de_entry_offset(table, 5)); + printf("dt_table_read_rw_entry_offset(5): %hx\n", dt_table_read_rw_entry_offset(table, 5)); printf("dt_table_read_entry_address(8): %lx\n", dt_table_read_entry_address(table, 8)); - printf("dt_table_read_entry_offset(8): %hx\n", dt_table_read_entry_offset(table, 8)); + printf("dt_table_read_de_entry_offset(8): %hx\n", dt_table_read_de_entry_offset(table, 8)); + printf("dt_table_read_rw_entry_offset(8): %hx\n", dt_table_read_rw_entry_offset(table, 8)); printf("swap 8 <-> 0\n"); dt_table_swap_entry_addresses(table, 0, 8); printf("dt_table_read_entry_address(0): %lx\n", dt_table_read_entry_address(table, 0)); - printf("dt_table_read_entry_offset(0): %hx\n", dt_table_read_entry_offset(table, 0)); + printf("dt_table_read_de_entry_offset(0): %hx\n", dt_table_read_de_entry_offset(table, 0)); + printf("dt_table_read_rw_entry_offset(0): %hx\n", dt_table_read_rw_entry_offset(table, 0)); printf("dt_table_read_entry_address(8): %lx\n", dt_table_read_entry_address(table, 8)); - printf("dt_table_read_entry_offset(8): %hx\n", dt_table_read_entry_offset(table, 8)); + printf("dt_table_read_de_entry_offset(8): %hx\n", dt_table_read_de_entry_offset(table, 8)); + printf("dt_table_read_rw_entry_offset(8): %hx\n", dt_table_read_rw_entry_offset(table, 8)); printf("dt_table_read_entry_address(9): %lx, %x\n", dt_table_read_entry_address(table, 9), *((int*)dt_table_read_entry_address(table, 9))); - printf("dt_table_read_entry_offset(9): %hx\n", dt_table_read_entry_offset(table, 9)); + printf("dt_table_read_de_entry_offset(9): %hx\n", dt_table_read_de_entry_offset(table, 9)); + printf("dt_table_read_rw_entry_offset(9): %hx\n", dt_table_read_rw_entry_offset(table, 9)); printf("dt_table_read_entry_active(9): %hx\n", dt_table_read_entry_active(table, 9)); printf("dt_table_read_entry_address(10): %lx, %x\n", dt_table_read_entry_address(table, 10), *((int*)dt_table_read_entry_address(table, 10))); - printf("dt_table_read_entry_offset(10): %hx\n", dt_table_read_entry_offset(table, 10)); + printf("dt_table_read_de_entry_offset(10): %hx\n", dt_table_read_de_entry_offset(table, 10)); + printf("dt_table_read_rw_entry_offset(10): %hx\n", dt_table_read_rw_entry_offset(table, 10)); printf("dt_table_read_entry_active(10): %hx\n", dt_table_read_entry_active(table, 10)); dt_table_swap_entry_contents(table, 10, 9); printf("dt_table_read_entry_address(9): %lx, %x\n", dt_table_read_entry_address(table, 9), *((int*)dt_table_read_entry_address(table, 9))); - printf("dt_table_read_entry_offset(9): %hx\n", dt_table_read_entry_offset(table, 9)); + printf("dt_table_read_de_entry_offset(9): %hx\n", dt_table_read_de_entry_offset(table, 9)); + printf("dt_table_read_rw_entry_offset(9): %hx\n", dt_table_read_rw_entry_offset(table, 9)); printf("dt_table_read_entry_active(9): %hx\n", dt_table_read_entry_active(table, 9)); printf("dt_table_read_entry_address(10): %lx, %x\n", dt_table_read_entry_address(table, 10), *((int*)dt_table_read_entry_address(table, 10))); - printf("dt_table_read_entry_offset(10): %hx\n", dt_table_read_entry_offset(table, 10)); + printf("dt_table_read_de_entry_offset(10): %hx\n", dt_table_read_de_entry_offset(table, 10)); + printf("dt_table_read_rw_entry_offset(10): %hx\n", dt_table_read_rw_entry_offset(table, 10)); printf("dt_table_read_entry_active(10): %hx\n", dt_table_read_entry_active(table, 10)); dt_table_write_to_file(table, "/tmp/testtable.bin"); } +void test_de_table(void) +{ + struct de_table_header *de_table = NULL; + + int entry_count = 11; + struct de_table_entry entry_ten = {1, 2, 4}; + struct de_table_entry entry_eleven = {11, 22, 33}; + struct de_table_entry entry_fiftyk = {111, 222, 333}; + + de_table = (struct de_table_header*)malloc(sizeof(struct de_table_header) + (entry_count*sizeof(struct de_table_entry))); + + de_table->entry_count = 11; + + de_table_write_entry((void*)de_table, 10, entry_ten); + de_table_write_entry((void*)de_table, 11, entry_eleven); + + de_table_write_entry((void*)de_table, 50000, entry_fiftyk); + + de_table_print_entry(de_table_read_entry((void*)de_table, 10)); + de_table_print_entry(de_table_read_entry((void*)de_table, 11)); + + /* + * Will return 0'd de_table_entry -- entry too high. + */ + de_table_print_entry(de_table_read_entry((void*)de_table, 50000)); + + printf("de_table_entry_count: %d\n", de_table_entry_count((void*)de_table)); +} + void test_rw_table(void) { struct rw_table_header *rw_table = NULL; @@ -886,8 +1089,9 @@ void test_rw_table(void) int main() { - test_rw_table(); - test_dollop_table(); + test_de_table(); + //test_rw_table(); + //test_dollop_table(); return 0; } #endif