This source file includes following definitions.
- addBufRange
- findRanges
- idx_valid
- idx2adr
- adr2idx
- adr2ptr
- idxcorr
- set_ignore_errors
- fwadr
- fwval
- fwRd
- fwRn
- fwRnMOV
- fwOp2
- LDR2adr
- LDR2idx
- LDR2val
- ADR2adr
- ALUop2
- ALUop2a
- idxFollowBranch
- followBranch
- followBranch2
- isLDR_PC
- isLDR_PC_cond
- isLDR_SP
- isLDR
- isLDR_cond
- isADR_PC
- isADR_PC_cond
- isADR
- isLDMFD
- isLDMFD_PC
- isSTMFD
- isSTMFD_LR
- isSTR
- isSTR_cond
- isBX
- isBX_cond
- isBX_LR
- isBLX
- isBL
- isBL_cond
- isBLEQ
- isB
- isBorBL
- isCMP
- isMOV
- isMOV_immed
- isORR
- isADD
- isSUB
- isASCIIstring
- find_Nth_str
- find_str
- find_str_bytes
- find_inst
- find_inst_rev
- find_Nth_inst
- find_Nth_inst_rev
- find_strptr_ref
- find_str_ref
- find_nxt_str_ref
- find_nxt_str_ref_alt
- find_BL
- find_B
- search_fw
- search_fw_bytes
- load_firmware
1
2
3
4
5
6
7
8
9
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <stdint.h>
13 #include <string.h>
14 #include <time.h>
15 #include <stdarg.h>
16
17 #include "dancingbits.h"
18 #include "stubs_load.h"
19 #include "firmware_load.h"
20
21
22
23
24 extern void error(char*, int);
25 extern void usage(char *err);
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 void addBufRange(firmware *fw, int o, int l)
54 {
55 BufRange *n = malloc(sizeof(BufRange));
56 n->p = fw->buf + o;
57 n->off = o;
58 n->len = l;
59 n->next = 0;
60 if (fw->br == 0)
61 {
62 fw->br = n;
63 }
64 else
65 {
66 fw->last->next = n;
67 }
68 fw->last = n;
69 }
70
71
72 void findRanges(firmware *fw)
73 {
74 int i, j, k;
75
76
77 fw->br = 0; fw->last = 0;
78 k = -1; j = 0;
79 for (i = 0; i < fw->size; i++)
80 {
81 if (fw->buf[i] == 0xFFFFFFFF)
82 {
83 if (k == -1)
84 {
85 k = i;
86 }
87 }
88 else
89 {
90 if (k != -1)
91 {
92 if (i - k > 32)
93 {
94 if (k - j > 8)
95 {
96
97 addBufRange(fw,j,k - j);
98 }
99 j = i;
100 }
101 k = -1;
102 }
103 }
104 }
105
106 if (k != -1)
107 {
108 if (k - j > 8)
109 {
110 addBufRange(fw,j,k - j);
111 }
112 }
113 else
114 {
115 if (i - j > 8)
116 {
117 addBufRange(fw,j,i - j);
118 }
119 }
120 }
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136 int idx_valid(firmware *fw, int i)
137 {
138 if ((i >= 0) && (i < fw->size))
139 return 1;
140 if ((fw->dryos_ver >= 51) && (fw->alt_base) && (i >= fw->size))
141 {
142 i = ((i * 4) - (fw->alt_base - fw->base)) / 4;
143 if ((i >= 0) && (i < fw->size))
144 return 1;
145 }
146 if (fw->dryos_ver >= 50)
147 {
148 int i2 = ((i * 4) + (fw->base - fw->base2)) / 4;
149 if ((i2 >= 0) && (i2 < fw->size2))
150 return 1;
151
152 if (idx2adr(fw,i)>=fw->base && idx2adr(fw,i)<(fw->base+fw->size*4))
153 return 1;
154 }
155 return 0;
156 }
157
158
159 uint32_t idx2adr(firmware *fw, int idx)
160 {
161 return fw->base + (idx << 2);
162 }
163
164
165 int adr2idx(firmware *fw, uint32_t adr)
166 {
167 if (adr < fw->base)
168 return -((fw->base - adr) >> 2);
169 else
170 return (adr - fw->base) >> 2;
171 }
172
173
174 char* adr2ptr(firmware *fw, uint32_t adr)
175 {
176 if ((fw->dryos_ver >= 51) && (fw->alt_base) && (adr >= fw->alt_base))
177 {
178 return ((char*)fw->buf) + (adr - fw->alt_base);
179 }
180 if ((fw->dryos_ver >= 50) && (adr < fw->base))
181 {
182 adr = (adr - fw->base2) + fw->base_copied;
183 }
184 return ((char*)fw->buf) + (adr - fw->base);
185 }
186
187
188 int idxcorr(firmware *fw, int idx)
189 {
190 static int inited = 0;
191 static int b2oidx, b2idx;
192 if (!inited)
193 {
194 b2oidx = adr2idx(fw, fw->base_copied);
195 b2idx = adr2idx(fw, fw->base2);
196 inited = 1;
197 }
198
199 if (fw->base2)
200 {
201 if ((idx >= b2oidx) && (idx < b2oidx + fw->size2))
202 {
203 idx = idx - b2oidx + b2idx;
204 }
205 }
206 return idx;
207 }
208
209
210 static int ignore_errors = 0;
211
212 void set_ignore_errors(int n)
213 {
214 ignore_errors = n;
215 }
216
217
218
219
220
221
222
223 uint32_t* fwadr(firmware *fw, int i)
224 {
225 if ((i >= 0) && (i < fw->size))
226 return &fw->buf[i];
227 if ((fw->dryos_ver >= 51) && (fw->alt_base) && (i >= fw->size))
228 {
229 i = ((i * 4) - (fw->alt_base - fw->base)) / 4;
230 if ((i >= 0) && (i < fw->size))
231 return &fw->buf[i];
232 }
233 if ((fw->dryos_ver >= 50) && (i < 0))
234 {
235 i = ((i * 4) + (fw->base - fw->base2)) / 4;
236 if ((i >= 0) && (i < fw->size2))
237 return &fw->buf2[i];
238 }
239 if (ignore_errors)
240 {
241 return &fw->buf[0];
242 }
243 fprintf(stderr,"Invalid firmware offset %d.\n",i);
244 error("\nInvalid firmware offset %d. Possible corrupt firmware or incorrect start address.\n",i);
245 return 0;
246 }
247
248
249 uint32_t fwval(firmware *fw, int i)
250 {
251 return *fwadr(fw,i);
252 }
253
254
255 int fwRd(firmware *fw, int i)
256 {
257
258 return (*fwadr(fw,i) & 0x0000F000) >> 12;
259 }
260
261
262 int fwRn(firmware *fw, int i)
263 {
264
265 return (*fwadr(fw,i) & 0x000F0000) >> 16;
266 }
267
268
269 int fwRnMOV(firmware *fw, int i)
270 {
271
272 return (*fwadr(fw,i) & 0x0000000F);
273 }
274
275
276 int fwOp2(firmware *fw, int i)
277 {
278
279 return (*fwadr(fw,i) & 0x00000FFF);
280 }
281
282
283
284
285 uint32_t LDR2adr(firmware *fw, int offset)
286 {
287 uint32_t inst = fwval(fw,offset);
288 int offst = (inst & 0xFFF);
289 uint32_t fadr = (inst & 0x00800000)?idx2adr(fw,offset+2)+offst:idx2adr(fw,offset+2)-offst;
290 return fadr;
291 }
292
293
294 uint32_t LDR2idx(firmware *fw, int offset)
295 {
296 return adr2idx(fw,LDR2adr(fw,offset));
297 }
298
299
300 uint32_t LDR2val(firmware *fw, int offset)
301 {
302 return fwval(fw,adr2idx(fw,LDR2adr(fw,offset)));
303 }
304
305
306
307
308
309 uint32_t ADR2adr(firmware *fw, int offset)
310 {
311 uint32_t inst = fwval(fw,offset);
312 int rot = 32 - ((inst & 0xF00) >> 7);
313 int offst = (inst & 0xFF) <<rot;
314 uint32_t fadr = 0;
315 switch (inst & 0x01E00000)
316 {
317 case 0x00400000:
318 fadr = idx2adr(fw,offset+2)-offst;
319 break;
320 case 0x00800000:
321 fadr = idx2adr(fw,offset+2)+offst;
322 break;
323 case 0x01A00000:
324
325 break;
326 case 0x01E00000:
327
328 break;
329 }
330 return fadr;
331 }
332
333
334 uint32_t ALUop2(firmware *fw, int offset)
335 {
336 uint32_t inst = fwval(fw,offset);
337 int rot = 32 - ((inst & 0xF00) >> 7);
338 int offst = (inst & 0xFF) <<rot;
339 uint32_t fadr = 0;
340 switch (inst & 0x03E00000)
341 {
342 case 0x02400000:
343 case 0x02800000:
344 case 0x03400000:
345 case 0x03A00000:
346 case 0x03C00000:
347 fadr = offst;
348 break;
349 }
350 return fadr;
351 }
352
353
354 uint32_t ALUop2a(firmware *fw, int offset)
355 {
356 uint32_t inst = fwval(fw,offset);
357 uint32_t rot = (inst>>7)&0x1e;
358 uint32_t imm8 = inst & 0xff;
359 uint32_t offst = (imm8>>rot) | (imm8<<(32-rot));
360 uint32_t fadr = 0;
361 switch (inst & 0x03E00000)
362 {
363 case 0x02400000:
364 case 0x02800000:
365 case 0x03A00000:
366 case 0x03C00000:
367 case 0x03800000:
368 fadr = offst;
369 break;
370 }
371 return fadr;
372 }
373
374
375
376
377
378
379
380
381
382
383 int idxFollowBranch(firmware *fw, int fidx, int offset)
384 {
385 if (offset)
386 {
387 uint32_t msk = ~(offset & 0xFF000000);
388 fidx += ((offset & 0x00FFFFFF) - 1);
389 uint32_t inst = fwval(fw,fidx);
390 if ((inst & (0xFF000000&msk)) == (0xEA000000&msk))
391 {
392 int o = inst & 0x00FFFFFF;
393 if (o & 0x00800000) o |= 0xFF000000;
394 fidx = fidx + o + 2;
395 }
396 else if ((inst & (0xFFFFF000)) == (0xE51FF000))
397 {
398 fidx = adr2idx(fw,LDR2val(fw,fidx));
399 }
400 }
401 return fidx;
402 }
403
404
405
406 uint32_t followBranch(firmware *fw, uint32_t fadr, int offset)
407 {
408 if (offset)
409 {
410 uint32_t msk = ~(offset & 0xFF000000);
411 uint32_t fidx = adr2idx(fw,fadr);
412 fidx += ((offset & 0x00FFFFFF) - 1);
413 uint32_t inst = fwval(fw,fidx);
414 if ((inst & (0xFF000000&msk)) == (0xEA000000&msk))
415 {
416 int o = inst & 0x00FFFFFF;
417 if (o & 0x00800000) o |= 0xFF000000;
418 if (idx_valid(fw,fidx+o+2))
419 fadr = idx2adr(fw,fidx+o+2);
420 }
421 else if ((inst & (0xFFFFF000)) == (0xE51FF000))
422 {
423 fadr = LDR2val(fw,fidx);
424 }
425 }
426 return fadr;
427 }
428
429
430 uint32_t followBranch2(firmware *fw, uint32_t fadr, int offset)
431 {
432 fadr = followBranch(fw, fadr, offset);
433 if ((offset & 0x00FFFFFF) == 1)
434 fadr = followBranch(fw, fadr, offset);
435 return fadr;
436 }
437
438
439
440
441
442
443 int isLDR_PC(firmware *fw, int offset)
444 {
445 return ((fwval(fw,offset) & 0xFE1F0000) == 0xE41F0000);
446 }
447
448
449 int isLDR_PC_cond(firmware *fw, int offset)
450 {
451 return ((fwval(fw,offset) & 0x0E1F0000) == 0x041F0000);
452 }
453
454
455 int isLDR_SP(firmware *fw, int offset)
456 {
457 return ((fwval(fw,offset) & 0xFFFF0000) == 0xE59D0000);
458 }
459
460
461 int isLDR(firmware *fw, int offset)
462 {
463 return ((fwval(fw,offset) & 0xFE100000) == 0xE4100000);
464 }
465
466
467 int isLDR_cond(firmware *fw, int offset)
468 {
469 return ((fwval(fw,offset) & 0x0E100000) == 0x04100000);
470 }
471
472
473 int isADR_PC(firmware *fw, int offset)
474 {
475 return ((fwval(fw,offset) & 0xFE0F0000) == 0xE20F0000);
476 }
477
478
479 int isADR_PC_cond(firmware *fw, int offset)
480 {
481 return ((fwval(fw,offset) & 0x0E0F0000) == 0x020F0000);
482 }
483
484
485 int isADR(firmware *fw, int offset)
486 {
487 return ((fwval(fw,offset) & 0xFE000000) == 0xE2000000);
488 }
489
490
491 int isLDMFD(firmware *fw, int offset)
492 {
493 return ((fwval(fw,offset) & 0xFFFF0000) == 0xE8BD0000);
494 }
495
496
497 int isLDMFD_PC(firmware *fw, int offset)
498 {
499 return ((fwval(fw,offset) & 0xFFFF8000) == 0xE8BD8000);
500 }
501
502
503 int isSTMFD(firmware *fw, int offset)
504 {
505 return ((fwval(fw,offset) & 0xFFFF0000) == 0xE92D0000);
506 }
507
508
509 int isSTMFD_LR(firmware *fw, int offset)
510 {
511 return ((fwval(fw,offset) & 0xFFFF4000) == 0xE92D4000);
512 }
513
514
515 int isSTR(firmware *fw, int offset)
516 {
517 return ((fwval(fw,offset) & 0xFE100000) == 0xE4000000);
518 }
519
520
521 int isSTR_cond(firmware *fw, int offset)
522 {
523 return ((fwval(fw,offset) & 0x0E100000) == 0x04000000);
524 }
525
526
527 int isBX(firmware *fw, int offset)
528 {
529 return ((fwval(fw,offset) & 0xFFFFFFF0) == 0xE12FFF10);
530 }
531
532
533 int isBX_cond(firmware *fw, int offset)
534 {
535 return ((fwval(fw,offset) & 0x0FFFFFF0) == 0x012FFF10);
536 }
537
538
539 int isBX_LR(firmware *fw, int offset)
540 {
541 return (fwval(fw,offset) == 0xE12FFF1E);
542 }
543
544
545 int isBLX(firmware *fw, int offset)
546 {
547 return ((fwval(fw,offset) & 0xFFFFFFF0) == 0xE12FFF30);
548 }
549
550
551 int isBL(firmware *fw, int offset)
552 {
553 return ((fwval(fw,offset) & 0xFF000000) == 0xEB000000);
554 }
555
556
557 int isBL_cond(firmware *fw, int offset)
558 {
559 return ((fwval(fw,offset) & 0x0F000000) == 0x0B000000);
560 }
561
562
563 int isBLEQ(firmware *fw, int offset)
564 {
565 return ((fwval(fw,offset) & 0xFF000000) == 0x0B000000);
566 }
567
568
569 int isB(firmware *fw, int offset)
570 {
571 return ((fwval(fw,offset) & 0xFF000000) == 0xEA000000);
572 }
573
574
575 int isBorBL(firmware *fw, int offset)
576 {
577 return ((fwval(fw,offset) & 0xFE000000) == 0xEA000000);
578 }
579
580
581 int isCMP(firmware *fw, int offset)
582 {
583 return ((fwval(fw,offset) & 0xFFF00000) == 0xE3500000);
584 }
585
586
587 int isMOV(firmware *fw, int offset)
588 {
589 return ((fwval(fw,offset) & 0xFFF00000) == 0xE1A00000);
590 }
591
592
593 int isMOV_immed(firmware *fw, int offset)
594 {
595 return ((fwval(fw,offset) & 0xFFF00000) == 0xE3A00000);
596 }
597
598
599 int isORR(firmware *fw, int offset)
600 {
601 return ((fwval(fw,offset) & 0xFFF00000) == 0xE3800000);
602 }
603
604
605 int isADD(firmware *fw, int offset)
606 {
607 return ((fwval(fw,offset) & 0xfff00000) == 0xe2800000);
608 }
609
610
611 int isSUB(firmware *fw, int offset)
612 {
613 return ((fwval(fw,offset) & 0xfff00000) == 0xe2400000);
614 }
615
616
617
618 int isASCIIstring(firmware *fw, uint32_t adr)
619 {
620 if (idx_valid(fw, adr2idx(fw, adr)))
621 {
622 unsigned char *p = (unsigned char*)adr2ptr(fw, adr);
623 int i;
624 for (i = 0; (i < 100) && (p[i] != 0); i++)
625 {
626 if (!((p[i] == '\r') || (p[i] == '\n') || (p[i] == '\t') || ((p[i] >= 0x20) && (p[i] <= 0x7f))))
627 {
628 return 0;
629 }
630 }
631 if ((i >= 2) && (p[i] == 0))
632 return 1;
633 }
634 return 0;
635 }
636
637
638
639
640
641
642 int find_Nth_str(firmware *fw, char *str, int N)
643 {
644 int nlen = strlen(str);
645 uint32_t nm0 = *((uint32_t*)str);
646 uint32_t *p;
647 int j;
648
649 BufRange *br = fw->br;
650 while (br)
651 {
652 for (p = br->p, j = 0; j < br->len - nlen/4; j++, p++)
653 {
654 if ((nm0 == *p) && ((nlen<=4) || (memcmp(p+1,str+4,nlen-4) == 0)) )
655 {
656 if (--N == 0)
657 return j+br->off;
658 }
659 }
660 br = br->next;
661 }
662
663 return -1;
664 }
665
666 int find_str(firmware *fw, char *str)
667 {
668 return find_Nth_str(fw, str, 1);
669 }
670
671
672
673 uint32_t find_str_bytes(firmware *fw, char *str)
674 {
675 BufRange *p = fw->br;
676 while (p)
677 {
678 int k;
679 for (k = p->off*4; k < (p->off + p->len)*4; k++)
680 {
681 if (strcmp(((char*)fw->buf)+k,str) == 0)
682 return fw->base+k;
683 }
684 p = p->next;
685 }
686
687 return 0;
688 }
689
690
691
692 int find_inst(firmware *fw, int (*inst)(firmware*,int), int idx, int len)
693 {
694 int k;
695 for (k = idx; (k < fw->size) && (k < idx + len); k++)
696 {
697 if (inst(fw, k))
698 return k;
699 }
700 return -1;
701 }
702
703
704
705 int find_inst_rev(firmware *fw, int (*inst)(firmware*,int), int idx, int len)
706 {
707 int k;
708 for (k = idx; (k > 0) && (k > idx - len); k--)
709 {
710 if (inst(fw, k))
711 return k;
712 }
713 return -1;
714 }
715
716
717
718 int find_Nth_inst(firmware *fw, int (*inst)(firmware*,int), int idx, int len, int N)
719 {
720 int k;
721 for (k = idx; (k < fw->size) && (k < idx + len); k++)
722 {
723 if (inst(fw, k))
724 N--;
725 if (N <= 0)
726 return k;
727 }
728 return -1;
729 }
730
731
732
733 int find_Nth_inst_rev(firmware *fw, int (*inst)(firmware*,int), int idx, int len, int N)
734 {
735 int k;
736 for (k = idx; (k > 0) && (k > idx - len); k--)
737 {
738 if (inst(fw, k))
739 N--;
740 if (N <= 0)
741 return k;
742 }
743 return -1;
744 }
745
746
747
748
749
750
751
752
753 int find_strptr_ref(firmware *fw, char *str)
754 {
755 uint32_t sadr = find_str_bytes(fw, str);
756 if (sadr > 0)
757 {
758 int k;
759 for (k=0; k<fw->size; k++)
760 {
761 if (fwval(fw,k) == sadr)
762 {
763 uint32_t fadr = idx2adr(fw,k);
764 int j;
765 for (j=0; j<fw->size; j++)
766 {
767 if (isADR_PC_cond(fw,j) && (ADR2adr(fw,j) == fadr))
768 {
769 return j;
770 }
771 else if (isLDR_PC_cond(fw,j) && (LDR2val(fw,j) == fadr))
772 {
773 return j;
774 }
775 }
776 }
777 }
778 }
779 return -1;
780 }
781
782
783
784
785
786 int find_str_ref(firmware *fw, char *str)
787 {
788 int k = find_str(fw, str);
789 if (k >= fw->lowest_idx)
790 {
791 uint32_t sadr = idx2adr(fw,k);
792 for (k=0; k<fw->size; k++)
793 {
794 if (isADR_PC_cond(fw,k) && (ADR2adr(fw,k) == sadr))
795 {
796 return k;
797 }
798 else if (isLDR_PC_cond(fw,k) && (LDR2val(fw,k) == sadr))
799 {
800 return k;
801 }
802 }
803 }
804 return -1;
805 }
806
807
808 int find_nxt_str_ref(firmware *fw, int str_adr, int ofst)
809 {
810 if (str_adr >= fw->lowest_idx)
811 {
812 int k;
813 uint32_t sadr = idx2adr(fw,str_adr);
814 for (k=ofst+1; k<fw->size; k++)
815 {
816 if (isADR_PC_cond(fw,k) && (ADR2adr(fw,k) == sadr))
817 {
818 return k;
819 }
820 else if (isLDR_PC_cond(fw,k) && (LDR2val(fw,k) == sadr))
821 {
822 return k;
823 }
824 }
825 }
826 return -1;
827 }
828
829
830 int find_nxt_str_ref_alt(firmware *fw, char *str, int ofst, int limit)
831 {
832 int k;
833 for (k=ofst; k<ofst+limit; k++)
834 {
835 if (isADR_PC_cond(fw,k) && idx_valid(fw,adr2idx(fw,ADR2adr(fw,k))) && (strcmp(str,adr2ptr(fw,ADR2adr(fw,k))) == 0))
836 {
837 return k;
838 }
839 else if (isLDR_PC_cond(fw,k) && idx_valid(fw,adr2idx(fw,LDR2val(fw,k))) && (strcmp(str,adr2ptr(fw,LDR2val(fw,k))) == 0))
840 {
841 return k;
842 }
843 }
844 return -1;
845 }
846
847
848
849
850
851 int find_BL(firmware *fw, int k, uint32_t v1, __attribute__ ((unused))uint32_t v2)
852 {
853 if (isBL(fw,k))
854 {
855 uint32_t n = idxFollowBranch(fw, k, 0x01000001);
856 if (n == v1)
857 return k;
858 }
859 return 0;
860 }
861
862
863
864 int find_B(firmware *fw, int k, uint32_t v1, __attribute__ ((unused))uint32_t v2)
865 {
866 if (isB(fw,k))
867 {
868 uint32_t n = idxFollowBranch(fw, k, 0x00000001);
869 if (n == v1)
870 return k;
871 }
872 return 0;
873 }
874
875
876
877
878
879
880
881 int search_fw(firmware *fw, int (*func)(firmware*, int, uint32_t, uint32_t), uint32_t v1, uint32_t v2, int len)
882 {
883 BufRange *p = fw->br;
884 while (p)
885 {
886 int k;
887 for (k = p->off; k <= p->off + p->len - len; k++)
888 {
889 int rv = func(fw,k,v1,v2);
890 if (rv != 0)
891 return rv;
892 }
893 p = p->next;
894 }
895 return 0;
896 }
897
898
899
900
901
902
903 int search_fw_bytes(firmware *fw, int (*func)(firmware*, int))
904 {
905 BufRange *p = fw->br;
906 while (p)
907 {
908 int k;
909 for (k = p->off*4; k < (p->off + p->len)*4; k++)
910 {
911 if (func(fw,k))
912 return 1;
913 }
914 p = p->next;
915 }
916 return 0;
917 }
918
919
920
921
922
923 void load_firmware(firmware *fw, const char *filename, const char *base_addr, const char *alt_base_addr, int os_type)
924 {
925
926 FILE *f = fopen(filename, "rb");
927 int i, j, k;
928
929 if (f == NULL)
930 {
931 fprintf(stderr,"Error opening %s\n",filename);
932 usage("firmware open");
933 }
934
935
936 fw->buf2 = 0;
937 fw->base2 = 0;
938 fw->size2 = 0;
939
940 fw->os_type = os_type;
941
942
943 fseek(f,0,SEEK_END);
944 fw->size = (ftell(f)+3)/4;
945 fseek(f,0,SEEK_SET);
946
947
948 fw->base = strtoul(base_addr, NULL, 0);
949 if (alt_base_addr)
950 fw->alt_base = strtoul(alt_base_addr, NULL, 0);
951 else
952 fw->alt_base = 0;
953
954
955
956 fw->buf = malloc((fw->size+32)*4);
957 k = fread(fw->buf, 4, fw->size, f);
958 fclose(f);
959
960
961 memset(&fw->buf[fw->size],0xff,32*4);
962
963
964 findRanges(fw);
965
966
967
968 fw->main_offs = 0;
969 if (os_type == OS_DRYOS)
970 {
971 k = find_str(fw, "gaonisoy");
972 if (k != 1)
973 {
974 fw->main_offs = 0x10000 / 4;
975 }
976 }
977
978 fw->real_dryos_ver = fw->dryos_ver = 0;
979 if (os_type == OS_DRYOS)
980 {
981 k = find_str(fw, "DRYOS version 2.3, release #");
982 if (k != -1)
983 {
984 fw->real_dryos_ver = fw->dryos_ver = atoi(((char*)&fw->buf[k])+28);
985 fw->dryos_ver_str = (char*)&fw->buf[k];
986 }
987 }
988
989
990 fw->firmware_ver_str = 0;
991 k = find_str(fw, "Firmware Ver ");
992 if (os_type == OS_VXWORKS)
993 {
994 if (k < 0)
995 {
996 k = find_str(fw, "Firmware Version GM");
997 }
998 if (k < 0)
999 {
1000 k = find_str(fw, "Firmware Version ");
1001 }
1002 }
1003 if (k != -1)
1004 {
1005 fw->firmware_ver_str = (char*)&fw->buf[k];
1006 fw->fwver_idx = k;
1007 }
1008
1009
1010 fw->fsize = -((int)fw->base)/4;
1011 if (fw->alt_base) fw->fsize = -((int)fw->alt_base)/4;
1012 fw->cam_idx = -1;
1013 fw->pid_adr = 0xffffffff;
1014 fw->cam = 0;
1015 fw->pid = 0;
1016 if (os_type == OS_DRYOS)
1017 {
1018 if (fw->dryos_ver > 59) fw->dryos_ver = 59;
1019 switch (fw->dryos_ver)
1020 {
1021 case 20:
1022 case 23:
1023 case 31:
1024 case 39:
1025 fw->cam_idx = adr2idx(fw,0xFFFE0110);
1026 fw->pid_adr = 0xFFFE0130;
1027 break;
1028 case 43:
1029 case 45:
1030 fw->cam_idx = adr2idx(fw,0xFFFE00D0);
1031 fw->pid_adr = 0xFFFE0130;
1032 break;
1033 case 47:
1034 fw->cam_idx = adr2idx(fw,(fw->base==0xFF000000)?0xFFF40170:0xFFFE0170);
1035 fw->pid_adr = (fw->base==0xFF000000)?0xFFF40040:0xFFFE0040;
1036 break;
1037 case 49:
1038 case 50:
1039 case 51:
1040 case 52:
1041 if (fw->alt_base)
1042 {
1043 fw->cam_idx = adr2idx(fw,(fw->alt_base==0xFF000000)?0xFFF40190:0xFFFE0170);
1044 fw->pid_adr = (fw->alt_base==0xFF000000)?0xFFF40040:0xFFFE0040;
1045 if (idx_valid(fw,fw->cam_idx) && (strncmp((char*)fwadr(fw,fw->cam_idx),"Canon ",6) != 0))
1046 fw->cam_idx = adr2idx(fw,(fw->alt_base==0xFF000000)?0xFFF40170:0xFFFE0170);
1047 }
1048 else
1049 {
1050 fw->cam_idx = adr2idx(fw,(fw->base==0xFF000000)?0xFFF40190:0xFFFE0170);
1051 fw->pid_adr = (fw->base==0xFF000000)?0xFFF40040:0xFFFE0040;
1052 if (idx_valid(fw,fw->cam_idx) && (strncmp((char*)fwadr(fw,fw->cam_idx),"Canon ",6) != 0))
1053 fw->cam_idx = adr2idx(fw,(fw->base==0xFF000000)?0xFFF40170:0xFFFE0170);
1054 }
1055 break;
1056 case 54:
1057 fw->cam_idx = adr2idx(fw,(fw->base==0xFF010000)?0xFFF40170:0xFFFF0170);
1058 fw->pid_adr = (fw->base==0xFF010000)?0xFFF40040:0xFFFF0040;
1059 break;
1060 case 55:
1061 case 57:
1062 fw->cam_idx = adr2idx(fw,(fw->base==0xFF010000)?0xFFFE0170:0xFFFF0170);
1063 fw->pid_adr = (fw->base==0xFF010000)?0xFFFE0040:0xFFFF0040;
1064 break;
1065 case 58:
1066 case 59:
1067 fw->cam_idx = adr2idx(fw,(fw->base==0xFF010000)?0xFFFE03A0:0xFFFF03A0);
1068 fw->pid_adr = (fw->base==0xFF010000)?0xFFFE0270:0xFFFF0270;
1069 break;
1070 }
1071 }
1072 else
1073 {
1074
1075 uint32_t vx_name_offsets[] = { 0xFFD70110, 0xFFD70120, 0xFFF80110, 0xFFFE0110 };
1076 uint32_t vx_pid_offsets[] = { 0xFFD70130, 0xFFD7014E, 0xFFF80130, 0xFFFE0130 };
1077 for (i=0; i<(int)(sizeof(vx_name_offsets)/sizeof(vx_name_offsets[0])); i++)
1078 {
1079 int k = adr2idx(fw,vx_name_offsets[i]);
1080 if (idx_valid(fw,k) && (strncmp((char*)fwadr(fw,k),"Canon ",6) == 0))
1081 {
1082 fw->cam_idx = k;
1083 fw->pid_adr = vx_pid_offsets[i];
1084 break;
1085 }
1086 }
1087 }
1088
1089
1090 if (idx_valid(fw,fw->cam_idx) && (strncmp((char*)fwadr(fw,fw->cam_idx),"Canon ",6) == 0))
1091 {
1092 fw->cam = (char*)fwadr(fw,fw->cam_idx);
1093 }
1094
1095
1096 if (idx_valid(fw,adr2idx(fw,fw->pid_adr)) && (fw->pid_adr != 0xffffffff))
1097 {
1098
1099 fw->pid = (fwval(fw,adr2idx(fw,fw->pid_adr)) >> ((fw->pid_adr & 2)?16:0)) & 0xFFFF;
1100 }
1101
1102
1103 fw->maxram = 0;
1104 if (os_type == OS_DRYOS)
1105 {
1106 if (((fw->buf[0x10 + fw->main_offs] & 0xFFFFFF00) == 0xE3A00000) && (fw->buf[0x11 + fw->main_offs] == 0xEE060F12))
1107 {
1108 fw->maxram = (1 << (((fw->buf[0x10 + fw->main_offs] & 0x3E) >> 1) + 1)) - 1;
1109 }
1110 else if (((fw->buf[0x14 + fw->main_offs] & 0xFFFFFF00) == 0xE3A00000) && (fw->buf[0x15 + fw->main_offs] == 0xEE060F12))
1111 {
1112 fw->maxram = (1 << (((fw->buf[0x14 + fw->main_offs] & 0x3E) >> 1) + 1)) - 1;
1113 }
1114 }
1115 else if (os_type == OS_VXWORKS)
1116 {
1117 for (k=16; k<100; k++)
1118 {
1119 if ((fw->buf[k] & 0xFFFF0FFF) == 0xEE060F12)
1120 {
1121 fw->maxram = (1 << (((fw->buf[k-1] & 0x3E) >> 1) + 1)) - 1;
1122 break;
1123 }
1124 }
1125 }
1126
1127
1128 fw->memisostart = 0;
1129 if (os_type == OS_DRYOS)
1130 {
1131 for (k=0 + fw->main_offs; k<(100 + fw->main_offs); k++)
1132 {
1133 if (isLDR_PC(fw,k) && (LDR2val(fw,k) == 0x1900) && isLDR_PC(fw,k+6))
1134 {
1135 fw->memisostart = LDR2val(fw,k+6);
1136 }
1137 }
1138 }
1139 else if (os_type == OS_VXWORKS)
1140 {
1141 for (k=16; k<100; k++)
1142 {
1143 if (isMOV_immed(fw,k) && (ALUop2(fw,k) == 0x1900) && isLDR_PC(fw,k+11))
1144 {
1145 fw->memisostart = LDR2val(fw,k+11);
1146
1147 if (isLDR_PC(fw,k-1) && isLDR_PC(fw,k-4) && ((fwval(fw,k-2) & 0xFFF0FFF0) == 0xE1500000))
1148 {
1149 uint32_t fadr = LDR2val(fw,k-1);
1150 uint32_t dadr = 0x1900;
1151 uint32_t eadr = LDR2val(fw,k-4);
1152 if ((fadr > fw->base) && (dadr < fw->base))
1153 {
1154 fw->data_start = dadr;
1155 fw->data_init_start = fadr;
1156 fw->data_len = eadr / 4;
1157 }
1158 }
1159 break;
1160 }
1161 else if (isMOV_immed(fw,k) && (ALUop2(fw,k) == 0x1900) && isLDR_PC(fw,k-2) && isLDR_PC(fw,k-3))
1162 {
1163
1164 fw->maxram = 0x1FFFFFF;
1165 fw->memisostart = 0x1900 + LDR2val(fw,k-3);
1166
1167 fw->data_init_start = LDR2val(fw,k-2);
1168 fw->data_start = 0x1900;
1169 j = idxFollowBranch(fw, k+6, 1);
1170 if (j != k+6)
1171 {
1172 k = idxFollowBranch(fw, j+1, 0x01000001);
1173 if (k != j+1)
1174 {
1175 if ( isLDR_PC(fw,k+3) )
1176 {
1177 uint32_t eadr = LDR2val(fw,k+3);
1178 if ( (eadr>0x1000) && (eadr< fw->memisostart - 0x1900) )
1179 {
1180 fw->data_len = (eadr - 0x1900) / 4;
1181 }
1182 }
1183 }
1184 }
1185 break;
1186 }
1187 else if (isMOV_immed(fw,k) && (ALUop2(fw,k) == 0x1900) && isLDR_PC(fw,k-2) &&
1188 ((fwval(fw,k-1) & 0xFFFF0F00) == 0xE50B0000) && isLDR_PC(fw,k+28) && isLDR_PC(fw,k+4)
1189 )
1190 {
1191
1192 fw->memisostart = LDR2val(fw,k+28);
1193
1194 fw->data_init_start = LDR2val(fw,k-2);
1195 fw->data_start = 0x1900;
1196 fw->data_len = (LDR2val(fw,k+4) - 0x1900) / 4;
1197 break;
1198 }
1199 }
1200 }
1201
1202
1203 fw->ksys_idx = 0;
1204 fw->ksys = 0;
1205 fw->dancing_bits_idx = 0;
1206 fw->dancing_bits = 0;
1207 if (os_type == OS_DRYOS)
1208 {
1209 uint32_t ofst = (fw->main_offs)?0:adr2idx(fw,0xFFFF0000);
1210 if (idx_valid(fw,ofst) && isB(fw,ofst) && isLDR_PC(fw,ofst+1))
1211 {
1212
1213 ofst = adr2idx(fw,LDR2val(fw,ofst+1));
1214 if (idx_valid(fw,ofst))
1215 {
1216 fw->ksys_idx = ofst;
1217 fw->ksys = "? Not found, possible new firmware encryption key.";
1218 switch (fwval(fw,ofst))
1219 {
1220
1221
1222 case 0x70726964: fw->ksys = "d3"; break;
1223 case 0x646C726F: fw->ksys = "d3enc"; break;
1224 case 0x774D450B: fw->ksys = "d4"; break;
1225 case 0x80751A95: fw->ksys = "d4a"; break;
1226 case 0x76894368: fw->ksys = "d4b"; break;
1227 case 0x50838EF7: fw->ksys = "d4c"; break;
1228 case 0xCCE4D2E6: fw->ksys = "d4d"; break;
1229 case 0x66E0C6D2: fw->ksys = "d4e"; break;
1230 case 0xE1268DB4: fw->ksys = "d4f"; break;
1231 case 0x216EA8C8: fw->ksys = "d4g"; break;
1232 case 0x45264974: fw->ksys = "d4h"; break;
1233 case 0x666363FC: fw->ksys = "d4i"; break;
1234 case 0xAE8DB5AF: fw->ksys = "d4j"; break;
1235 }
1236 }
1237
1238
1239 ofst = ofst + 4;
1240 if (idx_valid(fw,ofst))
1241 {
1242 for (i=0; i<VITALY && !fw->dancing_bits; i++)
1243 {
1244 fw->dancing_bits = i+1;
1245 for (j=0; j<8 && fw->dancing_bits; j++)
1246 {
1247 if ((fwval(fw,ofst+j) & 0xFF) != _chr_[i][j])
1248 {
1249 fw->dancing_bits = 0;
1250 }
1251 }
1252 }
1253 if (!fw->dancing_bits)
1254 {
1255
1256 ofst = ofst - 12;
1257 for (i=0; i<VITALY && !fw->dancing_bits; i++)
1258 {
1259 fw->dancing_bits = i+1;
1260 for (j=0; j<8 && fw->dancing_bits; j++)
1261 {
1262 if ((fwval(fw,ofst+j) & 0xFF) != _chr_[i][j])
1263 {
1264 fw->dancing_bits = 0;
1265 }
1266 }
1267 }
1268 }
1269 if (fw->dancing_bits != 0)
1270 {
1271
1272
1273 int need_dance = 1;
1274 for (k = ofst; (k>adr2idx(fw,0xFFFF0000)) && need_dance; k--)
1275 {
1276 if (isLDR_PC(fw,k) && (LDR2val(fw,k) == idx2adr(fw,ofst)))
1277 {
1278 j = find_inst_rev(fw,isSTMFD_LR,k-1,10);
1279 if (j >= 0)
1280 {
1281 uint32_t fadr = idx2adr(fw,j);
1282 for (i=j-200; i<j+200 && need_dance; i++)
1283 {
1284 if (isB(fw,i))
1285 {
1286 uint32_t badr = followBranch(fw,idx2adr(fw,i),1);
1287 if (badr == fadr)
1288 {
1289 int l;
1290 for (l=i-1; l>i-50; l--)
1291 {
1292 if (isLDR(fw,l) && isCMP(fw,l+1) && isBX_cond(fw,l+2))
1293 {
1294 need_dance = 0;
1295 break;
1296 }
1297 }
1298 }
1299 }
1300 }
1301 }
1302 }
1303 }
1304 if (need_dance)
1305 fw->dancing_bits_idx = ofst;
1306 else
1307 fw->dancing_bits = 0;
1308 }
1309 }
1310 }
1311 }
1312
1313 int dx = 3;
1314
1315 fw->lowest_idx = 0;
1316
1317
1318
1319
1320 if (fw->dryos_ver >= 50)
1321 {
1322
1323
1324 for (i=3 + fw->main_offs; i<(100 + fw->main_offs); i++)
1325 {
1326 if (isLDR_PC(fw,i) && isLDR_PC(fw,i+1) && (isLDR_PC(fw,i+2)))
1327 {
1328 uint32_t fadr = LDR2val(fw,i);
1329 uint32_t dadr = LDR2val(fw,i+1);
1330 uint32_t eadr = LDR2val(fw,i+2);
1331 if ((fadr > fw->base) && (dadr < fw->base))
1332 {
1333 fw->buf2 = &fw->buf[adr2idx(fw,fadr)];
1334 fw->base2 = dadr;
1335 fw->base_copied = fadr;
1336 fw->size2 = (eadr - dadr) / 4;
1337 fw->lowest_idx = adr2idx(fw,fw->base2);
1338 dx = i+3;
1339 break;
1340 }
1341 }
1342 }
1343 }
1344
1345
1346 if (os_type == OS_DRYOS)
1347 {
1348 for (i=dx; i<(100 + fw->main_offs); i++)
1349 {
1350 if (isLDR_PC(fw,i) && isLDR_PC(fw,i+1) && (isLDR_PC(fw,i+2)))
1351 {
1352 uint32_t fadr = LDR2val(fw,i);
1353 uint32_t dadr = LDR2val(fw,i+1);
1354 uint32_t eadr = LDR2val(fw,i+2);
1355 if ((fadr > fw->base) && (dadr < fw->base))
1356 {
1357 fw->data_start = dadr;
1358 fw->data_init_start = fadr;
1359 fw->data_len = (eadr - dadr) / 4;
1360 break;
1361 }
1362 }
1363 }
1364 }
1365 }
1366
1367