/* Simple program to find matching strings between two binaries and report on the statistics of their lengths, and show the longer ones. Used to defend against copyright infringement claims. */ #include #include #include #include #include #include #include #include #include #define MAX_SIZE 65536 int matches[MAX_SIZE]; int phase_mask[MAX_SIZE+MAX_SIZE]; #define NUM_CHUNKS 12 // Pairs of start, end memory addresses of known exact similarity with the open source Microsoft BASIC unsigned short microsoft_basic_chunks[NUM_CHUNKS * 2] = { 0xAEA8, 0xAEAC, 0xB1A5, 0xB1A9, 0xB248, 0xB24C, 0xB391, 0xB39D, 0xB3A2, 0xB3A5, 0xB849, 0xB97D, 0xB983, 0xBDC1, 0xBDDD, 0xBF51, 0xBF71, 0xBFFF, 0xE000, 0xE08C, 0xE264, 0xE2C2, // Two byte gap here is an optimization 0xE2C5, 0xE37A, }; int main(int argc,char **argv) { int verbose=0; int basic = 0; int high =0; if (argc<3) { fprintf(stderr,"usage: similarity [--verbose] [--basic]\n"); exit(-1); } if (argc >= 4) { for (int i = 3; i < argc; i++) { if (!strcmp(argv[i], "--verbose")) { verbose = 1; } else if (!strcmp(argv[i], "--basic")) { basic = 1; } else if (!strcmp(argv[i], "--high")) { high = 1; } else { fprintf(stderr, "Unrecognised directive.\n"); exit(-1); } } } for(int i=0;i= 0xE000)) { continue; } if (!high) { index1 = addr - 0xA000; index2 = index1; } else { index1 = addr - 0xE000; index2 = addr - 0xA000; } if (f1[index1] != f2[index2]) { printf("BASIC does not match MS BASIC at %X (%X != %X)\n", addr, f1[index1], f2[index2]); } f1[index1] = 0xFF; } } } fprintf(stderr,"Searching files for similarities...\n"); for(int i=0;i %d\n",i,j,phase); exit(-1); } if (phase>=(MAX_SIZE+MAX_SIZE)) { fprintf(stderr,"Phase too large : %04x %04x -> %d\n",i,j,phase); exit(-1); } if (phase_mask[phase]) { phase_mask[phase]--; continue; } for(k=0;((i+k)2) { char similarity_name[MAX_SIZE]; snprintf(similarity_name,MAX_SIZE,"strings/"); int offset=strlen(similarity_name); for(int b=0;b 3) { // Otherwise, the match is unexplained. matches[k]++; // Display particularly long matches printf("$%04X = $%04X :",i,j); for(int b=0;b