Changeset 1168
- Timestamp:
- 05/03/11 04:43:27 (2 years ago)
- File:
-
- 1 edited
-
trunk/tools/finsig.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/tools/finsig.c
r817 r1168 4 4 #include <string.h> 5 5 #include <unistd.h> 6 #include <time.h> 6 7 7 8 #define MAX_MATCHES (64) … … 24 25 } FuncsList; 25 26 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 else 46 { 47 last->next = n; 48 } 49 last = n; 50 } 51 26 52 #if defined(PLATFORMOS_vxworks) 27 #include "signatures_vxworks.h"53 #include "signatures_vxworks.h" 28 54 #elif defined(PLATFORMOS_dryos) 29 #include "signatures_dryos.h"55 #include "signatures_dryos.h" 30 56 #else 31 #error Undefined platform OS57 #error Undefined platform OS 32 58 #endif 33 59 34 60 int match_compare(const Match *p1, const Match *p2) 35 61 { 36 /* NOTE: If a function has *more* matches, it will be prefered, even if it has a lower percent matches */62 /* NOTE: If a function has *more* matches, it will be prefered, even if it has a lower percent matches */ 37 63 if (p1->success > p2->success){ 38 return -1;64 return -1; 39 65 } else 40 if (p1->success < p2->success){41 return 1;42 } else {43 if (p1->fail < p2->fail){44 return -1;45 } else46 if (p1->fail > p2->fail){47 return 1;48 }49 }50 51 /* scores are equal. prefer lower address */52 53 if (p1->ptr < p2->ptr){54 return -1;55 } else56 if (p1->ptr > p2->ptr){57 return 1;58 }59 60 return 0;66 if (p1->success < p2->success){ 67 return 1; 68 } else { 69 if (p1->fail < p2->fail){ 70 return -1; 71 } else 72 if (p1->fail > p2->fail){ 73 return 1; 74 } 75 } 76 77 /* scores are equal. prefer lower address */ 78 79 if (p1->ptr < p2->ptr){ 80 return -1; 81 } else 82 if (p1->ptr > p2->ptr){ 83 return 1; 84 } 85 86 return 0; 61 87 } 62 88 … … 70 96 { 71 97 Match matches[MAX_MATCHES]; 72 uint32_t *buf ;98 uint32_t *buf, *p; 73 99 FILE *f; 74 100 int size; … … 76 102 int fail, success; 77 103 uint32_t base; 78 FuncSig *sig ;104 FuncSig *sig, *s; 79 105 int count; 80 106 int ret = 0; 81 107 const char *curr_name; 108 BufRange *n; 109 110 clock_t t1 = clock(); 82 111 83 112 if (argc != 3) 84 usage();113 usage(); 85 114 86 115 f = fopen(argv[1], "r+b"); 87 116 88 117 if (f == NULL) 89 usage();118 usage(); 90 119 91 120 base = strtoul(argv[2], NULL, 0); … … 98 127 fseek(f,0,SEEK_SET); 99 128 100 buf=malloc(size*4); 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); 101 132 fread(buf, 4, size, f); 102 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 } 158 } 133 fclose(f); 134 memset(&buf[size],0xff,32*4); 135 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 } 164 } 165 // Add range for last valid block 166 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 else 177 { 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 function 217 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 results 224 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); 159 246 160 247 return ret;
Note: See TracChangeset
for help on using the changeset viewer.