Exemplo n.º 1
0
int boot_iboot() {
	irecv_error_t error = IRECV_E_SUCCESS;

	debug("Loading iBoot\n");
	if (device->chip_id == 8720) {
		error
				= irecv_send_command(client,
						"go image load 0x69626F74 0x9000000");
	} else {
		error = irecv_send_command(client,
				"go image load 0x69626F74 0x41000000");
	}
	if (error != IRECV_E_SUCCESS) {
		error("Unable load iBoot to memory\n");
		return -1;
	}

	debug("Shifting iBoot\n");
	if (device->chip_id == 8720) {
		error = irecv_send_command(client,
				"go memory move 0x9000040 0x9000000 0x48000");
	} else {
		error = irecv_send_command(client,
				"go memory move 0x41000040 0x41000000 0x48000");
	}
	if (error != IRECV_E_SUCCESS) {
		error("Unable to move iBoot into memory\n");
		return -1;
	}

	debug("Patching iBoot\n");
	if (device->chip_id == 8720) {
		error = irecv_send_command(client, "go patch 0x9000000 0x48000");
	} else {
		error = irecv_send_command(client, "go patch 0x41000000 0x48000");
	}
	if (error != IRECV_E_SUCCESS) {
		error("Unable to patch iBoot\n");
		return -1;
	}

	irecv_setenv(client, "auto-boot", "false");
	irecv_saveenv(client);

	debug("Jumping into iBoot\n");
	if (device->chip_id == 8720) {
		error = irecv_send_command(client, "go jump 0x9000000");
	} else {
		error = irecv_send_command(client, "go jump 0x41000000");
	}
	if (error != IRECV_E_SUCCESS) {
		error("Unable to jump into iBoot\n");
		return -1;
	}

	debug("Reconnecting to device\n");
	client = irecv_reconnect(client, 10);
	if (client == NULL) {
		error("Unable to boot the device tethered\n");
		return -1;
	}

	irecv_setenv(client, "auto-boot", "true");
	irecv_saveenv(client);

	if (upload_firmware_payload("iBoot") < 0) {
		error("Unable to boot the device tethered\n");
		return -1;
	}

	debug("Initializing greenpois0n in iBoot\n");
	irecv_send_command(client, "go");

	return 0;
}
Exemplo n.º 2
0
int boot_ramdisk() {
	irecv_error_t error = IRECV_E_SUCCESS;

	// Add an exception for this since it's very different
	if(device->index == DEVICE_APPLETV2) {
		debug("Preparing to upload ramdisk\n");
		if(upload_ramdisk() < 0) {
			error("Unable to upload ramdisk\n");
			return -1;
		}

		debug("Executing ramdisk\n");
		error = irecv_send_command(client, "ramdisk");
		if(error != IRECV_E_SUCCESS) {
			error("Unable to execute ramdisk command\n");
			return -1;
		}

		debug("Setting kernel bootargs\n");
		error = irecv_send_command(client, "go kernel bootargs rd=md0 -v keepsyms=1");
		if(error != IRECV_E_SUCCESS) {
			error("Unable to set kernel bootargs\n");
			return -1;
		}

		debug("Preparing to upload kernelcache\n");
		if(upload_kernelcache() < 0) {
			error("Unable to upload kernelcache\n");
			return -1;
		}

		error = irecv_send_command(client, "bootx");
		if(error != IRECV_E_SUCCESS) {
			error("Unable to move iBoot into memory\n");
			return -1;
		}

		return 0;
	}

	debug("Preparing to boot iBoot\n");
	if(boot_iboot() < 0) {
		error("Unable to boot iBoot\n");
		return -1;
	}

	debug("Preparing to upload ramdisk\n");
	if(upload_ramdisk() < 0) {
		error("Unable to upload ramdisk\n");
		return -1;
	}

	debug("Executing ramdisk\n");
	error = irecv_send_command(client, "go ramdisk 1 1");
	if(error != IRECV_E_SUCCESS) {
		error("Unable to execute ramdisk command\n");
		return -1;
	}

	debug("Moving ramdisk\n");
	if(device->chip_id == 8720) {
		error = irecv_send_command(client, "go memory move 0x9000040 0xC000000 0x100000");
	} else {
		error = irecv_send_command(client, "go memory move 0x41000040 0x44000000 0x100000");
	}
	if(error != IRECV_E_SUCCESS) {
		error("Unable to move ramdisk\n");
		return -1;
	}

	debug("Setting kernel bootargs\n");
	error = irecv_send_command(client, "go kernel bootargs rd=md0 -v keepsyms=1");
	if(error != IRECV_E_SUCCESS) {
		error("Unable to set kernel bootargs\n");
		return -1;
	}

	irecv_setenv(client, "boot-args", "0");
	irecv_setenv(client, "auto-boot", "true");
	irecv_saveenv(client);

	error = irecv_send_command(client, "go fsboot");
	if (error != IRECV_E_SUCCESS) {
		error("Unable to fsboot\n");
		return -1;
	}

	return 0;
}
Exemplo n.º 3
0
int boot_tethered() {
	irecv_error_t error = IRECV_E_SUCCESS;

	debug("Initializing greenpois0n in iBoot\n");
	irecv_send_command(client, "go");

	// Add an exception for this since it's very different
	if (device->index == DEVICE_APPLETV2) {
		debug("Preparing to upload kernelcache\n");
		if (upload_kernelcache() < 0) {
			error("Unable to upload kernelcache\n");
			return -1;
		}

		debug("Hooking jump_to command\n");
		error = irecv_send_command(client, "go rdboot");
		if (error != IRECV_E_SUCCESS) {
			error("Unable to hook jump_to\n");
			return -1;
		}

		debug("Booting kernel\n");
		error = irecv_send_command(client, "bootx");
		if (error != IRECV_E_SUCCESS) {
			error("Unable to boot kernel\n");
			return -1;
		}

		return 0;
	}

	debug("Preparing to boot iBoot\n");
	if (boot_iboot() < 0) {
		error("Unable to boot iBoot\n");
		return -1;
	}

	debug("Preparing to upload ramdisk\n");
	if (upload_ramdisk() < 0) {
		error("Unable to upload ramdisk\n");
		return -1;
	}

	debug("Executing ramdisk\n");
	error = irecv_send_command(client, "go ramdisk 1 1");
	if (error != IRECV_E_SUCCESS) {
		error("Unable to execute ramdisk command\n");
		return -1;
	}

	debug("Setting kernel bootargs\n");
	error = irecv_send_command(client,
			"go kernel bootargs rd=disk0s1 -v keepsyms=1");
	if (error != IRECV_E_SUCCESS) {
		error("Unable to set kernel bootargs\n");
		return -1;
	}

	irecv_setenv(client, "boot-args", "0");
	irecv_setenv(client, "auto-boot", "true");
	irecv_saveenv(client);

	error = irecv_send_command(client, "go fsboot");
	if (error != IRECV_E_SUCCESS) {
		error("Unable to fsboot\n");
		return -1;
	}

	return 0;
}
Exemplo n.º 4
0
int main(int argc, char* argv[]) {
	int i = 0;
	int opt = 0;
	int action = 0;
	unsigned long long ecid = 0;
	int mode = -1;
	char* argument = NULL;
	irecv_error_t error = 0;

	char* buffer = NULL;
	uint64_t buffer_length = 0;

	if (argc == 1) {
		print_usage(argc, argv);
		return 0;
	}

	while ((opt = getopt(argc, argv, "i:vhrsmnc:f:e:k::")) > 0) {
		switch (opt) {
			case 'i':
				if (optarg) {
					char* tail = NULL;
					ecid = strtoull(optarg, &tail, 16);
					if (tail && (tail[0] != '\0')) {
						ecid = 0;
					}
					if (ecid == 0) {
						fprintf(stderr, "ERROR: Could not parse ECID from argument '%s'\n", optarg);
						return -1;
					}
				}
				break;

			case 'v':
				verbose += 1;
				break;

			case 'h':
				print_usage(argc, argv);
				return 0;

			case 'm':
				action = kShowMode;
				break;

			case 'n':
				action = kRebootToNormalMode;
				break;

			case 'r':
				action = kResetDevice;
				break;

			case 's':
				action = kStartShell;
				break;

			case 'f':
				action = kSendFile;
				argument = optarg;
				break;

			case 'c':
				action = kSendCommand;
				argument = optarg;
				break;

			case 'k':
				action = kSendExploit;
				argument = optarg;
				break;

			case 'e':
				action = kSendScript;
				argument = optarg;
				break;

			default:
				fprintf(stderr, "Unknown argument\n");
				return -1;
		}
	}

	if (verbose)
		irecv_set_debug_level(verbose);

	irecv_init();
	irecv_client_t client = NULL;
	for (i = 0; i <= 5; i++) {
		debug("Attempting to connect... \n");

		if (irecv_open_with_ecid(&client, ecid) != IRECV_E_SUCCESS)
			sleep(1);
		else
			break;

		if (i == 5) {
			return -1;
		}
	}

	irecv_device_t device = NULL;
	irecv_devices_get_device_by_client(client, &device);
	if (device)
		debug("Connected to %s, model %s, cpid 0x%04x, bdid 0x%02x\n", device->product_type, device->hardware_model, device->chip_id, device->board_id);

	switch (action) {
		case kResetDevice:
			irecv_reset(client);
			break;

		case kSendFile:
			irecv_event_subscribe(client, IRECV_PROGRESS, &progress_cb, NULL);
			error = irecv_send_file(client, argument, 1);
			debug("%s\n", irecv_strerror(error));
			break;

		case kSendCommand:
			error = irecv_send_command(client, argument);
			debug("%s\n", irecv_strerror(error));
			break;

		case kSendExploit:
			if (argument != NULL) {
				irecv_event_subscribe(client, IRECV_PROGRESS, &progress_cb, NULL);
				error = irecv_send_file(client, argument, 0);
				if (error != IRECV_E_SUCCESS) {
					debug("%s\n", irecv_strerror(error));
					break;
				}
			}
			error = irecv_trigger_limera1n_exploit(client);
			debug("%s\n", irecv_strerror(error));
			break;

		case kStartShell:
			init_shell(client);
			break;

		case kSendScript:
			buffer_read_from_filename(argument, &buffer, &buffer_length);
			if (buffer) {
				buffer[buffer_length] = '\0';

				error = irecv_execute_script(client, buffer);
				if(error != IRECV_E_SUCCESS) {
					debug("%s\n", irecv_strerror(error));
				}

				free(buffer);
			} else {
				fprintf(stderr, "Could not read file '%s'\n", argument);
			}
			break;

		case kShowMode:
			irecv_get_mode(client, &mode);
			printf("%s Mode\n", mode_to_str(mode));
			break;

		case kRebootToNormalMode:
			error = irecv_setenv(client, "auto-boot", "true");
			if (error != IRECV_E_SUCCESS) {
				debug("%s\n", irecv_strerror(error));
				break;
			}

			error = irecv_saveenv(client);
			if (error != IRECV_E_SUCCESS) {
				debug("%s\n", irecv_strerror(error));
				break;
			}

			error = irecv_reboot(client);
			if (error != IRECV_E_SUCCESS) {
				debug("%s\n", irecv_strerror(error));
			} else {
				debug("%s\n", irecv_strerror(error));
			}
			break;
		default:
			fprintf(stderr, "Unknown action\n");
			break;
	}

	irecv_close(client);

	return 0;
}