int main(int argc, char **argv) { char uuid[0x50]; size_t size = 0x50; memset(uuid, 0, size); vm_address_t kbase, uuid_addr; kern_return_t ret; if(argc < 2) { fprintf(stderr, "Usage: %s new-uuid\n", argv[0]); return -1; } if((ret = sysctlbyname("kern.uuid", uuid, &size, NULL, 0)) != KERN_SUCCESS) { fprintf(stderr, "[!] Failed to create UUID, sysctlbyname returned %i\n", ret); return -1; } fprintf(stderr, "[*] UUID: %s\n", uuid); if((kbase = get_kernel_base()) == 0) { fprintf(stderr, "[!] Failed to locate kernel\n"); return -1; } if((uuid_addr = find_bytes_kern(kbase, kbase + 0x1000000, (unsigned char*)uuid, strlen(uuid))) == 0) { fprintf(stderr, "[!] Failed to find UUID in kernel memory\n"); return -1; } fprintf(stderr, "[*] Found UUID at 0x" ADDR "\n", uuid_addr); write_kernel(uuid_addr, (unsigned char*)argv[1], strlen(argv[1]) + 1); fprintf(stderr, "[*] Done, check \"sysctl kern.uuid\"\n"); return 0; }
static RList *ios_dbg_maps(RDebug *dbg, int only_modules) { boolt contiguous = R_FALSE; ut32 oldprot = UT32_MAX; ut32 oldmaxprot = UT32_MAX; char buf[1024]; char module_name[MAXPATHLEN]; mach_vm_address_t address = MACH_VM_MIN_ADDRESS; mach_vm_size_t size = (mach_vm_size_t) 0; mach_vm_size_t osize = (mach_vm_size_t) 0; natural_t depth = 0; int tid = dbg->pid; task_t task = pid_to_task (tid); RDebugMap *mr = NULL; RList *list = NULL; int i = 0; if (only_modules) { return xnu_dbg_modules (dbg); } #if __arm64__ || __aarch64__ size = osize = 16384; // acording to frida #else size = osize = 4096; #endif #if 0 if (dbg->pid == 0) { vm_address_t base = get_kernel_base (task); eprintf ("Kernel Base Address: 0x%"PFMT64x"\n", (ut64)base); return NULL; } #endif kern_return_t kr; for (;;) { struct vm_region_submap_info_64 info; mach_msg_type_number_t info_count; info_count = VM_REGION_SUBMAP_INFO_COUNT_64; memset (&info, 0, sizeof (info)); kr = mach_vm_region_recurse (task, &address, &size, &depth, (vm_region_recurse_info_t) &info, &info_count); if (kr != KERN_SUCCESS) { //eprintf ("Cannot kern succ recurse\n"); break; } if (info.is_submap) { depth++; continue; } if (!list) { list = r_list_new (); //list->free = (RListFree*)r_debug_map_free; } { module_name[0] = 0; int ret = proc_regionfilename (tid, address, module_name, sizeof (module_name)); module_name[ret] = 0; } #if 0 oldprot = info.protection; oldmaxprot = info.max_protection; // contiguous pages seems to hide some map names if (mr) { if (address == mr->addr + mr->size) { if (oldmaxprot == info.max_protection) { contiguous = R_FALSE; } else if (oldprot != UT32_MAX && oldprot == info.protection) { /* expand region */ mr->size += size; contiguous = R_TRUE; } else { contiguous = R_FALSE; } } else { contiguous = R_FALSE; } } else contiguous = R_FALSE; //if (info.max_protection == oldprot && !contiguous) { #endif if (1) { #define xwr2rwx(x) ((x&1)<<2) | (x&2) | ((x&4)>>2) // XXX: if its shared, it cannot be read? snprintf (buf, sizeof (buf), "%s %02x %s%s%s%s%s %s depth=%d", r_str_rwx_i (xwr2rwx (info.max_protection)), i, unparse_inheritance (info.inheritance), info.user_tag? " user": "", info.is_submap? " sub": "", info.inheritance? " inherit": "", info.is_submap ? " submap": "", module_name, depth); //info.shared ? "shar" : "priv", //info.reserved ? "reserved" : "not-reserved", //""); //module_name); mr = r_debug_map_new (buf, address, address+size, xwr2rwx (info.protection), 0); if (mr == NULL) { eprintf ("Cannot create r_debug_map_new\n"); break; } mr->file = strdup (module_name); i++; r_list_append (list, mr); } if (size<1) { eprintf ("EFUCK\n"); size = osize; // f**k } address += size; size = 0; } return list; }
NTSTATUS DriverEntry( IN PDRIVER_OBJECT drv_obj, IN PUNICODE_STRING reg_pth ) { // PIMAGE_DOS_HEADER d_head; // PIMAGE_NT_HEADERS n_head; NTSTATUS status = STATUS_UNSUCCESSFUL; HANDLE h_key = NULL; // u32 tstamp; do { if ( (h_key = reg_open_key(reg_pth->Buffer, NULL)) == NULL ) { DbgMsg("can not open service key\n"); break; } /* get ntoskrnl base */ if ( (ntkrn_base = get_kernel_base()) == NULL ) { DbgMsg("kernel base not found\n"); break; } DbgMsg("kernel base: %x\n", ntkrn_base); /* get ntoskrnl timestamp */ /* turned off because of the futility: dbghelp do this stuf if (reg_query_val(h_key, L"sym_timestamp", &tstamp, sizeof(tstamp)) == 0) { DbgMsg("unable to get ntoskrnl timestamp\n"); break; } */ /* validate ntoskrnl timestamp */ /* d_head = ntkrn_base; n_head = addof(d_head, d_head->e_lfanew); if (n_head->FileHeader.TimeDateStamp != tstamp) { DbgMsg("invalid ntoskrnl timestamp\n"); break; } */ if (init_hook_list() == 0){ DbgMsg("init_hook_list failed\n"); break; } if (init_dbg_item(h_key) == 0) { DbgMsg("init_dbg_item failed\n"); break; } if (init_debug(h_key) == 0) { DbgMsg("init_debug failed\n"); break; } if (init_syscall(h_key) == 0) { DbgMsg("init_syscall failed\n"); break; } DbgMsg("dbgapi initialized\n"); status = STATUS_SUCCESS; } while (0); if (h_key != NULL) { ZwClose(h_key); } return status; }
int main() { kern_return_t ret; task_t kernel_task; vm_address_t kbase; unsigned char buf[HEADER_SIZE]; // will hold the original mach-o header and load commands unsigned char header[HEADER_SIZE]; // header for the new mach-o file unsigned char* binary; // mach-o will be reconstructed in here FILE* f; size_t filesize = 0; #if __LP64__ struct segment_command_64* seg; struct mach_header_64* orig_hdr = (struct mach_header_64*)buf; struct mach_header_64* hdr = (struct mach_header_64*)header; #else struct segment_command* seg; struct mach_header* orig_hdr = (struct mach_header*)buf; struct mach_header* hdr = (struct mach_header*)header; #endif memset(header, 0, HEADER_SIZE); ret = task_for_pid(mach_task_self(), 0, &kernel_task); if (ret != KERN_SUCCESS) { printf("[!] failed to get access to the kernel task"); return -1; } if ((kbase = get_kernel_base()) == 0) { printf("[!] could not find kernel base address\n"); return -1; } printf("[*] found kernel base at address 0x" ADDR "\n", kbase); f = fopen("kernel.bin", "wb"); binary = calloc(1, KERNEL_SIZE); // too large for the stack printf("[*] reading kernel header...\n"); read_kernel(kbase, HEADER_SIZE, buf); memcpy(hdr, orig_hdr, sizeof(*hdr)); hdr->ncmds = 0; hdr->sizeofcmds = 0; /* * We now have the mach-o header with the LC_SEGMENT * load commands in it. * Next we are going to redo the loading process, * parse each load command and read the data from * vmaddr into fileoff. * Some parts of the mach-o can not be restored (e.g. LC_SYMTAB). * The load commands for these parts will be removed from the final * executable. */ printf("[*] restoring segments...\n"); CMD_ITERATE(orig_hdr, cmd) { switch(cmd->cmd) { case LC_SEGMENT: case LC_SEGMENT_64: { #if __LP64__ seg = (struct segment_command_64*)cmd; #else seg = (struct segment_command*)cmd; #endif printf("[+] found segment %s\n", seg->segname); read_kernel(seg->vmaddr, seg->filesize, binary + seg->fileoff); filesize = max(filesize, seg->fileoff + seg->filesize); } case LC_UUID: case LC_UNIXTHREAD: case 0x25: case 0x2a: case 0x26: memcpy(header + sizeof(*hdr) + hdr->sizeofcmds, cmd, cmd->cmdsize); hdr->sizeofcmds += cmd->cmdsize; hdr->ncmds++; break; } } // now replace the old header with the new one ... memcpy(binary, header, sizeof(*hdr) + orig_hdr->sizeofcmds); // ... and write the final binary to file fwrite(binary, filesize, 1, f); printf("[*] done, wrote 0x%lx bytes\n", filesize); fclose(f); free(binary); return 0; }