1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2012 Amaury Pouly
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
34 #define MIN(a,b) ((a) < (b) ? (a) : (b))
37 #define cprintf(col, ...) do {color(col); printf(__VA_ARGS__); }while(0)
39 #define cprintf_field(str1, ...) do{ cprintf(GREEN, str1); cprintf(YELLOW, __VA_ARGS__); }while(0)
42 char *g_out_prefix
= NULL
;
43 char *g_in_file
= NULL
;
46 #define let_the_force_flow(x) do { if(!g_force) return x; } while(0)
47 #define continue_the_force(x) if(x) let_the_force_flow(x)
49 #define check_field(v_exp, v_have, str_ok, str_bad) \
50 if((v_exp) != (v_have)) \
51 { cprintf(RED, str_bad); let_the_force_flow(__LINE__); } \
52 else { cprintf(RED, str_ok); }
54 static void print_hex(void *p
, int size
, int unit
)
59 for(int i
= 0; i
< size
; i
+= unit
, p8
++, p16
++, p32
++)
61 if(i
!= 0 && (i
% 16) == 0)
66 printf(" %04x", *p16
);
68 printf(" %08x", *p32
);
76 #define FWU_SIG_SIZE 16
77 #define FWU_BLOCK_SIZE 512
81 uint8_t sig
[FWU_SIG_SIZE
];
83 uint32_t block_size
;// always 512
86 uint8_t sig2
[FWU_SIG_SIZE
];
87 } __attribute__((packed
));
89 const uint8_t g_fwu_signature
[FWU_SIG_SIZE
] =
91 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x75
99 uint8_t sig2
[FWU_SIG_SIZE
];
102 struct version_desc_t g_version
[] =
104 { 1, 0xd, 0xd0, { 0x76, 0x5c, 0x50, 0x94, 0x69, 0xb0, 0xa7, 0x03, 0x10, 0xf1, 0x7e, 0xdb, 0x88, 0x90, 0x86, 0x9d } },
105 { 1, 0xe, 0xd0, { 0x92, 0x22, 0x7a, 0x77, 0x08, 0x67, 0xae, 0x06, 0x16, 0x06, 0xb8, 0x65, 0xa6, 0x42, 0xf7, 0X52 } },
106 { 3, 0x7e, 0xe1, { 0x3f, 0xad, 0xf8, 0xb0, 0x2e, 0xaf, 0x67, 0x49, 0xb9, 0x85, 0x5f, 0x63, 0x4e, 0x5e, 0x8e, 0x2e } },
109 #define NR_VERSIONS (int)(sizeof(g_version)/sizeof(g_version[0]))
111 typedef struct ptr_bundle_t
117 struct block_A_info_t
123 uint32_t *ptr6
; // size
124 uint32_t *ptr7
; // size
125 uint32_t *ptr5
; // size
129 uint32_t *ptr3
; // size
130 uint32_t *ptr4
; // size
144 struct block_A_info_t g_decode_A_info
;
145 uint8_t g_subblock_A
[0x128];
147 uint8_t g_perm_B
[258];
148 uint8_t g_crypto_info_byte
;
149 uint8_t *g_decode_buffer
;
150 uint8_t *g_decode_buffer2
;
151 void *g_decode_buffer3
;
153 #include "atj_tables.h"
155 void compute_checksum(uint8_t *buf
, int size
, uint8_t t
[20])
159 for(int i
= 0; i
< size
; i
++)
161 for(int i
= 0; i
< 20; i
++)
165 int check_block(uint8_t *buf
, uint8_t ref
[20], unsigned size
)
168 compute_checksum(buf
, size
, t
);
170 return memcmp(ref
, t
, 20);
174 int get_version(uint8_t *buf
, unsigned long size
)
177 struct fwu_hdr_t
*hdr
= (void *)buf
;
178 for(int i
= 0; i
< NR_VERSIONS
; i
++)
179 if(hdr
->version
== g_version
[i
].value
)
184 static int decode_block_A(uint8_t block
[1020])
186 uint8_t *p
= &g_check_block_A_table
[32 * (block
[998] & 0x1f)];
189 for(int i
= 0; i
< 20; i
++)
191 block
[1000 + i
] ^= p
[i
];
192 key
[i
] = block
[1000 + i
];
194 for(int i
= 20; i
< 32; i
++)
195 key
[i
] = key
[i
- 20];
197 for(int i
= 0; i
< 992; i
++)
198 block
[i
] ^= key
[i
% 32] ^ g_check_block_A_table
[i
];
200 return check_block(block
- 1, block
+ 1000, 1001);
203 static void compute_perm(uint8_t *keybuf
, int size
, uint8_t perm
[258])
205 for(int i
= 0; i
< 256; i
++)
207 perm
[256] = perm
[257] = 0;
209 for(int i
= 0; i
< 256; i
++)
212 idx
= (v
+ keybuf
[i
% size
] + idx
) % 256;
218 static void decode_perm(uint8_t *buf
, int size
, uint8_t perm
[258])
220 uint8_t idxa
= perm
[256];
221 uint8_t idxb
= perm
[257];
222 for(int i
= 0; i
< size
; i
++)
224 idxa
= (idxa
+ 1) % 256;
225 uint8_t v
= perm
[idxa
];
226 idxb
= (idxb
+ v
) % 256;
227 perm
[idxa
] = perm
[idxb
];
229 buf
[i
] ^= perm
[(v
+ perm
[idxa
]) % 256];
233 static void decode_block_with_perm(uint8_t *keybuf
, int keysize
,
234 uint8_t *buf
, int bufsize
, uint8_t perm
[258])
236 compute_perm(keybuf
, keysize
, perm
);
237 decode_perm(buf
, bufsize
, perm
);
240 static void apply_perm(uint8_t *inbuf
, uint8_t *outbuf
, int size
, int swap
)
242 memcpy(outbuf
, inbuf
, size
);
244 int b
= (swap
>> 4) + 16;
245 uint8_t v
= outbuf
[a
];
246 outbuf
[a
] = outbuf
[b
];
250 static void decode_block_with_swap(uint8_t keybuf
[32], int swap
,
251 uint8_t *buf
, int bufsize
, uint8_t perm
[258])
253 uint8_t keybuf_interm
[32];
255 apply_perm(keybuf
, keybuf_interm
, 32, swap
);
256 decode_block_with_perm(keybuf_interm
, 32, buf
, bufsize
, perm
);
259 static void clear_memory(void *buf
, int size_dwords
)
261 memset(buf
, 0, 4 * size_dwords
);
264 static void set_bit(int bit_pos
, uint32_t *buf
)
266 buf
[bit_pos
/ 32] |= 1 << (bit_pos
% 32);
269 static int fill_decode_info(uint8_t sz
)
271 if(sz
== 2) sz
= 233;
272 else if(sz
== 3) sz
= 163;
275 g_decode_A_info
.nr_bits
= sz
;
276 g_decode_A_info
.nr_bytes2
= sz
/ 8 + (sz
% 8 != 0);
277 g_decode_A_info
.nr_words
= 2 * g_decode_A_info
.nr_bytes2
;
278 g_decode_A_info
.nr_bytes
= sz
/ 8 + (sz
% 8 != 0);
279 g_decode_A_info
.nr_words2
= 2 * g_decode_A_info
.nr_bytes2
;
280 g_decode_A_info
.nr_dwords
= sz
/ 32 + (sz
% 32 != 0);
281 g_decode_A_info
.size
= 4 * g_decode_A_info
.nr_dwords
;
282 g_decode_A_info
.nr_dwords_x8
= 8 * g_decode_A_info
.nr_dwords
;
283 g_decode_A_info
.nr_dwords_m1
= g_decode_A_info
.nr_dwords
- 1;
284 g_decode_A_info
.nr_dwords_x2
= 2 * g_decode_A_info
.nr_dwords
;
285 g_decode_A_info
.nr_dwords_x2_m1
= g_decode_A_info
.nr_dwords_x2
- 1;
286 g_decode_A_info
.nr_dwords_x12
= 12 * g_decode_A_info
.nr_dwords
;
287 g_decode_A_info
.ptr1
.ptrA
= malloc(4 * g_decode_A_info
.nr_dwords
);
288 g_decode_A_info
.ptr1
.ptrB
= malloc(g_decode_A_info
.size
);
289 g_decode_A_info
.ptr3
= malloc(g_decode_A_info
.size
);
290 g_decode_A_info
.ptr4
= malloc(g_decode_A_info
.size
);
291 g_decode_A_info
.ptr5
= malloc(g_decode_A_info
.size
);
292 g_decode_A_info
.ptr6
= malloc(g_decode_A_info
.size
);
293 g_decode_A_info
.ptr7
= malloc(g_decode_A_info
.size
);
295 cprintf(BLUE
, " Decode Info:\n");
296 cprintf_field(" Nr Bits: ", "%d\n", g_decode_A_info
.nr_bits
);
297 cprintf_field(" Nr Bytes: ", "%d\n", g_decode_A_info
.nr_bytes
);
298 cprintf_field(" Nr Bytes 2: ", "%d\n", g_decode_A_info
.nr_bytes2
);
299 cprintf_field(" Nr Words: ", "%d\n", g_decode_A_info
.nr_words
);
300 cprintf_field(" Nr Words 2: ", "%d\n", g_decode_A_info
.nr_words2
);
301 cprintf_field(" Nr DWords: ", "%d\n", g_decode_A_info
.nr_dwords
);
302 cprintf_field(" Size: ", "%d\n", g_decode_A_info
.size
);
307 static int process_block_A(uint8_t block
[1024])
309 cprintf(BLUE
, "Block A\n");
310 int ret
= decode_block_A(block
+ 4);
311 cprintf(GREEN
, " Check: ");
312 check_field(ret
, 0, "Pass\n", "Fail\n");
314 memcpy(g_subblock_A
, block
, sizeof(g_subblock_A
));
315 ret
= fill_decode_info(g_subblock_A
[276]);
316 cprintf(GREEN
, " Info: ");
317 check_field(ret
, 0, "Pass\n", "Fail\n");
319 int tmp
= 2 * g_decode_A_info
.nr_bytes2
+ 38;
320 int offset
= 1004 - tmp
+ 5;
321 g_crypto_info_byte
= block
[offset
- 1];
322 g_decode_buffer
= malloc(g_decode_A_info
.size
);
323 g_decode_buffer2
= malloc(g_decode_A_info
.size
);
325 memset(g_decode_buffer
, 0, g_decode_A_info
.size
);
326 memset(g_decode_buffer2
, 0, g_decode_A_info
.size
);
328 memcpy(g_decode_buffer
, &block
[offset
], g_decode_A_info
.nr_bytes2
);
329 int offset2
= g_decode_A_info
.nr_bytes2
+ offset
;
330 memcpy(g_decode_buffer2
, &block
[offset2
], g_decode_A_info
.nr_bytes2
);
333 cprintf_field(" Word: ", "%d ", *(uint16_t *)&g_subblock_A
[286]);
334 check_field(*(uint16_t *)&g_subblock_A
[286], 1, "Ok\n", "Mismatch\n");
339 static void decode_key_B(uint8_t buf
[20], uint8_t buf2
[16], uint8_t key
[20])
341 for(int i
= 0; i
< 20; i
++)
343 uint8_t v
= buf
[i
] ^ g_decode_B_table
[i
];
345 buf
[i
] = v
^ buf2
[i
% 16];
349 static void decode_block_B(uint8_t *buf
, uint8_t key
[16], int size
)
351 decode_key_B(&buf
[size
], key
, g_key_B
);
352 decode_block_with_perm(g_key_B
, 20, buf
, size
, g_perm_B
);
355 static int find_last_bit_set(uint32_t *buf
, bool a
)
357 int i
= a
? g_decode_A_info
.nr_dwords_m1
: g_decode_A_info
.nr_dwords_x2_m1
;
359 while(i
>= 0 && buf
[i
] == 0)
363 for(int j
= 31; j
>= 0; j
--)
364 if(buf
[i
] & (1 << j
))
366 return -1; // unreachable
369 static void xor_with_ptrs(uint8_t *buf
, ptr_bundle_t
*ptrs
)
372 int sz = g_decode_A_info.nr_bytes2 - 1;
375 for(int i = 0; i < sz; i++)
376 buf[i] ^= ptrs->ptrA[i];
377 for(int i = sz; i < 32; i++)
378 buf[i] ^= ptrs->ptrB[i - sz];
381 for(int i = 0; i < 32; i++)
382 buf[i] ^= ptrs->ptrA[i];
384 uint8_t *ptrA
= (uint8_t *)ptrs
->ptrA
;
385 uint8_t *ptrB
= (uint8_t *)ptrs
->ptrB
;
386 int sz
= MIN(g_decode_A_info
.nr_bytes2
- 1, 32);
387 for(int i
= 0; i
< sz
; i
++)
389 for(int i
= sz
; i
< 32; i
++)
390 buf
[i
] ^= ptrB
[i
- sz
];
393 static void copy_memory(uint32_t *to
, uint32_t *from
)
395 for(int i
= 0; i
< g_decode_A_info
.nr_dwords
; i
++)
399 static void swap_memory(uint32_t *a
, uint32_t *b
)
401 for(int i
= 0; i
< g_decode_A_info
.nr_dwords
; i
++)
409 static void shift_left(uint32_t *buf
, int nr_bits
)
411 for(int i
= g_decode_A_info
.nr_dwords_m1
; i
>= 0; i
--)
412 buf
[i
+ (nr_bits
/ 32)] = buf
[i
];
413 memset(buf
, 0, 4 * (nr_bits
/ 32));
415 int size
= g_decode_A_info
.nr_dwords
+ (nr_bits
+ 31) / 32;
416 nr_bits
= nr_bits
% 32;
419 for(int i
= 0; i
< size
; i
++)
421 uint32_t new_val
= buf
[i
] << nr_bits
| acc
;
422 /* WARNING if nr_bits = 0 then the right shift by 32 is undefined and so
423 * the following code could break. The additional AND catches this case
424 * and make sure the result is 0 */
425 acc
= ((1 << nr_bits
) - 1) & (buf
[i
] >> (32 - nr_bits
));
430 static void xor_big(uint32_t *res
, uint32_t *a
, uint32_t *b
)
432 for(int i
= 0; i
< g_decode_A_info
.nr_dwords_x2
; i
++)
433 res
[i
] = a
[i
] ^ b
[i
];
436 static void decode_with_xor(uint32_t *res
, uint32_t *key
)
438 uint32_t *tmp
= malloc(g_decode_A_info
.nr_dwords_x8
);
439 uint32_t *copy
= malloc(g_decode_A_info
.nr_dwords_x8
);
440 uint32_t *copy_arg
= malloc(g_decode_A_info
.nr_dwords_x8
);
441 uint32_t *tmp2
= malloc(g_decode_A_info
.nr_dwords_x8
);
442 clear_memory(tmp
, g_decode_A_info
.nr_dwords_x2
);
443 clear_memory(res
, g_decode_A_info
.nr_dwords
);
445 clear_memory(tmp2
, g_decode_A_info
.nr_dwords
);
446 copy_memory(copy_arg
, key
);
447 copy_memory(copy
, (uint32_t *)g_decode_A_info
.ptr5
);
449 for(int i
= find_last_bit_set(copy_arg
, 1); i
; i
= find_last_bit_set(copy_arg
, 1))
451 int pos
= i
- find_last_bit_set(copy
, 1);
454 swap_memory(copy_arg
, copy
);
455 swap_memory(res
, tmp2
);
458 copy_memory(tmp
, copy
);
459 shift_left(tmp
, pos
);
460 xor_big(copy_arg
, copy_arg
, tmp
);
461 copy_memory(tmp
, tmp2
);
462 shift_left(tmp
, pos
);
463 xor_big(res
, res
, tmp
);
471 static void shift_left_one(uint32_t *a
)
473 int pos
= find_last_bit_set(a
, 0) / 32 + 1;
477 for(int i
= 0; i
< pos
; i
++)
479 uint32_t new_val
= v
| a
[i
] << 1;
489 static void xor_mult(uint32_t *a1
, uint32_t *a2
, uint32_t *a3
)
491 uint32_t *tmp2
= malloc(g_decode_A_info
.nr_dwords_x8
);
492 clear_memory(tmp2
, g_decode_A_info
.nr_dwords_x2
);
493 copy_memory(tmp2
, a3
);
495 int pos
= g_decode_A_info
.nr_dwords
;
497 for(int i
= 0; i
< 32; i
++)
499 for(int j
= 0; j
< g_decode_A_info
.nr_dwords
; j
++)
502 for(int k
= 0; k
< pos
; k
++)
503 a1
[j
+ k
] ^= tmp2
[k
];
505 shift_left_one(tmp2
);
507 pos
= find_last_bit_set(tmp2
, 0) / 32 + 1;
512 static void xor_mult(uint32_t *a1
, uint32_t *a2
, uint32_t *a3
)
514 for(int i
= 0; i
< 32 * g_decode_A_info
.nr_dwords
; i
++)
515 for(int j
= 0; j
< 32 * g_decode_A_info
.nr_dwords
; j
++)
518 uint32_t v1
= (a2
[i
/ 32] >> (i
% 32)) & 1;
519 uint32_t v2
= (a3
[j
/ 32] >> (j
% 32)) & 1;
520 a1
[k
/ 32] ^= (v1
* v2
) << (k
% 32);
525 static int compare(uint32_t *a
, uint32_t *b
)
527 return memcmp(a
, b
, g_decode_A_info
.nr_dwords
* 4);
530 static void xor_mult_high(uint32_t *a1
, uint32_t *buf
, uint32_t *a3
)
533 uint32_t *tmp
= malloc(g_decode_A_info
.nr_dwords_x8
);
534 int v4
= g_decode_A_info
.field_34
;
535 int pos
= find_last_bit_set(buf
, 0);
536 for(int i
= pos
- v4
; i
>= 0; i
= find_last_bit_set(buf
, 0) - v4
)
538 clear_memory(tmp
, g_decode_A_info
.nr_dwords_x2
);
539 copy_memory(tmp
, a3
);
541 xor_big(buf
, buf
, tmp
);
546 static void xor_small(uint32_t *res
, uint32_t *a
, uint32_t *b
)
548 for(int i
= 0; i
< g_decode_A_info
.nr_dwords
; i
++)
549 res
[i
] = a
[i
] ^ b
[i
];
552 static void crypto(ptr_bundle_t
*a1
, ptr_bundle_t
*a2
)
554 uint32_t *v2
= malloc(g_decode_A_info
.nr_dwords_x8
);
555 uint32_t *v3
= malloc(g_decode_A_info
.nr_dwords_x8
);
556 uint32_t *v4
= malloc(g_decode_A_info
.nr_dwords_x8
);
557 uint32_t *v5
= malloc(g_decode_A_info
.nr_dwords_x8
);
558 uint32_t *v6
= malloc(g_decode_A_info
.nr_dwords_x8
);
559 clear_memory(a2
->ptrA
, g_decode_A_info
.nr_dwords
);
560 clear_memory(a2
->ptrB
, g_decode_A_info
.nr_dwords
);
561 clear_memory(v3
, g_decode_A_info
.nr_dwords_x2
);
562 clear_memory(v6
, g_decode_A_info
.nr_dwords_x2
);
563 clear_memory(v4
, g_decode_A_info
.nr_dwords_x2
);
564 decode_with_xor(v4
, a1
->ptrA
);
565 clear_memory(v5
, g_decode_A_info
.nr_dwords_x2
);
567 xor_mult(v5
, v4
, a1
->ptrB
);
568 xor_mult_high(v5
, v5
, g_decode_A_info
.ptr5
);
569 xor_small(v2
, a1
->ptrA
, v5
);
570 xor_small(v4
, v2
, g_decode_A_info
.ptr6
);
571 clear_memory(v3
, g_decode_A_info
.nr_dwords_x2
);
572 xor_mult(v3
, v2
, v2
);
573 xor_mult_high(v3
, v3
, g_decode_A_info
.ptr5
);
574 xor_small(a2
->ptrA
, v4
, v3
);
575 clear_memory(v5
, g_decode_A_info
.nr_dwords_x2
);
576 xor_small(v4
, v2
, g_xor_key
);
577 xor_mult(v5
, v4
, a2
->ptrA
);
578 xor_mult_high(v5
, v5
, g_decode_A_info
.ptr5
);
579 clear_memory(v6
, g_decode_A_info
.nr_dwords_x2
);
580 xor_mult(v6
, a1
->ptrA
, a1
->ptrA
);
581 xor_mult_high(v6
, v6
, g_decode_A_info
.ptr5
);
582 xor_small(a2
->ptrB
, v5
, v6
);
590 static void crypto2(ptr_bundle_t
*a1
, ptr_bundle_t
*a2
, ptr_bundle_t
*a3
)
592 uint32_t *v3
= malloc(g_decode_A_info
.nr_dwords_x8
);
593 uint32_t *v4
= malloc(g_decode_A_info
.nr_dwords_x8
);
594 uint32_t *v5
= malloc(g_decode_A_info
.nr_dwords_x8
);
595 uint32_t *v6
= malloc(g_decode_A_info
.nr_dwords_x8
);
596 uint32_t *v7
= malloc(g_decode_A_info
.nr_dwords_x8
);
597 clear_memory(a3
->ptrA
, g_decode_A_info
.nr_dwords
);
598 clear_memory(a3
->ptrB
, g_decode_A_info
.nr_dwords
);
599 clear_memory(v4
, g_decode_A_info
.nr_dwords_x2
);
600 clear_memory(v7
, g_decode_A_info
.nr_dwords_x2
);
601 xor_small(v5
, a1
->ptrB
, a2
->ptrB
);
602 xor_small(v6
, a1
->ptrA
, a2
->ptrA
);
603 decode_with_xor(v7
, v6
);
604 clear_memory(v3
, g_decode_A_info
.nr_dwords_x2
);
605 xor_mult(v3
, v7
, v5
);
606 xor_mult_high(v3
, v3
, g_decode_A_info
.ptr5
);
607 xor_small(v5
, v3
, g_decode_A_info
.ptr6
);
608 clear_memory(v4
, g_decode_A_info
.nr_dwords_x2
);
609 xor_mult(v4
, v3
, v3
);
610 xor_mult_high(v4
, v4
, g_decode_A_info
.ptr5
);
611 xor_small(v7
, v5
, v4
);
612 xor_small(a3
->ptrA
, v7
, v6
);
613 xor_small(v5
, a1
->ptrA
, a3
->ptrA
);
614 xor_small(v6
, a3
->ptrA
, a1
->ptrB
);
615 clear_memory(v7
, g_decode_A_info
.nr_dwords_x2
);
616 xor_mult(v7
, v5
, v3
);
617 xor_mult_high(v7
, v7
, g_decode_A_info
.ptr5
);
618 xor_small(a3
->ptrB
, v7
, v6
);
626 static int crypto3(uint32_t *a1
, ptr_bundle_t
*ptrs_alt
, ptr_bundle_t
*ptrs
)
628 ptr_bundle_t ptrs_others
;
630 ptrs_others
.ptrA
= malloc(g_decode_A_info
.size
);
631 ptrs_others
.ptrB
= malloc(g_decode_A_info
.size
);
632 clear_memory(ptrs
->ptrA
, g_decode_A_info
.nr_dwords
);
633 clear_memory(ptrs
->ptrB
, g_decode_A_info
.nr_dwords
);
634 clear_memory(ptrs_others
.ptrA
, g_decode_A_info
.nr_dwords
);
635 clear_memory(ptrs_others
.ptrB
, g_decode_A_info
.nr_dwords
);
636 int pos
= find_last_bit_set(a1
, 1);
638 copy_memory(ptrs_others
.ptrA
, ptrs_alt
->ptrA
);
639 copy_memory(ptrs_others
.ptrB
, ptrs_alt
->ptrB
);
640 for(int bit
= (pos
% 32) - 1; bit
>= 0; bit
--)
642 crypto(&ptrs_others
, ptrs
);
643 copy_memory(ptrs_others
.ptrA
, ptrs
->ptrA
);
644 copy_memory(ptrs_others
.ptrB
, ptrs
->ptrB
);
645 if(a1
[pos
/ 32] & (1 << bit
))
647 crypto2(&ptrs_others
, ptrs_alt
, ptrs
);
648 copy_memory(ptrs_others
.ptrA
, ptrs
->ptrA
);
649 copy_memory(ptrs_others
.ptrB
, ptrs
->ptrB
);
652 for(int i
= pos
/ 32 - 1; i
>= 0; i
--)
654 for(int bit
= 31; bit
>= 0; bit
--)
656 crypto(&ptrs_others
, ptrs
);
657 copy_memory(ptrs_others
.ptrA
, ptrs
->ptrA
);
658 copy_memory(ptrs_others
.ptrB
, ptrs
->ptrB
);
659 if(a1
[i
] & (1 << bit
))
661 crypto2(&ptrs_others
, ptrs_alt
, ptrs
);
662 copy_memory(ptrs_others
.ptrA
, ptrs
->ptrA
);
663 copy_memory(ptrs_others
.ptrB
, ptrs
->ptrB
);
667 copy_memory(ptrs
->ptrA
, ptrs_others
.ptrA
);
668 copy_memory(ptrs
->ptrB
, ptrs_others
.ptrB
);
669 free(ptrs_others
.ptrA
);
670 free(ptrs_others
.ptrB
);
674 static int crypto4(uint8_t *a1
, ptr_bundle_t
*ptrs
, uint32_t *a3
)
676 ptr_bundle_t ptrs_others
;
678 ptrs_others
.ptrA
= malloc(g_decode_A_info
.size
);
679 ptrs_others
.ptrB
= malloc(g_decode_A_info
.size
);
680 clear_memory(ptrs_others
.ptrA
, g_decode_A_info
.nr_dwords
);
681 clear_memory(ptrs_others
.ptrB
, g_decode_A_info
.nr_dwords
);
682 int ret
= crypto3(a3
, ptrs
, &ptrs_others
);
684 xor_with_ptrs(a1
, &ptrs_others
);
685 free(ptrs_others
.ptrA
);
686 free(ptrs_others
.ptrB
);
690 static int crypto_bits(uint32_t *buf
, int a2
)
692 clear_memory(buf
, g_decode_A_info
.nr_dwords
);
693 g_decode_A_info
.field_34
= 0;
699 g_decode_A_info
.field_34
= 233;
709 g_decode_A_info
.field_34
= 163;
716 static int crypto_bits_copy(ptr_bundle_t
*a1
, char a2
)
718 int ret
= crypto_bits(g_decode_A_info
.ptr5
, a2
);
722 copy_memory(a1
->ptrA
, g_crypto_table
);
723 copy_memory(a1
->ptrB
, g_crypto_table2
);
724 copy_memory(g_decode_A_info
.ptr6
, g_crypto_data
);
725 copy_memory(g_decode_A_info
.ptr7
, g_crypto_key6
);
730 copy_memory(a1
->ptrA
, g_crypto_key3
);
731 copy_memory(a1
->ptrB
, g_crypto_key4
);
732 copy_memory(g_decode_A_info
.ptr6
, g_crypto_data3
);
733 copy_memory(g_decode_A_info
.ptr7
, g_crypto_key5
);
740 static void create_guid(void *uid
, int bit_size
)
743 for(int i
= 0; i
< bit_size
/ 8; i
++)
747 static int process_block_B(uint8_t block
[512])
749 cprintf(BLUE
, "Block B\n");
750 decode_block_B(block
+ 3, g_subblock_A
+ 4, 489);
751 cprintf_field(" Word: ", "%d ", *(uint16_t *)(block
+ 3));
752 check_field(*(uint16_t *)(block
+ 3), 1, "Ok\n", "Mismatch\n");
754 int ret
= check_block(block
, block
+ 492, 492);
755 cprintf(GREEN
, " Check: ");
756 check_field(ret
, 0, "Pass\n", "Fail\n");
758 g_decode_buffer3
= malloc(g_decode_A_info
.size
);
759 memset(g_decode_buffer3
, 0, g_decode_A_info
.size
);
760 int offset
= *(uint16_t *)(block
+ 13) + 16;
761 memcpy(g_decode_buffer3
, &block
[offset
], g_decode_A_info
.nr_bytes2
);
766 static int do_fwu_v3(int size
, uint8_t *buf
, uint8_t *blockA
, uint8_t *blockB
,
767 uint8_t *unk
, uint8_t *unk2
, uint8_t *blo
)
770 uint8_t smallblock
[512];
771 uint8_t bigblock
[1024];
773 memset(smallblock
, 0, sizeof(smallblock
));
774 memset(bigblock
, 0, sizeof(bigblock
));
776 uint8_t ba
= buf
[0x1ee] & 0xf;
777 uint8_t bb
= buf
[0x1fe] & 0xf;
779 cprintf_field(" Block A: ", "%d\n", ba
+ 2);
780 cprintf(" Block B: ", "%d\n", ba
+ bb
+ 5);
782 *blockA
= buf
[494] & 0xf;
783 *blockB
= buf
[510] & 0xf;
784 memcpy(bigblock
, &buf
[512 * (*blockA
+ 2)], sizeof(bigblock
));
786 int ret
= process_block_A(bigblock
);
787 continue_the_force(ret
);
789 memcpy(smallblock
, &buf
[512 * (*blockA
+ *blockB
+ 5)], sizeof(smallblock
));
790 ret
= process_block_B(smallblock
);
791 continue_the_force(ret
);
793 cprintf(BLUE
, "Main\n");
795 // WARNING you need more that 48 because 17+32 > 48 !! (see code below) */
796 uint8_t smallbuf
[50];
797 memcpy(smallbuf
, buf
+ 42, sizeof(smallbuf
));
798 cprintf_field(" Byte: ", "%d ", smallbuf
[16]);
799 check_field(smallbuf
[16], 3, "Ok\n", "Mismatch\n");
802 ptrs
.ptrA
= malloc(g_decode_A_info
.size
);
803 ptrs
.ptrB
= malloc(g_decode_A_info
.size
);
804 memset(ptrs
.ptrA
, 0, g_decode_A_info
.size
);
805 memset(ptrs
.ptrB
, 0, g_decode_A_info
.size
);
806 memcpy(ptrs
.ptrA
, buf
+ 91, g_decode_A_info
.nr_bytes2
);
807 memcpy(ptrs
.ptrB
, buf
+ 91 + g_decode_A_info
.nr_bytes2
, g_decode_A_info
.nr_bytes2
);
809 ret
= crypto_bits_copy(&g_decode_A_info
.ptr1
, g_crypto_info_byte
);
810 cprintf(GREEN
, " Crypto bits copy: ");
811 check_field(ret
, 0, "Pass\n", "Fail\n");
813 ret
= crypto4(smallbuf
+ 17, &ptrs
, g_decode_buffer3
);
814 cprintf(GREEN
, " Crypto 4: ");
815 check_field(ret
, 0, "Pass\n", "Fail\n");
817 memcpy(unk2
, &smallbuf
[17], 32);
818 int offset
= g_decode_A_info
.nr_words
+ 91;
820 decode_block_with_swap(unk2
, 0, &buf
[offset
], 512 - offset
, g_perm_B
);
822 int pos
= *(uint16_t *)&buf
[offset
];
823 cprintf_field(" Word: ", "%d ", pos
);
824 int tmp
= g_decode_A_info
.nr_words2
+ 199;
825 check_field(pos
, 510 - tmp
, "Ok\n", "Mismatch\n");
828 memcpy(midbuf
, &buf
[pos
+ offset
+ 2], sizeof(midbuf
));
830 cprintf_field(" Byte: ", "%d ", midbuf
[0]);
831 check_field(midbuf
[0], 2, "Ok\n", "Invalid\n");
832 cprintf_field(" DWord: ", "%d ", *(uint32_t *)&midbuf
[1]);
833 check_field(*(uint32_t *)&midbuf
[1], 2056, "Ok\n", "Invalid\n");
834 cprintf_field(" DWord: ", "%d ", *(uint32_t *)&midbuf
[5]);
835 check_field(*(uint32_t *)&midbuf
[5], 8, "Ok\n", "Invalid\n");
836 cprintf_field(" Byte: ", "%d ", midbuf
[41]);
837 check_field(midbuf
[41], 190, "Ok\n", "Invalid\n");
840 create_guid(smallblock
, 3808);
841 memcpy(smallblock
+ 476, midbuf
+ 42, 16);
842 compute_checksum(smallblock
, 492, blo
+ 492);
844 memcpy(blo
, smallblock
, bsz
);
845 memcpy(blo
+ bsz
, midbuf
+ 42, 16);
846 memcpy(blo
+ bsz
+ 16, smallblock
+ bsz
, 476 - bsz
);
848 decode_block_with_perm(blo
+ 492, 16, blo
, 492, g_perm_B
);
849 ret
= check_block(buf
+ 42, midbuf
+ 88, 450);
850 cprintf(GREEN
, " Decode block: ");
851 check_field(ret
, 0, "Pass\n", "Fail\n");
853 ret
= memcmp(g_subblock_A
+ 4, midbuf
+ 9, 16);
854 cprintf(GREEN
, " Compare: ");
855 check_field(ret
, 0, "Pass\n", "Fail\n");
858 memset(zero
, 0, sizeof(zero
));
859 ret
= memcmp(unk
, zero
, sizeof(zero
));
860 cprintf(GREEN
, " Sanity: ");
861 check_field(ret
, 0, "Pass\n", "Fail\n");
864 ret = memcmp(midbuf + 25, zero, sizeof(zero));
865 cprintf(GREEN, " Sanity: ");
866 check_field(ret, 0, "Pass\n", "Fail\n");
872 static int do_sthg_fwu_v3(uint8_t *buf
, int *size
, uint8_t *unk
, uint8_t *block
)
877 memset(unk2
, 0, sizeof(unk2
));
878 int ret
= do_fwu_v3(*size
, buf
, &blockA
, &blockB
, unk
, unk2
, block
);
879 continue_the_force(ret
);
882 uint8_t *tmpbuf
= malloc(*size
);
883 memset(tmpbuf
, 0, *size
);
884 int offsetA
= (blockA
+ 1) << 9;
885 int offsetB
= (blockB
+ 1) << 9;
886 memcpy(tmpbuf
, buf
+ 512, offsetA
);
887 memcpy(tmpbuf
+ offsetA
, buf
+ offsetA
+ 1536, offsetB
);
888 memcpy(tmpbuf
+ offsetA
+ offsetB
,
889 buf
+ offsetA
+ 1536 + offsetB
+ 512, *size
- offsetA
- offsetB
);
890 compute_perm(unk2
, 32, g_perm_B
);
891 decode_perm(tmpbuf
, *size
, g_perm_B
);
892 memcpy(buf
, tmpbuf
, *size
);
897 /* [add]: string to add when there is no extension
898 * [replace]: string to replace extension */
899 static void build_out_prefix(char *add
, char *replace
, bool slash
)
903 /** copy input filename with extra space */
904 g_out_prefix
= malloc(strlen(g_in_file
) + strlen(add
) + 16);
905 strcpy(g_out_prefix
, g_in_file
);
906 /** remove extension and add '/' */
907 char *filename
= strrchr(g_out_prefix
, '/');
908 // have p points to the beginning or after the last '/'
909 filename
= (filename
== NULL
) ? g_out_prefix
: filename
+ 1;
911 char *dot
= strrchr(filename
, '.');
914 *dot
= 0; // cut at the dot
915 strcat(dot
, replace
);
918 strcat(filename
, add
); // add extra string
922 strcat(filename
, "/");
923 /** make sure the directory exists */
924 mkdir(g_out_prefix
, S_IRWXU
| S_IRGRP
| S_IROTH
);
928 static int do_fwu(uint8_t *buf
, int size
)
930 struct fwu_hdr_t
*hdr
= (void *)buf
;
932 if(size
< (int)sizeof(struct fwu_hdr_t
))
934 cprintf(GREY
, "File too small\n");
937 cprintf(BLUE
, "Header\n");
938 cprintf(GREEN
, " Signature:");
939 for(int i
= 0; i
< FWU_SIG_SIZE
; i
++)
940 cprintf(YELLOW
, " %02x", hdr
->sig
[i
]);
941 if(memcmp(hdr
->sig
, g_fwu_signature
, FWU_SIG_SIZE
) == 0)
942 cprintf(RED
, " Ok\n");
945 cprintf(RED
, " Mismatch\n");
946 let_the_force_flow(__LINE__
);
949 cprintf_field(" FW size: ", "%d ", hdr
->fw_size
);
950 if((int)hdr
->fw_size
== size
)
951 cprintf(RED
, " Ok\n");
952 else if((int)hdr
->fw_size
< size
)
953 cprintf(RED
, " Ok (file greater than firmware)\n");
956 cprintf(RED
, " Error (file too small)\n");
957 let_the_force_flow(__LINE__
);
960 cprintf_field(" Block size: ", "%d ", hdr
->block_size
);
961 check_field(hdr
->block_size
, FWU_BLOCK_SIZE
, "Ok\n", "Invalid\n");
963 cprintf_field(" Version: ", "%x ", hdr
->version
);
964 int ver
= get_version(buf
, size
);
967 cprintf(RED
, "(Unknown)\n");
971 cprintf(RED
, "(Ver. %d)\n", g_version
[ver
].version
);
973 cprintf_field(" Unknown: ", "0x%x ", hdr
->unk
);
974 check_field(hdr
->unk
, g_version
[ver
].unk
, "Ok\n", "Invalid\n");
976 cprintf(GREEN
, " Signature:");
977 for(int i
= 0; i
< FWU_SIG_SIZE
; i
++)
978 cprintf(YELLOW
, " %02x", hdr
->sig2
[i
]);
979 if(memcmp(hdr
->sig2
, g_version
[ver
].sig2
, FWU_SIG_SIZE
) == 0)
980 cprintf(RED
, " Ok\n");
983 cprintf(RED
, " Mismatch\n");
984 let_the_force_flow(__LINE__
);
987 build_out_prefix(".afi", ".afi", false);
989 if(g_version
[ver
].version
== 3)
992 memset(unk
, 0, sizeof(unk
));
994 memset(block
, 0, sizeof(block
));
995 int ret
= do_sthg_fwu_v3(buf
, &size
, unk
, block
);
996 continue_the_force(ret
);
998 cprintf(GREY
, "Descrambling to %s... ", g_out_prefix
);
999 FILE *f
= fopen(g_out_prefix
, "wb");
1002 fwrite(buf
, size
, 1, f
);
1004 cprintf(RED
, "Ok\n");
1007 cprintf(RED
, "Failed: %m\n");
1013 static bool check_fwu(uint8_t *buf
, int size
)
1015 struct fwu_hdr_t
*hdr
= (void *)buf
;
1017 if(size
< (int)sizeof(struct fwu_hdr_t
))
1019 return memcmp(hdr
->sig
, g_fwu_signature
, FWU_SIG_SIZE
) == 0;
1025 * part of this work comes from s1mp3/s1fwx
1028 #define AFI_ENTRIES 126
1029 #define AFI_SIG_SIZE 4
1033 uint8_t sig
[AFI_SIG_SIZE
];
1035 uint16_t product_id
;
1037 uint8_t ext_ver_id
[2];
1043 } __attribute__((packed
));
1055 } __attribute__((packed
));
1057 struct afi_post_hdr_t
1061 } __attribute__((packed
));
1065 struct afi_hdr_t hdr
;
1066 struct afi_entry_t entry
[AFI_ENTRIES
];
1067 struct afi_post_hdr_t post
;
1070 #define AFI_ENTRY_BREC 'B'
1071 #define AFI_ENTRY_FWSC 'F'
1072 #define AFI_ENTRY_ADFUS 'A'
1073 #define AFI_ENTRY_FW 'I'
1075 #define AFI_ENTRY_DLADR_BREC 0x00000006 // 'B'
1076 #define AFI_ENTRY_DLADR_FWSC 0x00020008 // 'F'
1077 #define AFI_ENTRY_DLADR_ADFUS 0x000C0008 // 'A'
1078 #define AFI_ENTRY_DLADR_ADFU 0x00000000 // 'U'
1079 #define AFI_ENTRY_DLADR_FW 0x00000011 // 'I'
1081 const uint8_t g_afi_signature
[AFI_SIG_SIZE
] =
1086 static uint32_t afi_checksum(void *ptr
, int size
)
1090 for(; size
>= 4; size
-= 4)
1093 crc
+= *(uint8_t *)cp
;
1095 crc
+= *(uint16_t *)cp
;
1097 crc
+= *(uint16_t *)cp
+ ((*(uint8_t *)(cp
+ 2)) << 16);
1101 static void build_filename(char buf
[16], struct afi_entry_t
*ent
)
1104 for(int i
= 0; i
< 8 && ent
->name
[i
] != ' '; i
++)
1105 buf
[pos
++] = ent
->name
[i
];
1107 for(int i
= 0; i
< 3 && ent
->ext
[i
] != ' '; i
++)
1108 buf
[pos
++] = ent
->ext
[i
];
1112 static int do_afi(uint8_t *buf
, int size
)
1114 struct afi_t
*afi
= (void *)buf
;
1116 if(size
< (int)sizeof(struct afi_t
))
1118 cprintf(GREY
, "File too small\n");
1121 cprintf(BLUE
, "Header\n");
1122 cprintf(GREEN
, " Signature:");
1123 for(int i
= 0; i
< AFI_SIG_SIZE
; i
++)
1124 cprintf(YELLOW
, " %02x", afi
->hdr
.sig
[i
]);
1125 if(memcmp(afi
->hdr
.sig
, g_afi_signature
, AFI_SIG_SIZE
) == 0)
1126 cprintf(RED
, " Ok\n");
1129 cprintf(RED
, " Mismatch\n");
1130 let_the_force_flow(__LINE__
);
1133 cprintf_field(" Vendor ID: ", "0x%x\n", afi
->hdr
.vendor_id
);
1134 cprintf_field(" Product ID: ", "0x%x\n", afi
->hdr
.product_id
);
1135 cprintf_field(" Version: ", "%x.%x\n", afi
->hdr
.ver_id
[0], afi
->hdr
.ver_id
[1]);
1136 cprintf_field(" Ext Version: ", "%x.%x\n", afi
->hdr
.ext_ver_id
[0],
1137 afi
->hdr
.ext_ver_id
[1]);
1138 cprintf_field(" Date: ", "%x/%x/%x%x\n", afi
->hdr
.day
, afi
->hdr
.month
,
1139 afi
->hdr
.year
[0], afi
->hdr
.year
[1]);
1141 cprintf_field(" AFI size: ", "%d ", afi
->hdr
.afi_size
);
1142 if((int)afi
->hdr
.afi_size
== size
)
1143 cprintf(RED
, " Ok\n");
1144 else if((int)afi
->hdr
.afi_size
< size
)
1145 cprintf(RED
, " Ok (file greater than archive)\n");
1148 cprintf(RED
, " Error (file too small)\n");
1149 let_the_force_flow(__LINE__
);
1152 cprintf_field(" Reserved: ", "%x %x %x\n", afi
->hdr
.res
[0],
1153 afi
->hdr
.res
[1], afi
->hdr
.res
[2]);
1155 build_out_prefix(".fw", "", true);
1157 cprintf(BLUE
, "Entries\n");
1158 for(int i
= 0; i
< AFI_ENTRIES
; i
++)
1160 if(afi
->entry
[i
].name
[0] == 0)
1162 struct afi_entry_t
*entry
= &afi
->entry
[i
];
1164 build_filename(filename
, entry
);
1165 cprintf(RED
, " %s\n", filename
);
1166 cprintf_field(" Type: ", "%02x", entry
->type
);
1167 if(isprint(entry
->type
))
1168 cprintf(RED
, " %c", entry
->type
);
1170 cprintf_field(" Addr: ", "0x%x\n", entry
->addr
);
1171 cprintf_field(" Offset: ", "0x%x\n", entry
->offset
);
1172 cprintf_field(" Size: ", "0x%x\n", entry
->size
);
1173 cprintf_field(" Desc: ", "%.4s\n", entry
->desc
);
1174 cprintf_field(" Checksum: ", "0x%x ", entry
->checksum
);
1175 uint32_t chk
= afi_checksum(buf
+ entry
->offset
, entry
->size
);
1176 cprintf(RED
, "%s\n", chk
== entry
->checksum
? "Ok" : "Mismatch");
1178 char *name
= malloc(strlen(g_out_prefix
) + strlen(filename
) + 16);
1179 sprintf(name
, "%s%s", g_out_prefix
, filename
);
1181 cprintf(GREY
, "Unpacking to %s... ", name
);
1182 FILE *f
= fopen(name
, "wb");
1185 fwrite(buf
+ entry
->offset
, entry
->size
, 1, f
);
1187 cprintf(RED
, "Ok\n");
1190 cprintf(RED
, "Failed: %m\n");
1193 cprintf(BLUE
, "Post Header\n");
1194 cprintf_field(" Checksum: ", "%x ", afi
->post
.checksum
);
1195 uint32_t chk
= afi_checksum(buf
, sizeof(struct afi_t
) - 4);
1196 cprintf(RED
, "%s\n", chk
== afi
->post
.checksum
? "Ok" : "Mismatch");
1201 static bool check_afi(uint8_t *buf
, int size
)
1203 struct afi_hdr_t
*hdr
= (void *)buf
;
1205 if(size
< (int)sizeof(struct afi_hdr_t
))
1207 return memcmp(hdr
->sig
, g_afi_signature
, AFI_SIG_SIZE
) == 0;
1214 #define FW_SIG_SIZE 4
1216 #define FW_ENTRIES 240
1225 uint32_t block_offset
; // offset shift by 9
1229 } __attribute__((packed
));
1233 uint8_t sig
[FW_SIG_SIZE
];
1245 uint8_t res2
[8 * 16];
1248 char res3
[4 * 16 + 1];
1257 struct fw_entry_t entry
[FW_ENTRIES
];
1258 } __attribute__((packed
));
1260 const uint8_t g_fw_signature
[FW_SIG_SIZE
] =
1262 0x55, 0xaa, 0xf2, 0x0f
1265 static void build_filename_fw(char buf
[16], struct fw_entry_t
*ent
)
1268 for(int i
= 0; i
< 8 && ent
->name
[i
] != ' '; i
++)
1269 buf
[pos
++] = ent
->name
[i
];
1271 for(int i
= 0; i
< 3 && ent
->ext
[i
] != ' '; i
++)
1272 buf
[pos
++] = ent
->ext
[i
];
1276 static int do_fw(uint8_t *buf
, int size
)
1278 struct fw_hdr_t
*hdr
= (void *)buf
;
1280 if(size
< (int)sizeof(struct fw_hdr_t
))
1282 cprintf(GREY
, "File too small\n");
1285 cprintf(BLUE
, "Header\n");
1286 cprintf(GREEN
, " Signature:");
1287 for(int i
= 0; i
< FW_SIG_SIZE
; i
++)
1288 cprintf(YELLOW
, " %02x", hdr
->sig
[i
]);
1289 if(memcmp(hdr
->sig
, g_fw_signature
, FW_SIG_SIZE
) == 0)
1290 cprintf(RED
, " Ok\n");
1293 cprintf(RED
, " Mismatch\n");
1294 let_the_force_flow(__LINE__
);
1297 cprintf_field(" USB VID: ", "0x%x\n", hdr
->usb_vid
);
1298 cprintf_field(" USB PID: ", "0x%x\n", hdr
->usb_pid
);
1299 cprintf_field(" Date: ", "%x/%x/%x%x\n", hdr
->day
, hdr
->month
, hdr
->year
[0], hdr
->year
[1]);
1300 cprintf_field(" Checksum: ", "%x\n", hdr
->checksum
);
1301 cprintf_field(" Productor: ", "%.16s\n", hdr
->productor
);
1302 cprintf_field(" String 2: ", "%.16s\n", hdr
->str2
);
1303 cprintf_field(" String 3: ", "%.32s\n", hdr
->str3
);
1304 cprintf_field(" Device Name: ", "%.32s\n", hdr
->dev_name
);
1305 cprintf(GREEN
, " Unknown:\n");
1306 for(int i
= 0; i
< 8; i
++)
1308 cprintf(YELLOW
, " ");
1309 for(int j
= 0; j
< 16; j
++)
1310 cprintf(YELLOW
, "%02x ", hdr
->res2
[i
* 16 + j
]);
1311 cprintf(YELLOW
, "\n");
1313 cprintf_field(" USB Name 1: ", "%.8s\n", hdr
->usb_name1
);
1314 cprintf_field(" USB Name 2: ", "%.8s\n", hdr
->usb_name2
);
1315 cprintf_field(" MTP Name 1: ", "%.32s\n", hdr
->mtp_name1
);
1316 cprintf_field(" MTP Name 2: ", "%.32s\n", hdr
->mtp_name2
);
1317 cprintf_field(" MTP Version: ", "%.32s\n", hdr
->mtp_ver
);
1319 cprintf_field(" MTP VID: ", "0x%x\n", hdr
->mtp_vid
);
1320 cprintf_field(" MTP PID: ", "0x%x\n", hdr
->mtp_pid
);
1321 cprintf_field(" FW Version: ", "%.64s\n", hdr
->fw_ver
);
1323 build_out_prefix(".unpack", "", true);
1325 cprintf(BLUE
, "Entries\n");
1326 for(int i
= 0; i
< AFI_ENTRIES
; i
++)
1328 if(hdr
->entry
[i
].name
[0] == 0)
1330 struct fw_entry_t
*entry
= &hdr
->entry
[i
];
1332 build_filename_fw(filename
, entry
);
1333 cprintf(RED
, " %s\n", filename
);
1334 cprintf_field(" Attr: ", "%02x\n", entry
->attr
);
1335 cprintf_field(" Offset: ", "0x%x\n", entry
->block_offset
<< 9);
1336 cprintf_field(" Size: ", "0x%x\n", entry
->size
);
1337 cprintf_field(" Unknown: ", "%x\n", entry
->unk
);
1338 cprintf_field(" Checksum: ", "0x%x ", entry
->checksum
);
1339 uint32_t chk
= afi_checksum(buf
+ (entry
->block_offset
<< 9), entry
->size
);
1340 cprintf(RED
, "%s\n", chk
== entry
->checksum
? "Ok" : "Mismatch");
1343 char *name
= malloc(strlen(g_out_prefix
) + strlen(filename
) + 16);
1344 sprintf(name
, "%s%s", g_out_prefix
, filename
);
1346 cprintf(GREY
, "Unpacking to %s... ", name
);
1347 FILE *f
= fopen(name
, "wb");
1350 fwrite(buf
+ (entry
->block_offset
<< 9), entry
->size
, 1, f
);
1352 cprintf(RED
, "Ok\n");
1355 cprintf(RED
, "Failed: %m\n");
1362 static bool check_fw(uint8_t *buf
, int size
)
1364 struct fw_hdr_t
*hdr
= (void *)buf
;
1366 if(size
< (int)sizeof(struct fw_hdr_t
))
1368 return memcmp(hdr
->sig
, g_fw_signature
, FW_SIG_SIZE
) == 0;
1371 static void usage(void)
1373 printf("Usage: atjboottool [options] firmware\n");
1374 printf("Options:\n");
1375 printf(" -o <prefix>\tSet output prefix\n");
1376 printf(" -f/--force\tForce to continue on errors\n");
1377 printf(" -?/--help\tDisplay this message\n");
1378 printf(" -d/--debug\tDisplay debug messages\n");
1379 printf(" -c/--no-color\tDisable color output\n");
1380 printf(" --fwu\tUnpack a FWU firmware file\n");
1381 printf(" --afi\tUnpack a AFI archive file\n");
1382 printf(" --fw\tUnpack a FW archive file\n");
1383 printf("The default is to try to guess the format.\n");
1384 printf("If several formats are specified, all are tried.\n");
1385 printf("If no output prefix is specified, a default one is picked.\n");
1389 int main(int argc
, char **argv
)
1391 bool try_fwu
= false;
1392 bool try_afi
= false;
1393 bool try_fw
= false;
1397 static struct option long_options
[] =
1399 {"help", no_argument
, 0, '?'},
1400 {"debug", no_argument
, 0, 'd'},
1401 {"no-color", no_argument
, 0, 'c'},
1402 {"force", no_argument
, 0, 'f'},
1403 {"fwu", no_argument
, 0, 'u'},
1404 {"afi", no_argument
, 0, 'a'},
1405 {"fw", no_argument
, 0, 'w'},
1409 int c
= getopt_long(argc
, argv
, "?dcfo:a1", long_options
, NULL
);
1417 enable_color(false);
1429 g_out_prefix
= optarg
;
1445 if(argc
- optind
!= 1)
1451 g_in_file
= argv
[optind
];
1452 FILE *fin
= fopen(g_in_file
, "r");
1455 perror("Cannot open boot file");
1458 fseek(fin
, 0, SEEK_END
);
1459 long size
= ftell(fin
);
1460 fseek(fin
, 0, SEEK_SET
);
1462 void *buf
= malloc(size
);
1465 perror("Cannot allocate memory");
1469 if(fread(buf
, size
, 1, fin
) != 1)
1471 perror("Cannot read file");
1478 if(try_fwu
|| check_fwu(buf
, size
))
1479 ret
= do_fwu(buf
, size
);
1480 else if(try_afi
|| check_afi(buf
, size
))
1481 ret
= do_afi(buf
, size
);
1482 else if(try_fw
|| check_fw(buf
, size
))
1483 ret
= do_fw(buf
, size
);
1486 cprintf(GREY
, "No valid format found\n");
1492 cprintf(GREY
, "Error: %d", ret
);
1494 cprintf(GREY
, " (use --force to force processing)");