static void inspect_threads(const char *cmd, core_debug_state_t *states, int core_num) { thread_t *t = thread_list_head; while (t) { struct regs r; jmp_buf_to_regs(&r, t->jmpbuf); uintptr_t data = 0; uintptr_t pc = backtrace(&data, &r); int offs; const char *sym = lookup_kernel_symbol(pc, &offs); const char *state_str; switch (t->state) { case THREAD_READY: state_str = "READY"; break; case THREAD_RUN: state_str = "RUN"; break; case THREAD_SLEEP: state_str = "SLEEP"; break; case THREAD_DEAD: state_str = "DEAD"; break; default: state_str = "UNKNOWN"; break; } if (sym) kprintf("#%3d: %-5s [%s+%d]\n", t->id, state_str, sym, offs); else kprintf("#%3d: %-5s 0x%x\n", t->id, state_str, pc); t = t->next; } }
static void dbg_backtrace(const char *cmd, core_debug_state_t *states, int core) { uintptr_t data = 0; int offs; uintptr_t ip; while ((ip = backtrace(&data, states[core].registers)) != 0) { const char *sym = lookup_kernel_symbol(ip, &offs); kprintf("%08x", ip); if (sym) kprintf(" %s+%#x", sym, offs); kprintf("\n"); } }
long long symbol_handler(char* module, char* symbolName, long long addr, char is64) { // Locate the symbol in the list, if it exists, update it's address kernSymbols_t *symbol = lookup_kernel_symbol(symbolName); if(symbol) { symbol->addr = addr; } return 0xFFFFFFFF; // fixme }
static char * lookup_symbol (state_t *state, process_t *process, uint64_t address, gboolean kernel) { const char *sym; g_assert (process); if (kernel) { sym = lookup_kernel_symbol (address); } else { const map_t *map = process_locate_map (process, address); if (!map) { sym = make_message (state, "No map [%s]", process->comm); } else { bin_file_t *bin_file = state_get_bin_file (state, map->filename); const bin_symbol_t *bin_sym; address -= map->start; address += map->offset; if (map->inode && !bin_file_check_inode (bin_file, map->inode)) { /* If the inodes don't match, it's probably because the * file has changed since the process was started. */ sym = make_message (state, "%s: inode mismatch", map->filename); } else { bin_sym = bin_file_lookup_symbol (bin_file, address); sym = bin_symbol_get_name (bin_file, bin_sym); } } } if (sym) return unique_dup (state->unique_symbols, sym); else return NULL; }
static void patch_cpuid_set_info_64(void* kernelData, UInt32 impersonateFamily, UInt8 impersonateModel) { UInt8* bytes = (UInt8*)kernelData; kernSymbols_t *symbol = lookup_kernel_symbol("_cpuid_set_info"); UInt32 patchLocation = symbol ? symbol->addr - textAddress + textSection: 0; // (kernelSymbolAddresses[SYMBOL_CPUID_SET_INFO] - textAddress + textSection); patchLocation -= (UInt32)kernelData; // Remove offset //UInt32 jumpLocation = 0; if(symbol == 0 || symbol->addr == 0) { verbose("Unable to locate _cpuid_set_info\n"); return; } symbol = lookup_kernel_symbol("_panic"); UInt32 panicAddr = symbol ? symbol->addr - textAddress: 0; //kernelSymbolAddresses[SYMBOL_PANIC] - textAddress; if(symbol == 0 || symbol->addr == 0) { printf("Unable to locate _panic\n"); return; } panicAddr -= (UInt32)kernelData; //TODO: don't assume it'll always work (Look for *next* function address in symtab and fail once it's been reached) while( (bytes[patchLocation -1] != 0xE8) || ( ( (UInt32)(panicAddr - patchLocation - 4) + textSection ) != (UInt32)((bytes[patchLocation + 0] << 0 | bytes[patchLocation + 1] << 8 | bytes[patchLocation + 2] << 16 | bytes[patchLocation + 3] << 24))) ) { patchLocation++; } patchLocation--; // Remove panic just in ca se // The panic instruction is exactly 5 bytes long. bytes[patchLocation + 0] = 0x90; bytes[patchLocation + 1] = 0x90; bytes[patchLocation + 2] = 0x90; bytes[patchLocation + 3] = 0x90; bytes[patchLocation + 4] = 0x90; // Check for a 10.2.0+ kernel if(bytes[patchLocation - 19] == 0xC7 && bytes[patchLocation - 18] == 0x05) { UInt32 cpuid_cpufamily_addr = bytes[patchLocation - 17] << 0 | bytes[patchLocation - 16] << 8 | bytes[patchLocation - 15] << 16 | bytes[patchLocation - 14] << 24; // NOTE: may change, determined based on cpuid_info struct UInt32 cpuid_model_addr = cpuid_cpufamily_addr - 310; //ffffff8000228b3b -> 0x00490e8b //ffffff8000228c28 -> -237 -> 0x490D9E -> -310 // The mov is 10 bytes /* bytes[patchLocation - 19] = 0x90; // c7 bytes[patchLocation - 18] = 0x90; // 05 bytes[patchLocation - 17] = 0x90; // family location bytes[patchLocation - 16] = 0x90; // family location bytes[patchLocation - 15] = 0x90; // family location bytes[patchLocation - 14] = 0x90; // family location */ bytes[patchLocation - 13] = (impersonateFamily & 0x000000FF) >> 0; bytes[patchLocation - 12] = (impersonateFamily & 0x0000FF00) >> 8; bytes[patchLocation - 11] = (impersonateFamily & 0x00FF0000) >> 16; bytes[patchLocation - 10] = (impersonateFamily & 0xFF000000) >> 24; // The lea (%rip),%rip is 7 bytes bytes[patchLocation - 9] = 0xC7; bytes[patchLocation - 8] = 0x05; bytes[patchLocation - 7] = ((cpuid_model_addr -10) & 0x000000FF) >> 0; // NOTE: this opcode is relative in 64bit mode, subtract offset bytes[patchLocation - 6] = ((cpuid_model_addr -10) & 0x0000FF00) >> 8; bytes[patchLocation - 5] = ((cpuid_model_addr -10) & 0x00FF0000) >> 16; bytes[patchLocation - 4] = ((cpuid_model_addr -10) & 0xFF000000) >> 24; bytes[patchLocation - 3] = impersonateModel; // cpuid_model // The xor eax eax is 2 bytes bytes[patchLocation - 2] = 0x01; // cpuid_extmodel bytes[patchLocation - 1] = 0x00; // cpuid_extfamily // The panic instruction is exactly 5 bytes long. bytes[patchLocation - 0] = 0x02; // cpuid_stepping /*bytes[patchLocation + 1] = 0x90; bytes[patchLocation + 2] = 0x90; bytes[patchLocation + 3] = 0x90; bytes[patchLocation + 4] = 0x90; */ // Panic call has been removed. // Override the CPUID now. This requires ~ 10 bytes on 10.0.0 kernels // On 10.2.0+ kernels, this requires ~16 bytes // Total: 24 bytes printf("Running on a 10.2.0+ kernel\n"); getc(); }