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