/
sahara.h
executable file
·425 lines (386 loc) · 11.4 KB
/
sahara.h
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
/**
*
* (c) Gassan Idriss <ghassani@gmail.com>
*
* This file is part of libopenpst.
*
* libopenpst 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.
*
* libopenpst 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 libopenpst. If not, see <http://www.gnu.org/licenses/>.
*
* @file sahara.h
* @package openpst/libopenpst
* @brief Sahara protocol definitions and structures
*
* @author Gassan Idriss <ghassani@gmail.com>
*/
#pragma once
#include "definitions.h"
#ifndef SAHARA_MAX_PACKET_SIZE
#define SAHARA_MAX_PACKET_SIZE 0x400
#endif
#ifndef SAHARA_LOG_LENGTH
#define SAHARA_LOG_LENGTH 0x64
#endif
#ifndef SAHARA_MAX_MEMORY_DATA_SIZE
#define SAHARA_MAX_MEMORY_DATA_SIZE 0x1000
#endif
#ifndef SAHARA_RAM_ZI_SIZE
#define SAHARA_RAM_ZI_SIZE 0x20000
#endif
#ifndef SAHARA_MAX_MEMORY_REQUEST_SIZE
#define SAHARA_MAX_MEMORY_REQUEST_SIZE 0x50000
#endif
/**
* These are all known commands, both rx and tx.
*/
enum SaharaCommand {
kSaharaCommandHello = 0x01, // Initialize connection and protocol
kSaharaCommandHelloResponse = 0x02, // Acknowledge connection/protocol, mode of operation
kSaharaCommandReadData = 0x03, // Read specified number of bytes from host
kSaharaCommandEndImageTransfer = 0x04, // image transfer end / target transfer failure
kSaharaCommandDone = 0x05, // Acknowledgement: image transfer is complete
kSaharaCommandDoneResponse = 0x06, // Target is exiting protocol
kSaharaCommandReset = 0x07, // Instruct target to perform a reset
kSaharaCommandResetResponse = 0x08, // Indicate to host that target is about to reset
kSaharaCommandMemoryDebug = 0x09, // Indicate to host: target debug mode & ready to transfer memory content
kSaharaCommandMemoryRead = 0x0A, // Read number of bytes, starting from a specified address
kSaharaCommandReady = 0x0B, // Indicate to host: target ready to receive client commands,
kSaharaCommandSwitchMode = 0x0C, // Switch to a mode defined in enum SAHARA_MODE
kSaharaCommandExecute = 0x0D, // Indicate to host: to execute a given client command
kSaharaCommandExecuteResponse = 0x0E, // Indicate to host: target command execution status
kSaharaCommandExecuteData = 0x0F, // Indicate to target that host is ready to receive (more) data
kSaharaCommandMemoryDebug64 = 0x10,
kSaharaCommandMemoryRead64 = 0x11,
};
/**
* SAHARA_MODE
*
* These are all known modes available
* The initial hello lets you know which
* mode the device is currently in.
*/
enum SaharaMode {
kSaharaModeImageTxPending = 0x00,
kSaharaModeImageTxComplete = 0x01,
kSaharaModeMemoryDebug = 0x02,
kSaharaModeCommand = 0x03
};
/**
* SaharaClientCmd
*
* When in or switched to command mode, these are
* all commands that are currently known
*/
enum SaharaClientCmd {
kSaharaClientCmdNop = 0x00,
kSaharaClientCmdSerialNumRead = 0x01,
kSaharaClientCmdMsmHWIDRead = 0x02,
kSaharaClientOemPkHashRead = 0x03,
kSaharaClientCmdSwitchDMSS = 0x04, // haven't found a device/mode this works on
kSaharaClientCmdSwitchToStreamingDload = 0x05, // haven't found a device/mode this works on
kSaharaClientCmdReadDebugData = 0x06,
kSaharaClientCmdGetSblVersion = 0x07,
};
enum SaharaStatusCode {
kSaharaStatusSuccess = 0x00,
kSaharaStatusInvalidCmd = 0x01,
kSaharaStatusProtocolMismatch = 0x02,
kSaharaStatusInvalidTargetProtocol = 0x03,
kSaharaStatusInvalidHostProtocol = 0x04,
kSaharaStatusInvalidPacketSize = 0x05,
kSaharaStatusUnexpectedImageId = 0x06,
kSaharaStatusInvalidHeaderSize = 0x07,
kSaharaStatusInvalidDataSize = 0x08,
kSaharaStatusInvalidImageType = 0x09,
kSaharaStatusInvalidTxLength = 0x0A,
kSaharaStatusInvalidRxLength = 0x0B,
kSaharaStatusTxRxError = 0x0C,
kSaharaStatusReadDataError = 0x0D,
kSaharaStatusUnsupportedNumPhdrs = 0x0E,
kSaharaStatusInvalidPhdrSize = 0x0F,
kSaharaStatusMultipleSharedSeg = 0x10,
kSaharaStatusUninitPhdrLoc = 0x11,
kSaharaStatusInvalidDestAddress = 0x12,
kSaharaStatusInvalidImageHeaderSize = 0x13,
kSaharaStatusInvalidElfHeader = 0x14,
kSaharaStatusUnknownError = 0x15,
kSaharaStatusTimeoutRx = 0x16,
kSaharaStatusTimeoutTx = 0x17,
kSaharaStatusInvalidMode = 0x18,
kSaharaStatusInvalidMemoryRead = 0x19,
kSaharaStatusInvalidDataSizeRequest = 0x1A,
kSaharaStatusMemoryDebugNotSupported = 0x1B,
kSaharaStatusInvalidModeSwitch = 0x1C,
kSaharaStatusExecFailure = 0x1D,
kSaharaStatusExecCmdInvalidParam = 0x1E,
kSaharaStatusExecCmdUnsupported = 0x1F,
kSaharaStatusExecDataInvalid = 0x20,
kSaharaStatusHashTableAuthFailure = 0x21,
kSaharaStatusHashVerificationFailure = 0x22,
kSaharaStatusHashTableNotFound = 0x23,
kSaharaStatusTargetInitFailure = 0x24,
kSaharaStatusImageAuthFailure = 0x25,
kSaharaStatusInvalidImgHashTableSize = 0x26,
kSaharaStatusMax
};
#ifndef NO_POD_PACKET_STRUCTURES
/**
* SaharaHeader
*
* The header all transmissions use
* with the exception of a few
*/
typedef struct SaharaHeader {
uint32_t command;
uint32_t size;
} SaharaHeader;
/**
* SaharaAbstractPacket
*/
typedef struct SaharaAbstractPacket {
SaharaHeader header;
uint32_t parameters[2];
} SaharaAbstractPacket;
/**
* SaharaHelloRequestS
*
* The initial packet received from the device
* when first opening the COM port. If no data
* is available for read after the COM port is opened
* then the device may require a restart or it is not
* using sahara protocol
*/
typedef struct{ // 0x01
SaharaHeader header;
uint32_t version;
uint32_t minVersion;
uint32_t maxCommandPacketSize;
uint32_t mode;
uint32_t reserved[6];
} SaharaHelloRequest;
/**
* SaharaHelloResponse
*
* The initial packet sent to the device
* in response to the initial hello packet
*/
typedef struct { // 0x02
SaharaHeader header;
uint32_t version;
uint32_t minVersion;
uint32_t status; // ok or error
uint32_t mode;
uint32_t reserved[6];
} SaharaHelloResponse;
/**
* SaharaReadDataRequest
*
* When the device sends this packet
* it is requesting an image transfer and an initial
* chunk of the file for validation
*/
typedef struct { // 0x03
SaharaHeader header;
uint32_t imageId;
uint32_t offset;
uint32_t size;
} SaharaReadDataRequest;
/**
* SaharaEndImageTransferResponse
*
* When an error is encountered or an image transfer has
* ended.
*/
typedef struct { // 0x04
SaharaHeader header;
uint32_t file;
uint32_t status;
} SaharaEndImageTransferResponse;
/*
* SaharaDoneRequest
*
* Sent to the device in response to a successful SaharaEndImageTransferResponse
*/
typedef struct { // 0x05
SaharaHeader header;
} SaharaDoneRequest;
/*
* SaharaDoneResponse
*
* Received from the device after sending SaharaDoneRequest
*/
typedef struct { // 0x06
SaharaHeader header;
uint32_t imageTxStatus; // 0 pending, 1 complete
} SaharaDoneResponse;
/*
* SaharaResetRequest
*/
typedef struct { // 0x07
SaharaHeader header;
} SaharaResetRequest;
/*
* SaharaResetResponse
*/
typedef struct { // 0x08
SaharaHeader header;
} SaharaResetResponse;
typedef struct { // 0x09
SaharaHeader header;
uint32_t memoryTableAddress;
uint32_t memoryTableLength;
} SaharaMemoryDebugRequest;
typedef struct { // 0x0a
SaharaHeader header;
uint32_t address;
uint32_t size;
} SaharaMemoryReadRequest;
/**
* SaharaCommandReadyResponse
*
* Received from the device when in or switching to client
* command mode. ready to take a command (SaharaClientCommandRequest)
*/
typedef struct { // 0x0b
SaharaHeader header;
uint32_t imageTxStatus; // 0 pending, 1 complete
} SaharaCommandReadyResponse;
/**
* SaharaSwitchModeRequest
*
* Sent to the device to switch modes when in client command mode.
*
* Device should respond with SaharaHelloRequest
*/
typedef struct { // 0x0c
SaharaHeader header;
uint32_t mode;
} SaharaSwitchModeRequest;
/**
* SaharaClientCommandRequest
*
* Execute a client command
*
* If the command is invalid you will receive
* SaharaEndImageTransferResponse
*/
typedef struct { // 0x0d
SaharaHeader header;
uint32_t command;
} SaharaClientCommandRequest;
/**
* SaharaClientCommandResponse
*
* Received from the device in response to SaharaClientCommandRequest
* with the size of the data expected back from the command execution
*
*/
typedef struct { // 0x0e
SaharaHeader header;
uint32_t command;
uint32_t size;
} SaharaClientCommandResponse;
/**
* SaharaClientCommandExecuteDataRequest
*
* Sent in response to SaharaClientCommandResponse
* indicating we are ready to receive the data of n size
* defined in SaharaClientCommandResponse
*
* After sent, read the size of data from the device
*/
typedef struct { // 0x0f
SaharaHeader header;
uint32_t command;
} SaharaClientCommandExecuteDataRequest;
/**
*
* SaharaMemoryDebug64Request
*/
typedef struct { // 0x10
SaharaHeader header;
uint32_t memoryTableAddress;
uint32_t memoryTableLength;
} SaharaMemoryDebug64Request;
/**
* SaharaMemoryRead64Request
*/
typedef struct { // 0x11
SaharaHeader header;
uint64_t address;
uint64_t size;
} SaharaMemoryRead64Request;
#endif
/**
* SaharaMsmHwIdResponse
*
* represents a response from client command:
* kSaharaClientCmdMsmHWIDRead
*/
typedef struct {
uint16_t unknown1;
uint16_t unknown2;
uint16_t msmId;
} SaharaMsmHwIdResponse;
/**
* SaharaSerialNumberResponse
*
* represents a response from client command:
* kSaharaClientCmdSerialNumRead
*/
typedef struct {
uint32_t serial;
} SaharaSerialNumberResponse;
/**
* SaharaSblVersionResponse
*
* represents a response from client command:
* kSaharaClientCmdGetSblVersion
*/
typedef struct {
uint32_t version;
} SaharaSblVersionResponse;
/**
* SaharaSblVersionResponse
*
* represents a response from client command
* kSaharaClientOemPkHashRead
*/
typedef struct {
uint8_t hash[32];
} SaharaOemPkHashResponse;
/**
* SaharaDebugLogEntry
*
* represents a single log entry from client command
* kSaharaClientCmdReadDebugData response
*/
typedef struct {
uint8_t message[SAHARA_LOG_LENGTH];
} SaharaDebugLogEntry;
/**
* SaharaMemoryTableEntry
*
* This structure represents the memory table entry
* when reading the memory table from the specified address
* of a kSaharaCommandMemoryDebug response
*
* The total number of entries would be response.size / sizeof(SaharaMemoryTableEntry)
*/
PACKED(typedef struct {
uint32_t unknown1;
uint32_t address;
uint32_t size;
uint8_t name[20];
uint8_t filename[20];
}) SaharaMemoryTableEntry;