summaryrefslogtreecommitdiffstats
path: root/src/irecovery.c
diff options
context:
space:
mode:
authorGravatar Joshua Hill2010-11-06 18:09:53 -0400
committerGravatar Joshua Hill2010-11-06 18:09:53 -0400
commitd82a73f1180a5f201397b92e6f6db33411cbe686 (patch)
treebcc7c4ba2e103770f905972854392d8c3e448f16 /src/irecovery.c
parente89c9418e7072d5a1491055c8f78748bf82de49c (diff)
downloadlibirecovery-d82a73f1180a5f201397b92e6f6db33411cbe686.tar.gz
libirecovery-d82a73f1180a5f201397b92e6f6db33411cbe686.tar.bz2
updated libirecovery to the latest version from greenpois0n. it at least compiles on osx now, I need to test on other systems
Diffstat (limited to 'src/irecovery.c')
-rw-r--r--src/irecovery.c343
1 files changed, 0 insertions, 343 deletions
diff --git a/src/irecovery.c b/src/irecovery.c
deleted file mode 100644
index 0e981cd..0000000
--- a/src/irecovery.c
+++ /dev/null
@@ -1,343 +0,0 @@
1/**
2 * iRecovery - Utility for DFU 2.0, WTF and Recovery Mode
3 * Copyright (C) 2008 - 2009 westbaer
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 **/
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <unistd.h>
22#include <libirecovery.h>
23#include <readline/readline.h>
24#include <readline/history.h>
25
26#define FILE_HISTORY_PATH ".irecovery"
27#define debug(...) if(verbose) fprintf(stderr, __VA_ARGS__)
28
29enum {
30 kResetDevice, kStartShell, kSendCommand, kSendFile, kSendExploit, kSendScript
31};
32
33static unsigned int quit = 0;
34static unsigned int verbose = 0;
35
36void print_progress_bar(double progress);
37int received_cb(irecv_client_t client, const irecv_event_t* event);
38int progress_cb(irecv_client_t client, const irecv_event_t* event);
39int precommand_cb(irecv_client_t client, const irecv_event_t* event);
40int postcommand_cb(irecv_client_t client, const irecv_event_t* event);
41
42void shell_usage() {
43 printf("Usage:\n");
44 printf("\t/upload <file>\tSend file to client.\n");
45 printf("\t/exploit [file]\tSend usb exploit with optional payload\n");
46 printf("\t/help\t\tShow this help.\n");
47 printf("\t/exit\t\tExit interactive shell.\n");
48}
49
50void parse_command(irecv_client_t client, unsigned char* command, unsigned int size) {
51 char* cmd = strdup(command);
52 char* action = strtok(cmd, " ");
53 debug("Executing %s\n", action);
54 if (!strcmp(cmd, "/exit")) {
55 quit = 1;
56 } else
57
58 if (!strcmp(cmd, "/help")) {
59 shell_usage();
60 } else
61
62 if (!strcmp(cmd, "/upload")) {
63 char* filename = strtok(NULL, " ");
64 debug("Uploading files %s\n", filename);
65 if (filename != NULL) {
66 irecv_send_file(client, filename);
67 }
68 } else
69
70 if (!strcmp(cmd, "/exploit")) {
71 char* filename = strtok(NULL, " ");
72 debug("Sending exploit %s\n", filename);
73 if (filename != NULL) {
74 irecv_send_file(client, filename);
75 }
76 irecv_send_exploit(client);
77 } else
78
79 if (!strcmp(cmd, "/execute")) {
80 char* filename = strtok(NULL, " ");
81 debug("Executing script %s\n", filename);
82 if (filename != NULL) {
83 irecv_execute_script(client, filename);
84 }
85 }
86
87
88 free(action);
89}
90
91void load_command_history() {
92 read_history(FILE_HISTORY_PATH);
93}
94
95void append_command_to_history(char* cmd) {
96 add_history(cmd);
97 write_history(FILE_HISTORY_PATH);
98}
99
100void init_shell(irecv_client_t client) {
101 irecv_error_t error = 0;
102 load_command_history();
103 irecv_event_subscribe(client, IRECV_PROGRESS, &progress_cb, NULL);
104 irecv_event_subscribe(client, IRECV_RECEIVED, &received_cb, NULL);
105 irecv_event_subscribe(client, IRECV_PRECOMMAND, &precommand_cb, NULL);
106 irecv_event_subscribe(client, IRECV_POSTCOMMAND, &postcommand_cb, NULL);
107 while (!quit) {
108 error = irecv_receive(client);
109 if (error != IRECV_E_SUCCESS) {
110 debug("%s\n", irecv_strerror(error));
111 break;
112 }
113
114 char* cmd = readline("> ");
115 if (cmd && *cmd) {
116 error = irecv_send_command(client, cmd);
117 if (error != IRECV_E_SUCCESS) {
118 quit = 1;
119 }
120
121 append_command_to_history(cmd);
122 free(cmd);
123 }
124 }
125}
126
127int received_cb(irecv_client_t client, const irecv_event_t* event) {
128 if (event->type == IRECV_RECEIVED) {
129 int i = 0;
130 int size = event->size;
131 char* data = event->data;
132 for (i = 0; i < size; i++) {
133 printf("%c", data[i]);
134 }
135 }
136 return 0;
137}
138
139int precommand_cb(irecv_client_t client, const irecv_event_t* event) {
140 if (event->type == IRECV_PRECOMMAND) {
141 irecv_error_t error = 0;
142 if (event->data[0] == '/') {
143 parse_command(client, event->data, event->size);
144 return -1;
145 }
146 }
147 return 0;
148}
149
150int postcommand_cb(irecv_client_t client, const irecv_event_t* event) {
151 char* value = NULL;
152 char* action = NULL;
153 char* command = NULL;
154 char* argument = NULL;
155 irecv_error_t error = IRECV_E_SUCCESS;
156
157 if (event->type == IRECV_POSTCOMMAND) {
158 command = strdup(event->data);
159 action = strtok(command, " ");
160 if (!strcmp(action, "getenv")) {
161 argument = strtok(NULL, " ");
162 error = irecv_getenv(client, argument, &value);
163 if (error != IRECV_E_SUCCESS) {
164 debug("%s\n", irecv_strerror(error));
165 free(command);
166 return error;
167 }
168 printf("%s\n", value);
169 free(value);
170 }
171
172 if (!strcmp(action, "reboot")) {
173 quit = 1;
174 }
175 }
176
177 if (command) free(command);
178 return 0;
179}
180
181int progress_cb(irecv_client_t client, const irecv_event_t* event) {
182 if (event->type == IRECV_PROGRESS) {
183 print_progress_bar(event->progress);
184 }
185 return 0;
186}
187
188void print_progress_bar(double progress) {
189 int i = 0;
190 if(progress < 0) {
191 return;
192 }
193
194 if(progress > 100) {
195 progress = 100;
196 }
197
198 printf("\r[");
199 for(i = 0; i < 50; i++) {
200 if(i < progress / 2) {
201 printf("=");
202 } else {
203 printf(" ");
204 }
205 }
206
207 printf("] %3.1f%%", progress);
208 fflush(stdout);
209 if(progress == 100) {
210 printf("\n");
211 }
212}
213
214void print_usage() {
215 printf("iRecovery - iDevice Recovery Utility\n");
216 printf("Usage: ./irecovery [args]\n");
217 printf("\t-v\t\tStart irecovery in verbose mode.\n");
218 printf("\t-c <cmd>\tSend command to client.\n");
219 printf("\t-f <file>\tSend file to client.\n");
220 printf("\t-k [payload]\tSend usb exploit to client.\n");
221 printf("\t-h\t\tShow this help.\n");
222 printf("\t-r\t\tReset client.\n");
223 printf("\t-s\t\tStart interactive shell.\n");
224 printf("\t-e <script>\tExecutes recovery shell script.\n");
225 exit(1);
226}
227
228int main(int argc, char** argv) {
229 int i = 0;
230 int opt = 0;
231 int action = 0;
232 char* argument = NULL;
233 irecv_error_t error = 0;
234 if (argc == 1) print_usage();
235 while ((opt = getopt(argc, argv, "vhrsc:f:e:k::")) > 0) {
236 switch (opt) {
237 case 'v':
238 verbose += 1;
239 break;
240
241 case 'h':
242 print_usage();
243 break;
244
245 case 'r':
246 action = kResetDevice;
247 break;
248
249 case 's':
250 action = kStartShell;
251 break;
252
253 case 'f':
254 action = kSendFile;
255 argument = optarg;
256 break;
257
258 case 'c':
259 action = kSendCommand;
260 argument = optarg;
261 break;
262
263 case 'k':
264 action = kSendExploit;
265 argument = optarg;
266 break;
267
268 case 'e':
269 action = kSendScript;
270 argument = optarg;
271 break;
272
273 default:
274 fprintf(stderr, "Unknown argument\n");
275 return -1;
276 }
277 }
278
279 irecv_client_t client = NULL;
280 for (i = 0; i <= 5; i++) {
281 debug("Attempting to connect... \n");
282
283 if (irecv_open(&client) != IRECV_E_SUCCESS)
284 sleep(1);
285 else
286 break;
287
288 if (i == 5) {
289 return -1;
290 }
291 }
292
293 if (verbose) irecv_set_debug_level(verbose);
294
295 switch (action) {
296 case kResetDevice:
297 irecv_reset(client);
298 break;
299
300 case kSendFile:
301 irecv_event_subscribe(client, IRECV_PROGRESS, &progress_cb, NULL);
302 error = irecv_send_file(client, argument);
303 debug("%s\n", irecv_strerror(error));
304 break;
305
306 case kSendCommand:
307 error = irecv_send_command(client, argument);
308 debug("%s\n", irecv_strerror(error));
309 break;
310
311 case kSendExploit:
312 if (argument != NULL) {
313 irecv_event_subscribe(client, IRECV_PROGRESS, &progress_cb, NULL);
314 error = irecv_send_file(client, argument);
315 if (error != IRECV_E_SUCCESS) {
316 debug("%s\n", irecv_strerror(error));
317 break;
318 }
319 }
320 error = irecv_send_exploit(client);
321 debug("%s\n", irecv_strerror(error));
322 break;
323
324 case kStartShell:
325 init_shell(client);
326 break;
327
328 case kSendScript:
329 error = irecv_execute_script(client, argument);
330 if(error != IRECV_E_SUCCESS) {
331 debug("%s\n", irecv_strerror(error));
332 }
333 break;
334
335 default:
336 fprintf(stderr, "Unknown action\n");
337 break;
338 }
339
340 irecv_close(client);
341 return 0;
342}
343