-
Notifications
You must be signed in to change notification settings - Fork 5
/
loadibec.c
143 lines (116 loc) · 3.03 KB
/
loadibec.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// Reverse engineering courtesty of c1de0x, et al. of the iPhone Dev Team
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <libusb-1.0/libusb.h>
#include <readline/readline.h>
#define USB_APPLE_ID 0x05AC
#define USB_RECOVERY 0x1281
#define USB_DFU_MODE 0x1227
struct libusb_device_handle* open_device(int devid) {
int configuration = 0;
struct libusb_device_handle* handle = NULL;
libusb_init(NULL);
handle = libusb_open_device_with_vid_pid(NULL, USB_APPLE_ID, devid);
if (handle == NULL) {
printf("open_device: unable to connect to device.\n");
return NULL;
}
libusb_get_configuration(handle, &configuration);
if(configuration != 1) {
if (libusb_set_configuration(handle, 1) < 0) {
printf("open_device: error setting configuration.\n");
return NULL;
}
}
if (libusb_claim_interface(handle, 0) < 0) {
printf("open_device: error claiming interface.");
return NULL;
}
return handle;
}
int close_device(struct libusb_device_handle* handle) {
if (handle == NULL) {
printf("close_device: device has not been initialized yet.\n");
return -1;
}
libusb_release_interface(handle, 0);
libusb_release_interface(handle, 1);
libusb_close(handle);
libusb_exit(NULL);
return 0;
}
int send_command(struct libusb_device_handle* handle, char* command) {
size_t length = strlen(command);
if (length >= 0x200) {
printf("send_command: command is too long.\n");
return -1;
}
if (!libusb_control_transfer(handle, 0x40, 0, 0, 0, command, length + 1, 1000)) {
printf("send_command: unable to send command.\n");
return -1;
}
return 0;
}
int send_file(struct libusb_device_handle *handle, const char* filename) {
if(handle == NULL) {
printf("send_file: device has not been initialized yet.\n");
return -1;
}
FILE* file = fopen(filename, "rb");
if(file == NULL) {
printf("send_file: unable to find file.\n");
return 1;
}
fseek(file, 0, SEEK_END);
long len = ftell(file);
fseek(file, 0, SEEK_SET);
char* buffer = malloc(len);
if (buffer == NULL) {
printf("send_file: error allocating memory.\n");
fclose(file);
return 1;
}
fread(buffer, 1, len, file);
fclose(file);
int packets = len / 0x800;
if(len % 0x800) {
packets++;
}
int last = len % 0x800;
if(!last) {
last = 0x800;
}
libusb_control_transfer(handle, 0x41, 0, 0, 0, 0, 0, 1000);
int i = 0;
char response[6];
for(i = 0; i < packets; i++) {
int size = i + 1 < packets ? 0x800 : last;
int bytes = 0;
if(libusb_bulk_transfer(handle, 4, &buffer[i * 0x800], size, &bytes, 1000)) {
printf("send_file: error sending packet.\n");
return -1;
}
}
free(buffer);
return 0;
}
int main(int argc, char* argv[]) {
struct libusb_device_handle* handle = NULL;
if (argc != 2) {
printf("usage: loadibec <img3>\n");
return -1;
}
handle = open_device(USB_RECOVERY);
if (handle == NULL) {
printf("your device must be in recovery mode.\n");
return -1;
}
// TODO: add interactive mode
if(send_file(handle, argv[1]) >= 0) {
send_command(handle, "go");
}
close_device(handle);
return 0;
}