예제 #1
0
파일: libpois0n.c 프로젝트: m1r4ge/syringe
int pois0n_is_ready() {
	irecv_error_t error = IRECV_E_SUCCESS;

	//////////////////////////////////////
	// Begin
	// debug("Connecting to device\n");
	error = irecv_open_with_ecid(&client, 0);
	if (error != IRECV_E_SUCCESS) {
		debug("Device must be in DFU mode to continue\n");
		return -1;
	}
	irecv_event_subscribe(client, IRECV_PROGRESS, &recovery_callback, NULL);

	//////////////////////////////////////
	// Check device
	// debug("Checking the device mode\n");
	int mode;

	if (irecv_get_mode(client, &mode) != IRECV_E_SUCCESS) {
		error("Unable to get current mode\n");
		return -1;
	}

	if (mode != IRECV_K_DFU_MODE) {
		error("Device must be in DFU mode to continue\n");
		irecv_close(client);
		return -1;
	}

	return 0;
}
예제 #2
0
파일: libpois0n.c 프로젝트: m1r4ge/syringe
int upload_dfu_image(const char* type) {
	char image[255];
	struct stat buf;
	irecv_error_t error = IRECV_E_SUCCESS;

	memset(image, '\0', 255);
	snprintf(image, 254, "%s.%s", type, device->hardware_model);

	debug("Checking if %s already exists\n", image);
	if (stat(image, &buf) != 0) {
		if (fetch_dfu_image(type, image) < 0) {
			error("Unable to upload DFU image\n");
			return -1;
		}
	}

	int mode;

	if (irecv_get_mode(client, &mode) != IRECV_E_SUCCESS) {
		error("Unable to get current mode\n");
		return -1;
	}

	if (mode != IRECV_K_DFU_MODE) {
		debug("Resetting device counters\n");
		error = irecv_reset_counters(client);
		if (error != IRECV_E_SUCCESS) {
			debug("%s\n", irecv_strerror(error));
			return -1;
		}
	}

	debug("Uploading %s to device\n", image);
	error = irecv_send_file(client, image, 1);
	if (error != IRECV_E_SUCCESS) {
		debug("%s\n", irecv_strerror(error));
		return -1;
	}
	return 0;
}
예제 #3
0
int recovery_check_mode(struct idevicerestore_client_t* client) {
	irecv_client_t recovery = NULL;
	irecv_error_t recovery_error = IRECV_E_SUCCESS;
	int mode = 0;

	irecv_init();
	recovery_error=irecv_open_with_ecid(&recovery, client->ecid);

	if (recovery_error != IRECV_E_SUCCESS) {
		return -1;
	}

	irecv_get_mode(recovery, &mode);

	if ((mode == IRECV_K_DFU_MODE) || (mode == IRECV_K_WTF_MODE)) {
		irecv_close(recovery);
		return -1;
	}

	irecv_close(recovery);
	recovery = NULL;

	return 0;
}
예제 #4
0
int dfu_check_mode(struct idevicerestore_client_t* client, int* mode) {
	irecv_client_t dfu = NULL;
	irecv_error_t dfu_error = IRECV_E_SUCCESS;
	int probe_mode = -1;

	irecv_init();
	dfu_error = irecv_open_with_ecid(&dfu, client->ecid);
	if (dfu_error != IRECV_E_SUCCESS) {
		return -1;
	}

	irecv_get_mode(dfu, &probe_mode);

	if ((probe_mode != IRECV_K_DFU_MODE) && (probe_mode != IRECV_K_WTF_MODE)) {
		irecv_close(dfu);
		return -1;
	}

	*mode = (probe_mode == IRECV_K_WTF_MODE) ? MODE_WTF : MODE_DFU;

	irecv_close(dfu);

	return 0;
}
예제 #5
0
int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_identity) {
	irecv_error_t dfu_error = IRECV_E_SUCCESS;
	int mode = 0;

	if (dfu_client_new(client) < 0) {
		error("ERROR: Unable to connect to DFU device\n");
		return -1;
	}

	irecv_get_mode(client->dfu->client, &mode);

	if (mode != IRECV_K_DFU_MODE) {
		info("NOTE: device is not in DFU mode, assuming recovery mode.\n");
		client->mode = &idevicerestore_modes[MODE_RECOVERY];
		return 0;
	}

	if (dfu_send_component(client, build_identity, "iBSS") < 0) {
		error("ERROR: Unable to send iBSS to device\n");
		irecv_close(client->dfu->client);
		client->dfu->client = NULL;
		return -1;
	}

	irecv_usb_control_transfer(client->dfu->client, 0x21, 1, 0, 0, 0, 0, 5000);

	dfu_error = irecv_reset(client->dfu->client);
	if (dfu_error != IRECV_E_SUCCESS) {
		error("ERROR: Unable to reset device\n");
		irecv_close(client->dfu->client);
		client->dfu->client = NULL;
		return -1;
	}

	if (client->build_major > 8) {
		/* reconnect */
		dfu_client_free(client);
		sleep(2);
		dfu_client_new(client);

		/* get nonce */
		unsigned char* nonce = NULL;
		int nonce_size = 0;
		int nonce_changed = 0;
		if (dfu_get_ap_nonce(client, &nonce, &nonce_size) < 0) {
			error("ERROR: Unable to get ApNonce from device!\n");
			return -1;
		}

		if (!client->nonce || (nonce_size != client->nonce_size) || (memcmp(nonce, client->nonce, nonce_size) != 0)) {
			nonce_changed = 1;
			if (client->nonce) {
				free(client->nonce);
			}
			client->nonce = nonce;
			client->nonce_size = nonce_size;
		} else {
			free(nonce);
		}

		info("Nonce: ");
		int i;
		for (i = 0; i < client->nonce_size; i++) {
			info("%02x ", client->nonce[i]);
		}
		info("\n");

		if (nonce_changed && !(client->flags & FLAG_CUSTOM)) {
			// Welcome iOS5. We have to re-request the TSS with our nonce.
			plist_free(client->tss);
			if (get_tss_response(client, build_identity, &client->tss) < 0) {
				error("ERROR: Unable to get SHSH blobs for this device\n");
				return -1;
			}
			if (!client->tss) {
				error("ERROR: can't continue without TSS\n");
				return -1;
			}
			fixup_tss(client->tss);
		}

		if (irecv_usb_set_configuration(client->dfu->client, 1) < 0) {
			error("ERROR: set configuration failed\n");
		}

		/* send iBEC */
		if (dfu_send_component(client, build_identity, "iBEC") < 0) {
			error("ERROR: Unable to send iBEC to device\n");
			irecv_close(client->dfu->client);
			client->dfu->client = NULL;
			return -1;
		}

		irecv_usb_control_transfer(client->dfu->client, 0x21, 1, 0, 0, 0, 0, 5000);

		dfu_error = irecv_reset(client->dfu->client);
		if (dfu_error != IRECV_E_SUCCESS) {
			error("ERROR: Unable to reset device\n");
			irecv_close(client->dfu->client);
			client->dfu->client = NULL;
			return -1;
		}
	}

	dfu_client_free(client);

	sleep(7);

	// Reconnect to device, but this time make sure we're not still in DFU mode
	if (recovery_client_new(client) < 0) {
		error("ERROR: Unable to connect to recovery device\n");
		if (client->recovery->client) {
			irecv_close(client->recovery->client);
			client->recovery->client = NULL;
		}
		return -1;
	}

	irecv_get_mode(client->recovery->client, &mode);

	if (mode == IRECV_K_DFU_MODE) {
		error("ERROR: Unable to connect to recovery device\n");
		if (client->recovery->client) {
			irecv_close(client->recovery->client);
			client->recovery->client = NULL;
		}
		return -1;
	}

	return 0;
}
예제 #6
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;
}
예제 #7
0
static void parse_command(irecv_client_t client, unsigned char* command, unsigned int size) {
	char* cmd = strdup((char*)command);
	char* action = strtok(cmd, " ");

	if (!strcmp(cmd, "/exit")) {
		quit = 1;
	} else if (!strcmp(cmd, "/help")) {
		shell_usage();
	} else if (!strcmp(cmd, "/upload")) {
		char* filename = strtok(NULL, " ");
		debug("Uploading files %s\n", filename);
		if (filename != NULL) {
			irecv_send_file(client, filename, 0);
		}
	} else if (!strcmp(cmd, "/deviceinfo")) {
		int ret, mode;
		unsigned int cpid, bdid;
		unsigned long long ecid;
		char srnm[12], imei[15];

		ret = irecv_get_cpid(client, &cpid);
		if(ret == IRECV_E_SUCCESS) {
			printf("CPID: %d\n", cpid);
		}

		ret = irecv_get_bdid(client, &bdid);
		if(ret == IRECV_E_SUCCESS) {
			printf("BDID: %d\n", bdid);
		}

		ret = irecv_get_ecid(client, &ecid);
		if(ret == IRECV_E_SUCCESS) {
			printf("ECID: " _FMT_lld "\n", ecid);
		}

		ret = irecv_get_srnm(client, srnm);
		if(ret == IRECV_E_SUCCESS) {
			printf("SRNM: %s\n", srnm);
		}

		ret = irecv_get_imei(client, imei);
		if(ret == IRECV_E_SUCCESS) {
			printf("IMEI: %s\n", imei);
		}

		ret = irecv_get_mode(client, &mode);
		if (ret == IRECV_E_SUCCESS) {
			printf("MODE: %s\n", mode_to_str(mode));
		}

	} else if (!strcmp(cmd, "/limera1n")) {
		char* filename = strtok(NULL, " ");
		debug("Sending limera1n payload %s\n", filename);
		if (filename != NULL) {
			irecv_send_file(client, filename, 0);
		}
		irecv_trigger_limera1n_exploit(client);
	} else if (!strcmp(cmd, "/execute")) {
		char* filename = strtok(NULL, " ");
		debug("Executing script %s\n", filename);
		if (filename != NULL) {
			char* buffer = NULL;
			uint64_t buffer_length = 0;
			buffer_read_from_filename(filename, &buffer, &buffer_length);
			if (buffer) {
				buffer[buffer_length] = '\0';
				irecv_execute_script(client, buffer);
				free(buffer);
			} else {
				printf("Could not read file '%s'\n", filename);
			}
		}
	}

	free(action);
}
예제 #8
0
static void parse_command(irecv_client_t client, unsigned char* command, unsigned int size) {
	char* cmd = strdup((char*)command);
	char* action = strtok(cmd, " ");

	if (!strcmp(cmd, "/exit")) {
		quit = 1;
	} else if (!strcmp(cmd, "/help")) {
		shell_usage();
	} else if (!strcmp(cmd, "/upload")) {
		char* filename = strtok(NULL, " ");
		debug("Uploading file %s\n", filename);
		if (filename != NULL) {
			irecv_send_file(client, filename, 0);
		}
	} else if (!strcmp(cmd, "/deviceinfo")) {
		int ret, mode;
		const struct irecv_device_info *devinfo = irecv_get_device_info(client);

		if (devinfo) {
			printf("CPID: %04x\n", devinfo->cpid);
			printf("CPRV: %02x\n", devinfo->cprv);
			printf("BDID: %02x\n", devinfo->bdid);
			printf("ECID: " _FMT_lld "\n", devinfo->ecid);
			printf("CPFM: %02x\n", devinfo->cpfm);
			printf("SCEP: %02x\n", devinfo->scep);
			printf("IBFL: %02x\n", devinfo->ibfl);
			printf("SRNM: %s\n", (devinfo->srnm) ? devinfo->srnm : "N/A");
			printf("IMEI: %s\n", (devinfo->imei) ? devinfo->imei : "N/A");
		} else {
			printf("Could not get device info?!\n");
		}

		ret = irecv_get_mode(client, &mode);
		if (ret == IRECV_E_SUCCESS) {
			printf("MODE: %s\n", mode_to_str(mode));
		}

	} else if (!strcmp(cmd, "/limera1n")) {
		char* filename = strtok(NULL, " ");
		debug("Sending limera1n payload %s\n", filename);
		if (filename != NULL) {
			irecv_send_file(client, filename, 0);
		}
		irecv_trigger_limera1n_exploit(client);
	} else if (!strcmp(cmd, "/execute")) {
		char* filename = strtok(NULL, " ");
		debug("Executing script %s\n", filename);
		if (filename != NULL) {
			char* buffer = NULL;
			uint64_t buffer_length = 0;
			buffer_read_from_filename(filename, &buffer, &buffer_length);
			if (buffer) {
				buffer[buffer_length] = '\0';
				irecv_execute_script(client, buffer);
				free(buffer);
			} else {
				printf("Could not read file '%s'\n", filename);
			}
		}
	} else {
		printf("Unsupported command %s. Use /help to get a list of available commands.\n", cmd);
	}

	free(action);
}