Пример #1
0
irecv_error_t mobiledevice_openpipes(irecv_client_t client)
{
	if (client->iBootPath
	    && !(client->hIB =
		 CreateFile(client->iBootPath, GENERIC_READ | GENERIC_WRITE,
			    FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
			    OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL))) {
		irecv_close(client);
		return IRECV_E_UNABLE_TO_CONNECT;
	}
	if (client->DfuPath
	    && !(client->hDFU =
		 CreateFile(client->DfuPath, GENERIC_READ | GENERIC_WRITE,
			    FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
			    OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL))) {
		irecv_close(client);
		return IRECV_E_UNABLE_TO_CONNECT;
	}

	if (client->iBootPath == NULL) {
		client->mode = kDfuMode;
		client->handle = client->hDFU;
	} else {
		client->mode = kRecoveryMode2;
		client->handle = client->hIB;
	}

	return IRECV_E_SUCCESS;
}
Пример #2
0
int recovery_send_applelogo(const char* ipsw, plist_t tss) {
	irecv_client_t recovery = NULL;
	const char* component = "applelogo";
	irecv_error_t recovery_error = IRECV_E_SUCCESS;

	info("Sending %s...\n", component);
	if (recovery_open_with_timeout(&recovery) < 0) {
		return -1;
	}

	if (recovery_send_signed_component(recovery, ipsw, tss, "AppleLogo") < 0) {
		error("ERROR: Unable to send %s to device.\n", component);
		irecv_close(recovery);
		return -1;
	}

	recovery_error = irecv_send_command(recovery, "setpicture 1");
	if (recovery_error != IRECV_E_SUCCESS) {
		error("ERROR: Unable to set %s\n", component);
		irecv_close(recovery);
		return -1;
	}

	recovery_error = irecv_send_command(recovery, "bgcolor 0 0 0");
	if (recovery_error != IRECV_E_SUCCESS) {
		error("ERROR: Unable to display %s\n", component);
		irecv_close(recovery);
		return -1;
	}

	irecv_close(recovery);
	recovery = NULL;
	return 0;
}
Пример #3
0
int recovery_send_kernelcache(const char* ipsw, plist_t tss) {
	irecv_client_t recovery = NULL;
	const char* component = "kernelcache";
	irecv_error_t recovery_error = IRECV_E_SUCCESS;

	if (recovery_open_with_timeout(&recovery) < 0) {
		return -1;
	}

	if (recovery_send_signed_component(recovery, ipsw, tss, "RestoreKernelCache") < 0) {
		error("ERROR: Unable to send %s to device.\n", component);
		irecv_close(recovery);
		return -1;
	}

	recovery_error = irecv_send_command(recovery, "bootx");
	if (recovery_error != IRECV_E_SUCCESS) {
		error("ERROR: Unable to execute %s\n", component);
		irecv_close(recovery);
		return -1;
	}

	irecv_close(recovery);
	recovery = NULL;
	return 0;
}
Пример #4
0
int normal_enter_recovery(struct idevicerestore_client_t* client) {
	idevice_t device = NULL;
	irecv_client_t recovery = NULL;
	lockdownd_client_t lockdown = NULL;
	irecv_error_t recovery_error = IRECV_E_SUCCESS;
	idevice_error_t device_error = IDEVICE_E_SUCCESS;
	lockdownd_error_t lockdown_error = LOCKDOWN_E_SUCCESS;

	device_error = idevice_new(&device, client->uuid);
	if (device_error != IDEVICE_E_SUCCESS) {
		error("ERROR: Unable to find device\n");
		return -1;
	}

	lockdown_error = lockdownd_client_new(device, &lockdown, "idevicerestore");
	if (lockdown_error != LOCKDOWN_E_SUCCESS) {
		error("ERROR: Unable to connect to lockdownd service\n");
		idevice_free(device);
		return -1;
	}

	lockdown_error = lockdownd_enter_recovery(lockdown);
	if (lockdown_error != LOCKDOWN_E_SUCCESS) {
		error("ERROR: Unable to place device in recovery mode\n");
		lockdownd_client_free(lockdown);
		idevice_free(device);
		return -1;
	}

	lockdownd_client_free(lockdown);
	idevice_free(device);
	lockdown = NULL;
	device = NULL;

	if (recovery_open_with_timeout(client) < 0) {
		error("ERROR: Unable to enter recovery mode\n");
		return -1;
	}

	recovery_error = irecv_send_command(recovery, "setenv auto-boot true");
	if (recovery_error != IRECV_E_SUCCESS) {
		error("ERROR: Unable to reset auto-boot variable\n");
		irecv_close(recovery);
		return -1;
	}

	recovery_error = irecv_send_command(recovery, "saveenv");
	if (recovery_error != IRECV_E_SUCCESS) {
		error("ERROR: Unable to save auto-boot variable\n");
		irecv_close(recovery);
		return -1;
	}

	//client->mode = &idevicerestore_modes[MODE_RECOVERY];
	irecv_close(recovery);
	recovery = NULL;
	return 0;
}
Пример #5
0
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;
}
Пример #6
0
int main(int argc, char *argv[]) {
	printf("iRecovery - Recovery Utility\n");
	printf("by westbaer\nThanks to pod2g, tom3q, planetbeing, geohot and posixninja.\n\n");
	if(argc < 2) {
		irecv_usage();
		return -1;
	}

	struct usb_dev_handle* handle = irecv_init(RECV_MODE);
	if (handle == NULL) {
		handle = irecv_init(WTF_MODE);
		if (handle == NULL) {
		    printf("No iPhone/iPod found.\n");
		    return -1;
		    
		} else {
		    printf("Found iPhone/iPod in DFU/WTF mode\n");
		}
	} else {
	    printf("Found iPhone/iPod in Recovery mode\n");
	}
	
	if(!strcmp(argv[1], "-f")) {
	    if(argc == 3) {
            irecv_upload(handle, argv[2]);
        }
            
	} else if(!strcmp(argv[1], "-c")) {
	   	if(argc >= 3) {
	        irecv_command(handle, argc-2, &argv[2]);
	    }

	} else if(!strcmp(argv[1], "-k")) {
	   	if(argc >= 3) {
	        irecv_exploit(handle, argv[2]);
	    } else {
	        irecv_exploit(handle, NULL);
	    }

	} else if(!strcmp(argv[1], "-s")) {
	   	if(argc >= 3) {
            irecv_console(handle, argv[2]);
	    } else {
	        irecv_console(handle, NULL);
	    }
	    
	} else if(!strcmp(argv[1], "-r")) {
        irecv_reset(handle);
	} else if (!strcmp(argv[1], "-l")) {
	    irecv_list(handle, argv[2]);
	}
	  else if (!strcmp(argv[1], "-x")) {
	    if(argc == 3) {
	    irecv_upload(handle, argv[2]);
	    irecv_reset(handle);
		}
	}
	irecv_close(handle);
	return 0;
}
Пример #7
0
/*
 * Class:     Jsyringe
 * Method:    wait_for_connect
 * Signature: (I)Ljava/lang/Boolean;
 */
