This repository has been archived by the owner on May 14, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 25
/
boot.c
129 lines (113 loc) · 3.71 KB
/
boot.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
/*
* boot.c
* copyright (C) 2020/05/25 dora2ios
*
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ircv.h>
static int send_data(irecv_client_t client, unsigned char* data, size_t size){
return irecv_usb_control_transfer(client, 0x21, 1, 0, 0, data, size, 100);
}
static int irecv_get_device(irecv_client_t client) {
if(client) {
irecv_close(client);
client = NULL;
}
irecv_open_with_ecid(&client, 0);
if(!client) {
return -1;
}
int mode = 0;
irecv_get_mode(client, &mode);
if(mode != IRECV_K_DFU_MODE) {
irecv_close(client);
client = NULL;
return -1;
}
return 0;
}
int boot_client_n(irecv_client_t client, char* ibss, size_t ibss_sz) {
int ret;
printf("\x1b[36mUploading image\x1b[39m\n");
ret = irecv_send_buffer(client, (unsigned char*)ibss, ibss_sz, 0);
if(ret != 0) {
printf("\x1b[31mERROR: Failed to upload image.\x1b[39m\n");
return -1;
}
ret = irecv_finish_transfer(client);
if(ret != 0) {
printf("\x1b[31mERROR: Failed to execute image.\x1b[39m\n");
return -1;
}
return 0;
}
// boot for 32-bit checkm8 devices
int boot_client(irecv_client_t client, void* buf, size_t sz) {
int ret;
if(!client) {
ret = irecv_get_device(client);
if(ret != 0) {
printf("\x1b[31mERROR: No device found.\x1b[39m");
return -1;
}
}
const struct irecv_device_info* info = irecv_get_device_info(client);
char* pwnd_str = strstr(info->serial_string, "PWND:[");
if(!pwnd_str) {
irecv_close(client);
printf("Device not in pwned DFU mode.\n");
return -1;
}
char* checkm8_str = strstr(info->serial_string, "ipwnder");
if(!checkm8_str) {
//printf("This device is not in checkm8 pwned DFU mode.\n");
boot_client_n(client, buf, sz); // jump to normal boot
free(buf);
return 0;
}
if(info->cpid == 0x8960){
//printf("This device is in checkm8 pwned DFU mode. But this is 64-bit.\n");
boot_client_n(client, buf, sz); // // jump to normal boot
free(buf);
return 0;
}
unsigned char blank[16];
bzero(blank, 16);
send_data(client, blank, 16);
irecv_usb_control_transfer(client, 0x21, 1, 0, 0, NULL, 0, 100);
irecv_usb_control_transfer(client, 0xA1, 3, 0, 0, blank, 6, 100);
irecv_usb_control_transfer(client, 0xA1, 3, 0, 0, blank, 6, 100);
printf("\x1b[36mUploading pwned iBSS\x1b[39m\n");
size_t len = 0;
size_t size;
size_t sent;
while(len < sz) {
size = ((sz - len) > 0x800) ? 0x800 : (sz - len);
sent = irecv_usb_control_transfer(client, 0x21, 1, 0, 0, (unsigned char*)&buf[len], size, 1000);
if(sent != size) {
printf("\x1b[31mERROR: Failed to upload image.\x1b[39m\n");
return -1;
}
len += size;
}
irecv_usb_control_transfer(client, 0xA1, 2, 0xFFFF, 0, NULL, 0, 100);
//irecv_close(client);
return 0;
}