Changeset 1169
- Timestamp:
- 05/03/11 06:24:44 (2 years ago)
- File:
-
- 1 edited
-
trunk/tools/finsig.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/tools/finsig.c
r1168 r1169 4 4 #include <string.h> 5 5 #include <unistd.h> 6 #include <time.h>7 6 8 7 #define MAX_MATCHES (64) … … 25 24 } FuncsList; 26 25 27 typedef struct bufrange {28 uint32_t *p;29 int len;30 struct bufrange* next;31 } BufRange;32 33 BufRange *br, *last;34 35 void addBufRange(uint32_t *p, int l)36 {37 BufRange *n = malloc(sizeof(BufRange));38 n->p = p;39 n->len = l;40 n->next = 0;41 if (br == 0)42 {43 br = n;44 }45 else46 {47 last->next = n;48 }49 last = n;50 }51 52 26 #if defined(PLATFORMOS_vxworks) 53 #include "signatures_vxworks.h"27 #include "signatures_vxworks.h" 54 28 #elif defined(PLATFORMOS_dryos) 55 #include "signatures_dryos.h"29 #include "signatures_dryos.h" 56 30 #else 57 #error Undefined platform OS31 #error Undefined platform OS 58 32 #endif 59 33 60 34 int match_compare(const Match *p1, const Match *p2) 61 35 { 62 /* NOTE: If a function has *more* matches, it will be prefered, even if it has a lower percent matches */36 /* NOTE: If a function has *more* matches, it will be prefered, even if it has a lower percent matches */ 63 37 if (p1->success > p2->success){ 64 return -1;38 return -1; 65 39 } else 66 if (p1->success < p2->success){67 return 1;68 } else {69 if (p1->fail < p2->fail){70 return -1;71 } else72 if (p1->fail > p2->fail){73 return 1;74 }75 }40 if (p1->success < p2->success){ 41 return 1; 42 } else { 43 if (p1->fail < p2->fail){ 44 return -1; 45 } else 46 if (p1->fail > p2->fail){ 47 return 1; 48 } 49 } 76 50 77 /* scores are equal. prefer lower address */51 /* scores are equal. prefer lower address */ 78 52 79 if (p1->ptr < p2->ptr){80 return -1;81 } else82 if (p1->ptr > p2->ptr){83 return 1;84 }53 if (p1->ptr < p2->ptr){ 54 return -1; 55 } else 56 if (p1->ptr > p2->ptr){ 57 return 1; 58 } 85 59 86 return 0;60 return 0; 87 61 } 88 62 … … 96 70 { 97 71 Match matches[MAX_MATCHES]; 98 uint32_t *buf , *p;72 uint32_t *buf; 99 73 FILE *f; 100 74 int size; … … 102 76 int fail, success; 103 77 uint32_t base; 104 FuncSig *sig , *s;78 FuncSig *sig; 105 79 int count; 106 80 int ret = 0; 107 81 const char *curr_name; 108 BufRange *n;109 110 clock_t t1 = clock();111 82 112 83 if (argc != 3) 113 usage();84 usage(); 114 85 115 86 f = fopen(argv[1], "r+b"); 116 87 117 88 if (f == NULL) 118 usage();89 usage(); 119 90 120 91 base = strtoul(argv[2], NULL, 0); … … 127 98 fseek(f,0,SEEK_SET); 128 99 129 // Max sig size if 32, add extra space at end of buffer and fill with 0xFFFFFFFF 130 // Allows sig matching past end of firmware without checking each time in the inner loop 131 buf=malloc((size+32)*4); 100 buf=malloc(size*4); 132 101 fread(buf, 4, size, f); 133 fclose(f);134 memset(&buf[size],0xff,32*4);135 102 136 // Find all the valid ranges for checking (skips over large blocks of 0xFFFFFFFF) 137 br = 0; last = 0; 138 k = -1; j = 0; 139 for (i = 0; i < size; i++) 140 { 141 if (buf[i] == 0xFFFFFFFF) // Possible start of block to skip 142 { 143 if (k == -1) // Mark start of possible skip block 144 { 145 k = i; 146 } 147 } 148 else // Found end of block ? 149 { 150 if (k != -1) 151 { 152 if (i - k > 32) // If block more than 32 words then we want to skip it 153 { 154 if (k - j > 8) 155 { 156 // Add a range record for the previous valid range (ignore short ranges) 157 addBufRange(&buf[j],k - j); 158 } 159 j = i; // Reset valid range start to current position 160 } 161 k = -1; // Reset marker for skip block 162 } 163 } 103 for (k=0;func_list[k].name;k++){ 104 105 count = 0; 106 curr_name = func_list[k].name; 107 108 while (1) { 109 sig = func_list[k].sig; 110 111 for (i=0;i<size;i++){ 112 fail = 0; 113 success = 0; 114 for (j=0;sig[j].offs!=-1;j++){ 115 if ((i+sig[j].offs) >= size || (buf[i+sig[j].offs] & sig[j].mask) != sig[j].value){ 116 fail++; 117 } else { 118 success++; 119 } 120 } 121 if (success > fail){ 122 matches[count].ptr = base+i*4; 123 matches[count].success = success; 124 matches[count].fail = fail; 125 count ++; 126 if (count >= MAX_MATCHES){ 127 printf("// WARNING: too many matches for %s!\n", func_list[k].name); 128 break; 129 } 130 } 131 } 132 133 // same name, so we have another version of the same function 134 if ((func_list[k+1].name == NULL) || (strcmp(curr_name, func_list[k+1].name) != 0)) { 135 break; 136 } 137 k++; 138 } 139 140 // find best match and report results 141 if (count == 0){ 142 printf("// ERROR: %s is not found!\n", curr_name); 143 ret = 1; 144 } else { 145 if (count > 1){ 146 qsort(matches, count, sizeof(Match), (void*)match_compare); 147 } 148 149 if (matches->fail > 0) 150 printf("// Best match: %d%%\n", matches->success*100/(matches->success+matches->fail)); 151 152 printf("NSTUB(%s, 0x%x)\n", curr_name, matches->ptr); 153 154 for (i=1;i<count && matches[i].fail==matches[0].fail;i++){ 155 printf("// ALT: NSTUB(%s, 0x%x) // %d/%d\n", curr_name, matches[i].ptr, matches[i].success, matches[i].fail); 156 } 157 } 164 158 } 165 // Add range for last valid block166 if (k != -1)167 {168 if (i - k > 32)169 {170 if (k - j > 8)171 {172 addBufRange(&buf[j],k - j);173 }174 }175 }176 else177 {178 if (i - j > 8)179 {180 addBufRange(&buf[j], i - j);181 }182 }183 184 for (k = 0; func_list[k].name; k++){185 186 count = 0;187 curr_name = func_list[k].name;188 189 while (1) {190 sig = func_list[k].sig;191 192 for (n = br; n != 0; n = n->next){193 for (p = n->p, i = 0; i < n->len; p++, i++){194 fail = 0;195 success = 0;196 for (s = sig; s->offs != -1; s++){197 if ((p[s->offs] & s->mask) != s->value){198 fail++;199 } else {200 success++;201 }202 }203 if (success > fail){204 matches[count].ptr = base+(i<<2);205 matches[count].success = success;206 matches[count].fail = fail;207 count ++;208 if (count >= MAX_MATCHES){209 printf("// WARNING: too many matches for %s!\n", func_list[k].name);210 break;211 }212 }213 }214 }215 216 // same name, so we have another version of the same function217 if ((func_list[k+1].name == NULL) || (strcmp(curr_name, func_list[k+1].name) != 0)) {218 break;219 }220 k++;221 }222 223 // find best match and report results224 if (count == 0){225 printf("// ERROR: %s is not found!\n", curr_name);226 ret = 1;227 } else {228 if (count > 1){229 qsort(matches, count, sizeof(Match), (void*)match_compare);230 }231 232 if (matches->fail > 0)233 printf("// Best match: %d%%\n", matches->success*100/(matches->success+matches->fail));234 235 printf("NSTUB(%s, 0x%x)\n", curr_name, matches->ptr);236 237 for (i=1;i<count && matches[i].fail==matches[0].fail;i++){238 printf("// ALT: NSTUB(%s, 0x%x) // %d/%d\n", curr_name, matches[i].ptr, matches[i].success, matches[i].fail);239 }240 }241 }242 243 clock_t t2 = clock();244 245 fprintf(stderr,"Time to generate stubs %.2f seconds\n",(double)(t2-t1)/(double)CLOCKS_PER_SEC);246 159 247 160 return ret;
Note: See TracChangeset
for help on using the changeset viewer.