int device_autoboot() { printf("[Device] Enabling auto-boot.\r\n"); char* command[3]; command[0] = "setenv auto-boot true"; command[1] = "saveenv"; command[2] = "reboot"; device_sendcmd(&command[0]); device_sendcmd(&command[1]); device_sendcmd(&command[2]); return 1; }
int exploit() { printf("[Exploit] iBoot Envirement Overflow being executed \n"); char* cmd = "setenv a bbbbbbbbb1bbbbbbbbb2bbbbbbbbb3bbbbbbbbb4bbbbbbbbb5bbbbbbbbb6bbbbbbbbb7bbbbbbbbb8bbbbbbbbb9bbbbbbbbbAbbbbbbbbbBbbbbbbbbbCbbbbbbbbbDbbbbbbbbbEbbbbbbbbbbbbtbbbbbbbbbubbbbbbbbbvbbbbbbbbbwbbbbbbbbbxbbbbbbbbbybbbbbbbbbzbbbbbbbbbHbbbbbbbbbIbbbbbbbbbJbbbbgeohotbbbbbbbbbLbbbbbbbbbMbbbbbbbbbNbbbbbbbbbObbbbbbbbbPbbbbbbbbbbQbbbbbbbbbRbbbbbbbbbSbbbbbbbbbTbbbbbbbbbUbbbbbbbbbVbbbbbbbbbWbbbbbbbxxxx $a $a $a $a geohotaaaa \"\x04\x01\" \\ \"\x0c\" \\ \\ \\ \\ \\ \"\x41\x04\xA0\x02\" \\ \\ \\ \\ wwww;echo copyright;echo geohot"; device_sendcmd(cmd); return -1; }
int prog_batch(char *filename) { //max command length char line[0x200]; FILE* script = fopen(filename, "rb"); if (script == NULL) { printf("[Program] Unable to find batch file.\r\n"); return -1; } printf("\n"); while (fgets(line, 0x200, script) != NULL) { if(!((line[0]=='/') && (line[1]=='/'))) { if(line[0] == '/') { printf("[Program] Running command: %s", line); char byte; int offset = (strlen(line) - 1); while(offset > 0) { if (line[offset] == 0x0D || line[offset] == 0x0A) line[offset--] = 0x00; else break; }; prog_parse(&line[1]); } else { char *command[1]; command[0] = line; device_sendcmd(command); } } } fclose(script); return 0; }
void prog_handle(int argc, char *argv[]) { if (! strcmp(argv[1], "-a")) { device_autoboot(); } else if (! strcmp(argv[1], "-c")) { if (argc >= 3) { if (argc > 3) { char command[0x200]; int i = 2; for (i; i < argc; i++) { if (i > 2) strcat(command, " "); strcat(command, argv[i]); } argv[2] = command; } device_sendcmd(&argv[2]); } } else if (! strcmp(argv[1], "-r")) { device_reset(); } else if (! strcmp(argv[1], "-b")) { prog_batch(argv[2]); } else if (! strcmp(argv[1], "-u") || ! strcmp(argv[1], "-x")) { if (argc == 3) { device_upload(argv[2]); if (! strcmp(argv[1], "-x")) { device_reset(); } } } else if(! strcmp(argv[1], "-e")) { if(argc >= 3) device_exploit(argv[2]); else device_exploit(NULL); } else if (! strcmp(argv[1], "-s")) { if (argc >= 3) //Logfile specified prog_console(argv[2]); else prog_console(NULL); } else { printf("[Program] Invalid program argument specified.\r\n"); prog_usage(); } }
int prog_console(char* logfile) { if(libusb_set_configuration(device, 1) < 0) { printf("[Program] Error setting configuration.\r\n"); return -1; } if(libusb_claim_interface(device, 1) < 0) { printf("[Program] Error claiming interface.\r\n"); return -1; } if(libusb_set_interface_alt_setting(device, 1, 1) < 0) { printf("[Program] Error claiming alt interface.\r\n"); return -1; } char* buffer = malloc(BUF_SIZE); if(buffer == NULL) { printf("[Program] Error allocating memory.\r\n"); return -1; } FILE* fd = NULL; if(logfile != NULL) { fd = fopen(logfile, "w"); if(fd == NULL) { printf("[Program] Unable to open log file.\r\n"); free(buffer); return -1; } } printf("[Program] Attached to Recovery Console.\r\n"); if (logfile) printf("[Program] Output being logged to: %s.\r\n", logfile); read_history(CMD_LOG); while(1) { int bytes = 0; memset(buffer, 0, BUF_SIZE); libusb_bulk_transfer(device, 0x81, buffer, BUF_SIZE, &bytes, 500); if (bytes>0) { int i; for(i = 0; i < bytes; ++i) { fprintf(stdout, "%c", buffer[i]); if(fd) fprintf(fd, "%c", buffer[i]); } } char *command = readline("iRecovery> "); if (command != NULL && *command) { add_history(command); write_history(CMD_LOG); if(fd) fprintf(fd, ">%s\n", command); if (command[0] == '/' && strlen(command) > 1 && command[1] != ' ' && prog_parse(&command[1]) < 0) { free(command); continue; } device_sendcmd(&command); char* action = strtok(strdup(command), " "); if (! strcmp(action, "getenv")) { char response[0x200]; libusb_control_transfer(device, 0xC0, 0, 0, 0, response, 0x200, 1000); printf("Env: %s\r\n", response); } if (! strcmp(action, "reboot")) return -1; } free(command); } free(buffer); if(fd) fclose(fd); libusb_release_interface(device, 1); }
void image_transfer(FILE *fp, ftdi_context_t *c, u8 dump, u8 type, u32 addr, u32 size) { u32 ram_addr = addr; int bytes_left = size; int bytes_done = 0; int bytes_do; int trunc_flag = 0; int i; int chunk = 0; struct timespec time_start; struct timespec time_stop; double time_duration; time_t time_diff_seconds; long time_diff_nanoseconds; dev_cmd_resp_t r; // make sure handle is valid if(!c->handle) die(err[DEV_ERR_NULL_HANDLE], __FUNCTION__); // decide a better, more optimized chunk size if(size > 16 * 1024 * 1024) chunk = 32; else if( size > 2 * 1024 * 1024) chunk = 16; else chunk = 4; // convert to megabytes chunk *= 128 * 1024; if(c->verbose) _printf(info[INFO_CHUNK], CHUNK_SIZE); if(c->verbose) _printf(info[INFO_OPT_CHUNK], chunk); // get initial time count // QueryPerformanceFrequency(&time_freq); // QueryPerformanceCounter(&time_start); clock_gettime(CLOCK_MONOTONIC, &time_start); while(1){ if(bytes_left >= chunk) bytes_do = chunk; else bytes_do = bytes_left; if(bytes_do % 512 != 0) { trunc_flag = 1; bytes_do -= (bytes_do % 512); } if(bytes_do <= 0) break; for(i = 0; i < 2; i++){ if(i == 1) { printf("\n"); _printf("Retrying\n"); FT_ResetPort(c->handle); FT_ResetDevice(c->handle); _printf("Retrying FT_ResetDevice() success\n"); // set synchronous FIFO mode //FT_SetBitMode(c->handle, 0xff, 0x40); _printf("Retrying FT_SetBitMode() success\n"); FT_Purge(c->handle, FT_PURGE_RX | FT_PURGE_TX); _printf("Retrying FT_Purge() success\n"); } device_sendcmd(c, &r, dump ? DEV_CMD_DUMPRAM : DEV_CMD_LOADRAM, 2, 0, 1, ram_addr, (bytes_do & 0xffffff) | type << 24); if(dump){ c->status = FT_Read(c->handle, buffer, bytes_do, &c->bytes_written); fwrite(buffer, bytes_do, 1, fp); }else{ fread(buffer, bytes_do, 1, fp); c->status = FT_Write(c->handle, buffer, bytes_do, &c->bytes_written); } if(c->bytes_written) break; } // check for a timeout if(c->bytes_written == 0) die(err[DEV_ERR_TIMED_OUT], __FUNCTION__); // dump success response c->status = FT_Read(c->handle, buffer, 4, &c->bytes_read); bytes_left -= bytes_do; bytes_done += bytes_do; ram_addr += bytes_do; // progress bar prog_draw(bytes_done, size); c->status = FT_GetStatus(c->handle, &c->bytes_read, &c->bytes_written, &c->event_status); } // stop the timer // QueryPerformanceCounter(&time_stop); clock_gettime(CLOCK_MONOTONIC, &time_stop); // get the difference of the timer time_diff_seconds = time_stop.tv_sec - time_start.tv_sec; time_diff_nanoseconds = time_stop.tv_nsec - time_start.tv_nsec; time_duration = (double)time_diff_seconds + (double)(time_diff_nanoseconds/1000000000.0f); // erase progress bar prog_erase(); if(c->verbose && trunc_flag) _printf(info[INFO_TRUNCATED]); if(c->verbose) _printf(info[INFO_COMPLETED_TIME], time_duration, (float)size/1048576.0f/(float)time_duration); }
void image_set_save(ftdi_context_t *c, u8 save_type) { dev_cmd_resp_t r; device_sendcmd(c, &r, DEV_CMD_SETSAVE, 1, 0, 0, save_type, 0); }