JNIEXPORT jboolean JNICALL Java_Jsyringe_wait_1for_1connect
  (JNIEnv *env, jclass jClass)
{
	jboolean jresult = JNI_FALSE;
	if (g_syringe_client != NULL) {
		irecv_close(&g_syringe_client);
	}
	if (0 == irecv_open(&g_syringe_client) && g_syringe_client->mode == kDfuMode) {
		if (irecv_get_device(g_syringe_client, &g_syringe_device) == IRECV_E_SUCCESS) {
			g_model = g_syringe_device->model;
			jresult = JNI_TRUE;
		}
	}
cleanup:
	if (g_syringe_client != NULL)
		irecv_close(&g_syringe_client);
	return jresult;
}
Пример #8
0
int recovery_check_mode() {
	irecv_client_t recovery = NULL;
	irecv_error_t recovery_error = IRECV_E_SUCCESS;

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

	if (recovery->mode == kDfuMode) {
		irecv_close(recovery);
		return -1;
	}

	irecv_close(recovery);
	recovery = NULL;
	return 0;
}
Пример #9
0
int recovery_get_bdid(uint32_t* bdid) {
	irecv_client_t recovery = NULL;
	irecv_error_t recovery_error = IRECV_E_SUCCESS;

	if (recovery_open_with_timeout(&recovery) < 0) {
		return -1;
	}

	recovery_error = irecv_get_bdid(recovery, bdid);
	if (recovery_error != IRECV_E_SUCCESS) {
		irecv_close(recovery);
		return -1;
	}

	irecv_close(recovery);
	recovery = NULL;
	return 0;
}
Пример #10
0
void recovery_client_free(struct idevicerestore_client_t* client) {
	if(client) {
		if (client->recovery) {
			if(client->recovery->client) {
				irecv_close(client->recovery->client);
				client->recovery->client = NULL;
			}
			free(client->recovery);
			client->recovery = NULL;
		}
	}
}
Пример #11
0
void dfu_client_free(struct idevicerestore_client_t* client) {
	if(client != NULL) {
		if (client->dfu != NULL) {
			if(client->dfu->client != NULL) {
				irecv_close(client->dfu->client);
				client->dfu->client = NULL;
			}
			free(client->dfu);
		}
		client->dfu = NULL;
	}
}
Пример #12
0
int recovery_check_mode(struct idevicerestore_client_t* client) {
	irecv_client_t recovery = NULL;
	irecv_error_t recovery_error = IRECV_E_SUCCESS;

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

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

	if ((recovery->mode == kDfuMode) || (recovery->mode == kWTFMode)) {
		irecv_close(recovery);
		return -1;
	}

	irecv_close(recovery);
	recovery = NULL;

	return 0;
}
Пример #13
0
int recovery_send_ibec(const char* ipsw, plist_t tss) {
	irecv_client_t recovery = NULL;
	const char* component = "iBEC";
	irecv_error_t recovery_error = IRECV_E_SUCCESS;

	if (recovery_open_with_timeout(&recovery) < 0) {
		return -1;
	}

	recovery_error = irecv_send_command(recovery, "setenv auto-boot true");
	if (recovery_error != IRECV_E_SUCCESS) {
		error("ERROR: Unable to set auto-boot environmental variable\n");
		irecv_close(recovery);
		return -1;
	}

	recovery_error = irecv_send_command(recovery, "saveenv");
	if (recovery_error != IRECV_E_SUCCESS) {
		error("ERROR: Unable to save environmental variable\n");
		irecv_close(recovery);
		return -1;
	}

	if (recovery_send_signed_component(recovery, ipsw, tss, "iBEC") < 0) {
		error("ERROR: Unable to send %s to device.\n", component);
		irecv_close(recovery);
		return -1;
	}

	recovery_error = irecv_send_command(recovery, "go");
	if (recovery_error != IRECV_E_SUCCESS) {
		error("ERROR: Unable to execute %s\n", component);
		irecv_close(recovery);
		return -1;
	}

	irecv_close(recovery);
	recovery = NULL;
	return 0;
}
Пример #14
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;

	irecv_init();
	dfu_error=irecv_open(&dfu, client->ecid);

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

	if ((dfu->mode != kDfuMode) && (dfu->mode != kWTFMode)) {
		irecv_close(dfu);
		return -1;
	}

	*mode = (dfu->mode == kWTFMode) ? MODE_WTF : MODE_DFU;

	irecv_close(dfu);

	return 0;
}
Пример #15
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;
}
Пример #16
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;
}
Пример #17
0
irecv_client_t irecv_reconnect(irecv_client_t client, int initial_pause)
{
	irecv_error_t error = 0;
	irecv_client_t new_client = NULL;
	irecv_event_cb_t progress_callback = client->progress_callback;
#ifdef _WIN32
#ifdef _GUI_ENABLE_
	char buffer[256];
#endif
#endif

	if (check_context(client) == IRECV_E_SUCCESS) {
		irecv_close(client);
	}

#ifdef _WIN32
#ifdef _GUI_ENABLE_
	snprintf(buffer, 256, "Waiting %d seconds for the device...\n", initial_pause);
	SendMessage(hStatus3, WM_SETTEXT, 0, (LPARAM)buffer);
	InvalidateRect(window, NULL, TRUE);
#endif
#endif
	if (initial_pause > 0) {
		DPRINT("Waiting %d seconds for the device to pop up...\n",
		       initial_pause);
		sleep(initial_pause);
	}
#ifdef _WIN32
#ifdef _GUI_ENABLE_
	SendMessage(hStatus3, WM_SETTEXT, 0, (LPARAM) TEXT(" "));
	InvalidateRect(window, NULL, TRUE);
#endif
#endif

	error = irecv_open_attempts(&new_client, 10);
	if (error != IRECV_E_SUCCESS) {
		return NULL;
	}

	new_client->progress_callback = progress_callback;
	return new_client;
}
Пример #18
0
const char* dfu_check_hardware_model(struct idevicerestore_client_t* client) {
	irecv_client_t dfu = NULL;
	irecv_error_t dfu_error = IRECV_E_SUCCESS;
	irecv_device_t device = NULL;

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

	dfu_error = irecv_devices_get_device_by_client(dfu, &device);
	if (dfu_error != IRECV_E_SUCCESS) {
		return NULL;
	}

	irecv_close(dfu);

	return device->hardware_model;
}
Пример #19
0
int dfu_send_buffer(struct idevicerestore_client_t* client, char* buffer, uint32_t size)
{
	irecv_error_t error = 0;

	info("Sending data (%d bytes)...\n", size);

	error = irecv_send_buffer(client->dfu->client, buffer, size, 1);
	if (error != IRECV_E_SUCCESS) {
		error("ERROR: Unable to send data: %s\n", irecv_strerror(error));
		return -1;
	}

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

	return 0;
}
Пример #20
0
/*
 * Class:     Jsyringe
 * Method:    exploit
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_Jsyringe_exploit
  (JNIEnv * env, jclass jClass)
{
	int result = 0;
	irecv_error_t ir_error = IRECV_E_SUCCESS;
	irecv_client_t client = g_syringe_client;

	libpois0n_debug = 1;

	pois0n_init();

	info("Waiting for device to enter DFU mode\n");
	while(pois0n_is_ready()) {
		sleep(1);
	}

	info("Found device in DFU mode\n");
	result = pois0n_is_compatible();
	if (result < 0) {
		error("Your device in incompatible with this exploit!\n");
		goto cleanup;
	}

	result = pois0n_injectonly();
	if (result < 0) {
		error("Exploit injection failed!\n");
		goto cleanup;
	}
	result = 0;

cleanup:
	fflush(stderr);
	if (g_syringe_client) {
		irecv_close(&g_syringe_client);
		g_syringe_client = NULL;
	}
	
	//pois0n_exit();
	return result;
}
Пример #21
0
irecv_client_t irecv_reconnect(irecv_client_t client, int initial_pause) {
	irecv_error_t error = 0;
	irecv_client_t new_client = NULL;
	irecv_event_cb_t progress_callback = client->progress_callback;

	if (check_context(client) == IRECV_E_SUCCESS) {
		irecv_close(client);
	}

	if (initial_pause > 0) {
		debug("Waiting %d seconds for the device to pop up...\n", initial_pause);
		sleep(initial_pause);
	}
	
	error = irecv_open_attempts(&new_client, 10);
	if(error != IRECV_E_SUCCESS) {
		return NULL;
	}

	new_client->progress_callback = progress_callback;
	return new_client;
}
Пример #22
0
void irecv_sendcmd(char *cmd) {
	int length;
	char *sendbuf;
	irecv_init(RECV_MODE);

	if(devPhone == 0) {
		printf("No iPhone/iPod found.\n");
		exit(EXIT_FAILURE);
	}
	
	sendbuf = malloc(160);
	
	length = (int)(((strlen(cmd)-1)/0x10)+1)*0x10;
	memset(sendbuf, 0, length);
	memcpy(sendbuf, cmd, strlen(cmd));
	if(!usb_control_msg(devPhone, 0x40, 0, 0, 0, sendbuf, length, 1000)) {
		printf("[!] %s", usb_strerror());
	}
	
	free(sendbuf);
	irecv_close(devPhone);	
}
Пример #23
0
int pois0n_is_ready() {
	irecv_error_t error = IRECV_E_SUCCESS;

	//////////////////////////////////////
	// Begin
	// debug("Connecting to device\n");
	error = irecv_open(&client, device->chip_id);
	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");
	if (client->mode != kDfuMode) {
		error("Device must be in DFU mode to continue\n");
		irecv_close(client);
		return -1;
	}

	return 0;
}
Пример #24
0
int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_identity) {
	irecv_client_t dfu = NULL;
	const char* component = "iBSS";
	irecv_error_t dfu_error = IRECV_E_SUCCESS;

	if (recovery_open_with_timeout(client) < 0 || dfu->mode != kDfuMode) {
		error("ERROR: Unable to connect to DFU device\n");
		if (dfu)
			irecv_close(dfu);
		return -1;
	}

	if (recovery_send_component(client, build_identity, component) < 0) {
		error("ERROR: Unable to send %s to device\n", component);
		irecv_close(dfu);
		return -1;
	}

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

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

	client->mode = &idevicerestore_modes[MODE_RECOVERY];
	irecv_close(client->dfu->client);
	client->dfu->client = NULL;
	return 0;
}
Пример #25
0
irecv_error_t mobiledevice_connect(irecv_client_t* client) {
	irecv_error_t ret;

	SP_DEVICE_INTERFACE_DATA currentInterface;
	HDEVINFO usbDevices;
	DWORD i;
	LPSTR path;
	irecv_client_t _client = (irecv_client_t) malloc(sizeof(struct irecv_client));
	memset(_client, 0, sizeof(struct irecv_client));

	// Get DFU paths
	usbDevices = SetupDiGetClassDevs(&GUID_DEVINTERFACE_DFU, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
	if(!usbDevices) {
		return IRECV_E_UNABLE_TO_CONNECT;
	}
	currentInterface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
	for(i = 0; SetupDiEnumDeviceInterfaces(usbDevices, NULL, &GUID_DEVINTERFACE_DFU, i, &currentInterface); i++) {
		DWORD requiredSize = 0;
		PSP_DEVICE_INTERFACE_DETAIL_DATA details;
		SetupDiGetDeviceInterfaceDetail(usbDevices, &currentInterface, NULL, 0, &requiredSize, NULL);
		details = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc(requiredSize);
		details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
		if(!SetupDiGetDeviceInterfaceDetail(usbDevices, &currentInterface, details, requiredSize, NULL, NULL)) {
			irecv_close(_client);
			free(details);
			SetupDiDestroyDeviceInfoList(usbDevices);
			return IRECV_E_UNABLE_TO_CONNECT;
		} else {
			LPSTR result = (LPSTR) malloc(requiredSize - sizeof(DWORD));
			memcpy((void*) result, details->DevicePath, requiredSize - sizeof(DWORD));
			free(details);
			path = (LPSTR) malloc(requiredSize - sizeof(DWORD));
			memcpy((void*) path, (void*) result, requiredSize - sizeof(DWORD));
			TCHAR* pathEnd = strstr(path, "#{");
			*pathEnd = '\0';
			_client->DfuPath = result;
			break;
		}
	}
	SetupDiDestroyDeviceInfoList(usbDevices);
	// Get iBoot path
	usbDevices = SetupDiGetClassDevs(&GUID_DEVINTERFACE_IBOOT, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
	if(!usbDevices) {
		irecv_close(_client);
		return IRECV_E_UNABLE_TO_CONNECT;
	}
	currentInterface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
	for(i = 0; SetupDiEnumDeviceInterfaces(usbDevices, NULL, &GUID_DEVINTERFACE_IBOOT, i, &currentInterface); i++) {
		DWORD requiredSize = 0;
		PSP_DEVICE_INTERFACE_DETAIL_DATA details;
		SetupDiGetDeviceInterfaceDetail(usbDevices, &currentInterface, NULL, 0, &requiredSize, NULL);
		details = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc(requiredSize);
		details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
		if(!SetupDiGetDeviceInterfaceDetail(usbDevices, &currentInterface, details, requiredSize, NULL, NULL)) {
			irecv_close(_client);
			free(details);
			SetupDiDestroyDeviceInfoList(usbDevices);
			return IRECV_E_UNABLE_TO_CONNECT;
		} else {
			LPSTR result = (LPSTR) malloc(requiredSize - sizeof(DWORD));
			memcpy((void*) result, details->DevicePath, requiredSize - sizeof(DWORD));
			free(details);

			if(strstr(result, path) == NULL) {
				free(result);
				continue;
			}
			
			_client->iBootPath = result;
			break;
		}
	}
	SetupDiDestroyDeviceInfoList(usbDevices);
	free(path);
	
	ret = mobiledevice_openpipes(_client);
	if (ret != IRECV_E_SUCCESS) return ret;
	
	*client = _client;
	return IRECV_E_SUCCESS;
}
Пример #26
0
int main(int argc, char* argv[]) {
	int i = 0;
	int opt = 0;
	int action = 0;
	char* argument = NULL;
	irecv_error_t error = 0;
	if (argc == 1) print_usage();
	while ((opt = getopt(argc, argv, "vhrsc:f:e:k::")) > 0) {
		switch (opt) {
		case 'v':
			verbose += 1;
			break;

		case 'h':
			print_usage();
			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(&client) != IRECV_E_SUCCESS)
			sleep(1);
		else
			break;

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

	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_send_exploit(client);
		debug("%s\n", irecv_strerror(error));
		break;

	case kStartShell:
		init_shell(client);
		break;

	case kSendScript:
		error = irecv_execute_script(client, argument);
		if(error != IRECV_E_SUCCESS) {
			debug("%s\n", irecv_strerror(error));
		}
		break;

	default:
		fprintf(stderr, "Unknown action\n");
		break;
	}

	irecv_close(client);
	return 0;
}
Пример #27
0
void pois0n_exit() {
	debug("Exiting libpois0n\n");
	irecv_close(client);
	irecv_exit();
}
Пример #28
0
int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_identity) {
	irecv_error_t dfu_error = IRECV_E_SUCCESS;

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

	if (client->dfu->client->mode != kDfuMode) {
		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);
		return -1;
	}

	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);
		return -1;
	}

	if (client->build[0] > '8') {
		/* reconnect */
		dfu_client_free(client);
		sleep(1);
		dfu_client_new(client);

		/* get nonce */
		unsigned char* nonce = NULL;
		int nonce_size = 0;
		int nonce_changed = 0;
		if (dfu_get_nonce(client, &nonce, &nonce_size) < 0) {
			error("ERROR: Unable to get nonce 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_shsh_blobs(client, client->ecid, client->nonce, client->nonce_size, 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_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);
			return -1;
		}

		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);
			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 || client->recovery->client->mode == kDfuMode) {
		error("ERROR: Unable to connect to recovery device\n");
		if (client->recovery->client)
			irecv_close(client->recovery->client);
		return -1;
	}
	return 0;
}
Пример #29
0
void irecv_sendfile(char *filename) {
	FILE *file;
	int packets, len, last, i, a, c, sl;
	char *fbuf, buf[6];
	
	if(!filename)
		return;

	file = fopen(filename, "rb");
	if(file == NULL) {
		printf("File %s not found.\n", filename);
		exit(EXIT_FAILURE);
	}
	fseek(file, 0, 0);
	fclose(file);

	irecv_init(WTF_MODE);
	if(!devPhone) {
		devPhone = irecv_init(RECV_MODE);
		if(devPhone) {
			printf("Found iPhone/iPod in Recovery mode\n");
		}
	} else {
		printf("Found iPhone/iPod in DFU/WTF mode\n");
	}

	if(!devPhone) {
		printf("No iPhone/iPod found.\n");
		exit(EXIT_FAILURE);
	}

	if(usb_set_configuration(devPhone, 1)) {
		printf("Error setting configuration\n");
	}

	printf("\n");

	file = fopen(filename, "rb");
	fseek(file, 0, SEEK_END);
	len = ftell(file);
	fseek(file, 0, 0);

	packets = len / 0x800;
	if(len % 0x800)
		packets++;
	last = len % 0x800;

	printf("Loaded image file (len: 0x%x, packets: %d, last: 0x%x).\n", len, packets, last);

	fbuf = malloc(packets * 0x800);
	if(!last) {
		last = 0x800;
	}
	
	fread(fbuf, 1, len, file);
	fclose(file);

	printf("Sending 0x%x bytes\n", len);

	for(i=0, a=0, c=0; i<packets; i++, a+=0x800, c++) {
		sl = 0x800;

		if(i == packets-1) {
			sl = last;
		}

		printf("Sending 0x%x bytes in packet %d... ", sl, c);

		if(usb_control_msg(devPhone, 0x21, 1, c, 0, &fbuf[a], sl, 1000)) {
			printf(" OK\n");
		} else{
			printf(" x\n");
		}

		if(usb_control_msg(devPhone, 0xA1, 3, 0, 0, buf, 6, 1000) != 6){
			printf("Error receiving status!\n");
		} else {
			irecv_hexdump(buf, 6);
			if(buf[4]!=5) {
				printf("Status error!\n");
			}
		}
	}

	printf("Successfully uploaded file!\nExecuting it...\n");	

	usb_control_msg(devPhone, 0x21, 1, c, 0, fbuf, 0, 1000);

	for(i=6; i<=8; i++) {
		if(usb_control_msg(devPhone, 0xA1, 3, 0, 0, buf, 6, 1000) != 6){
			printf("Error receiving status!\n");
		} else {
			irecv_hexdump(buf, 6);
			if(buf[4]!=i) {
				printf("Status error!\n");
			}
		}
	}

	free(fbuf);
	irecv_close(devPhone);
}
Пример #30
0
int tethered_boot(const char *ibssFile, const char *ibecFile, const char *kernelcacheFile, const char *ramdiskFile, const char *devicetreeFile)
{
	int result = 0;
	irecv_error_t ir_error = IRECV_E_SUCCESS;
	irecv_client_t client = g_syringe_client;

	libpois0n_debug = 1;

	pois0n_init();

	info("Waiting for device to enter DFU mode\n");
	while(pois0n_is_ready()) {
		sleep(1);
	}

	info("Found device in DFU mode\n");
	result = pois0n_is_compatible();
	if (result < 0) {
		error("Your device in incompatible with this exploit!\n");
		goto cleanup;
	}

	result = pois0n_injectonly();
	if (result < 0) {
		error("Exploit injection failed!\n");
		goto cleanup;
	}
	client = g_syringe_client;

	if (ibssFile != NULL) {
		debug("Uploading %s to device, mode: 0x%x\n", ibssFile, client->mode);
		ir_error = irecv_send_file(client, ibssFile, 1);
		if(ir_error != IRECV_E_SUCCESS) {
			error("Unable to upload iBSS\n");
			debug("%s\n", irecv_strerror(ir_error));
			result = -1;
			goto cleanup;
		}
		
		sleep(10);

	} else {
		error("ibss can't be null\n");
		result = -1;
		goto cleanup;
	}

	if (ibecFile != NULL) {
		client = g_syringe_client = irecv_reconnect(client, 10);

		debug("Uploading iBEC %s to device, mode: 0x%x\n", ibecFile, client->mode);
		ir_error = irecv_send_file(client, ibecFile, 1);
		if(ir_error != IRECV_E_SUCCESS) {
			error("Unable to upload iBEC\n");
			debug("%s\n", irecv_strerror(ir_error));
			result = -1;
			goto cleanup;
		}

		sleep(5);
	}

	client = g_syringe_client = irecv_reconnect(client, 10);

	if (ramdiskFile != NULL) {
		debug("Uploading ramdisk %s to device\n", ramdiskFile);
		ir_error = irecv_send_file(client, ramdiskFile, 1);
		if(ir_error != IRECV_E_SUCCESS) {
			error("Unable to upload ramdisk\n");
			debug("%s\n", irecv_strerror(ir_error));
			result = -1;
			goto cleanup;
		}

		sleep(5);

		ir_error = irecv_send_command(client, "ramdisk");
		if(ir_error != IRECV_E_SUCCESS) {
			error("Unable send the ramdisk command\n");
			result = -1;
			goto cleanup;
		}	
	}

	if (devicetreeFile != NULL) {
	        debug("Uploading device tree %s to device\n", devicetreeFile);
		ir_error = irecv_send_file(client, devicetreeFile, 1);
		if(ir_error != IRECV_E_SUCCESS) {
			error("Unable to upload device tree\n");
			debug("%s\n", irecv_strerror(ir_error));
			result = -1;
			goto cleanup;
		}

		ir_error = irecv_send_command(client, "devicetree");
		if(ir_error != IRECV_E_SUCCESS) {
			error("Unable to send the devicetree command\n");
			result = -1;
			goto cleanup;
		}
	}
	
	if (kernelcacheFile != NULL) {
		debug("Uploading kernel %s to device, mode: 0x%x\n", kernelcacheFile, client->mode);
		ir_error = irecv_send_file(client, kernelcacheFile, 1);
		if(ir_error != IRECV_E_SUCCESS) {
			error("Unable to upload kernelcache\n");
			debug("%s\n", irecv_strerror(ir_error));
			result = -1;
			goto cleanup;
		}

		ir_error = irecv_send_command(client, "bootx");
		if(ir_error != IRECV_E_SUCCESS) {
			error("Unable send the bootx command\n");
			result = -1;
			goto cleanup;
		}
	} else {
		error("kernelcache can't be null\n");
		result = -1;
		goto cleanup;
	}

	result = 0;

cleanup:
	fflush(stderr);
	if (g_syringe_client) {
		irecv_close(&g_syringe_client);
		g_syringe_client = NULL;
	}
	
	//pois0n_exit();
	return result;
}