diff options
| -rw-r--r-- | include/libirecovery.h | 1 | ||||
| -rw-r--r-- | src/irecovery.c | 23 | ||||
| -rw-r--r-- | src/libirecovery.c | 15 |
3 files changed, 36 insertions, 3 deletions
diff --git a/include/libirecovery.h b/include/libirecovery.h index a636813..fdc418b 100644 --- a/include/libirecovery.h +++ b/include/libirecovery.h | |||
| @@ -65,6 +65,7 @@ irecv_error_t irecv_open(irecv_client_t* client); | |||
| 65 | irecv_error_t irecv_reset(irecv_client_t client); | 65 | irecv_error_t irecv_reset(irecv_client_t client); |
| 66 | irecv_error_t irecv_close(irecv_client_t client); | 66 | irecv_error_t irecv_close(irecv_client_t client); |
| 67 | irecv_error_t irecv_receive(irecv_client_t client); | 67 | irecv_error_t irecv_receive(irecv_client_t client); |
| 68 | irecv_error_t irecv_send_exploit(irecv_client_t client); | ||
| 68 | irecv_error_t irecv_set_debug(irecv_client_t client, int level); | 69 | irecv_error_t irecv_set_debug(irecv_client_t client, int level); |
| 69 | irecv_error_t irecv_getenv(irecv_client_t client, unsigned char** var); | 70 | irecv_error_t irecv_getenv(irecv_client_t client, unsigned char** var); |
| 70 | irecv_error_t irecv_get_ecid(irecv_client_t client, unsigned long long* pecid); | 71 | irecv_error_t irecv_get_ecid(irecv_client_t client, unsigned long long* pecid); |
diff --git a/src/irecovery.c b/src/irecovery.c index 7150f90..98b1e90 100644 --- a/src/irecovery.c +++ b/src/irecovery.c | |||
| @@ -27,7 +27,7 @@ | |||
| 27 | #define debug(...) if(verbose) fprintf(stderr, __VA_ARGS__) | 27 | #define debug(...) if(verbose) fprintf(stderr, __VA_ARGS__) |
| 28 | 28 | ||
| 29 | enum { | 29 | enum { |
| 30 | kResetDevice, kStartShell, kSendCommand, kSendFile | 30 | kResetDevice, kStartShell, kSendCommand, kSendFile, kSendExploit |
| 31 | }; | 31 | }; |
| 32 | 32 | ||
| 33 | static unsigned int quit = 0; | 33 | static unsigned int quit = 0; |
| @@ -146,9 +146,9 @@ void print_usage() { | |||
| 146 | printf("iRecovery - iDevice Recovery Utility\n"); | 146 | printf("iRecovery - iDevice Recovery Utility\n"); |
| 147 | printf("Usage: ./irecovery [args]\n"); | 147 | printf("Usage: ./irecovery [args]\n"); |
| 148 | printf("\t-v\t\tStart irecovery in verbose mode.\n"); | 148 | printf("\t-v\t\tStart irecovery in verbose mode.\n"); |
| 149 | printf("\t-u <uuid>\ttarget specific client by its 40-digit client UUID\n"); | ||
| 150 | printf("\t-c <cmd>\tSend command to client.\n"); | 149 | printf("\t-c <cmd>\tSend command to client.\n"); |
| 151 | printf("\t-f <file>\tSend file to client.\n"); | 150 | printf("\t-f <file>\tSend file to client.\n"); |
| 151 | printf("\t-k [exploit]\tSend usb exploit to client.\n"); | ||
| 152 | printf("\t-h\t\tShow this help.\n"); | 152 | printf("\t-h\t\tShow this help.\n"); |
| 153 | printf("\t-r\t\tReset client.\n"); | 153 | printf("\t-r\t\tReset client.\n"); |
| 154 | printf("\t-s\t\tStart interactive shell.\n"); | 154 | printf("\t-s\t\tStart interactive shell.\n"); |
| @@ -162,7 +162,7 @@ int main(int argc, char** argv) { | |||
| 162 | char* argument = NULL; | 162 | char* argument = NULL; |
| 163 | irecv_error_t error = 0; | 163 | irecv_error_t error = 0; |
| 164 | if(argc == 1) print_usage(); | 164 | if(argc == 1) print_usage(); |
| 165 | while ((opt = getopt(argc, argv, "vhrsc:f:")) > 0) { | 165 | while ((opt = getopt(argc, argv, "vhrsc:f:k::")) > 0) { |
| 166 | switch (opt) { | 166 | switch (opt) { |
| 167 | case 'v': | 167 | case 'v': |
| 168 | verbose += 1; | 168 | verbose += 1; |
| @@ -190,6 +190,11 @@ int main(int argc, char** argv) { | |||
| 190 | argument = optarg; | 190 | argument = optarg; |
| 191 | break; | 191 | break; |
| 192 | 192 | ||
| 193 | case 'k': | ||
| 194 | action = kSendExploit; | ||
| 195 | argument = optarg; | ||
| 196 | break; | ||
| 197 | |||
| 193 | default: | 198 | default: |
| 194 | fprintf(stderr, "Unknown argument\n"); | 199 | fprintf(stderr, "Unknown argument\n"); |
| 195 | return -1; | 200 | return -1; |
| @@ -225,6 +230,18 @@ int main(int argc, char** argv) { | |||
| 225 | debug("%s\n", irecv_strerror(error)); | 230 | debug("%s\n", irecv_strerror(error)); |
| 226 | break; | 231 | break; |
| 227 | 232 | ||
| 233 | case kSendExploit: | ||
| 234 | if(argument != NULL) { | ||
| 235 | error = irecv_send_file(client, argument); | ||
| 236 | if(error != IRECV_E_SUCCESS) { | ||
| 237 | debug("%s\n", irecv_strerror(error)); | ||
| 238 | break; | ||
| 239 | } | ||
| 240 | } | ||
| 241 | error = irecv_send_exploit(client); | ||
| 242 | debug("%s\n", irecv_strerror(error)); | ||
| 243 | break; | ||
| 244 | |||
| 228 | case kStartShell: | 245 | case kStartShell: |
| 229 | init_shell(client); | 246 | init_shell(client); |
| 230 | break; | 247 | break; |
diff --git a/src/libirecovery.c b/src/libirecovery.c index 78745b1..6587fe0 100644 --- a/src/libirecovery.c +++ b/src/libirecovery.c | |||
| @@ -428,6 +428,21 @@ irecv_error_t irecv_get_ecid(irecv_client_t client, unsigned long long* ecid) { | |||
| 428 | return IRECV_E_SUCCESS; | 428 | return IRECV_E_SUCCESS; |
| 429 | } | 429 | } |
| 430 | 430 | ||
| 431 | |||
| 432 | irecv_error_t irecv_send_exploit(irecv_client_t client) { | ||
| 433 | if(client == NULL || client->handle == NULL) { | ||
| 434 | return IRECV_E_NO_DEVICE; | ||
| 435 | } | ||
| 436 | |||
| 437 | irecv_error_t error = irecv_set_interface(client, 1, 1); | ||
| 438 | if(error != IRECV_E_SUCCESS) { | ||
| 439 | return error; | ||
| 440 | } | ||
| 441 | |||
| 442 | libusb_control_transfer(client->handle, 0x21, 2, 0, 0, NULL, 0, 100); | ||
| 443 | return IRECV_E_SUCCESS; | ||
| 444 | } | ||
| 445 | |||
| 431 | const char* irecv_strerror(irecv_error_t error) { | 446 | const char* irecv_strerror(irecv_error_t error) { |
| 432 | switch(error) { | 447 | switch(error) { |
| 433 | case IRECV_E_SUCCESS: | 448 | case IRECV_E_SUCCESS: |
