From 0e4fb99549e0a1b4f5330598ec30a222e0fb75cc Mon Sep 17 00:00:00 2001 From: Nikias Bassen Date: Mon, 16 Jul 2012 23:41:02 +0200 Subject: moved *.c to src/ subdirectory --- src/irecovery.c | 397 +++++++++++++ src/libirecovery.c | 1684 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 2081 insertions(+) create mode 100644 src/irecovery.c create mode 100644 src/libirecovery.c (limited to 'src') diff --git a/src/irecovery.c b/src/irecovery.c new file mode 100644 index 0000000..89f30a6 --- /dev/null +++ b/src/irecovery.c @@ -0,0 +1,397 @@ +/** + * GreenPois0n iRecovery - irecovery.c + * Copyright (C) 2010-2011 Chronic-Dev Team + * Copyright (C) 2010-2011 Joshua Hill + * Copyright (C) 2008-2011 Nicolas Haunold + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + +#include +#include +#include +#include +#include +#include +#include + +#define FILE_HISTORY_PATH ".irecovery" +#define debug(...) if(verbose) fprintf(stderr, __VA_ARGS__) + +enum { + kResetDevice, kStartShell, kSendCommand, kSendFile, kSendExploit, kSendScript +}; + +static unsigned int quit = 0; +static unsigned int verbose = 0; + +void print_progress_bar(double progress); +int received_cb(irecv_client_t client, const irecv_event_t* event); +int progress_cb(irecv_client_t client, const irecv_event_t* event); +int precommand_cb(irecv_client_t client, const irecv_event_t* event); +int postcommand_cb(irecv_client_t client, const irecv_event_t* event); + +void shell_usage() { + printf("Usage:\n"); + printf("\t/upload \tSend file to client.\n"); + printf("\t/exploit [file]\tSend usb exploit with optional payload\n"); + printf("\t/deviceinfo\tShow device information (ECID, IMEI, etc.)\n"); + printf("\t/help\t\tShow this help.\n"); + printf("\t/exit\t\tExit interactive shell.\n"); +} + +void parse_command(irecv_client_t client, unsigned char* command, unsigned int size) { + char* cmd = strdup(command); + char* action = strtok(cmd, " "); + debug("Executing %s\n", action); + 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; + unsigned int cpid, bdid; + unsigned long long ecid; + unsigned char srnm[12], imei[15], bt[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: %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); + } + } else + + if (!strcmp(cmd, "/exploit")) { + char* filename = strtok(NULL, " "); + debug("Sending exploit %s\n", filename); + if (filename != NULL) { + irecv_send_file(client, filename, 0); + } + irecv_send_exploit(client); + } else + + if (!strcmp(cmd, "/execute")) { + char* filename = strtok(NULL, " "); + debug("Executing script %s\n", filename); + if (filename != NULL) { + irecv_execute_script(client, filename); + } + } + + + free(action); +} + +void load_command_history() { + read_history(FILE_HISTORY_PATH); +} + +void append_command_to_history(char* cmd) { + add_history(cmd); + write_history(FILE_HISTORY_PATH); +} + +void init_shell(irecv_client_t client) { + irecv_error_t error = 0; + load_command_history(); + irecv_event_subscribe(client, IRECV_PROGRESS, &progress_cb, NULL); + irecv_event_subscribe(client, IRECV_RECEIVED, &received_cb, NULL); + irecv_event_subscribe(client, IRECV_PRECOMMAND, &precommand_cb, NULL); + irecv_event_subscribe(client, IRECV_POSTCOMMAND, &postcommand_cb, NULL); + while (!quit) { + error = irecv_receive(client); + + if (error != IRECV_E_SUCCESS) { + debug("%s\n", irecv_strerror(error)); + break; + } + + char* cmd = readline("> "); + if (cmd && *cmd) { + error = irecv_send_command(client, cmd); + if (error != IRECV_E_SUCCESS) { + quit = 1; + } + + append_command_to_history(cmd); + free(cmd); + } + } +} + +int received_cb(irecv_client_t client, const irecv_event_t* event) { + if (event->type == IRECV_RECEIVED) { + int i = 0; + int size = event->size; + char* data = event->data; + for (i = 0; i < size; i++) { + printf("%c", data[i]); + } + } + return 0; +} + +int precommand_cb(irecv_client_t client, const irecv_event_t* event) { + if (event->type == IRECV_PRECOMMAND) { + irecv_error_t error = 0; + if (event->data[0] == '/') { + parse_command(client, event->data, event->size); + return -1; + } + } + return 0; +} + +int postcommand_cb(irecv_client_t client, const irecv_event_t* event) { + char* value = NULL; + char* action = NULL; + char* command = NULL; + char* argument = NULL; + irecv_error_t error = IRECV_E_SUCCESS; + + if (event->type == IRECV_POSTCOMMAND) { + command = strdup(event->data); + action = strtok(command, " "); + if (!strcmp(action, "getenv")) { + argument = strtok(NULL, " "); + error = irecv_getenv(client, argument, &value); + if (error != IRECV_E_SUCCESS) { + debug("%s\n", irecv_strerror(error)); + free(command); + return error; + } + printf("%s\n", value); + free(value); + } + + if (!strcmp(action, "reboot")) { + quit = 1; + } + } + + if (command) free(command); + return 0; +} + +int progress_cb(irecv_client_t client, const irecv_event_t* event) { + if (event->type == IRECV_PROGRESS) { + print_progress_bar(event->progress); + } + return 0; +} + +void print_progress_bar(double progress) { + int i = 0; + if(progress < 0) { + return; + } + + if(progress > 100) { + progress = 100; + } + + printf("\r["); + for(i = 0; i < 50; i++) { + if(i < progress / 2) { + printf("="); + } else { + printf(" "); + } + } + + printf("] %3.1f%%", progress); + fflush(stdout); + if(progress == 100) { + printf("\n"); + } +} + +void print_usage() { + printf("iRecovery - iDevice Recovery Utility\n"); + printf("Usage: irecovery [args]\n"); + printf("\t-i \tTarget specific device by its hexadecimal ECID\n"); + printf("\t-v\t\tStart irecovery in verbose mode.\n"); + printf("\t-c \tSend command to client.\n"); + printf("\t-f \tSend file to client.\n"); + printf("\t-k [payload]\tSend usb exploit to client.\n"); + printf("\t-h\t\tShow this help.\n"); + printf("\t-r\t\tReset client.\n"); + printf("\t-s\t\tStart interactive shell.\n"); + printf("\t-e