source: trunk/tools/finsig_dryos.c @ 1391

Revision 1391, 84.5 KB checked in by philmoz, 19 months ago (diff)

Update to dryos signature finder.

  • Add NEED_ENCODED_DISKBOOT and KEYSYS values to stubs_entry.S
  • New section for above value (and PLATFORMID and MAXRAMADDR)
  • Moved dancingbits array to dancingbits.h since it is also now used in finsig_dryos.c.
Line 
1#include <stdlib.h>
2#include <stdio.h>
3#include <stdint.h>
4#include <string.h>
5#include <unistd.h>
6#include <time.h>
7#include <stdarg.h>
8
9#include "dancingbits.h"
10
11//------------------------------------------------------------------------------------------------------------
12
13// For testing - define to compare new values against old values in stubs_entry.S.orig
14//#define COMP_OSTUBS     1
15
16// For testing - define to add entries to stubs_entry_2.s where new address does not match old address
17// and not already defined in stubs_entry_2.s (for backwards compatability).
18//#define UPDATE_STUBS2   1
19
20//------------------------------------------------------------------------------------------------------------
21
22// Buffer output into header and body sections
23
24char    out_buf[32*1024] = "";
25int             out_len = 0;
26char    hdr_buf[32*1024] = "";
27int             hdr_len = 0;
28int             out_hdr = 1;
29
30void bprintf(char *fmt, ...)
31{
32        va_list argp;
33        va_start(argp, fmt);
34
35        if (out_hdr)
36                hdr_len += vsprintf(hdr_buf+hdr_len,fmt,argp);
37        else
38                out_len += vsprintf(out_buf+out_len,fmt,argp);
39
40        va_end(argp);
41}
42
43void add_blankline()
44{
45        if (strcmp(hdr_buf+hdr_len-2,"\n\n") != 0)
46        {
47                hdr_buf[hdr_len++] = '\n';
48                hdr_buf[hdr_len] = 0;
49        }
50}
51
52void write_output()
53{
54        add_blankline();
55        printf("%s",hdr_buf);
56        printf("%s",out_buf);
57}
58
59//------------------------------------------------------------------------------------------------------------
60
61void usage(char *err)
62{
63    printf("finsig <primary> <base> - Error = %s\n",err);
64    exit(1);
65}
66
67//------------------------------------------------------------------------------------------------------------
68
69// Load original stubs_entry.S, stubs_entry_2.s and stubs_min.S to compare results to
70
71typedef struct _osig
72{
73    char        nm[100];
74    uint32_t    val;
75        char            sval[100];
76    int         pct;
77    struct _osig *nxt;
78} osig;
79
80#ifdef  COMP_OSTUBS
81osig *stubs = 0;
82#endif
83osig *stubs2 = 0;
84osig *stubs_min = 0;
85osig *modemap = 0;
86
87void print_stubs(osig *p)
88{
89    while (p)
90    {
91        bprintf("//%s 0x%08x (%s) %d\n",p->nm,p->val,p->sval,p->pct);
92        p = p->nxt;
93    }
94}
95
96int read_line(FILE *f, char *buf)
97{
98    int eof = 0;
99    int len = 0;
100    while (1)
101    {
102        if (fread(buf,1,1,f) != 1) { eof = 1; break; }
103        if ((*buf == 0x0A) || (*buf == 0x0D)) break;
104        len++;
105        buf++;
106    }
107    *buf = 0;
108    return (eof == 0) || (len > 0);
109}
110
111char* get_str(char *s, char *d)
112{
113    while ((*s == ' ') || (*s == '\t') || (*s == ',')) s++;
114    while (*s && (*s != ' ') && (*s != '\t') && (*s != ',') && (*s != ')'))
115    {
116        *d++ = *s++;
117    }
118        while (*s && (*s != ',') && (*s != ')'))
119        {
120                if (*s == '+')
121                {
122                        *d++ = *s++;
123                        while ((*s == ' ') || (*s == '\t') || (*s == ',')) s++;
124                        while (*s && (*s != ' ') && (*s != '\t') && (*s != ',') && (*s != ')'))
125                        {
126                                *d++ = *s++;
127                        }
128                }
129                else s++;
130        }
131    *d = 0;
132    return s;
133}
134
135void add_sig(char *nm, char *val, int pct, osig **hdr)
136{
137    osig *p = malloc(sizeof(osig));
138    strcpy(p->nm, nm);
139        strcpy(p->sval, val);
140    p->pct = pct;
141    p->nxt = *hdr;
142    *hdr = p;
143
144        uint32_t v = 0, n = 0;
145        if ((strncmp(val,"0x",2) == 0) || (strncmp(val,"0X",2) == 0))
146        {
147                while (val)
148                {
149                        sscanf(val,"%x",&n);
150                        v += n;
151                        val = strchr(val,'+');
152                        if (val) val++;
153                }
154        }
155        else
156        {
157                sscanf(val,"%d",&v);
158        }
159
160        p->val = v;
161}
162
163osig* find_sig(osig* p, const char *nm)
164{
165    while (p)
166    {
167        if (strcmp(p->nm, nm) == 0) return p;
168        p = p->nxt;
169    }
170    return 0;
171}
172
173osig* find_sig_val(osig* p, uint32_t val)
174{
175    while (p)
176    {
177        if (p->val == val) return p;
178        p = p->nxt;
179    }
180    return 0;
181}
182
183#ifdef  COMP_OSTUBS
184void load_stubs()
185{
186    FILE *f = fopen("stubs_entry.S.orig", "rb");
187
188    if (f == NULL) return;
189
190    char line[500];
191    char nm[100];
192    char val[12];
193    int pct = 100;
194    char *s;
195
196    while (read_line(f,line))
197    {
198        s = strstr(line, "Best match:");
199        if (s != 0)
200        {
201            strncpy(val,s+12,2); val[2] = 0;
202            pct = atoi(val);
203            continue;
204        }
205       
206        s = strstr(line, "NSTUB(");
207        if (s != 0)
208        {
209            if (strstr(line, "ALT: ") == 0)
210            {
211                s = get_str(s+6,nm);
212                get_str(s,val);
213                add_sig(nm, val, pct, &stubs);
214                pct = 100;
215                continue;
216            }
217        }
218
219        s = strstr(line, "ERROR:");
220        if (s != 0)
221        {
222            get_str(s+6,nm);
223            add_sig(nm, "0", 0, &stubs);
224            continue;
225        }
226    }
227}
228#endif
229
230void load_stubs2()
231{
232    FILE *f = fopen("stubs_entry_2.S", "rb");
233
234    if (f == NULL) return;
235
236    char line[500];
237    char nm[100];
238    char val[12];
239    int pct = 100;
240    char *s;
241
242    while (read_line(f,line))
243    {
244                int off = 7;
245        s = strstr(line, "NHSTUB(");
246                if (s == 0) { off = 6; s = strstr(line, "NSTUB("); }
247                if (s == 0) { off = 4; s = strstr(line, "DEF("); }
248        if (s != 0)
249        {
250            char *c = strstr(line, "//");
251            if ((c == 0) || (c > s))
252            {
253                s = get_str(s+off,nm);
254                get_str(s,val);
255                add_sig(nm, val, pct, &stubs2);
256                pct = 100;
257                continue;
258            }
259        }
260    }
261}
262
263void load_stubs_min()
264{
265    FILE *f = fopen("stubs_min.S", "rb");
266
267    if (f == NULL) return;
268
269    char line[500];
270    char nm[100];
271    char val[12];
272    int pct = 100;
273    char *s;
274
275    while (read_line(f,line))
276    {
277                int off = 7;
278        s = strstr(line, "NHSTUB(");
279                if (s == 0) { off = 4; s = strstr(line, "DEF("); }
280        if (s != 0)
281        {
282            char *c = strstr(line, "//");
283            if ((c == 0) || (c > s))
284            {
285                s = get_str(s+off,nm);
286                get_str(s,val);
287                add_sig(nm, val, pct, &stubs_min);
288                pct = 100;
289                continue;
290            }
291        }
292    }
293}
294
295void load_modemap()
296{
297    FILE *f = fopen("../../shooting.c", "rb");
298
299    if (f == NULL) return;
300
301    char line[500];
302    char nm[100];
303    char val[12];
304        int found_modemap = 0;
305    char *s;
306
307    while (read_line(f,line))
308    {
309                if (found_modemap)
310                {
311                        s = strstr(line, "};");
312                        if (s != 0) return;
313                        s = strstr(line, "MODE_");
314                        if (s != 0)
315                        {
316                                char *c = strstr(line, "//");
317                                if ((c == 0) || (c > s))
318                                {
319                                        s = get_str(s,nm);
320                                        get_str(s,val);
321                                        add_sig(nm, val, 0, &modemap);
322                                }
323                        }
324                }
325                else
326                {
327                        s = strstr(line, "modemap[");
328                        if (s != 0) found_modemap = 1;
329                }
330    }
331}
332
333//------------------------------------------------------------------------------------------------------------
334
335// Signature match handling
336
337typedef struct {
338    uint32_t ptr;
339    uint32_t fail;
340    uint32_t success;
341    int k;
342        int sig;
343} Match;
344
345int     disp_sort = 0;
346
347int match_compare1(const Match *p1, const Match *p2)
348{
349    /* NOTE: If a function has *more* matches, it will be prefered, even if it has a lower percent matches */
350    if (p1->success > p2->success)
351        {
352                if (p2->fail != 0)
353                {
354                        return -1;
355                }
356                else
357                {
358                        return 1;
359                }
360    }
361        else if (p1->success < p2->success)
362        {
363                if ((p1->fail == 0) && (p2->fail > 0))
364                {
365                        return -1;
366                }
367                else
368                {
369                        return 1;
370                }
371    }
372        else
373        {
374        if (p1->fail < p2->fail)
375                {
376            return -1;
377        }
378                else if (p1->fail > p2->fail)
379                {
380            return 1;
381        }
382    }
383
384        if (p1->sig < p2->sig)
385        {
386                return -1;
387        }
388        else if (p1->sig > p2->sig)
389        {
390                return 1;
391        }
392       
393    /* scores are equal. prefer lower address */
394
395    if (p1->ptr < p2->ptr)
396        {
397        return -1;
398    }
399        else if (p1->ptr > p2->ptr)
400        {
401        return 1;
402    }
403
404    return 0;
405}
406
407int match_compare(const Match *p1, const Match *p2)
408{
409        int r = match_compare1(p1, p2);
410        if (disp_sort)
411        {
412                bprintf("  // %08x %2d %2d %3d %3d <-> %08x %2d %2d %3d %3d == %d\n",
413                        p1->ptr,p1->success,p1->fail,p1->k,p1->sig,
414                        p2->ptr,p2->success,p2->fail,p2->k,p2->sig,
415                        r);
416        }
417        return r;
418}
419
420#define MAX_MATCHES (8192)
421
422Match matches[MAX_MATCHES];
423int count;
424
425void addMatch(uint32_t fadr, int s, int f, int k, int sig)
426{
427    matches[count].ptr = fadr;
428    matches[count].success = s;
429    matches[count].fail = f;
430    matches[count].k = k;
431        matches[count].sig = sig;
432    count++;
433}
434
435void print_matches()
436{
437    int i;
438    for (i=0; i<count; i++)
439    {
440        bprintf("\t//0x%08x %2d %2d %d %d\n",matches[i].ptr,matches[i].success,matches[i].fail,matches[i].k,matches[i].sig);
441    }
442}
443
444//------------------------------------------------------------------------------------------------------------
445
446// Signature structures generated by gensig2.exe
447
448typedef struct {
449    uint32_t offs;
450    uint32_t value;
451    uint32_t mask;
452} FuncSig;
453
454typedef struct {
455    const char *name;
456    FuncSig *sig;
457        int ver;
458} FuncsList;
459
460//------------------------------------------------------------------------------------------------------------
461
462// Firmware handling
463
464typedef struct bufrange {
465    uint32_t *p;
466    int off;
467    int len;
468    struct bufrange* next;
469} BufRange;
470
471typedef struct {
472    uint32_t    *buf;
473    uint32_t    base;
474    int         size;
475    BufRange    *br, *last;
476        int                     dryos_ver;
477    int         pid;
478    int         maxram;
479        char            cam[100];
480} firmware;
481
482void addBufRange(firmware *fw, int o, int l)
483{
484    BufRange *n = malloc(sizeof(BufRange));
485    n->p = &fw->buf[o];
486    n->off = o;
487    n->len = l;
488    n->next = 0;
489    if (fw->br == 0)
490    {
491        fw->br = n;
492    }
493    else
494    {
495        fw->last->next = n;
496    }
497    fw->last = n;
498}
499
500int find_str(firmware *fw, char *str)
501{
502    int nlen = strlen(str);
503    uint32_t nm0 = *((uint32_t*)str);
504        uint32_t *p;
505        int j;
506
507    for (p = fw->buf, j = 0; j < fw->size - nlen/4; j++, p++)
508    {
509        if ((nm0 == *p) && (memcmp(p+1,str+4,nlen-4) == 0))
510        {
511                        return j;
512                }
513        }
514       
515        return -1;
516}
517
518void findRanges(firmware *fw)
519{
520    int i, j, k;
521
522    // Find all the valid ranges for checking (skips over large blocks of 0xFFFFFFFF)
523    fw->br = 0; fw->last = 0;
524    k = -1; j = 0;
525    for (i = 0; i < fw->size; i++)
526    {
527        if (fw->buf[i] == 0xFFFFFFFF)   // Possible start of block to skip
528        {
529            if (k == -1)            // Mark start of possible skip block
530            {
531                k = i;
532            }
533        }
534        else                        // Found end of block ?
535        {
536            if (k != -1)
537            {
538                if (i - k > 32)     // If block more than 32 words then we want to skip it
539                {
540                    if (k - j > 8)
541                    {
542                        // Add a range record for the previous valid range (ignore short ranges)
543                        addBufRange(fw,j,k - j);
544                    }
545                    j = i;          // Reset valid range start to current position
546                }
547                k = -1;             // Reset marker for skip block
548            }
549        }
550    }
551    // Add range for last valid block
552    if (k != -1)   
553    {
554        if (k - j > 8)
555        {
556            addBufRange(fw,j,k - j);
557        }
558    }
559    else
560    {
561        if (i - j > 8)
562        {
563            addBufRange(fw,j,i - j);
564        }
565    }
566}
567
568uint32_t idx2adr(firmware *fw, int idx)
569{
570    return fw->base + (idx << 2);
571}
572
573uint32_t adr2idx(firmware *fw, int adr)
574{
575    return (adr - fw->base) >> 2;
576}
577
578uint32_t ptr2idx(firmware *fw, int idx)
579{
580    return (fw->buf[idx] - fw->base) >> 2;
581}
582
583int idxFollowBranch(firmware *fw, int fidx, int offset)
584{
585    if (offset)
586    {
587                uint32_t msk = ~(offset & 0xFF000000);
588        fidx += ((offset & 0x00FFFFFF) - 1);
589        uint32_t inst = fw->buf[fidx];
590        if ((inst & (0xFF000000&msk)) == (0xEA000000&msk))    // Branch (not BL)?
591        {
592            int o = inst & 0x00FFFFFF;
593            if (o & 0x00800000) o |= 0xFF000000;
594            fidx = fidx + o + 2;
595        }
596    }
597    return fidx;
598}
599
600uint32_t followBranch(firmware *fw, uint32_t fadr, int offset)
601{
602    if (offset)
603    {
604                uint32_t msk = ~(offset & 0xFF000000);
605        uint32_t fidx = adr2idx(fw,fadr);  // function index
606        fidx += ((offset & 0x00FFFFFF) - 1);
607        uint32_t inst = fw->buf[fidx];
608        if ((inst & (0xFF000000&msk)) == (0xEA000000&msk))    // Branch (not BL)?
609        {
610            int o = inst & 0x00FFFFFF;
611            if (o & 0x00800000) o |= 0xFF000000;
612            fadr = idx2adr(fw,fidx+o+2);
613        }
614    }
615    return fadr;
616}
617
618uint32_t followBranch2(firmware *fw, uint32_t fadr, int offset)
619{
620        fadr = followBranch(fw, fadr, offset);
621        if ((offset & 0x00FFFFFF) == 1)
622                fadr = followBranch(fw, fadr, offset);
623        return fadr;
624}
625
626uint32_t ADR2adr(firmware *fw, int offset)  // decode ADR instruction at offset and return firmware address pointed to
627{
628    uint32_t inst = fw->buf[offset];
629    int rot = 32 - ((inst & 0xF00) >> 7);
630    int offst = (inst & 0xFF) <<rot;
631    uint32_t fadr = 0;
632    switch (inst & 0x01E00000)
633    {
634    case 0x00400000:    // SUB
635        fadr = idx2adr(fw,offset+2)-offst;
636        break;
637    case 0x00800000:    // ADD
638        fadr = idx2adr(fw,offset+2)+offst;
639        break;
640    case 0x01A00000:    // MOV
641        //fprintf(stderr,"***** ADR2adr MOV\n");
642        break;
643    case 0x01E00000:    // MVN
644        //fprintf(stderr,"***** ADR2adr MVN\n");
645        break;
646    }
647    return fadr;
648}
649
650uint32_t ALUop2(firmware *fw, int offset)  // decode operand2 from ALU inst (not complete!)
651{
652    uint32_t inst = fw->buf[offset];
653    int rot = 32 - ((inst & 0xF00) >> 7);
654    int offst = (inst & 0xFF) <<rot;
655    uint32_t fadr = 0;
656    switch (inst & 0x03E00000)
657    {
658    case 0x02400000:    // SUB Immed
659    case 0x02800000:    // ADD Immed
660    case 0x03A00000:    // MOV Immed
661    case 0x03C00000:    // BIC Immed
662                fadr = offst;
663        break;
664    }
665    return fadr;
666}
667
668uint32_t LDR2adr(firmware *fw, int offset)  // decode LDR instruction at offset and return firmware address pointed to
669{
670    uint32_t inst = fw->buf[offset];
671    int offst = (inst & 0xFFF);
672    uint32_t fadr = (inst & 0x00800000)?idx2adr(fw,offset+2)+offst:idx2adr(fw,offset+2)-offst;
673    return fadr;
674}
675
676uint32_t LDR2idx(firmware *fw, int offset)  // decode LDR instruction at offset and return firmware buffer index of the new address
677{
678        return adr2idx(fw,LDR2adr(fw,offset));
679}
680
681int isLDR_PC(firmware *fw, int offset)
682{
683        return ((fw->buf[offset] & 0xFE1F0000) == 0xE41F0000);
684}
685
686int isLDR_PC_cond(firmware *fw, int offset)
687{
688        return ((fw->buf[offset] & 0x0E1F0000) == 0x041F0000);
689}
690
691int isSTR_PC(firmware *fw, int offset)
692{
693        return ((fw->buf[offset] & 0xFE1F0000) == 0xE40F0000);
694}
695
696int isLDR(firmware *fw, int offset)
697{
698        return ((fw->buf[offset] & 0xFE100000) == 0xE4100000);
699}
700
701int isSTR(firmware *fw, int offset)
702{
703        return ((fw->buf[offset] & 0xFE100000) == 0xE4000000);
704}
705
706int isBL(firmware *fw, int offset)
707{
708        return ((fw->buf[offset] & 0xFF000000) == 0xEB000000);  // BL
709}
710
711void load_firmware(firmware *fw, char *filename, char *base_addr)
712{
713    FILE *f = fopen(filename, "rb");
714
715    if (f == NULL)
716        {
717                fprintf(stderr,"Error opening %s\n",filename);
718        usage("firmware open");
719        }
720
721    fw->base = strtoul(base_addr, NULL, 0);
722
723    fseek(f,0,SEEK_END);
724    fw->size = (ftell(f)+3)/4;
725    fseek(f,0,SEEK_SET);
726
727    // Max sig size if 32, add extra space at end of buffer and fill with 0xFFFFFFFF
728    // Allows sig matching past end of firmware without checking each time in the inner loop
729    fw->buf = malloc((fw->size+32)*4);
730    fread(fw->buf, 4, fw->size, f);
731    fclose(f);
732       
733    memset(&fw->buf[fw->size],0xff,32*4);
734
735        bprintf("// Camera info:\n");
736       
737        // Get DRYOS version
738        fw->dryos_ver = 0;
739        int k = find_str(fw, "DRYOS version 2.3, release #");
740        if (k == -1)
741        {
742                bprintf("//   Can't find DRYOS version !!!\n\n");
743        }
744        else
745        {
746                fw->dryos_ver = atoi(((char*)&fw->buf[k])+28);
747        if (fw->dryos_ver > 49)
748                bprintf("//   DRYOS R%d (%s) *** New DRYOS Version - please update finsig_dryos.c ***\n",fw->dryos_ver,(char*)&fw->buf[k]);
749        else
750                bprintf("//   DRYOS R%d (%s)\n",fw->dryos_ver,(char*)&fw->buf[k]);
751        }
752       
753        // Get firmware version info
754        k = find_str(fw, "Firmware Ver ");
755        if (k == -1)
756        {
757                bprintf("//   Can't find firmware version !!!\n\n");
758        }
759        else
760        {
761                bprintf("//   %s",(char*)&fw->buf[k]);
762                bprintf("\n");
763        }
764
765        // Get camera name & platformid
766        int fsize = -((int)fw->base)/4;
767        int cam_idx = 0;
768    int pid_idx = 0;
769        switch (fw->dryos_ver)
770        {
771        case 20:
772        case 23:
773        case 31:
774        case 39:
775        cam_idx = (0xFFFE0110 - fw->base) / 4;
776        pid_idx = (0xFFFE0130 - fw->base) / 4;
777        break;
778        case 43:
779        case 45:
780        cam_idx = (0xFFFE00D0 - fw->base) / 4;
781        pid_idx = (0xFFFE0130 - fw->base) / 4;
782        break;
783        case 47:
784        cam_idx = (((fw->base==0xFF000000)?0xFFF40170:0xFFFE0170) - fw->base) / 4;
785        pid_idx = (((fw->base==0xFF000000)?0xFFF40040:0xFFFE0040) - fw->base) / 4;
786        break;
787        case 49:
788        cam_idx = (((fw->base==0xFF000000)?0xFFF40190:0xFFFE0170) - fw->base) / 4;
789        pid_idx = (((fw->base==0xFF000000)?0xFFF40040:0xFFFE0040) - fw->base) / 4;
790        break;
791        }
792
793    if (fsize > (fw->size + 256))
794        {
795                bprintf("//   Possible corrupt firmware dump - file size to small for start address 0x%08x\n",fw->base);
796                bprintf("//     file size = %.2fMB, should be %.2fMB\n", ((double)fw->size*4.0)/(1024.0*1024.0),((double)fsize*4.0)/(1024.0*1024.0));
797        }
798       
799        strcpy(fw->cam,"Unknown");
800        if ((cam_idx < fw->size) && (strncmp((char*)&fw->buf[cam_idx],"Canon ",6) == 0))
801        {
802                strcpy(fw->cam,(char*)&fw->buf[cam_idx]);
803                bprintf("//   %s\n",fw->cam);
804        }
805        else
806        {
807                bprintf("//   Could not find Camera name - possible corrupt firmware dump\n");
808        }
809
810        bprintf("\n// Values for makefile.inc\n");
811
812    if ((pid_idx > 0) && (pid_idx < fw->size))
813    {
814        fw->pid = fw->buf[pid_idx] & 0xFFFF;
815                bprintf("//   PLATFORMID = %d (0x%04x) // Found @ 0x%08x\n",fw->pid,fw->pid,idx2adr(fw,pid_idx));
816    }
817    else fw->pid = 0;
818
819    // Calc MAXRAMADDR
820    if (((fw->buf[0x10] & 0xFFFFFF00) == 0xE3A00000) && (fw->buf[0x11] == 0xEE060F12))
821    {
822        fw->maxram = (1 << (((fw->buf[0x10] & 0x3E) >> 1) + 1)) - 1;
823    }
824    else if (((fw->buf[0x14] & 0xFFFFFF00) == 0xE3A00000) && (fw->buf[0x15] == 0xEE060F12))
825    {
826        fw->maxram = (1 << (((fw->buf[0x14] & 0x3E) >> 1) + 1)) - 1;
827    }
828    else fw->maxram = 0;
829
830    if (fw->maxram != 0)
831                bprintf("//   MAXRAMADDR = 0x%08x\n",fw->maxram);
832
833    uint32_t ofst = adr2idx(fw,0xFFFF0000);    // Offset of area to find dancing bits
834    if ((ofst < fw->size) && (fw->buf[ofst] == 0xEA000001) && isLDR_PC(fw,ofst+1))
835    {
836        // Get KEYSYS value
837        ofst = adr2idx(fw,fw->buf[LDR2idx(fw,ofst+1)]);     // Address of firmware encryption key
838        if (ofst < fw->size)
839        {
840            char *ksys = "? Not found, possible new firmware encryption key.";
841            switch (fw->buf[ofst])
842            {
843            case 0x70726964:    ksys = "d3   "; break;
844            case 0x646C726F:    ksys = "d3enc"; break;
845            case 0x774D450B:    ksys = "d4   "; break;
846            case 0x80751A95:    ksys = "d4a  "; break;
847            case 0x76894368:    ksys = "d4b  "; break;
848            case 0x50838EF7:    ksys = "d4c  "; break;
849            }
850            bprintf("//   KEYSYS = %s              // Found @ 0x%08x\n",ksys,idx2adr(fw,ofst));
851        }
852
853        // Get NEED_ENCODED_DISKBOOT value
854        ofst = ofst + 4; // Address of dancing bits data (try after firmware key)
855        if (ofst < fw->size)
856        {
857            int fnd = 0, i, j;
858            for (i=0; i<VITALY && !fnd; i++)
859            {
860                fnd = i+1;
861                for (j=0; j<8 && fnd; j++)
862                {
863                    if ((fw->buf[ofst+j] & 0xFF) != _chr_[i][j])
864                    {
865                        fnd = 0;
866                    }
867                }
868            }
869            if (!fnd)
870            {
871                // Try before firmware key
872                ofst = ofst - 12;
873                for (i=0; i<VITALY && !fnd; i++)
874                {
875                    fnd = i+1;
876                    for (j=0; j<8 && fnd; j++)
877                    {
878                        if ((fw->buf[ofst+j] & 0xFF) != _chr_[i][j])
879                        {
880                            fnd = 0;
881                        }
882                    }
883                }
884            }
885            if (fnd)
886            {
887                        bprintf("//   NEED_ENCODED_DISKBOOT = %d   // Found @ 0x%08x\n",fnd,idx2adr(fw,ofst));
888            }
889            else
890            {
891                        bprintf("//   NEED_ENCODED_DISKBOOT = ? Not found, possible new 'dancing bits' entry needed. // Found @ 0x%08x\n",idx2adr(fw,ofst));
892            }
893        }
894    }
895
896        bprintf("\n");
897}
898
899//------------------------------------------------------------------------------------------------------------
900
901// Signature matches to save for reference by later signature searches
902
903typedef struct {
904        char            *name;
905        uint32_t        val;
906} sig_stuff;
907
908sig_stuff saved_sigs[] = {
909        { "task_PhySw", 0 },
910        { "kbd_p1_f", 0 },
911        { "kbd_read_keys", 0 },
912        { "UpdateMBROnFlash", 0 },
913        { "MakeSDCardBootable", 0 },
914        { "CreateJumptable", 0 },
915        { "strtol", 0 },
916        { "LockAndRefresh", 0 },
917        { "StartRecModeMenu", 0 },
918        { "GetSDProtect", 0 },
919        { "DispCon_ShowBitmapColorBar", 0 },
920        { "FreeUncacheableMemory", 0 },
921        { "GetParameterData", 0 },
922       
923        { 0, 0 }
924};
925
926sig_stuff min_ver[] = {
927        { "CreateJumptable", 10000 },
928        { "ScreenLock", 39 },
929        { "ScreenUnlock", 39 },
930        { "MakeSDCardBootable", 47 },
931       
932        { 0, 0 }
933};
934
935sig_stuff max_ver[] = {
936        { "UpdateMBROnFlash", 45 },
937       
938        { 0, 0 }
939};
940
941int find_min_ver(const char *name)
942{
943        int i;
944        for (i=0; min_ver[i].name != 0; i++)
945        {
946                if (strcmp(name,min_ver[i].name) == 0)
947                {
948                        return min_ver[i].val;
949                }
950        }
951        return 0;
952}
953
954int find_max_ver(const char *name)
955{
956        int i;
957        for (i=0; max_ver[i].name != 0; i++)
958        {
959                if (strcmp(name,max_ver[i].name) == 0)
960                {
961                        return max_ver[i].val;
962                }
963        }
964        return 99999;
965}
966
967uint32_t find_saved_sig(const char *name)
968{
969        int i;
970        for (i=0; saved_sigs[i].name != 0; i++)
971        {
972                if (strcmp(name,saved_sigs[i].name) == 0)
973                {
974                        return i;
975                }
976        }
977        return -1;
978}
979
980void save_sig(const char *name, uint32_t val)
981{
982        int i = find_saved_sig(name);
983        if (i >= 0)
984        {
985                saved_sigs[i].val = val;
986        }
987}
988
989uint32_t get_saved_sig(firmware *fw, const char *name)
990{
991        int j = find_saved_sig(name);
992        if (j >= 0)
993        {
994                if (saved_sigs[j].val == 0)
995                {
996                        int find_func(const char* name);
997                        int k1 = find_func(name);
998                        if (k1 >= 0)
999                        {
1000                                int find_matches(firmware*,int);
1001                                find_matches(fw, k1);
1002                                count = 0;
1003                        }
1004                        else
1005                        {
1006                                void find_str_sig_matches(firmware*,const char*);
1007                                find_str_sig_matches(fw, name);
1008                                count = 0;
1009                        }
1010                }
1011                if (saved_sigs[j].val == 0)
1012                {
1013                        j = -1;
1014                }
1015        }
1016        return j;
1017}
1018
1019//------------------------------------------------------------------------------------------------------------
1020
1021// New string / signature matching structure
1022
1023typedef struct {
1024    int     type;           // 1 = func*, string, 2 = string, ... string*, func*, 3 = ADR Rx, func, ADR Ry, string, BL, ... string
1025    char    *name;
1026    char    *ev_name;
1027    int     offset;
1028        int             dryos20_offset;
1029        int             dryos23_offset;
1030        int             dryos31_offset;
1031        int             dryos39_offset;
1032        int             dryos43_offset;
1033        int             dryos45_offset;
1034        int             dryos47_offset;
1035        int             dryos49_offset;
1036} string_sig;
1037
1038#if defined(PLATFORMOS_dryos)
1039#include "signatures_dryos.h"
1040uint32_t log_test[] = {
1041        0x1526E50E, 0x3FDBCB7B, 0
1042};
1043string_sig string_sigs[] = {
1044        { 1, "AllocateMemory", "AllocateMemory", 1 },
1045    { 1, "Close", "Close", 1 },
1046        { 1, "CreateTask", "CreateTask", 1 },
1047        { 1, "DoAFLock", "PT_DoAFLock", 0x01000002 },
1048    { 1, "ExitTask", "ExitTask", 1 },
1049        { 1, "exmem_alloc", "ExMem.AllocCacheable", 4 },
1050    { 1, "Fclose_Fut", "Fclose_Fut", 1 },
1051    { 1, "Feof_Fut", "Feof_Fut", 1 },
1052    { 1, "Fflush_Fut", "Fflush_Fut", 1 },
1053    { 1, "Fgets_Fut", "Fgets_Fut", 1 },
1054    { 1, "Fopen_Fut", "Fopen_Fut", 1 },
1055    { 1, "Fread_Fut", "Fread_Fut", 1 },
1056        { 1, "FreeMemory", "FreeMemory", 1 },
1057    { 1, "Fseek_Fut", "Fseek_Fut", 1 },
1058    { 1, "Fwrite_Fut", "Fwrite_Fut", 1 },
1059        { 1, "GetParameterData", "PTM_RestoreUIProperty", 0xF0000004 },
1060        { 1, "GetPropertyCase", "PT_GetPropertyCaseString", 1 },
1061        { 1, "GetPropertyCase", "PT_GetPropertyCaseInt", 0x0100000F },
1062        { 1, "GetSDProtect", "GetSDProtect", 1 },
1063        { 1, "GetSystemTime", "GetSystemTime", 1 },
1064        { 1, "LEDDrive", "LEDDrive", 1 },
1065    { 1, "LockMainPower", "LockMainPower", 1 },
1066    { 1, "Lseek", "Lseek", 1 },
1067    { 1, "lseek", "Lseek", 1 },
1068    { 1, "memcpy", "memcpy", 1 },
1069    { 1, "memcmp", "memcmp", 1 },
1070    { 1, "memset", "memset", 1 },
1071    { 1, "NewTaskShell", "NewTaskShell", 1 },
1072    { 1, "Open", "Open", 1 },
1073    { 1, "PostLogicalEventToUI", "PostLogicalEventToUI", 1 },
1074    { 1, "PostLogicalEventForNotPowerType", "PostLogicalEventForNotPowerType", 1 },
1075    { 1, "Read", "Read", 1 },
1076    { 1, "read", "Read", 1 },
1077        { 1, "RefreshPhysicalScreen", "RefreshPhysicalScreen", 1 },
1078    { 1, "SetAutoShutdownTime", "SetAutoShutdownTime", 1 },
1079    { 1, "SetCurrentCaptureModeType", "SetCurrentCaptureModeType", 1 },
1080    { 1, "SetLogicalEventActive", "UiEvnt_SetLogicalEventActive", 1 },
1081    { 1, "SetParameterData", "PTM_BackupUIProperty", 1 },
1082        { 1, "SetPropertyCase", "PT_SetPropertyCaseInt", 0x01000003 },
1083        { 1, "SetScriptMode", "SetScriptMode", 1 },
1084    { 1, "SleepTask", "SleepTask", 1 },
1085    { 1, "strcmp", "strcmp", 0 },
1086    { 1, "strcpy", "strcpy", 1 },
1087    { 1, "strlen", "strlen", 1 },
1088    { 1, "strtol", "atol", 3 },
1089    { 1, "TakeSemaphore", "TakeSemaphore", 1 },
1090    { 1, "UIFS_WriteFirmInfoToFile", "UIFS_WriteFirmInfoToFile", 1 },
1091        { 1, "UnlockAF", "PT_UnlockAF", 0x01000002 },
1092    { 1, "UnlockMainPower", "UnlockMainPower", 1 },
1093    { 1, "VbattGet", "VbattGet", 1 },
1094    { 1, "Write", "Write", 1 },
1095    { 1, "write", "Write", 1 },
1096
1097    { 2, "GetBatteryTemperature", "GetBatteryTemperature", 1 },
1098    { 2, "GetCCDTemperature", "GetCCDTemperature", 1 },
1099    { 2, "GetOpticalTemperature", "GetOpticalTemperature", 1 },
1100    { 2, "GetFocusLensSubjectDistance", "GetCurrentTargetDistance", 1 },
1101    { 2, "GetZoomLensCurrentPoint", "GetZoomLensCurrentPoint", 1 },
1102    { 2, "GetZoomLensCurrentPosition", "GetZoomLensCurrentPosition", 1 },
1103    { 2, "MoveFocusLensToDistance", "MoveFocusLensToDistance", 1 },
1104    { 2, "MoveZoomLensWithPoint", "MoveZoomLensWithPoint", 1 },
1105    { 2, "GetCurrentAvValue", "GetCurrentAvValue", 1 },
1106        { 2, "PT_MoveOpticalZoomAt", "PT_MoveOpticalZoomAt", 1 },
1107        { 2, "PT_MoveDigitalZoomToWide", "PT_MoveDigitalZoomToWide", 1 },
1108        { 2, "MoveIrisWithAv", "MoveIrisWithAv", 1},
1109    { 2, "PutInNdFilter", "TurnOnNdFilter", 1 },
1110    { 2, "PutOutNdFilter", "TurnOffNdFilter", 1 },
1111    { 2, "PutInNdFilter", "PutInNdFilter", 1 },
1112    { 2, "PutOutNdFilter", "PutOutNdFilter", 1 },
1113        { 2, "IsStrobeChargeCompleted", "EF.IsChargeFull", 1 },
1114        { 2, "GetPropertyCase", "PT_GetPropertyCaseInt", 0x01000012 },
1115        { 2, "SetPropertyCase", "PT_SetPropertyCaseInt", 0x01000008 },
1116        { 2, "SetPropertyCase", "PT_SetPropertyCaseInt", 0x01000009 },
1117        { 2, "UnlockAF", "PT_UnlockAF", 0x01000002 },
1118        { 2, "DoAFLock", "PT_DoAFLock", 0x01000002 },
1119        { 2, "GetSystemTime", "PT_GetSystemTime", 0x01000003 },
1120        { 2, "PT_PlaySound", "PT_PlaySound", 0x01000005 },
1121        { 2, "StartRecModeMenu", "StartRecModeMenu", 1 },
1122        { 2, "GetSDProtect", "GetSDProtect", 1 },
1123        { 2, "DispCon_ShowBitmapColorBar", "DispCon_ShowBitmapColorBar", 1 },
1124        { 2, "SetAE_ShutterSpeed", "SetAE_ShutterSpeed", 1 },
1125       
1126        { 3, "AllocateMemory", "AllocateMemory", 1 },
1127        { 3, "FreeMemory", "FreeMemory", 1 },
1128    { 3, "PostLogicalEventToUI", "PostLogicalEventToUI", 1 },
1129    { 3, "PostLogicalEventForNotPowerType", "PostLogicalEventForNotPowerType", 1 },
1130    { 3, "LockMainPower", "LockMainPower", 1 },
1131    { 3, "UnlockMainPower", "UnlockMainPower", 1 },
1132    { 3, "SetAutoShutdownTime", "SetAutoShutdownTime", 1 },
1133    { 3, "NewTaskShell", "NewTaskShell", 1 },
1134    { 3, "VbattGet", "VbattGet", 1 },
1135        { 3, "LEDDrive", "LEDDrive", 1 },
1136        { 3, "SetPropertyCase", "PT_SetPropertyCaseInt", 0x01000003 },
1137        { 3, "UnlockAF", "PT_UnlockAF", 0x01000002 },
1138        { 3, "DoAFLock", "PT_DoAFLock", 0x01000002 },
1139    { 3, "UIFS_WriteFirmInfoToFile", "UIFS_WriteFirmInfoToFile", 1 },
1140        { 3, "PT_MoveOpticalZoomAt", "PT_MoveOpticalZoomAt", 1 },
1141        { 3, "PT_MoveDigitalZoomToWide", "PT_MoveDigitalZoomToWide", 1 },
1142        { 3, "PT_PlaySound", "PT_PlaySound", 1 },
1143        { 3, "exmem_alloc", "ExMem.AllocCacheable", 4 },
1144        { 3, "GetSDProtect", "GetSDProtect", 1 },
1145
1146    { 4, "TurnOnBackLight", "TurnOnBackLight", 1 },
1147    { 4, "TurnOffBackLight", "TurnOffBackLight", 1 },
1148    { 4, "EnterToCompensationEVF", "SSAPI::EnterToCompensationEVF", 1 },
1149    { 4, "EnterToCompensationEVF", "ExpComp On", 1 },
1150    { 4, "EnterToCompensationEVF", "ExpOn", 1 },
1151    { 4, "ExitFromCompensationEVF", "SSAPI::ExitFromCompensationEVF", 1 },
1152    { 4, "ExitFromCompensationEVF", "ExpComp Off", 1 },
1153    { 4, "ExitFromCompensationEVF", "ExpOff", 1 },
1154    { 4, "PB2Rec", "AC:PB2Rec", 1 },
1155    { 4, "PB2Rec", "AC:PB2Rec", 6 },
1156    { 4, "PB2Rec", "AC:PB2Rec", 11 },
1157    { 4, "Rec2PB", "AC:Rec2PB", 1 },
1158        { 4, "RefreshPhysicalScreen", "ScreenUnLock", 1 },
1159        { 4, "RefreshPhysicalScreen", "ScreenUnLock", 7 },
1160        { 4, "RefreshPhysicalScreen", "ScreenUnLock", 15 },
1161        { 4, "RefreshPhysicalScreen", "Reduce ScreenUnLock", 5 },
1162        { 4, "RefreshPhysicalScreen", "Window:IneffectiveLockPhysicalScreen", 8 },
1163        { 4, "UnsetZoomForMovie", "ZoomCon_UnsetZoomForMovie", 1 },
1164        { 4, "ExpCtrlTool_StopContiAE", "StopContiAE", 9 },
1165        { 4, "ExpCtrlTool_StopContiAE", "StopContiAE", 10 },
1166        { 4, "ExpCtrlTool_StartContiAE", "StartContiAE", 9 },
1167        { 4, "ExpCtrlTool_StartContiAE", "StartContiAE", 10 },
1168
1169    { 5, "UIFS_WriteFirmInfoToFile", "UIFS_WriteFirmInfoToFile", 1 },
1170
1171    { 6, "Restart", "Bye", 0 },
1172        { 6, "GetImageFolder", "GetCameraObjectTmpPath ERROR[ID:%lx] [TRY:%lx]\n", 0 },
1173       
1174        { 7, "task_CaptSeq", "CaptSeqTask", 1 },
1175        { 7, "task_ExpDrv", "ExpDrvTask", 1 },
1176        { 7, "task_InitFileModules", "InitFileModules", 1 },
1177        { 7, "task_MovieRecord", "MovieRecord", 1 },
1178        { 7, "task_PhySw", "PhySw", 1 },
1179        { 7, "task_RotaryEncoder", "RotaryEncoder", 1 },
1180        { 7, "task_RotaryEncoder", "RotarySw", 1 },
1181       
1182        { 8, "WriteSDCard", "Mounter.c", 0 },
1183       
1184        //                                                                                                                                       R20   R23   R31   R39   R43   R45   R47   R49
1185        { 9, "kbd_p1_f", "task_PhySw", 0x01000001,                                                         5,    5,    5,    5,    5,    5,    5,    5 },
1186        { 9, "kbd_p2_f", "task_PhySw", 0xf1000001,                                                         7,    7,    7,    7,    7,    7,    7,    7 },
1187        { 9, "kbd_read_keys", "kbd_p1_f", 0x01000001,                                              2,    2,    2,    2,    2,    2,    2,    2 },
1188        { 9, "kbd_p1_f_cont", "kbd_p1_f", 0,                                                               3,    3,    3,    3,    3,    3,    3,    3 },
1189        { 9, "kbd_read_keys_r2", "kbd_read_keys", 0x0100000C },
1190        { 9, "GetKbdState", "kbd_read_keys", 0x01000009 },
1191        { 9, "GetKbdState", "kbd_read_keys", 0x0100000A },
1192        { 9, "strtolx", "strtol", 2 },
1193       
1194        { 10, "task_CaptSeq", "CaptSeqTask", 1 },
1195        { 10, "task_ExpDrv", "ExpDrvTask", 1 },
1196        { 10, "task_InitFileModules", "InitFileModules", 1 },
1197        { 10, "task_MovieRecord", "MovieRecord", 1 },
1198        { 10, "task_PhySw", "PhySw", 1 },
1199        { 10, "task_RotaryEncoder", "RotaryEncoder", 1 },
1200        { 10, "task_RotaryEncoder", "RotarySw", 1 },
1201
1202        //                                                                                                                                       R20   R23   R31   R39   R43   R45   R47   R49
1203        { 11, "DebugAssert", "\nAssert: File %s Line %d\n", 0,                             5,    5,    5,    5,    5,    5,    5,    5 },
1204        { 11, "set_control_event", "Button:0x%08X:%s", 0x01000001,                        14,   14,   14,   14,   14,   14,   14,   14 },
1205        { 11, "set_control_event", "Button:0x%08X:%s", 0x01000001,                        15,   15,   15,   15,   15,   15,   15,   15 },
1206        { 11, "set_control_event", "Button:0x%08X:%s", 0x01000001,                        20,   20,   20,   20,   20,   20,   19,   20 },
1207        { 11, "_log", (char*)log_test, 0x01000001,                                                         1,    1,    1,    1,    1,    1,    1,    1 },
1208       
1209        //                                                                                                                                       R20   R23   R31   R39   R43   R45   R47   R49
1210        { 12, "DeleteFile_Fut", "DeleteFile_Fut", 1,                                            0x38, 0x38, 0x4C, 0x4C, 0x4C, 0x54, 0x54, 0x54 },
1211        { 12, "AllocateUncacheableMemory", "AllocateUncacheableMemory", 1,      0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x34, 0x34, 0x38 },
1212        { 12, "FreeUncacheableMemory", "FreeUncacheableMemory", 1,                      0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x38, 0x38 },
1213        { 12, "free", "free", 1,                                                                                        0x28, 0x28, 0x28, 0x28, 0x28, 0x30, 0x30, 0x30 },
1214        { 12, "malloc", "malloc", 0x01000003,                                                           0x24, 0x24, 0x24, 0x24, 0x24, 0x2C, 0x2C, 0x2C },
1215        { 12, "TakeSemaphore", "TakeSemaphore", 1,                                                      0x14, 0x14, 0x14, 0x14, 0x14, 0x1C, 0x1C, 0x1C },
1216        { 12, "GiveSemaphore", "GiveSemaphore", 1,                                                      0x18, 0x18, 0x18, 0x18, 0x18, 0x20, 0x20, 0x20 },
1217        { 12, "_log10", "_log10", 0x01000006,                                                      0x278,0x280,0x280,0x284,0x294,0x2FC,0x2FC,0x31C },
1218        { 12, "_log10", "_log10", 0x01000006,                                                      0x000,0x278,0x27C,0x000,0x000,0x000,0x000,0x000 },
1219        { 12, "_log10", "_log10", 0x01000006,                                                      0x000,0x000,0x2C4,0x000,0x000,0x000,0x000,0x000 },
1220       
1221        { 13, "strftime", "Sunday", 1 },
1222       
1223        { 14, "_pow", "_pow", 0 },
1224       
1225    { 0, 0, 0, 0 }
1226};
1227#else
1228#error Incorrect platform OS - DryOS only.
1229#endif
1230
1231int find_func(const char* name)
1232{
1233        int i;
1234        for (i=0; func_list[i].name != 0; i++)
1235        {
1236                if (strcmp(name, func_list[i].name) == 0)
1237                {
1238                        return i;
1239                }
1240        }
1241        return -1;
1242}
1243
1244int dryos_offset(firmware *fw, string_sig *sig)
1245{
1246        switch (fw->dryos_ver)
1247        {
1248        case 20:        return sig->dryos20_offset;
1249        case 23:        return sig->dryos23_offset;
1250        case 31:        return sig->dryos31_offset;
1251        case 39:        return sig->dryos39_offset;
1252        case 43:        return sig->dryos43_offset;
1253        case 45:        return sig->dryos45_offset;
1254        case 47:        return sig->dryos47_offset;
1255        case 49:        return sig->dryos49_offset;
1256        }
1257        return 0;
1258}
1259       
1260//------------------------------------------------------------------------------------------------------------
1261
1262// Optional functions, if not found no error is written to output
1263
1264char *optional[] = {
1265        "DebugAssert",
1266        "PT_MoveOpticalZoomAt",
1267        "PT_MoveDigitalZoomToWide",
1268        "PT_ChangeZoomSpeed",
1269        "MoveIrisWithAv",
1270        "err_init_task",
1271        "PutInNdFilter",
1272        "PutOutNdFilter",
1273        "GiveSemaphore",
1274        "GetImageFolder",
1275        "UnsetZoomForMovie",
1276        "task_RotaryEncoder",
1277        "task_PhySw",
1278        "MakeSDCardBootable",
1279        "LEDDrive",
1280        0
1281};
1282
1283//------------------------------------------------------------------------------------------------------------
1284
1285// Load optional list of signatures to ignore
1286
1287char* ignore_list[200];
1288int num_ignore = 0;
1289char* ignore_names;
1290
1291void load_ignore_list()
1292{
1293    FILE *f = fopen("../ignore_stubs.txt","r");
1294    if (f != NULL)
1295    {
1296        fseek(f,0,SEEK_END);
1297        int size = ftell(f);
1298        fseek(f,0,SEEK_SET);
1299
1300        ignore_names = malloc(size+1);
1301        fread(ignore_names, 1, size, f);
1302        ignore_names[size] = 0;
1303
1304        int save = 1;
1305        int i;
1306        for (i = 0; i < size; i++)
1307        {
1308            if (save)
1309            {
1310                ignore_list[num_ignore] = &ignore_names[i];
1311                num_ignore++;
1312                save = 0;
1313            }
1314            if (ignore_names[i] == 0x0d) { ignore_names[i] = 0; }
1315            if (ignore_names[i] == 0x0a) { ignore_names[i] = 0; save = 1; }
1316        }
1317
1318        fclose(f);
1319    }
1320}
1321
1322int is_in_list(const char *str, char *list[])
1323{
1324        int i;
1325        for (i=0; list[i] != 0; i++)
1326        {
1327                if (strcmp(str,list[i]) == 0)
1328                {
1329                        return 1;
1330                }
1331        }
1332        return 0;
1333}
1334
1335//------------------------------------------------------------------------------------------------------------
1336
1337// New string / signature matching functions
1338
1339// Sig pattern:
1340//              Function pointer        -       DCD     func
1341//              String                          -       DCB     "func"
1342int find_strsig1(firmware *fw, string_sig *sig, int k)
1343{
1344    int nlen = strlen(sig->ev_name);
1345    uint32_t nm0 = *((uint32_t*)sig->ev_name);
1346        uint32_t *p;
1347        int j;
1348
1349    for (p = fw->buf, j = 0; j < fw->size - nlen/4; j++, p++)
1350    {
1351        if ((nm0 == *p) && (memcmp(p+1,sig->ev_name+4,nlen-3) == 0))
1352        {
1353            uint32_t fadr = fw->buf[j-1];       // function address (*padr)
1354            if (fadr >= fw->base)
1355            {
1356                                if (sig->offset > 1) fadr = followBranch(fw, fadr, 1);
1357                fadr = followBranch2(fw, fadr, sig->offset);
1358                //fprintf(stderr,"%s %08x\n",curr_name,fadr);
1359                addMatch(fadr,32,0,k,101);
1360                return 1;
1361            }
1362        }
1363    }
1364        return 0;
1365}
1366
1367// Sig pattern:
1368//              String pointer          -               DCD     str
1369//              Function pointer        -               DCD     func
1370//                              ...
1371//              String                          -       str     DCB     "func"
1372int find_strsig2(firmware *fw, string_sig *sig, int k)
1373{
1374    int nlen = strlen(sig->ev_name);
1375        int j;
1376       
1377    char *c = (char*)(&fw->buf[0]);
1378    for (j = 0; j < fw->size*4 - nlen; j++, c++)
1379    {
1380        if (strcmp(c,sig->ev_name) == 0)
1381        {
1382            uint32_t sadr = fw->base + j;        // string address
1383            int j1;
1384            uint32_t *p1;
1385            for (p1 = fw->buf, j1 = 0; j1 < fw->size - nlen/4; j1++, p1++)
1386            {
1387                if (*p1 == sadr)                // pointer to string?
1388                {
1389                    uint32_t fadr = fw->buf[j1+1];      // function address (*padr)
1390                    if (fadr >= fw->base)
1391                    {
1392                        uint32_t bfadr = followBranch2(fw, fadr, sig->offset);
1393                                                if ((sig->offset <= 1) || (bfadr != fadr))
1394                                                {
1395                                                        //fprintf(stderr,"%s %08x\n",curr_name,fadr);
1396                                                        addMatch(bfadr,32,0,k,102);
1397                                                        return 1;
1398                                                }
1399                    }
1400                }
1401            }
1402        }
1403    }
1404
1405        return 0;
1406}
1407
1408// Sig pattern:
1409//              Load Func Address       -       ADR     Rx, func
1410//              Load String Address     -       ADR     Rx, "func"
1411//              Branch                          -       BL
1412//                              ...
1413//              String                          -       DCB     "func"
1414int find_strsig3(firmware *fw, string_sig *sig, int k)
1415{
1416    int nlen = strlen(sig->ev_name);
1417        uint32_t nm0 = *((uint32_t*)sig->ev_name);
1418        uint32_t *p;
1419        int j;
1420       
1421        for (p = fw->buf, j = 0; j < fw->size - nlen/4; j++, p++)
1422        {
1423                if ((nm0 == *p) && (memcmp(p+1,sig->ev_name+4,nlen-3) == 0))
1424                {
1425                        uint32_t sadr = idx2adr(fw,j);        // string address
1426                        int j1;
1427                        uint32_t *p1;
1428                        for (p1 = p-3, j1 = j-3; j1 >= 0; j1--, p1--)
1429                        {
1430                                if (((p1[1] & 0xFE0F0000) == 0xE20F0000) && // ADR ?
1431                                        ((p1[2] & 0xFE000000) == 0xEA000000))   // B or BL ?
1432                                {
1433                                        uint32_t padr = ADR2adr(fw,j1+1);
1434                                        if (padr == sadr)
1435                                        {
1436                                                int j2 = j1;
1437                                                int found = 0;
1438                                                if ((p1[0] & 0xFE0F0000) == 0xE20F0000) // ADR ?
1439                                                        found = 1;
1440                                                else
1441                                                {
1442                                                        uint32_t *p2;
1443                                                        for (p2 = p1-2, j2 = j1-2; j2 >= 0 && j2 >= j1-4096; j2--, p2--)
1444                                                        {
1445                                                                if (((p2[0] & 0xFE0F0000) == 0xE20F0000) && // ADR ?
1446                                                                        ((p2[1] & 0xFF000000) == 0xEA000000))   // B
1447                                                                {
1448                                                                        uint32_t fa = idx2adr(fw,j2+1);
1449                                                                        fa = followBranch(fw,fa,1);
1450                                                                        if (adr2idx(fw,fa) == j1+1)
1451                                                                        {
1452                                                                                found = 1;
1453                                                                                break;
1454                                                                        }
1455                                                                }
1456                                                        }
1457                                                }
1458                                                if (found)
1459                                                {
1460                                                        uint32_t fadr = ADR2adr(fw,j2);
1461                                                        if (sig->offset > 1) fadr = followBranch(fw, fadr, 1);
1462                                                        fadr = followBranch2(fw, fadr, sig->offset);
1463                                                        //fprintf(stderr,"%s %08x\n",curr_name,fadr);
1464                                                        addMatch(fadr,32,0,k,103);
1465                                                        return 1;
1466                                                }
1467                                        }
1468                                }
1469                        }
1470                }
1471        }
1472
1473        return 0;
1474}
1475
1476// Sig pattern:
1477//              Save Regs                       -       STMFD
1478//                              ... (ofst)
1479//              Load String Address     -       ADR     Rx, "func"
1480//                              ...
1481//              String                          -       DCB     "func"
1482int find_strsig4(firmware *fw, string_sig *sig, int k)
1483{
1484    int nlen = strlen(sig->ev_name);
1485        uint32_t nm0 = *((uint32_t*)sig->ev_name);
1486        uint32_t *p;
1487        int j;
1488
1489        for (p = fw->buf, j = 0; j < fw->size - nlen/4; j++, p++)
1490        {
1491                if ((nm0 == *p) && (memcmp(p+1,sig->ev_name+4,nlen-3) == 0))
1492                {
1493                        uint32_t sadr = idx2adr(fw,j);        // string address
1494                        int j1;
1495                        uint32_t *p1;
1496                        int ofst = sig->offset;
1497                        for (p1 = p-ofst-1, j1 = j-ofst-1; j1 >= 0; j1--, p1--)
1498                        {
1499                                if (((p1[0] & 0xFFFF0000) == 0xE92D0000) &&     // STMFD
1500                                        ((p1[ofst] & 0xFE0F0000) == 0xE20F0000))        // ADR ?
1501                                {
1502                                        uint32_t padr = ADR2adr(fw,j1+ofst);
1503                                        if (padr == sadr)
1504                                        {
1505                                                uint32_t fadr = idx2adr(fw,j1);
1506                                                //fprintf(stderr,"%s %08x\n",curr_name,fadr);
1507                                                addMatch(fadr,32,0,k,104);
1508                                                return 1;
1509                                        }
1510                                }
1511                        }
1512                }
1513        }
1514 
1515        return 0;
1516}
1517
1518// Sig pattern:
1519//              Load Func Address       -       LDR     Rx, =func
1520//              Load String Address     -       ADR     Rx, "func"
1521//              Branch                          -       BL
1522//                              ...
1523//              String                          -       DCB     "func"
1524int find_strsig5(firmware *fw, string_sig *sig, int k)
1525{
1526    int nlen = strlen(sig->ev_name);
1527        uint32_t nm0 = *((uint32_t*)sig->ev_name);
1528        uint32_t *p;
1529        int j;
1530
1531        for (p = fw->buf, j = 0; j < fw->size - nlen/4; j++, p++)
1532        {
1533                if ((nm0 == *p) && (memcmp(p+1,sig->ev_name+4,nlen-3) == 0))
1534                {
1535                        uint32_t sadr = idx2adr(fw,j);        // string address
1536                        int j1;
1537                        uint32_t *p1;
1538                        for (p1 = p-3, j1 = j-3; j1 >= 0; j1--, p1--)
1539                        {
1540                                if (((p1[1] & 0xFE0F0000) == 0xE20F0000) && // ADR ?
1541                                        ((p1[2] & 0xFE000000) == 0xEA000000))   // B or BL ?
1542                                {
1543                                        uint32_t padr = ADR2adr(fw,j1+1);
1544                                        if (padr == sadr)
1545                                        {
1546                                                int j2 = j1;
1547                                                int found = 0;
1548                                                if ((p1[0] & 0xFE1F0000) == 0xE41F0000) // LDR ?
1549                                                        found = 1;
1550                                                else
1551                                                {
1552                                                        uint32_t *p2;
1553                                                        for (p2 = p1-2, j2 = j1-2; j2 >= 0 && j2 >= j1-4096; j2--, p2--)
1554                                                        {
1555                                                                if (((p2[0] & 0xFE1F0000) == 0xE41F0000) && // LDR ?
1556                                                                        ((p2[1] & 0xFF000000) == 0xEA000000))   // B
1557                                                                {
1558                                                                        uint32_t fa = idx2adr(fw,j2+1);
1559                                                                        fa = followBranch(fw,fa,1);
1560                                                                        if (adr2idx(fw,fa) == j1+1)
1561                                                                        {
1562                                                                                found = 1;
1563                                                                                break;
1564                                                                        }
1565                                                                }
1566                                                        }
1567                                                }
1568                                                if (found)
1569                                                {
1570                                                        uint32_t fadr = fw->buf[LDR2idx(fw,j2)];
1571                                                        if (sig->offset > 1) fadr = followBranch(fw, fadr, 1);
1572                                                        fadr = followBranch2(fw, fadr, sig->offset);
1573                                                        //fprintf(stderr,"%s %08x\n",curr_name,fadr);
1574                                                        addMatch(fadr,32,0,k,105);
1575                                                        return 1;
1576                                                }
1577                                        }
1578                                }
1579                        }
1580                }
1581        }
1582
1583        return 0;
1584}
1585
1586// Sig pattern:
1587//      Function immediately preceeding string
1588int find_strsig6(firmware *fw, string_sig *sig, int k)
1589{
1590    int nlen = strlen(sig->ev_name);
1591        uint32_t nm0 = *((uint32_t*)sig->ev_name);
1592        uint32_t *p;
1593        int j;
1594       
1595        for (p = fw->buf, j = 0; j < fw->size - nlen/4; j++, p++)
1596        {
1597                if ((nm0 == *p) && (memcmp(p+1,sig->ev_name+4,nlen-3) == 0))
1598                {
1599                        int j1;
1600                        uint32_t *p1;
1601                        for (p1 = p-1, j1 = j-1; j1 >= 0; j1--, p1--)
1602                        {
1603                                if ((p1[0] & 0xFFFFF000) == 0xe92d4000)    // STMFD SP!, {..,LR}
1604                                {
1605                                        uint32_t fadr = idx2adr(fw,j1);
1606                                        //fprintf(stderr,"%s %08x\n",curr_name,fadr);
1607                                        addMatch(fadr,32,0,k,106);
1608                                        return 1;
1609                                }
1610                        }
1611                }
1612        }
1613
1614        return 0;
1615}
1616
1617// Sig pattern:
1618//              Load Func Address       -       ADR     R3, func        - these four may occur in any order ?
1619//              Load String Address     -       ADR     R0, "func"     
1620//              Load value                      -       MOV R2, x               
1621//              Load value                      -       MOV R1, y               
1622//              Branch                          -       BL
1623//                              ...
1624//              String                          -       DCB     "func"
1625int find_strsig7(firmware *fw, string_sig *sig, int k)
1626{
1627    int nlen = strlen(sig->ev_name);
1628        uint32_t nm0 = *((uint32_t*)sig->ev_name);
1629        uint32_t *p;
1630        int j;
1631       
1632        for (p = fw->buf, j = 0; j < fw->size - nlen/4; j++, p++)
1633        {
1634                if ((nm0 == *p) && (memcmp(p+1,sig->ev_name+4,nlen-3) == 0))
1635                {
1636                        uint32_t sadr = idx2adr(fw,j);        // string address
1637                        int j1;
1638                        uint32_t *p1;
1639                        for (p1 = p-5, j1 = j-5; j1 >= 0; j1--, p1--)
1640                        {
1641                                if (((p1[0] & 0xFE000000) == 0xE2000000) && // ADR or MOV
1642                                        ((p1[1] & 0xFE000000) == 0xE2000000) && // ADR or MOV
1643                                        ((p1[2] & 0xFE000000) == 0xE2000000) && // ADR or MOV
1644                                        ((p1[3] & 0xFE000000) == 0xE2000000) && // ADR or MOV
1645                                        ((p1[4] & 0xFE000000) == 0xEA000000))   // B or BL ?
1646                                {
1647                                        uint32_t padr;
1648                                        padr = ADR2adr(fw,j1+0);
1649                                        if (padr != sadr) padr = ADR2adr(fw,j1+1);
1650                                        if (padr != sadr) padr = ADR2adr(fw,j1+2);
1651                                        if (padr != sadr) padr = ADR2adr(fw,j1+3);
1652                                        if (padr == sadr)
1653                                        {
1654                                                uint32_t fadr = 0;
1655                                                if ((p1[0] & 0xFE0FF000) == 0xE20F3000)          fadr = ADR2adr(fw,j1);         // R3 ?
1656                                                else if ((p1[1] & 0xFE0FF000) == 0xE20F3000) fadr = ADR2adr(fw,j1+1);   // R3 ?
1657                                                else if ((p1[2] & 0xFE0FF000) == 0xE20F3000) fadr = ADR2adr(fw,j1+2);   // R3 ?
1658                                                else if ((p1[3] & 0xFE0FF000) == 0xE20F3000) fadr = ADR2adr(fw,j1+3);   // R3 ?
1659                                                if (fadr != 0)
1660                                                {
1661                                                        fadr = followBranch2(fw, fadr, sig->offset);
1662                                                        //fprintf(stderr,"%s %08x\n",curr_name,fadr);
1663                                                        addMatch(fadr,32,0,k,107);
1664                                                        return 1;
1665                                                }
1666                                        }
1667                                }
1668                        }
1669                }
1670        }
1671
1672        return 0;
1673}
1674
1675// Sig pattern:
1676//              Special case for WriteSDCard
1677int find_strsig8(firmware *fw, string_sig *sig, int k)
1678{
1679    int nlen = strlen(sig->ev_name);
1680        uint32_t nm0 = *((uint32_t*)sig->ev_name);
1681        uint32_t *p;
1682        uint32_t fadr = 0;
1683        int srch = 20;
1684
1685        // Find "UpdateMBROnFlash" code
1686        int j = get_saved_sig(fw,"UpdateMBROnFlash");
1687        if (j >= 0)
1688        {
1689                fadr = saved_sigs[j].val;
1690        }
1691        else
1692        {
1693                j = get_saved_sig(fw,"MakeSDCardBootable");
1694                if (j >= 0)
1695                {
1696                        fadr = saved_sigs[j].val;
1697                        srch = 32;
1698                }
1699        }
1700       
1701        if (fadr == 0) return 0;
1702       
1703        int idx = adr2idx(fw, fadr);
1704        int ofst = -1;
1705       
1706        for (j=idx+srch; j<idx+srch+12; j++)
1707        {
1708                if (isLDR(fw,j) && isLDR(fw,j+1) && isLDR(fw,j+2))
1709                {
1710                        ofst = (fw->buf[j] & 0xfff) + (fw->buf[j+1] & 0xfff) + (fw->buf[j+2] & 0xfff);
1711                        break;
1712                }
1713        }
1714       
1715        if (ofst == -1) return 0;
1716       
1717        for (p = fw->buf, j = 0; j < fw->size - nlen/4; j++, p++)
1718        {
1719                if ((nm0 == *p) && (memcmp(p+1,sig->ev_name+4,nlen-3) == 0))
1720                {
1721                        int j1;
1722                        for (j1=j-2; j1<j+8; j1++)
1723                        {
1724                                fadr = idx2adr(fw,j1);
1725                                if (fw->buf[j1] >= fw->base)    // pointer ??
1726                                {
1727                                        int j2;
1728                                        for (j2=j1-1; j2>=j1-1000 && j2>=0; j2--)
1729                                        {
1730                                                if (isLDR_PC(fw,j2) && (LDR2adr(fw,j2) == fadr))        // LDR ?
1731                                                {
1732                                                        if ((isSTR(fw,j2+1) && ((fw->buf[j2+1] & 0xfff) == ofst)) ||    // STR ?
1733                                                                (isSTR(fw,j2+2) && ((fw->buf[j2+2] & 0xfff) == ofst)))          // STR ?
1734                                                        {
1735                                                                fadr = fw->buf[j1];
1736                                                                if (fadr >= fw->base)
1737                                                                {
1738                                                                        //fprintf(stderr,"%s %08x\n",curr_name,fadr);
1739                                                                        addMatch(fadr,32,0,k,108);
1740                                                                        return 1;
1741                                                                }
1742                                                        }
1743                                                }
1744                                        }
1745                                }
1746                        }
1747                }
1748        }
1749
1750        return 0;
1751}
1752
1753// Sig pattern:
1754//              Func is B/BL @ offset from previous found func
1755//                      prev_func
1756//                              ... (offset)
1757//                              BL      func
1758int find_strsig9(firmware *fw, string_sig *sig, int k)
1759{
1760        int j = get_saved_sig(fw,sig->ev_name);
1761        if (j >= 0)
1762        {
1763                if (saved_sigs[j].val != 0)
1764                {                       
1765                        int ofst = dryos_offset(fw, sig);
1766                        uint32_t fadr = followBranch(fw, saved_sigs[j].val+ofst*4, sig->offset);
1767                        if ((sig->offset == 0) || (fadr != saved_sigs[j].val+ofst*4))
1768                        {
1769                                //fprintf(stderr,"%s %08x\n",curr_name,fadr);
1770                                addMatch(fadr,32,0,k,109);
1771                                return 1;
1772                        }
1773                }
1774        }
1775
1776        return 0;
1777}
1778
1779// Sig pattern:
1780//              Load Func Address       -       LDR     R3, =func       - these four may occur in any order ?
1781//              Load String Address     -       ADR     R0, "func"     
1782//              Load value                      -       MOV R2, x               
1783//              Load value                      -       MOV R1, y               
1784//              Branch                          -       BL
1785//                              ...
1786//              String                          -       DCB     "func"
1787int find_strsig10(firmware *fw, string_sig *sig, int k)
1788{
1789    int nlen = strlen(sig->ev_name);
1790        uint32_t nm0 = *((uint32_t*)sig->ev_name);
1791        uint32_t *p;
1792        int j;
1793       
1794        for (p = fw->buf, j = 0; j < fw->size - nlen/4; j++, p++)
1795        {
1796                if ((nm0 == *p) && (memcmp(p+1,sig->ev_name+4,nlen-3) == 0))
1797                {
1798                        uint32_t sadr = idx2adr(fw,j);        // string address
1799                        int j1;
1800                        uint32_t *p1;
1801                        for (p1 = p-5, j1 = j-5; j1 >= 0; j1--, p1--)
1802                        {
1803                                if ((((p1[0] & 0xFE000000) == 0xE2000000) || ((p1[0] & 0xFE000000) == 0xE4000000)) && // LDR, ADR or MOV
1804                                        (((p1[1] & 0xFE000000) == 0xE2000000) || ((p1[1] & 0xFE000000) == 0xE4000000)) && // LDR, ADR or MOV
1805                                        (((p1[2] & 0xFE000000) == 0xE2000000) || ((p1[2] & 0xFE000000) == 0xE4000000)) && // LDR, ADR or MOV
1806                                        (((p1[3] & 0xFE000000) == 0xE2000000) || ((p1[3] & 0xFE000000) == 0xE4000000)) && // LDR, ADR or MOV
1807                                        ((p1[4] & 0xFE000000) == 0xEA000000))   // B or BL ?
1808                                {
1809                                        uint32_t padr;
1810                                        padr = ADR2adr(fw,j1+0);
1811                                        if (padr != sadr) padr = ADR2adr(fw,j1+1);
1812                                        if (padr != sadr) padr = ADR2adr(fw,j1+2);
1813                                        if (padr != sadr) padr = ADR2adr(fw,j1+3);
1814                                        if (padr == sadr)
1815                                        {
1816                                                uint32_t fadr = 0;
1817                                                if ((p1[0] & 0xFE0FF000) == 0xE40F3000)          fadr = LDR2adr(fw,j1);         // R3 ?
1818                                                else if ((p1[1] & 0xFE0FF000) == 0xE40F3000) fadr = LDR2adr(fw,j1+1);   // R3 ?
1819                                                else if ((p1[2] & 0xFE0FF000) == 0xE40F3000) fadr = LDR2adr(fw,j1+2);   // R3 ?
1820                                                else if ((p1[3] & 0xFE0FF000) == 0xE40F3000) fadr = LDR2adr(fw,j1+3);   // R3 ?
1821                                                if (fadr != 0)
1822                                                {
1823                                                        fadr = followBranch2(fw, fw->buf[adr2idx(fw,fadr)], sig->offset);
1824                                                        //fprintf(stderr,"%s %08x\n",curr_name,fadr);
1825                                                        addMatch(fadr,32,0,k,110);
1826                                                        return 1;
1827                                                }
1828                                        }
1829                                }
1830                        }
1831                }
1832        }
1833
1834        return 0;
1835}
1836
1837// Sig pattern:
1838//              Func -                  func
1839//                      .... (offset)
1840//              Ref to string -         ADR Rx, str
1841//                      ....
1842//              String -                        DCB "str"
1843int find_strsig11(firmware *fw, string_sig *sig, int k)
1844{
1845    int nlen = strlen(sig->ev_name);
1846        uint32_t nm0 = *((uint32_t*)sig->ev_name);
1847        uint32_t *p;
1848        int j;
1849
1850        int ofst = dryos_offset(fw, sig);
1851       
1852        for (p = fw->buf, j = 0; j < fw->size - nlen/4; j++, p++)
1853        {
1854                if ((nm0 == *p) && (memcmp(p+1,sig->ev_name+4,nlen-4) == 0))
1855                {
1856                        uint32_t sadr = idx2adr(fw,j);        // string address
1857                        int j1;
1858                        uint32_t *p1;
1859                        for (p1 = p-1, j1 = j-1; j1 >= 0; j1--, p1--)
1860                        {
1861                                if ((p1[0] & 0x0E0F0000) == 0x020F0000) // ADR ?
1862                                {
1863                                        uint32_t padr = ADR2adr(fw,j1);
1864                                        if (padr == sadr)
1865                                        {
1866                                                uint32_t fadr = idx2adr(fw,j1-ofst);
1867                                                uint32_t bfadr = followBranch(fw,fadr,sig->offset);
1868                                                // special case for 'set_control_event'
1869                                                int found = 0;
1870                                                if (strcmp(sig->name,"set_control_event") == 0)
1871                                                {
1872                                                        uint32_t *p2 = p1 - ofst;
1873                                                        if (((p2[0] & 0xFF000000) == 0xEB000000) &&             // BL
1874                                                                ((p2[1] & 0xFFFFF000) == 0xE59D0000) &&         // LDR R0,[SP,x]
1875                                                                ((p2[2] & 0xFF000000) == 0xEB000000) &&         // BL
1876                                                                ((p2[3] & 0xFFFFF000) == 0xE1A04000))           // LDR R4, R0
1877                                                        {
1878                                                                found = 1;
1879                                                        }
1880                                                }
1881                                                else
1882                                                        found = 1;
1883                                                if (found && ((sig->offset == 0) || (bfadr != fadr)))
1884                                                {
1885                                                        //fprintf(stderr,"%s %08x\n",curr_name,fadr);
1886                                                        addMatch(bfadr,32,0,k,111);
1887                                                        return 1;
1888                                                }
1889                                        }
1890                                }
1891                        }
1892                }
1893        }
1894
1895        return 0;
1896}
1897
1898// Sig pattern:
1899//              Func is referenced in 'CreateJumptable'
1900//                      LDR R1, =func
1901//                      STR R1, [R0,nnn]
1902//              nnn - dryos version dependant offset
1903int find_strsig12(firmware *fw, string_sig *sig, int k)
1904{
1905        int j = get_saved_sig(fw,"CreateJumptable");   
1906
1907        int ofst = dryos_offset(fw, sig);
1908       
1909        if (ofst == 0) return 0;
1910       
1911        if (j >= 0)
1912        {
1913                if (saved_sigs[j].val != 0)
1914                {
1915                        int idx = adr2idx(fw, saved_sigs[j].val);
1916                        for(; fw->buf[idx] != 0xE12FFF1E; idx++)        // BX LR
1917                        {
1918                                if (((fw->buf[idx+1] & 0xFFFFF000) == 0xE5801000) && // STR R1,[R0,nnn]
1919                                    ((fw->buf[idx+1] & 0x00000FFF) == ofst))
1920                                {
1921                                        uint32_t fadr = fw->buf[LDR2idx(fw,idx)];
1922                                        uint32_t bfadr = followBranch2(fw,fadr,sig->offset);
1923                                        if ((sig->offset <= 1) || ((bfadr != fadr) && ((fw->buf[adr2idx(fw,fadr)] & 0xFFFF0000) == 0xE92D0000)))
1924                                        {
1925                                                //fprintf(stderr,"%s %08x\n",curr_name,bfadr);
1926                                                addMatch(bfadr,32,0,k,112);
1927                                                return 1;
1928                                        }
1929                                }
1930                                else if ((fw->buf[idx] & 0xFF000000) == 0xEA000000)     // B
1931                                {
1932                                        idx = adr2idx(fw,followBranch(fw,idx2adr(fw,idx),1)) - 1;
1933                                }
1934                        }
1935                }
1936        }
1937
1938        return 0;
1939}
1940
1941// Sig pattern:
1942//              Func -                  func
1943//                      ... (offset)
1944//              Str ref -                       LDR Rx, =str_ptr
1945//                      ...
1946//              Str ptr -                       DCD str_ptr
1947//                      ...
1948//              Str ptr -               str_ptr
1949//                                                      DCD str
1950//                      ...
1951//              String                          DCB "str"
1952int find_strsig13(firmware *fw, string_sig *sig, int k)
1953{
1954    int nlen = strlen(sig->ev_name);
1955        char *p;
1956        int j;
1957       
1958        for (p = (char*)fw->buf, j = 0; j < fw->size*4 - nlen; j++, p++)
1959        {
1960                if (strncmp(sig->ev_name,(char*)p,nlen) == 0)
1961                {
1962                        uint32_t sadr = fw->base + j;                   // string address
1963                        int j1;
1964                        uint32_t *p1;
1965                        for (p1 = &fw->buf[(j/4)-1], j1 = (j/4)-1; j1 >= 0; j1--, p1--)
1966                        {
1967                                if (p1[0] == sadr)    // string ptr
1968                                {
1969                                        uint32_t padr = idx2adr(fw,j1);         // string ptr address
1970                                        int j2;
1971                                        uint32_t *p2;
1972                                        for (p2 = p1-1, j2 = j1-1; j2 >= 0; j2--, p2--)
1973                                        {
1974                                                if (p2[0] == padr)    // string ptr address
1975                                                {
1976                                                        uint32_t ppadr = idx2adr(fw,j2);                // string ptr ptr address
1977                                                        int j3;
1978                                                        for (j3 = j2-1; j3 >= 0; j3--)
1979                                                        {
1980                                                                if (isLDR_PC(fw,j3) && (LDR2adr(fw,j3) == ppadr))
1981                                                                {
1982                                                                        uint32_t fadr = idx2adr(fw,j3-sig->offset);
1983                                                                        //fprintf(stderr,"%s %08x\n",curr_name,fadr);
1984                                                                        addMatch(fadr,32,0,k,113);
1985                                                                        return 1;
1986                                                                }
1987                                                        }
1988                                                }
1989                                        }
1990                                }
1991                        }
1992                }
1993        }
1994
1995        return 0;
1996}
1997
1998// Sig pattern:
1999//              Special case for _pow
2000int find_strsig14(firmware *fw, string_sig *sig, int k)
2001{
2002        uint32_t *p;
2003        int j;
2004       
2005        for (p = fw->buf, j = 0; j < fw->size; j++, p++)
2006        {
2007                // Find values passed to _pow
2008                if ((p[0] == 0x00000000) && (p[1] == 0x40000000) && (p[2] == 0x00000000) && (p[3] == 0x408F4000))
2009                {
2010                        uint32_t adr1 = idx2adr(fw,j);          // address of 1st value
2011                        uint32_t adr2 = idx2adr(fw,j+2);        // address of 2nd value
2012                        uint32_t *p1;
2013                        int j1;
2014                       
2015                        for (p1 = p-5, j1 = j-5; j1>0; p1--, j1--)
2016                        {
2017                                if (((p1[0] & 0x0E0F0000) == 0x020F0000) &&     // ADR ?
2018                                         (p1[1] == 0xE8900003) &&                               // LDMIA R0,{R0,R1}
2019                                        ((p1[2] & 0xFF000000) == 0xEB000000) && // BL
2020                                        ((p1[4] & 0x0E0F0000) == 0x020F0000))   // ADR ?
2021                                {
2022                                        if ((ADR2adr(fw,j1) == adr1) && (ADR2adr(fw,j1+4) == adr2))
2023                                        {
2024                                                uint32_t fadr = followBranch(fw,idx2adr(fw,j1+2),0x01000001);
2025                                                //fprintf(stderr,"%s %08x\n",curr_name,fadr);
2026                                                addMatch(fadr,32,0,k,114);
2027                                                return 1;
2028                                        }
2029                                }
2030                                else
2031                                if (((p1[0] & 0x0E0F0000) == 0x020F0000) &&     // ADR ?
2032                                         (p1[2] == 0xE8900003) &&                               // LDMIA R0,{R0,R1}
2033                                        ((p1[3] & 0xFF000000) == 0xEB000000) && // BL
2034                                        ((p1[4] & 0x0E0F0000) == 0x020F0000))   // ADR ?
2035                                {
2036                                        if ((ADR2adr(fw,j1) == adr1) && (ADR2adr(fw,j1+4) == adr2))
2037                                        {
2038                                                uint32_t fadr = followBranch(fw,idx2adr(fw,j1+3),0x01000001);
2039                                                //fprintf(stderr,"%s %08x\n",curr_name,fadr);
2040                                                addMatch(fadr,32,0,k,114);
2041                                                return 1;
2042                                        }
2043                                }
2044                        }
2045                }
2046        }
2047       
2048        return 0;
2049}
2050
2051int find_strsig(firmware *fw, string_sig *sig, int k)
2052{
2053        switch (sig->type)
2054        {
2055                case 1:         return find_strsig1(fw, sig, k);
2056                case 2:         return find_strsig2(fw, sig, k);
2057                case 3:         return find_strsig3(fw, sig, k);
2058                case 4:         return find_strsig4(fw, sig, k);
2059                case 5:         return find_strsig5(fw, sig, k);
2060                case 6:         return find_strsig6(fw, sig, k);
2061                case 7:         return find_strsig7(fw, sig, k);
2062                case 8:         return find_strsig8(fw, sig, k);
2063                case 9:         return find_strsig9(fw, sig, k);
2064                case 10:        return find_strsig10(fw, sig, k);
2065                case 11:        return find_strsig11(fw, sig, k);
2066                case 12:        return find_strsig12(fw, sig, k);
2067                case 13:        return find_strsig13(fw, sig, k);
2068                case 14:        return find_strsig14(fw, sig, k);
2069        }
2070       
2071        return 0;
2072}
2073
2074//------------------------------------------------------------------------------------------------------------
2075
2076// Matching functions
2077
2078void find_str_sig_matches(firmware *fw, const char *curr_name)
2079{
2080        int i;
2081       
2082        int found_ev = 0;
2083        int tried_ev = 0;
2084
2085        count = 0;
2086
2087        for (i = 0; string_sigs[i].ev_name != 0 && !found_ev; i++)
2088        {
2089                if (strcmp(curr_name, string_sigs[i].name) == 0)
2090                {
2091                        tried_ev = 1;
2092                        if (find_strsig(fw, &string_sigs[i], -1))
2093                        {
2094                                found_ev = 1;
2095                                break;
2096                        }
2097                }
2098        }
2099
2100        if (count > 1)
2101        {
2102                //if (strcmp(curr_name,"GetDrive_FreeClusters") == 0) disp_sort = 1; else disp_sort = 0;
2103                qsort(matches, count, sizeof(Match), (void*)match_compare);
2104    }
2105
2106        if (count > 0)
2107        {
2108                save_sig(curr_name, matches->ptr);     
2109        }
2110}
2111
2112int find_matches(firmware *fw, int k)
2113{
2114    const char *curr_name;
2115    FuncSig *sig, *s;
2116    BufRange *n;
2117    uint32_t *p;
2118        int i;
2119    int fail, success;
2120       
2121        int found_ev = 0;
2122        int tried_ev = 0;
2123
2124        count = 0;
2125    curr_name = func_list[k].name;
2126
2127        while (1) {
2128                sig = func_list[k].sig;
2129
2130                for (i = 0; string_sigs[i].ev_name != 0 && !found_ev; i++)
2131                {
2132                        if (strcmp(curr_name, string_sigs[i].name) == 0)
2133                        {
2134                                tried_ev = 1;
2135                                if (find_strsig(fw, &string_sigs[i], k))
2136                                {
2137                                        found_ev = 1;
2138                                        break;
2139                                }
2140                        }
2141                }
2142
2143                if (!found_ev)
2144                {
2145                        for (n = fw->br; n != 0; n = n->next){
2146                                for (p = n->p, i = 0; i < n->len; p++, i++){
2147                                        fail = 0;
2148                                        success = 0;
2149                                        for (s = sig; s->offs != -1; s++){
2150                                                if ((p[s->offs] & s->mask) != s->value){
2151                                                        fail++;
2152                                                } else {
2153                                                        success++;
2154                                                }
2155                                        }
2156                                        if (success > fail){
2157                                                if (s->mask == -2)
2158                                                {
2159                                                        int end_branch = 0;
2160                                                        uint32_t idx = 0;
2161                                                        uint32_t *p1 = 0;
2162                                                        if ((fw->buf[n->off+i+s->value] & 0x0F000000) == 0x0A000000)   // B
2163                                                        {
2164                                                                idx = adr2idx(fw, followBranch2(fw, idx2adr(fw,n->off+i+s->value), 0xF0000001));
2165                                                                if ((idx >= 0) && (idx < fw->size))
2166                                                                {
2167                                                                        end_branch = 1;
2168                                                                        p1 = &fw->buf[idx];
2169                                                                }
2170                                                        }
2171                                                        int fail2 = 0;
2172                                                        int success2 = 0;
2173                                                        //fprintf(stderr,"\t%s %d %08x %08x %d %d\n",curr_name,idx,idx2adr(fw,idx),idx2adr(fw,i+n->off),success,fail);
2174                                                        s++;
2175                                                        for (; s->offs != -1; s++){
2176                                                                if (!end_branch || (p1[s->offs] & s->mask) != s->value){
2177                                                                        fail2++;
2178                                                                } else {
2179                                                                        success2++;
2180                                                                }
2181                                                        }
2182                                                        if (fail2 == 0)
2183                                                        {
2184                                                                success = success + fail + success2;
2185                                                                fail = 0;
2186                                                        }
2187                                                        else
2188                                                        {
2189                                                                success = success + success2;
2190                                                                fail = fail + fail2;
2191                                                        }
2192                                                        //fprintf(stderr,"\t%s %d %08x %08x %d %d\n",curr_name,idx,idx2adr(fw,idx),idx2adr(fw,i+n->off),success,fail);
2193                                                }
2194                                        }
2195                                        if (success > fail){
2196                                                addMatch(idx2adr(fw,i+n->off),success,fail,k,func_list[k].ver);
2197                                                if (count >= MAX_MATCHES){
2198                                                        bprintf("// WARNING: too many matches for %s!\n", func_list[k].name);
2199                                                        break;
2200                                                }
2201                                        }
2202                                }
2203                        }
2204                }
2205
2206                // same name, so we have another version of the same function
2207                if ((func_list[k+1].name == NULL) || (strcmp(curr_name, func_list[k+1].name) != 0)) {
2208                        break;
2209                }
2210                k++;
2211        }
2212
2213        if (count > 1)
2214        {
2215                //if (strcmp(curr_name,"GetDrive_FreeClusters") == 0) disp_sort = 1; else disp_sort = 0;
2216                qsort(matches, count, sizeof(Match), (void*)match_compare);
2217    }
2218
2219        if (count > 0)
2220        {
2221                save_sig(curr_name, matches->ptr);     
2222        }
2223               
2224        return k;
2225}
2226
2227void print_results(const char *curr_name)
2228{
2229        int i;
2230        int err = 0;
2231    char line[500] = "";
2232       
2233        // find best match and report results
2234#ifdef  COMP_OSTUBS
2235        osig* ostub = find_sig(stubs,curr_name);
2236#endif
2237        osig* ostub2 = find_sig(stubs2,curr_name);
2238
2239        if ((count == 0)
2240                || (matches->fail > 0)
2241                || (ostub2 && (matches->ptr != ostub2->val))
2242#ifdef  COMP_OSTUBS
2243                || (ostub && (matches->ptr != ostub->val) && (ostub->pct != 0) && (!ostub2 || (matches->ptr != ostub2->val)))
2244#endif
2245       )
2246                err = 1;
2247
2248        // write to header (if error) or body buffer (no error)
2249        out_hdr = err;
2250
2251        char *macro = "NSTUB";
2252        if (strncmp(curr_name,"task_",5) == 0) macro = "  DEF";
2253       
2254#if defined(UPDATE_STUBS2) && defined(COMP_OSTUBS)
2255    if (ostub && (count > 0) && (ostub->val != matches->ptr) && (ostub->pct != 0) && out_hdr && !ostub2)
2256    {
2257        static int hdr_added = 0;
2258        FILE *fp = fopen("stubs_entry_2.S","a");
2259        if (hdr_added == 0)
2260        {
2261            fprintf(fp,"\n\n// Added by finsig_dryos V2 to match old values found by finsig.\n");
2262            fprintf(fp,"// Values should be checked in firmware, if the new address in stubs_entry.S\n// is correct then delete the correspoding entry below.\n");
2263            hdr_added = 1;
2264        }
2265        fprintf(fp,"NHSTUB(%-30s,0x%08x) // New address = 0x%08x\n",curr_name,ostub->val,matches->ptr);
2266        fclose(fp);
2267
2268        ostub2 = malloc(sizeof(osig));
2269        strcpy(ostub2->nm, curr_name);
2270        ostub2->val = ostub->val;
2271    }
2272#endif
2273
2274        if (count == 0)
2275        {
2276                int opt = is_in_list(curr_name,optional);
2277                if (opt == 1) return;
2278                char fmt[50] = "";
2279                sprintf(fmt, "// ERROR: %%s is not found. %%%ds//--- --- ", 34-strlen(curr_name));
2280                sprintf(line+strlen(line), fmt, curr_name, "");
2281        }
2282        else
2283        {
2284                if (ostub2)
2285                    sprintf(line+strlen(line),"//%s(%-38s,0x%08x) //%3d ", macro, curr_name, matches->ptr, matches->sig);
2286                else
2287                        sprintf(line+strlen(line),"%s(%-40s,0x%08x) //%3d ", macro, curr_name, matches->ptr, matches->sig);
2288
2289                if (matches->fail > 0)
2290                        sprintf(line+strlen(line),"%2d%% ", matches->success*100/(matches->success+matches->fail));
2291                else
2292                        sprintf(line+strlen(line),"    ");
2293        }
2294
2295        if (ostub2)
2296        {
2297                if ((count > 0) && (matches->ptr == ostub2->val))
2298                        sprintf(line+strlen(line),"       == 0x%08x    ",ostub2->val);
2299                else
2300                        sprintf(line+strlen(line),"   *** != 0x%08x    ",ostub2->val);
2301        }
2302        else
2303                sprintf(line+strlen(line),"                        ");
2304
2305#ifdef  COMP_OSTUBS
2306        if (ostub)
2307        {
2308                if ((count > 0) && (ostub->val != matches->ptr) && (ostub->pct != 0))
2309                {
2310                        if (out_hdr)
2311                                sprintf(line+strlen(line),"  *** != 0x%08x @ %3d%%",ostub->val,ostub->pct);
2312                        else
2313                                sprintf(line+strlen(line),"      != 0x%08x @ %3d%%",ostub->val,ostub->pct);
2314                }
2315                else if ((ostub->pct != 0) && (ostub->pct != 100))
2316                {
2317                        sprintf(line+strlen(line),"      == 0x%08x @ %3d%%",ostub->val,ostub->pct);
2318                }
2319                else if (ostub->pct == 0)
2320                {
2321                        sprintf(line+strlen(line),"          Not Found");
2322                }
2323        }
2324#endif
2325
2326    for (i=strlen(line)-1; i>=0 && line[i]==' '; i--) line[i] = 0;
2327    bprintf("%s\n",line);
2328
2329        for (i=1;i<count && matches[i].fail==matches[0].fail;i++)
2330        {
2331                if (matches[i].ptr != matches->ptr)
2332                {
2333                        bprintf("// ALT: %s(%s, 0x%x) // %d %d/%d\n", macro, curr_name, matches[i].ptr, matches[i].sig, matches[i].success, matches[i].fail);
2334                }
2335        }
2336}
2337
2338//------------------------------------------------------------------------------------------------------------
2339
2340int find_str_ref(firmware *fw, char *str)
2341{
2342        int k = find_str(fw, str);
2343        if (k >= 0)
2344        {
2345                uint32_t sadr = idx2adr(fw,k);          // string address
2346                for (k=0; k<fw->size; k++)
2347                {
2348                        if (((fw->buf[k] & 0x0E0F0000) == 0x020F0000) && // ADR ?
2349                                (ADR2adr(fw,k) == sadr))
2350                        {
2351                                return k;
2352                        }
2353                }
2354        }
2355        return -1;
2356}
2357
2358//------------------------------------------------------------------------------------------------------------
2359
2360typedef struct
2361{
2362        uint16_t mode;
2363        char *nm;
2364} ModeMapName;
2365
2366ModeMapName mmnames[] = {
2367        { 32768,"MODE_AUTO" },
2368        { 32769,"MODE_M" },
2369        { 32770,"MODE_AV" },
2370        { 32771,"MODE_TV" },
2371        { 32772,"MODE_P" },
2372       
2373        { 65535,"" }
2374};
2375
2376char* mode_name(uint16_t v)
2377{
2378        int i;
2379        for (i=0; mmnames[i].mode != 65535; i++)
2380        {
2381                if (mmnames[i].mode == v)
2382                        return mmnames[i].nm;
2383        }
2384       
2385        return "";
2386}
2387
2388void find_modemap(firmware *fw)
2389{
2390        int k,k1,cnt = 0;
2391       
2392        out_hdr = 1;
2393        add_blankline();
2394
2395        bprintf("// Check of modemap from 'platform/CAMERA/shooting.c':\n");
2396
2397        k = find_str_ref(fw, "AC:PTM_Init");
2398        if (k >= 0)
2399        {
2400                bprintf("// Firmware modemap table found @%08x -> ",idx2adr(fw,k));
2401                if (isBL(fw,k+2))
2402                {
2403                        k = idxFollowBranch(fw,k+2,0x01000001);
2404                        bprintf("%08x -> ",idx2adr(fw,k));
2405                        for (k1 = 22; k1 <= 26; k1++)
2406                        {
2407                                if (isBL(fw,k+k1))
2408                                {
2409                                        k = idxFollowBranch(fw,k+k1,0x01000001);
2410                                        bprintf("%08x -> ",idx2adr(fw,k));
2411                                        for (k1 = 37; k1 <= 41; k1++)
2412                                        {
2413                                                if (isBL(fw,k+k1))
2414                                                {
2415                                                        k = idxFollowBranch(fw,k+k1,0x01000001);
2416                                                        bprintf("%08x -> ",idx2adr(fw,k));
2417                                                        if (isLDR_PC(fw,k))
2418                                                        {
2419                                                                k = adr2idx(fw,fw->buf[LDR2idx(fw,k)]);
2420                                                                bprintf("%08x\n",idx2adr(fw,k));
2421                                                                uint16_t *p = (uint16_t*)(&fw->buf[k]);
2422                                                                k = 0;
2423                                                                while ((*p != 0xFFFF) && (k < 50))
2424                                                                {
2425                                                                        if ((*p < 8000) || (*p > 8999))
2426                                                                        {
2427                                                                                osig *m = find_sig_val(modemap, *p);
2428                                                                                if (!m)
2429                                                                                {
2430                                                                                        char *s = mode_name(*p);
2431                                                                                        bprintf("// Mode %5d in firmware but not in current modemap",*p);
2432                                                                                        if (strcmp(s,"") != 0)
2433                                                                                                bprintf(" (%s)",s);
2434                                                                                        bprintf("\n");
2435                                                                                        cnt++;
2436                                                                                }
2437                                                                                else
2438                                                                                {
2439                                                                                        m->pct = 100;
2440                                                                                }
2441                                                                        }
2442                                                                        p++;
2443                                                                        k++;
2444                                                                }
2445                                                        }
2446                                                        osig *m = modemap;
2447                                                        while (m)
2448                                                        {
2449                                                                if (m->pct != 100)      // not matched above?
2450                                                                {
2451                                                                        bprintf("// Current modemap entry not found in firmware - %-24s %5d\n",m->nm,m->val);
2452                                                                        cnt++;
2453                                                                }
2454                                                                m = m->nxt;
2455                                                        }
2456                                                        if (cnt == 0)
2457                                                        {
2458                                                                bprintf("// No problems found with modemap table.\n");
2459                                                        }
2460                                                        return;
2461                                                }
2462                                        }
2463                                }
2464                        }
2465                }
2466                bprintf("\n");
2467        }
2468}
2469
2470//------------------------------------------------------------------------------------------------------------
2471
2472uint32_t craw_bufsize = 0;
2473
2474// Search for things that go in 'platform_camera.h'
2475void find_platform_vals(firmware *fw)
2476{
2477        int k,k1;
2478       
2479        out_hdr = 1;
2480        add_blankline();
2481
2482        bprintf("// Values below go in 'platform_camera.h':\n");
2483        bprintf("//#define CAM_DRYOS         1\n");
2484        if (fw->dryos_ver >= 39)
2485                bprintf("//#define CAM_DRYOS_2_3_R39 1 // Defined for cameras with DryOS version R39 or higher\n");
2486        if (fw->dryos_ver >= 47)
2487                bprintf("//#define CAM_DRYOS_2_3_R47 1 // Defined for cameras with DryOS version R47 or higher\n");
2488
2489        // Find 'RAW' image size
2490        uint32_t raw_width = 0;
2491        uint32_t raw_height = 0;
2492        uint32_t kw=0, kh=0;
2493       
2494        k = find_str_ref(fw, "\r[%ld] AdjDrvType[%02ld] -> DrvType[%02");
2495        if (k >= 0)
2496        {
2497                for (k1 = k-1; k1 >= k-20; k1--)
2498                {
2499                        if ((fw->buf[k1] & 0x0FFF0FFF) == 0x058D0030)                   // STRxx Rn, [SP,#0x30]
2500                        {
2501                                if ((fw->buf[k1-1] & 0x0FFF0000) == 0x03A00000)         // MOVxx Rn, #YYY
2502                                {
2503                                        raw_height = ALUop2(fw, k1-1);
2504                                        kh = k1-1;
2505                                }
2506                                else if ((fw->buf[k1-2] & 0x0FFF0000) == 0x03A00000)// MOVxx Rn, #YYY
2507                                {
2508                                        raw_height = ALUop2(fw, k1-2);
2509                                        kh = k1-2;
2510                                }
2511                                else if (isLDR_PC_cond(fw,k1-1))
2512                                {
2513                                        raw_height = fw->buf[LDR2idx(fw,k1-1)];
2514                                        kh = k1-1;
2515                                }
2516                                else if (isLDR_PC_cond(fw,k1-2))
2517                                {
2518                                        raw_height = fw->buf[LDR2idx(fw,k1-2)];
2519                                        kh = k1-2;
2520                                }
2521                        }
2522                        if ((fw->buf[k1] & 0x0FFF0FFF) == 0x058D0034)                   // STRxx Rn, [SP,#0x34]
2523                        {
2524                                if ((fw->buf[k1-1] & 0x0FFF0000) == 0x03A00000)         // MOVxx Rn, #YYY
2525                                {
2526                                        raw_width = ALUop2(fw, k1-1);
2527                                        kw = k1-1;
2528                                }
2529                                else if ((fw->buf[k1-2] & 0x0FFF0000) == 0x03A00000)// MOVxx Rn, #YYY
2530                                {
2531                                        raw_width = ALUop2(fw, k1-2);
2532                                        kw = k1-2;
2533                                }
2534                                else if (isLDR_PC_cond(fw,k1-1))
2535                                {
2536                                        raw_width = fw->buf[LDR2idx(fw,k1-1)];
2537                                        kw = k1-1;
2538                                }
2539                                else if (isLDR_PC_cond(fw,k1-2))
2540                                {
2541                                        raw_width = fw->buf[LDR2idx(fw,k1-2)];
2542                                        kw = k1-2;
2543                                }
2544                        }
2545                }
2546        }
2547
2548        if ((raw_width == 0) && (raw_height == 0))
2549        {
2550                k = find_str_ref(fw, " CrwAddress %lx, CrwSize H %ld V %ld\r");
2551                if (k >= 0)
2552                {
2553                        // Width
2554                        for (k1=k-1; k1>=k-5; k1--)
2555                        {
2556                                if ((fw->buf[k1] & 0xFFFFF000) == 0xE3A02000)   // MOV R2, #nnn
2557                                {
2558                                        raw_width = ALUop2(fw,k1);
2559                                        kw = k1;
2560                                }
2561                                else
2562                                if (isLDR_PC(fw,k1) && ((fw->buf[k1]& 0x0000F000) == 0x00002000))       // LDR R2, =nnn
2563                                {
2564                                        raw_width = fw->buf[LDR2idx(fw,k1)];
2565                                        kw = k1;
2566                                }
2567                        }
2568                        // Height
2569                        for (k1=k-1; k1>=k-5; k1--)
2570                        {
2571                                if ((fw->buf[k1] & 0xFFFFF000) == 0xE3A03000)   // MOV R3, #nnn
2572                                {
2573                                        raw_height = ALUop2(fw,k1);
2574                                        kh = k1;
2575                                }
2576                                else
2577                                if (isLDR_PC(fw,k1) && ((fw->buf[k1]& 0x0000F000) == 0x00003000))       // LDR R3, =nnn
2578                                {
2579                                        raw_height = fw->buf[LDR2idx(fw,k1)];
2580                                        kh = k1;
2581                                }
2582                                else
2583                                if ((fw->buf[k1] & 0xFFFFF000) == 0xE2423000)   // SUB R3, R2, #nnn
2584                                {
2585                                        raw_height = raw_width - ALUop2(fw,k1);
2586                                        kh = k1;
2587                                }
2588                        }
2589                }
2590        }
2591       
2592        if (raw_width != 0)
2593        {
2594                bprintf("//#define CAM_RAW_ROWPIX    %d // Found @0x%08x\n",raw_width,idx2adr(fw,kw));
2595        }
2596        if (raw_height != 0)
2597        {
2598                bprintf("//#define CAM_RAW_ROWS      %d // Found @0x%08x\n",raw_height,idx2adr(fw,kh));
2599        }
2600
2601        // Find 'CAM_UNCACHED_BIT'
2602        k = get_saved_sig(fw, "FreeUncacheableMemory");
2603        if (k >= 0)
2604        {
2605                uint32_t fadr = saved_sigs[k].val;
2606                int idx = adr2idx(fw, fadr);
2607               
2608                for (k=idx; k<idx+8; k++)
2609                {
2610                        if ((fw->buf[k] & 0x0FFFF000) == 0x03C00000)    // BIC
2611                        {
2612                                fadr = ALUop2(fw,k);
2613                                bprintf("//#undef  CAM_UNCACHED_BIT\n");
2614                                bprintf("//#define CAM_UNCACHED_BIT  0x%08x // Found @0x%08x\n",fadr,idx2adr(fw,k));
2615                        }
2616                }
2617        }
2618}
2619
2620//------------------------------------------------------------------------------------------------------------
2621
2622// Search for things that go in 'lib.c'
2623void find_lib_vals(firmware *fw)
2624{
2625        int k,k1;
2626       
2627        out_hdr = 1;
2628        add_blankline();
2629
2630        bprintf("// Values below go in 'lib.c':\n");
2631
2632        // Find 'vid_get_bitmap_fb'
2633        k = get_saved_sig(fw, "DispCon_ShowBitmapColorBar");
2634        if (k >= 0)
2635        {
2636                uint32_t fadr = saved_sigs[k].val;
2637                int idx = adr2idx(fw, fadr);
2638               
2639                for (k=idx+1; k<idx+30; k++)
2640                {
2641                        if (((fw->buf[k-1] & 0xFF000000) == 0xEB000000) && // BL
2642                            (isLDR_PC(fw,k)))
2643                        {
2644                                uint32_t v1 = fw->buf[LDR2idx(fw,k)];
2645                                bprintf("//void *vid_get_bitmap_fb()        { return (void*)0x%08x; } // Found @0x%08x\n",v1,idx2adr(fw,k));
2646                                break;
2647                        }
2648                        else
2649                        if (((fw->buf[k-1] & 0xFF000000) == 0xEB000000) && // BL
2650                            (isLDR_PC(fw,k+1)))
2651                        {
2652                                uint32_t v1 = fw->buf[LDR2idx(fw,k+1)];
2653                                bprintf("//void *vid_get_bitmap_fb()        { return (void*)0x%08x; } // Found @0x%08x\n",v1,idx2adr(fw,k));
2654                                break;
2655                        }
2656                }
2657        }
2658       
2659        // find 'vid_get_viewport_fb'
2660        k = find_str_ref(fw, "VRAM Address  : %p\r");
2661        if (k >= 0)
2662        {
2663                for (k1=k-1; k1>k-8; k1--)
2664                {
2665                        if (isLDR(fw,k1) && isLDR(fw,k1+1))
2666                        {
2667                                uint32_t v1 = fw->buf[LDR2idx(fw,k1)];
2668                                uint32_t v2 = fw->buf[LDR2idx(fw,k1+1)];
2669                                if (v2 > v1) v1 = v2;
2670                                bprintf("//void *vid_get_viewport_fb()      { return (void*)0x%08x; } // Found @0x%08x\n",v1,idx2adr(fw,k1));
2671                        }
2672                }
2673        }
2674       
2675        // find 'camera_jpeg_count_str'
2676        k = find_str_ref(fw, "9999");
2677        if (k >= 0)
2678        {
2679                if (isLDR(fw,k-1) && ((fw->buf[k+1] & 0xFF000000) == 0xEB000000))
2680                {
2681                        uint32_t v1 = fw->buf[LDR2idx(fw,k-1)];
2682                        bprintf("//char *camera_jpeg_count_str()    { return (char*)0x%08x; } // Found @0x%08x\n",v1,idx2adr(fw,k-1));
2683                }
2684        }
2685       
2686        // find 'hook_raw_size'
2687        k = find_str_ref(fw, "CRAW BUFF SIZE  %p");
2688        if (k >= 0)
2689        {
2690                if (isLDR(fw,k-1))
2691                {
2692                        craw_bufsize = fw->buf[LDR2idx(fw,k-1)];
2693                        bprintf("//long hook_raw_size()             { return 0x%08x; }        // Found @0x%08x\n",craw_bufsize,idx2adr(fw,k-1));
2694                }
2695        }
2696       
2697        // Find value for 'get_flash_params_count'
2698        k = get_saved_sig(fw, "GetParameterData");
2699        if (k >= 0)
2700        {
2701                uint32_t fadr = saved_sigs[k].val;
2702                int idx = adr2idx(fw, fadr);
2703               
2704                for (k=idx; k<idx+30; k++)
2705                {
2706                        if ((fw->buf[k] & 0xFFF00FFF) == 0xE3C00901)    // BIC Rn, Rn, #0x4000
2707                        {
2708                                uint32_t r = fw->buf[k] & 0x000F0000;   // Register
2709                                if (((fw->buf[k+1] & 0xFFF00000) == 0xE3500000) && ((fw->buf[k+1] & 0x000F0000) == r))  // CMP, Rn #val
2710                                {
2711                                        bprintf("//int get_flash_params_count(void) { return 0x%02x; }              // Found @0x%08x\n",fw->buf[k+1]&0xFFF,idx2adr(fw,k+1));
2712                                        break;
2713                                }
2714                        }
2715                }
2716        }
2717}
2718
2719//------------------------------------------------------------------------------------------------------------
2720
2721void print_stubs_min(firmware *fw, const char *name, uint32_t fadr, uint32_t atadr)
2722{
2723        osig *o = find_sig(stubs_min,name);
2724        bprintf("//DEF(%-40s,0x%08x) // Found @0x%08x",name,fadr,atadr);
2725        if (o)
2726        {
2727                if (fadr != o->val)
2728                {
2729                        bprintf(", ** != ** stubs_min = 0x%08x (%s)",o->val,o->sval);
2730                }
2731                else
2732                {
2733                        bprintf(",          stubs_min = 0x%08x (%s)",o->val,o->sval);
2734                }
2735        }
2736        bprintf("\n");
2737}
2738
2739// Search for things that go in 'stubs_min.S'
2740void find_stubs_min(firmware *fw)
2741{
2742        int k,k1;
2743       
2744        out_hdr = 1;
2745        add_blankline();
2746
2747        bprintf("// Values below go in 'stubs_min.S':\n");
2748
2749        // Find 'physw_status'
2750        k = get_saved_sig(fw, "kbd_read_keys");
2751        if (k >= 0)
2752        {
2753                uint32_t fadr = saved_sigs[k].val;
2754                int idx = adr2idx(fw, fadr);
2755               
2756                for (k=0; k<5; k++)
2757                {
2758                        if (isLDR_PC(fw,idx+k))
2759                        {
2760                                print_stubs_min(fw,"physw_status",fw->buf[LDR2idx(fw,idx+k)],idx2adr(fw,idx+k));
2761                                //break;
2762                        }
2763                }
2764        }
2765       
2766        // Find 'physw_run'
2767        k = get_saved_sig(fw, "task_PhySw");
2768        if (k >= 0)
2769        {
2770                uint32_t fadr = saved_sigs[k].val;
2771                int idx = adr2idx(fw, fadr);
2772               
2773                for (k=0; k<5; k++)
2774                {
2775                        if (isLDR_PC(fw,idx+k))
2776                        {
2777                                uint32_t base = fw->buf[LDR2idx(fw,idx+k)];
2778                                uint32_t fadr = followBranch(fw, idx2adr(fw,idx+k+1), 1);
2779                                uint32_t ofst = fw->buf[adr2idx(fw,fadr)] & 0x00000FFF;
2780                                print_stubs_min(fw,"physw_run",base+ofst,idx2adr(fw,idx+k));
2781                                //break;
2782                        }
2783                }
2784        }
2785       
2786        // Find 'levent_table'
2787        for (k=0; k<fw->size; k++)
2788        {
2789                if ((fw->buf[k] > fw->base) && (fw->buf[k+1] == 0x00000800) && (fw->buf[k+2] == 0x00000002))
2790                {
2791                        print_stubs_min(fw,"levent_table",idx2adr(fw,k),idx2adr(fw,k));
2792                        //break;
2793                }
2794        }
2795       
2796        // Find 'FlashParamsTable'
2797        for (k=0; k<fw->size; k++)
2798        {
2799                if ((fw->buf[k] > fw->base) && (fw->buf[k+1] == 0x00010000) && (fw->buf[k+2] == 0xFFFF0002))
2800                {
2801                        uint32_t fadr = idx2adr(fw,k);
2802                        for (k1=0; k1<fw->size; k1++)
2803                        {
2804                                if (fw->buf[k1] == fadr)
2805                                {
2806                                        print_stubs_min(fw,"FlashParamsTable",idx2adr(fw,k1),idx2adr(fw,k1));
2807                                        k = fw->size;
2808                                        //break;
2809                                }
2810                        }
2811                }
2812        }
2813       
2814        // Find 'movie_status'
2815        for (k=0; k<fw->size; k++)
2816        {
2817                if (isLDR_PC(fw, k) &&                                                          // LDR R0, =base
2818                        ((fw->buf[k+1] & 0xFE0F0000) == 0xE20F0000) &&  // ADR R1, =sub
2819                        isSTR(fw, k+2) &&                                                               // STR R1, [R0,N]
2820                        (fw->buf[k+3] == 0xE3A01003) &&                                 // MOV R1, 3
2821                        isSTR(fw, k+4) &&                                                               // STR R1, [R0,ofst]
2822                        (fw->buf[LDR2idx(fw,k)] < fw->base))
2823                {
2824                        uint32_t base = fw->buf[LDR2idx(fw,k)];
2825                        uint32_t ofst = fw->buf[k+4] & 0x00000FFF;
2826                        print_stubs_min(fw,"movie_status",base+ofst,idx2adr(fw,k));
2827                        //break;
2828                }
2829                else
2830                if (isLDR_PC(fw, k) &&                                                          // LDR R1, =sub
2831                        isLDR_PC(fw, k+1) &&                                                    // LDR R0, =base
2832                        isSTR(fw, k+2) &&                                                               // STR R1, [R0,N]
2833                        (fw->buf[k+3] == 0xE3A01003) &&                                 // MOV R1, 3
2834                        isSTR(fw, k+4) &&                                                               // STR R1, [R0,ofst]
2835                        (fw->buf[LDR2idx(fw,k+1)] < fw->base))
2836                {
2837                        uint32_t base = fw->buf[LDR2idx(fw,k+1)];
2838                        uint32_t ofst = fw->buf[k+4] & 0x00000FFF;
2839                        print_stubs_min(fw,"movie_status",base+ofst,idx2adr(fw,k));
2840                        //break;
2841                }
2842        }
2843       
2844        // Find 'full_screen_refresh'
2845        for (k=0; k<fw->size; k++)
2846        {
2847                if (((fw->buf[k] & 0xFF1FF000) == 0xE51F0000) &&        // LDR R0, =base
2848                        (fw->buf[k+1] == 0xE5D01000) &&                                 // LDRB R1, [R0]
2849                        (fw->buf[k+2] == 0xE3811002) &&                                 // ORR R1, R1, #2
2850                        (fw->buf[k+3] == 0xE5C01000) &&                                 // STRB R1, [R0]
2851                        (fw->buf[k+4] == 0xE12FFF1E))                                   // BX LR
2852                {
2853                        uint32_t base = fw->buf[LDR2idx(fw,k)];
2854                        print_stubs_min(fw,"full_screen_refresh",base,idx2adr(fw,k));
2855                        //break;
2856                }
2857        }
2858       
2859        // Find 'canon_menu_active'
2860        k = get_saved_sig(fw, "StartRecModeMenu");
2861        if (k >= 0)
2862        {
2863                uint32_t fadr = saved_sigs[k].val;
2864                int idx = adr2idx(fw, fadr);
2865               
2866                for (k=0; k<5; k++)
2867                {
2868                        if (isLDR_PC(fw,idx+k))
2869                        {
2870                                uint32_t base = fw->buf[LDR2idx(fw,idx+k)];
2871                                for (k1=k+1; k1<k+5; k1++)
2872                                {
2873                                        if (isLDR(fw,idx+k1))
2874                                        {
2875                                                uint32_t ofst = fw->buf[idx+k1] & 0x00000FFF;
2876                                                print_stubs_min(fw,"canon_menu_active",base+ofst,idx2adr(fw,idx+k));
2877                                                //break;
2878                                        }
2879                                }
2880                        }
2881                }
2882        }
2883       
2884        // Find 'canon_shoot_menu_active'
2885        for (k=0; k<fw->size; k++)
2886        {
2887                if (((fw->buf[k]   & 0xFF1FF000) == 0xE51F1000) &&      // LDR R1, =base
2888                        ((fw->buf[k+1] & 0xFFFFF000) == 0xE5D10000) &&  // LDRB R0, [R1, #n]
2889                        (fw->buf[k+2] == 0xE2800001) &&                                 // ADD R0, R0, #1
2890                        ((fw->buf[k+3] & 0xFFFFF000) == 0xE5C10000) &&  // STRB R0, [R1, #n]
2891                        ((fw->buf[k+4] & 0xFF000000) == 0xEA000000))    // B
2892                {
2893                        uint32_t base = fw->buf[LDR2idx(fw,k)];
2894                        uint32_t ofst = fw->buf[k+1] & 0x00000FFF;
2895                        print_stubs_min(fw,"canon_shoot_menu_active",base+ofst,idx2adr(fw,k));
2896                        //break;
2897                }
2898                else
2899                if (((fw->buf[k]   & 0xFF1FF000) == 0xE51F0000) &&      // LDR R0, =base
2900                        ((fw->buf[k+1] & 0xFFFFF000) == 0xE5D01000) &&  // LDRB R1, [R0, #n]
2901                        (fw->buf[k+2] == 0xE2811001) &&                                 // ADD R1, R1, #1
2902                        ((fw->buf[k+3] & 0xFFFFF000) == 0xE5C01000) &&  // STRB R1, [R0, #n]
2903                        ((fw->buf[k+4] & 0xFF000000) == 0xEA000000))    // B
2904                {
2905                        uint32_t base = fw->buf[LDR2idx(fw,k)];
2906                        uint32_t ofst = fw->buf[k+1] & 0x00000FFF;
2907                        print_stubs_min(fw,"canon_shoot_menu_active",base+ofst,idx2adr(fw,k));
2908                        //break;
2909                }
2910        }
2911       
2912        // Find 'playrec_mode'
2913        for (k=0; k<fw->size; k++)
2914        {
2915                if (((fw->buf[k]    & 0xFF1FF000) == 0xE51F1000) &&     // LDR R1, =base
2916                        ((fw->buf[k+1]  & 0xFFFFF000) == 0xE5810000) && // STR R0, [R1, #n]
2917                    ((fw->buf[k+3]  & 0xFF1FF000) == 0xE51F0000) &&     // LDR R0, =base
2918                        ((fw->buf[k+4]  & 0xFFFFF000) == 0xE5900000) && // LDR R0, [R0, #n]
2919                    ((fw->buf[k+6]  & 0xFF1FF000) == 0xE51F1000) &&     // LDR R1, =base
2920                    ((fw->buf[k+9]  & 0xFF1FF000) == 0xE51F0000) &&     // LDR R0, =base
2921                    ((fw->buf[k+12] & 0xFF1FF000) == 0xE51F1000) &&     // LDR R1, =base
2922                    ((fw->buf[k+15] & 0xFF1FF000) == 0xE51F0000) &&     // LDR R0, =base
2923                    ((fw->buf[k+18] & 0xFF1FF000) == 0xE51F1000) &&     // LDR R1, =base
2924                        (fw->buf[LDR2idx(fw,k)] == fw->buf[LDR2idx(fw,k+3)]) &&
2925                        (fw->buf[LDR2idx(fw,k)] == fw->buf[LDR2idx(fw,k+6)]) &&
2926                        (fw->buf[LDR2idx(fw,k)] == fw->buf[LDR2idx(fw,k+9)]) &&
2927                        (fw->buf[LDR2idx(fw,k)] == fw->buf[LDR2idx(fw,k+12)]) &&
2928                        (fw->buf[LDR2idx(fw,k)] == fw->buf[LDR2idx(fw,k+15)]) &&
2929                        (fw->buf[LDR2idx(fw,k)] == fw->buf[LDR2idx(fw,k+18)]))
2930                {
2931                        uint32_t base = fw->buf[LDR2idx(fw,k)];
2932                        uint32_t ofst = fw->buf[k+1] & 0x00000FFF;
2933                        print_stubs_min(fw,"playrec_mode",base+ofst,idx2adr(fw,k));
2934                        //break;
2935                }
2936        }
2937       
2938        // Find 'zoom_status'
2939        int found_zoom_status = 0;
2940       
2941        k = find_str_ref(fw, "m_ZoomState            :%d\n");
2942        if (k >= 0)
2943        {
2944                if (isLDR(fw,k-1))
2945                {
2946                        uint32_t ofst = fw->buf[k-1] & 0x00000FFF;
2947                        uint32_t reg = (fw->buf[k-1] & 0x000F0000) >> 16;
2948                        uint32_t ldr_inst = 0xE51F0000 | (reg << 12);
2949                        for (k1=k-2; k1>k-20; k1--)
2950                        {
2951                                if ((fw->buf[k1] & 0xFF1FF000) == ldr_inst)
2952                                {
2953                                        uint32_t base = fw->buf[LDR2idx(fw,k1)];
2954                                        print_stubs_min(fw,"zoom_status",base+ofst,idx2adr(fw,k));
2955                                        found_zoom_status = 1;
2956                                        break;
2957                                }
2958                        }
2959                }
2960        }
2961       
2962        if (!found_zoom_status)
2963        {
2964                for (k=0; k<fw->size; k++)
2965                {
2966                        if (((fw->buf[k] & 0xFF1FF000) == 0xE51F0000) &&        // LDR R0, =base
2967                                (fw->buf[k+1] == 0xE5D00000) &&                                 // LDRB R0, [R0]
2968                                (fw->buf[k+2] == 0xE1B00000) &&                                 // MOVS R0, R0
2969                                (fw->buf[k+3] == 0x13A00001) &&                                 // MOVNE R0, #1
2970                                (fw->buf[k+4] == 0xE12FFF1E))                                   // BX LR
2971                        {
2972                                uint32_t base = fw->buf[LDR2idx(fw,k)];
2973                                print_stubs_min(fw,"zoom_status",base,idx2adr(fw,k));
2974                                found_zoom_status = 1;
2975                                //break;
2976                        }
2977                }
2978        }
2979       
2980        if (!found_zoom_status)
2981        {
2982                k = find_str_ref(fw, "TerminateDeliverToZoomController");
2983                if (k >= 0)
2984                {
2985                        for (k1=0; k1<5; k1++)
2986                        {
2987                                if (isLDR_PC(fw,k+k1))
2988                                {
2989                                        uint32_t base = fw->buf[LDR2idx(fw,k+k1)];
2990                                        print_stubs_min(fw,"zoom_status",base+0x20,idx2adr(fw,k+k1));
2991                                        found_zoom_status = 1;
2992                                        break;
2993                                }
2994                        }
2995                }
2996        }
2997       
2998        // Find 'some_flag_for_af_scan'
2999        for (k=0; k<fw->size; k++)
3000        {
3001                if (((fw->buf[k]    & 0xFF000000) == 0xEA000000) &&     // B loc
3002                        ((fw->buf[k+1]  & 0xFF000000) == 0xEA000000) && // B loc
3003                        ((fw->buf[k+2]  & 0xFF000000) == 0xEA000000) && // B loc
3004                        ((fw->buf[k+3]  & 0xFF000000) == 0xEA000000) && // B loc
3005                        ((fw->buf[k+4]  & 0xFF000000) == 0xEA000000) && // B loc
3006                        ((fw->buf[k+5]  & 0xFF000000) == 0xEA000000) && // B loc
3007                        ((fw->buf[k+6]  & 0xFF000000) == 0xEA000000) && // B loc
3008                        ((fw->buf[k+7]  & 0xFF000000) == 0xEA000000) && // B loc
3009                        (followBranch(fw,idx2adr(fw,k),1) != followBranch(fw,idx2adr(fw,k+1),1)) &&
3010                        (followBranch(fw,idx2adr(fw,k),1) == followBranch(fw,idx2adr(fw,k+2),1)) &&
3011                        (followBranch(fw,idx2adr(fw,k),1) == followBranch(fw,idx2adr(fw,k+3),1)) &&
3012                        (followBranch(fw,idx2adr(fw,k),1) != followBranch(fw,idx2adr(fw,k+4),1)) &&
3013                        (followBranch(fw,idx2adr(fw,k),1) != followBranch(fw,idx2adr(fw,k+5),1)) &&
3014                        (followBranch(fw,idx2adr(fw,k),1) == followBranch(fw,idx2adr(fw,k+6),1)) &&
3015                        (followBranch(fw,idx2adr(fw,k),1) == followBranch(fw,idx2adr(fw,k+7),1)) &&
3016                        (isLDR_PC(fw,adr2idx(fw,followBranch(fw,idx2adr(fw,k),1)))))    // LDR R0, =base
3017                {
3018                        uint32_t base = fw->buf[LDR2idx(fw,adr2idx(fw,followBranch(fw,idx2adr(fw,k),1)))];
3019                        print_stubs_min(fw,"some_flag_for_af_scan",base,followBranch(fw,idx2adr(fw,k),1));
3020                        //break;
3021                }
3022        }
3023}
3024
3025//------------------------------------------------------------------------------------------------------------
3026
3027void print_kval(firmware *fw, uint32_t tadr, int tsiz, int tlen, uint32_t ev, const char *name)
3028{
3029        int tidx = adr2idx(fw,tadr);
3030        int k, kval = 0;
3031        for (k=0; k<tlen; k+=tsiz)
3032        {
3033                if (fw->buf[tidx+k+1] == ev)
3034                {
3035                        kval = fw->buf[tidx+k];
3036                        tadr = idx2adr(fw,tidx+k);
3037                        break;
3038                }
3039        }
3040        if (kval > 0)
3041        {
3042                char fn[100], rn[100];
3043                strcpy(fn,name); strcat(fn,"_FLAG");
3044                strcpy(rn,name); strcat(rn,"_IDX");
3045               
3046                int r = (kval >> 5) & 7;
3047                uint32_t b = (1 << (kval & 0x1F));
3048               
3049                bprintf("//#define %-20s0x%08x // Found @0x%08x, levent 0x%x\n",fn,b,tadr,ev);
3050                bprintf("//#define %-20s%d\n",rn,r);
3051        }
3052}
3053
3054typedef struct {
3055        int                     reg;
3056        uint32_t        bits;
3057        char            nm[32];
3058        uint32_t        fadr;
3059        uint32_t        ev;
3060} kinfo;
3061
3062int             kmask[3];
3063kinfo   key_info[100];
3064int             kcount = 0;
3065
3066void add_kinfo(int r, uint32_t b, const char *nm, uint32_t adr, uint32_t ev)
3067{
3068        key_info[kcount].reg = r;
3069        key_info[kcount].bits = b;
3070        strcpy(key_info[kcount].nm, nm);
3071        key_info[kcount].fadr = adr;
3072        key_info[kcount].ev = ev;
3073        kcount++;
3074        kmask[r] |= b;
3075}
3076
3077uint32_t add_kmval(firmware *fw, uint32_t tadr, int tsiz, int tlen, uint32_t ev, const char *name, uint32_t xtra)
3078{
3079        int tidx = adr2idx(fw,tadr);
3080        int r, k, kval = 0;
3081        uint32_t b = 0;
3082        for (k=0; k<tlen; k+=tsiz)
3083        {
3084                if (fw->buf[tidx+k+1] == ev)
3085                {
3086                        kval = fw->buf[tidx+k];
3087                        tadr = idx2adr(fw,tidx+k);
3088                        break;
3089                }
3090        }
3091        if (kval > 0)
3092        {
3093                r = (kval >> 5) & 7;
3094                b = (1 << (kval & 0x1F));
3095               
3096                add_kinfo(r,b|xtra,name,tadr,ev);
3097        }
3098       
3099        return b;
3100}
3101
3102int kinfo_compare(const kinfo *p1, const kinfo *p2)
3103{
3104    if (p1->reg > p2->reg)
3105        {
3106                return 1;
3107    }
3108        else if (p1->reg < p2->reg)
3109        {
3110                return -1;
3111    }
3112    if (p1->bits > p2->bits)
3113        {
3114        return 1;
3115    }
3116        else if (p1->bits < p2->bits)
3117        {
3118        return -1;
3119    }
3120
3121    return 0;
3122}
3123
3124void print_kmvals()
3125{
3126        qsort(key_info, kcount, sizeof(kinfo), (void*)kinfo_compare);
3127       
3128        bprintf("//static KeyMap keymap[] = {\n");
3129       
3130        int k;
3131        for (k=0; k<kcount; k++)
3132        {
3133                bprintf("//    { %d, %-16s,0x%08x }, // Found @0x%08x, levent 0x%02x\n",key_info[k].reg,key_info[k].nm,key_info[k].bits,key_info[k].fadr,key_info[k].ev);
3134        }
3135       
3136        bprintf("//    { 0, 0, 0 }\n//};\n");
3137}
3138
3139void find_key_vals(firmware *fw)
3140{
3141        int k,k1;
3142       
3143        out_hdr = 1;
3144        add_blankline();
3145
3146        // find 'SD_READONLY_FLAG'
3147        uint32_t tadr = 0;
3148        k = get_saved_sig(fw, "GetSDProtect");
3149        if (k >= 0)
3150        {
3151                uint32_t fadr = saved_sigs[k].val;
3152                k = adr2idx(fw,fadr);
3153                if ((fw->buf[k+1] & 0xFF000000) == 0xEA000000)  // B
3154                {
3155                        fadr = followBranch(fw,fadr+4,1);
3156                        k1 = adr2idx(fw,fadr);
3157                        if (isLDR_PC(fw,k1))
3158                        {
3159                                tadr = fw->buf[LDR2idx(fw,k1)];
3160                        }
3161                }
3162        }
3163        if (tadr == 0)
3164        {
3165                k = find_str_ref(fw,"SD Not Exist\n");
3166                if (k >= 0)
3167                {
3168                        for (k1=k-1; k1>k-5; k1--)
3169                        {
3170                                if ((fw->buf[k1] & 0xFF000000) == 0xEB000000)   // BL
3171                                {
3172                                        uint32_t fadr = followBranch(fw,idx2adr(fw,k1),0x01000001);
3173                                        int k2 = adr2idx(fw,fadr);
3174                                        if (isLDR_PC(fw,k2))
3175                                        {
3176                                                tadr = fw->buf[LDR2idx(fw,k2)];
3177                                        }
3178                                }
3179                        }
3180                }
3181        }
3182        if (tadr != 0)
3183        {
3184                int tsiz = 2;
3185                if (fw->buf[adr2idx(fw,tadr)+2] == 0) tsiz = 3;
3186               
3187                uint32_t madr = fw->base + (fw->size*4-4);
3188                for (k=0; k<(tadr-fw->base)/4; k++)
3189                {
3190                        if (isLDR_PC(fw,k))
3191                        {
3192                                uint32_t adr = fw->buf[LDR2idx(fw,k)];
3193                                if ((adr > tadr) && (adr < madr))
3194                                {
3195                                        madr = adr;
3196                                }
3197                        }
3198                }
3199                int tlen = (madr - tadr) / 4;
3200                if (tsiz == 2)
3201                {
3202                        k1 = adr2idx(fw,tadr);
3203                        for (k=0; k<tlen/3; k+=3)
3204                        {
3205                                if ((fw->buf[k1+k+1] == 0xFFFFFFFF) && (fw->buf[k1+k+4] == 0xFFFFFFFF))
3206                                {
3207                                        tsiz = 3;
3208                                        break;
3209                                }
3210                        }
3211                }
3212                if (tlen > 50*tsiz) tlen = 50*tsiz;
3213               
3214                bprintf("// Bitmap masks and physw_status index values for SD_READONLY and USB power flags (for kbd.c).\n");
3215        if (fw->dryos_ver == 49)
3216        {
3217            // Event ID's have changed in DryOS R49 **********
3218                print_kval(fw,tadr,tsiz,tlen,0x20A,"SD_READONLY");
3219                print_kval(fw,tadr,tsiz,tlen,0x202,"USB");
3220        }
3221        else
3222        {
3223                print_kval(fw,tadr,tsiz,tlen,0x90A,"SD_READONLY");
3224                print_kval(fw,tadr,tsiz,tlen,0x902,"USB");
3225        }
3226                               
3227                uint32_t key_half = add_kmval(fw,tadr,tsiz,tlen,0,"KEY_SHOOT_HALF",0);
3228                add_kmval(fw,tadr,tsiz,tlen,1,"KEY_SHOOT_FULL",key_half);
3229                add_kmval(fw,tadr,tsiz,tlen,2,"KEY_ZOOM_IN",0);
3230                add_kmval(fw,tadr,tsiz,tlen,3,"KEY_ZOOM_OUT",0);
3231                add_kmval(fw,tadr,tsiz,tlen,4,"KEY_UP",0);
3232                add_kmval(fw,tadr,tsiz,tlen,5,"KEY_DOWN",0);
3233                add_kmval(fw,tadr,tsiz,tlen,6,"KEY_LEFT",0);
3234                add_kmval(fw,tadr,tsiz,tlen,7,"KEY_RIGHT",0);
3235                add_kmval(fw,tadr,tsiz,tlen,8,"KEY_SET",0);
3236                add_kmval(fw,tadr,tsiz,tlen,9,"KEY_MENU",0);
3237                add_kmval(fw,tadr,tsiz,tlen,0xA,"KEY_DISPLAY",0);
3238                               
3239                bprintf("\n// Keymap values for kbd.c. Additional keys may be present, only common values included here.\n");
3240                print_kmvals();
3241        }
3242}
3243
3244//------------------------------------------------------------------------------------------------------------
3245
3246int main(int argc, char **argv)
3247{
3248    firmware fw;
3249    int k;
3250    int ret = 0;
3251    const char *curr_name;
3252
3253    clock_t t1 = clock();
3254
3255    if (argc != 3)
3256        usage("args");
3257
3258    //load_ignore_list();
3259
3260#ifdef  COMP_OSTUBS
3261    load_stubs();
3262    //print_stubs(stubs);
3263#endif
3264    load_stubs2();
3265    //print_stubs(stubs2);
3266        load_stubs_min();
3267    //print_stubs(stubs_min);
3268        load_modemap();
3269    //print_stubs(modemap);
3270       
3271    bprintf("// !!! THIS FILE IS GENERATED. DO NOT EDIT. !!!\n");
3272    bprintf("#include \"stubs_asm.h\"\n\n");
3273
3274    load_firmware(&fw,argv[1],argv[2]);
3275       
3276    // Find all the valid ranges for checking (skips over large blocks of 0xFFFFFFFF)
3277    findRanges(&fw);
3278
3279#ifdef  COMP_OSTUBS
3280        out_hdr = 1;
3281        bprintf("// Stubs below should be checked. Stub not matched 100%%, or difference\n");
3282        bprintf("// found to current 'stubs_entry_2.S' or original 'stubs_entry.S'\n");
3283        bprintf("//    Name                                     Address      Rule  %%  Comp to stubs_entry_2.S  Comp to stubs_entry.S.orig\n");
3284        out_hdr = 0;
3285        bprintf("// Stubs below matched 100%%.\n");
3286        bprintf("//    Name                                     Address                Comp to stubs_entry_2.S  Comp to stubs_entry.S.orig\n");
3287#else
3288        out_hdr = 1;
3289        bprintf("// Stubs below should be checked. Stub not matched 100%%, or difference found to current 'stubs_entry_2.S'\n");
3290        bprintf("//    Name                                     Address      Rule  %%  Comp to stubs_entry_2.S\n");
3291        out_hdr = 0;
3292        bprintf("// Stubs below matched 100%%.\n");
3293        bprintf("//    Name                                     Address                Comp to stubs_entry_2.S\n");
3294#endif
3295
3296    for (k = 0; func_list[k].name; k++){
3297
3298        count = 0;
3299        curr_name = func_list[k].name;
3300
3301        int ignore = is_in_list(curr_name,ignore_list);
3302
3303        if (!ignore)
3304        {
3305                        k = find_matches(&fw, k);
3306
3307                        if ((fw.dryos_ver >= find_min_ver(curr_name)) && (fw.dryos_ver <= find_max_ver(curr_name)))
3308                                print_results(curr_name);
3309
3310                        if (count == 0)
3311                        {
3312                                ret = 1;
3313                        }
3314        }
3315    }
3316
3317    clock_t t2 = clock();
3318
3319        find_modemap(&fw);
3320        find_stubs_min(&fw);
3321        find_lib_vals(&fw);
3322        find_key_vals(&fw);
3323        find_platform_vals(&fw);
3324
3325    fprintf(stderr,"Time to generate stubs %.2f seconds\n",(double)(t2-t1)/(double)CLOCKS_PER_SEC);
3326       
3327        write_output();
3328       
3329    return ret;
3330}
3331
3332//------------------------------------------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.