Ignore:
Timestamp:
02/04/12 00:00:20 (2 years ago)
Author:
philmoz
Message:

Update for finsig_dryos:

  • try and find details for vid_get_viewport_fb_d() function and nrflag variable
  • add error handling to prevent crash if incorrect start address used.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/release-1_0/tools/finsig_dryos.c

    r1530 r1635  
    518518        char            cam[100]; 
    519519} firmware; 
     520 
     521uint32_t fwval(firmware *fw, int i) 
     522{ 
     523    if ((i >= 0) && (i < fw->size)) 
     524        return fw->buf[i]; 
     525    fprintf(stderr,"Invalid firmware offset %d.\n",i); 
     526    bprintf("\nInvalid firmware offset %d. Possible corrupt firmware or incorrect start address.\n",i); 
     527    write_output(); 
     528    exit(1); 
     529} 
    520530 
    521531void addBufRange(firmware *fw, int o, int l) 
     
    617627uint32_t ptr2idx(firmware *fw, int idx) 
    618628{ 
    619     return (fw->buf[idx] - fw->base) >> 2; 
     629    return (fwval(fw,idx) - fw->base) >> 2; 
    620630} 
    621631 
     
    626636                uint32_t msk = ~(offset & 0xFF000000); 
    627637        fidx += ((offset & 0x00FFFFFF) - 1); 
    628         uint32_t inst = fw->buf[fidx]; 
     638        uint32_t inst = fwval(fw,fidx); 
    629639        if ((inst & (0xFF000000&msk)) == (0xEA000000&msk))    // Branch (B or BL depending on msk) 
    630640        { 
     
    644654        uint32_t fidx = adr2idx(fw,fadr);  // function index 
    645655        fidx += ((offset & 0x00FFFFFF) - 1); 
    646         uint32_t inst = fw->buf[fidx]; 
     656        uint32_t inst = fwval(fw,fidx); 
    647657        if ((inst & (0xFF000000&msk)) == (0xEA000000&msk))    // Branch (B or BL depending on msk) 
    648658        { 
     
    665675uint32_t ADR2adr(firmware *fw, int offset)  // decode ADR instruction at offset and return firmware address pointed to 
    666676{ 
    667     uint32_t inst = fw->buf[offset]; 
     677    uint32_t inst = fwval(fw,offset); 
    668678    int rot = 32 - ((inst & 0xF00) >> 7); 
    669679    int offst = (inst & 0xFF) <<rot; 
     
    689699uint32_t ALUop2(firmware *fw, int offset)  // decode operand2 from ALU inst (not complete!) 
    690700{ 
    691     uint32_t inst = fw->buf[offset]; 
     701    uint32_t inst = fwval(fw,offset); 
    692702    int rot = 32 - ((inst & 0xF00) >> 7); 
    693703    int offst = (inst & 0xFF) <<rot; 
     
    707717uint32_t LDR2adr(firmware *fw, int offset)  // decode LDR instruction at offset and return firmware address pointed to 
    708718{ 
    709     uint32_t inst = fw->buf[offset]; 
     719    uint32_t inst = fwval(fw,offset); 
    710720    int offst = (inst & 0xFFF); 
    711721    uint32_t fadr = (inst & 0x00800000)?idx2adr(fw,offset+2)+offst:idx2adr(fw,offset+2)-offst; 
     
    720730uint32_t LDR2val(firmware *fw, int offset)  // decode LDR instruction at offset and return firmware value stored at the address 
    721731{ 
    722         return fw->buf[adr2idx(fw,LDR2adr(fw,offset))]; 
     732        return fwval(fw,adr2idx(fw,LDR2adr(fw,offset))); 
    723733} 
    724734 
    725735int isLDR_PC(firmware *fw, int offset) 
    726736{ 
    727         return ((fw->buf[offset] & 0xFE1F0000) == 0xE41F0000); 
     737        return ((fwval(fw,offset) & 0xFE1F0000) == 0xE41F0000); 
    728738} 
    729739 
    730740int isLDR_PC_cond(firmware *fw, int offset) 
    731741{ 
    732         return ((fw->buf[offset] & 0x0E1F0000) == 0x041F0000); 
     742        return ((fwval(fw,offset) & 0x0E1F0000) == 0x041F0000); 
    733743} 
    734744 
    735745int isADR_PC(firmware *fw, int offset) 
    736746{ 
    737         return ((fw->buf[offset] & 0xFE0F0000) == 0xE20F0000); 
     747        return ((fwval(fw,offset) & 0xFE0F0000) == 0xE20F0000); 
     748} 
     749 
     750int isADR_PC_cond(firmware *fw, int offset) 
     751{ 
     752        return ((fwval(fw,offset) & 0x0E0F0000) == 0x020F0000); 
    738753} 
    739754 
    740755int isSTR_PC(firmware *fw, int offset) 
    741756{ 
    742         return ((fw->buf[offset] & 0xFE1F0000) == 0xE40F0000); 
     757        return ((fwval(fw,offset) & 0xFE1F0000) == 0xE40F0000); 
    743758} 
    744759 
    745760int isLDR(firmware *fw, int offset) 
    746761{ 
    747         return ((fw->buf[offset] & 0xFE100000) == 0xE4100000); 
     762        return ((fwval(fw,offset) & 0xFE100000) == 0xE4100000); 
    748763} 
    749764 
    750765int isSTR(firmware *fw, int offset) 
    751766{ 
    752         return ((fw->buf[offset] & 0xFE100000) == 0xE4000000); 
     767        return ((fwval(fw,offset) & 0xFE100000) == 0xE4000000); 
    753768} 
    754769 
    755770int isBL(firmware *fw, int offset) 
    756771{ 
    757         return ((fw->buf[offset] & 0xFF000000) == 0xEB000000);  // BL 
     772        return ((fwval(fw,offset) & 0xFF000000) == 0xEB000000); // BL 
    758773} 
    759774 
    760775int isB(firmware *fw, int offset) 
    761776{ 
    762         return ((fw->buf[offset] & 0xFF000000) == 0xEA000000);  // B 
     777        return ((fwval(fw,offset) & 0xFF000000) == 0xEA000000); // B 
    763778} 
    764779 
     
    978993        { "ResetZoomLens", 0 }, 
    979994        { "ResetFocusLens", 0 }, 
     995        { "NR_GetDarkSubType", 0 }, 
    980996         
    981997        { 0, 0 } 
     
    11011117    { "ResetZoomLens", 0, 0 }, 
    11021118    { "ResetFocusLens", 0, 0 }, 
     1119    { "NR_GetDarkSubType", 0, 0 }, 
    11031120    { 0, 0, 0} 
    11041121}; 
     
    11921209    { 2, "ResetZoomLens", "ResetZoomLens", 1 }, 
    11931210    { 2, "ResetFocusLens", "ResetFocusLens", 1 }, 
     1211    { 2, "NR_GetDarkSubType", "NR_GetDarkSubType", 1 }, 
     1212    { 2, "NR_GetDarkSubType", "NRTBL.GetDarkSubType", 1 }, 
    11941213         
    11951214        { 3, "AllocateMemory", "AllocateMemory", 1 }, 
     
    13521371    "ResetZoomLens", 
    13531372    "ResetFocusLens", 
     1373    "NR_GetDarkSubType", 
    13541374        0 
    13551375}; 
     
    24622482                for (k=0; k<fw->size; k++) 
    24632483                { 
    2464                         if (((fw->buf[k] & 0x0E0F0000) == 0x020F0000) && // ADR ? 
    2465                                 (ADR2adr(fw,k) == sadr)) 
     2484                        if (isADR_PC_cond(fw,k) && (ADR2adr(fw,k) == sadr)) 
    24662485                        { 
    24672486                                return k; 
    24682487                        } 
     2488            else if (isLDR_PC_cond(fw,k) && (LDR2val(fw,k) == sadr)) 
     2489            { 
     2490                return k; 
     2491            } 
     2492                } 
     2493        } 
     2494        return -1; 
     2495} 
     2496 
     2497int find_nxt_str_ref(firmware *fw, int str_adr, int ofst) 
     2498{ 
     2499        if (str_adr >= 0) 
     2500        { 
     2501        int k; 
     2502                uint32_t sadr = idx2adr(fw,str_adr);            // string address 
     2503                for (k=ofst+1; k<fw->size; k++) 
     2504                { 
     2505                        if (isADR_PC_cond(fw,k) && (ADR2adr(fw,k) == sadr)) 
     2506                        { 
     2507                                return k; 
     2508                        } 
     2509            else if (isLDR_PC_cond(fw,k) && (LDR2val(fw,k) == sadr)) 
     2510            { 
     2511                return k; 
     2512            } 
    24692513                } 
    24702514        } 
     
    27772821                        { 
    27782822                                uint32_t v1 = LDR2val(fw,k); 
    2779                                 bprintf("//void *vid_get_bitmap_fb()        { return (void*)0x%08x; } // Found @0x%08x\n",v1,idx2adr(fw,k)); 
     2823                                bprintf("//void *vid_get_bitmap_fb()        { return (void*)0x%08x; }             // Found @0x%08x\n",v1,idx2adr(fw,k)); 
    27802824                                break; 
    27812825                        } 
     
    27852829                        { 
    27862830                                uint32_t v1 = LDR2val(fw,k+1); 
    2787                                 bprintf("//void *vid_get_bitmap_fb()        { return (void*)0x%08x; } // Found @0x%08x\n",v1,idx2adr(fw,k)); 
     2831                                bprintf("//void *vid_get_bitmap_fb()        { return (void*)0x%08x; }             // Found @0x%08x\n",v1,idx2adr(fw,k)); 
    27882832                                break; 
    27892833                        } 
     
    28022846                                uint32_t v2 = LDR2val(fw,k1+1); 
    28032847                                if (v2 > v1) v1 = v2; 
    2804                                 bprintf("//void *vid_get_viewport_fb()      { return (void*)0x%08x; } // Found @0x%08x\n",v1,idx2adr(fw,k1)); 
    2805                         } 
    2806                 } 
     2848                                bprintf("//void *vid_get_viewport_fb()      { return (void*)0x%08x; }             // Found @0x%08x\n",v1,idx2adr(fw,k1)); 
     2849                        } 
     2850                } 
     2851        } 
     2852         
     2853        // find 'vid_get_viewport_fb_d' 
     2854    static int fbd[3][3] = 
     2855    { 
     2856        { -2, -3,  1 }, 
     2857        {  1,  3,  4 }, 
     2858        { -1, -2,  1 }, 
     2859    }; 
     2860    int sadr = find_str(fw, "ImagePlayer.c"); 
     2861        k = find_nxt_str_ref(fw, sadr, -1); 
     2862    int found = 0; 
     2863        while ((k >= 0) && !found) 
     2864        { 
     2865        int f; 
     2866        for (f=0; f<3 && !found; f++) 
     2867        { 
     2868                    if (isLDR(fw,k+fbd[f][0]) && isLDR(fw,k+fbd[f][1]) && isLDR(fw,k+fbd[f][2])) 
     2869                    { 
     2870                int reg = fw->buf[k+fbd[f][2]] & 0x000F0000;    // Index register used 
     2871                int ka = 0; 
     2872                if (((fw->buf[k+fbd[f][0]] & 0x0000F000) << 4) == reg)      { ka = k+fbd[f][0]; } 
     2873                else if (((fw->buf[k+fbd[f][1]] & 0x0000F000) << 4) == reg) { ka = k+fbd[f][1]; } 
     2874                if (ka > 0) 
     2875                { 
     2876                    uint32_t adr = LDR2val(fw,ka); 
     2877                    for (k1=k+2; k1<k+20; k1++) 
     2878                    { 
     2879                        if (isSTR(fw,k1) && ((fw->buf[k1] & 0x000F0000) == reg)) 
     2880                        { 
     2881                            uint32_t ofst = fw->buf[k1] & 0x00000FFF; 
     2882                                    bprintf("//void *vid_get_viewport_fb_d()    { return (void*)(*(int*)(0x%04x+0x%02x)); } // Found @0x%08x & 0x%08x\n",adr,ofst,idx2adr(fw,ka),idx2adr(fw,k1)); 
     2883                            found = 1; 
     2884                            break; 
     2885                        } 
     2886                    } 
     2887                } 
     2888                    } 
     2889        } 
     2890        k = find_nxt_str_ref(fw, sadr, k); 
    28072891        } 
    28082892         
     
    28142898                { 
    28152899                        uint32_t v1 = LDR2val(fw,k-1); 
    2816                         bprintf("//char *camera_jpeg_count_str()    { return (char*)0x%08x; } // Found @0x%08x\n",v1,idx2adr(fw,k-1)); 
     2900                        bprintf("//char *camera_jpeg_count_str()    { return (char*)0x%08x; }             // Found @0x%08x\n",v1,idx2adr(fw,k-1)); 
    28172901                } 
    28182902        } 
     
    28252909                { 
    28262910                        craw_bufsize = LDR2val(fw,k-1); 
    2827                         bprintf("//long hook_raw_size()             { return 0x%08x; }        // Found @0x%08x\n",craw_bufsize,idx2adr(fw,k-1)); 
     2911                        bprintf("//long hook_raw_size()             { return 0x%08x; }                    // Found @0x%08x\n",craw_bufsize,idx2adr(fw,k-1)); 
    28282912                } 
    28292913        } 
     
    28432927                                if (((fw->buf[k+1] & 0xFFF00000) == 0xE3500000) && ((fw->buf[k+1] & 0x000F0000) == r))  // CMP, Rn #val 
    28442928                                { 
    2845                                         bprintf("//int get_flash_params_count(void) { return 0x%02x; }              // Found @0x%08x\n",fw->buf[k+1]&0xFFF,idx2adr(fw,k+1)); 
     2929                                        bprintf("//int get_flash_params_count(void) { return 0x%02x; }                          // Found @0x%08x\n",fw->buf[k+1]&0xFFF,idx2adr(fw,k+1)); 
    28462930                                        break; 
    28472931                                } 
     
    33193403//------------------------------------------------------------------------------------------------------------ 
    33203404 
    3321 // Search for things that go in 'stubs_min.S' 
     3405// Search for things 
    33223406void find_other_vals(firmware *fw) 
    33233407{ 
     
    33533437    { 
    33543438        bprintf("//DEF(ctypes, *** Not Found ***)\n"); 
     3439    } 
     3440 
     3441    // Look for nrflag (for capt_seq.c) 
     3442    int k, k1, k2, k3, k4, idx, ofst1, ofst2; 
     3443        k = get_saved_sig(fw, "NR_GetDarkSubType"); 
     3444        if (k >= 0) 
     3445        { 
     3446                uint32_t fadr = saved_sigs[k].val; 
     3447                idx = adr2idx(fw, fadr); 
     3448 
     3449        // Found NR_GetDarkSubType function, now follow first BL call. 
     3450        k1 = 0; 
     3451        for (k=idx; k<idx+20; k++) 
     3452        { 
     3453            if (isBL(fw,k)) 
     3454            { 
     3455                k1 = idxFollowBranch(fw,k,0x01000001); 
     3456                break; 
     3457            } 
     3458        } 
     3459 
     3460        if (k1 > 0) 
     3461        { 
     3462            int found = 0; 
     3463            // Found function called from NR_GetDarkSubType 
     3464            // Check if old version - see what value passed in R3 
     3465            for (k2=0; k2<fw->size && !found; k2++) 
     3466            { 
     3467                if (isBL(fw,k2) && (idxFollowBranch(fw,k2,0x01000001) == k1)) 
     3468                { 
     3469                    // Found call to function, work out R3 value passed in 
     3470                    ofst1 = 0; 
     3471                    k4 = 0; 
     3472                    for (k3=k2; k3>k2-30 && !found; k3--) 
     3473                    { 
     3474                        if ((fw->buf[k3] & 0x0F0FF000) == 0x020D3000)       // Dest = R3, Src = SP = skip 
     3475                            break; 
     3476                        if ((fw->buf[k3] & 0xFF0FF000) == 0xE2033000)       // ADD/SUB R3,R3,x 
     3477                        { 
     3478                            k4 = k3; 
     3479                            if ((fw->buf[k3] & 0x00F00000) == 0x00400000)   // SUB 
     3480                                ofst1 -= (fw->buf[k3] & 0x00000FFF); 
     3481                            else 
     3482                                ofst1 += (fw->buf[k3] & 0x00000FFF); 
     3483                        } 
     3484                        if (isLDR_PC(fw,k3) && ((fw->buf[k3] & 0x0000F000) == 0x00003000)) 
     3485                        { 
     3486                            ofst2 = LDR2val(fw,k3); 
     3487                            bprintf("\n// For capt_seq.c\n"); 
     3488                            if (ofst1 == 0) 
     3489                                bprintf("//static long *nrflag = (long*)(0x%04x);       // Found @ %08x\n",ofst2,idx2adr(fw,k3)); 
     3490                            else if (ofst1 < 0) 
     3491                                bprintf("//static long *nrflag = (long*)(0x%04x-0x%02x);  // Found @ %08x & %08x\n",ofst2,-ofst1,idx2adr(fw,k3),idx2adr(fw,k4)); 
     3492                            else 
     3493                                bprintf("//static long *nrflag = (long*)(0x%04x+0x%02x);  // Found @ %08x & %08x\n",ofst2,ofst1,idx2adr(fw,k3),idx2adr(fw,k4)); 
     3494                            found = 1; 
     3495                            break; 
     3496                        } 
     3497                    } 
     3498                } 
     3499            } 
     3500 
     3501            // Try for new version, find address inside function 
     3502            static int fx[2][5] = 
     3503            { 
     3504                {  0, 1, 2, 3, 4 }, 
     3505                {  0, 1, 3, 4, 5 }, 
     3506            }; 
     3507                for (k=k1; k<k1+200 && !found; k++) 
     3508            { 
     3509                if ((fw->buf[k] & 0xFFFF0FFF) == 0x13E00000)    // MOVNE Rx, 0xFFFFFFFF 
     3510                { 
     3511                    for (k2=k-5; k2>k-16 && !found; k2--) 
     3512                    { 
     3513                        int f; 
     3514                        for (f=0; f<2; f++) 
     3515                        { 
     3516                            if (isLDR(fw,k2+fx[f][0]) &&                                   // LDR  
     3517                                ((fw->buf[k2+fx[f][1]] & 0xFFF0FFFF) == 0xE3500000) &&     // CMP Rx, #0 
     3518                                ((fw->buf[k2+fx[f][2]] & 0xFFF00000) == 0x15800000) &&     // STRNE 
     3519                                isLDR(fw,k2+fx[f][3]) &&                                   // LDR 
     3520                                ((fw->buf[k2+fx[f][4]] & 0xFFF0FFFF) == 0xE3500000))       // CMP Rx, #0 
     3521                            { 
     3522                                ofst1 = fw->buf[k2+fx[f][0]] & 0x00000FFF; 
     3523                                ofst2 = fw->buf[k2+fx[f][3]] & 0x00000FFF; 
     3524                                int reg1 = fw->buf[k2+fx[f][0]] & 0x000F0000; 
     3525                                int reg2 = fw->buf[k2+fx[f][3]] & 0x000F0000; 
     3526                                if ((reg1 == reg2) && (ofst1 == ofst2 - 4)) 
     3527                                { 
     3528                                    reg1 = reg1 >> 4; 
     3529                                    for (k3=k2; k3>k2-50 && !found; k3--) 
     3530                                    { 
     3531                                        if (isLDR_PC(fw,k3) && ((fw->buf[k3] & 0x0000F000) == reg1)) 
     3532                                        { 
     3533                                            ofst2 = LDR2val(fw,k3); 
     3534                                            bprintf("\n// For capt_seq.c\n"); 
     3535                                            bprintf("//static long *nrflag = (long*)(0x%04x+0x%02x);  // Found @ %08x & %08x\n",ofst2,ofst1,idx2adr(fw,k3),idx2adr(fw,k2)); 
     3536                                            bprintf("//#define NR_AUTO (0)                          // have to explictly reset value back to 0 to enable auto\n"); 
     3537                                            found = 1; 
     3538                                            break; 
     3539                                        } 
     3540                                    } 
     3541                                } 
     3542                            } 
     3543                        } 
     3544                    } 
     3545                } 
     3546            } 
     3547        } 
    33553548    } 
    33563549} 
Note: See TracChangeset for help on using the changeset viewer.