// // ICQDecrypt.c // // This code is provided AS IS and is placed // within the public domain. // // This code has been compiled on an Amiga // running SAS/C 6.57, without errors. // No Amiga-specific functions are called, // so it should run on any other system too. // #include #include #include #include void HexDump(UBYTE *data, LONG size) { LONG i; LONG x; BOOL r=TRUE; UBYTE bfr[64]; for(i=0, x=0;;i++) { if(i0x7f) bfr[x]='.'; } else { if(x==0) break; else { printf(" "); bfr[x]=' '; r=FALSE; } } x++; if(!(x<16)) { bfr[x]=0; printf("%s\n", bfr); x=0; if(!r) break; } } } BOOL LoadBlock(FILE *fp, UBYTE *bfr, int len, int *size) { UBYTE *p=bfr; *size=0; while(!feof(fp)) { ULONG b; do { b=fgetc(fp); if(b!=' ' && b!='\t' && b!='\n' && b!='r') break; } while(b!=EOF); if(b==EOF) { return TRUE; } if(b>='0' && b<='9') *p=(b-'0')*0x10; else if(toupper(b)>='A' && toupper(b)<='F') *p=(b-'A'+0x0a)*0x10; else { printf("Invalid character: %c\n", b); return FALSE; } b=fgetc(fp); if(b==EOF) { printf("EOF\n"); return FALSE; } if(b>='0' && b<='9') *p|=b-'0'; else if(toupper(b)>='A' && toupper(b)<='F') *p|=(b-'A'+0x0a)&0x0f; else { printf("Invalid character: %c\n", b); return FALSE; } p++; *size=*size+1; if(*size>len) { printf("Buffer too small. (%ld > %ld)\n", *size, len); return FALSE; } } return TRUE; } UBYTE icq_check_data[256] = { 0x0a, 0x5b, 0x31, 0x5d, 0x20, 0x59, 0x6f, 0x75, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x20, 0x49, 0x43, 0x51, 0x20, 0x6d, 0x61, 0x6b, 0x65, 0x73, 0x2e, 0x20, 0x4a, 0x75, 0x73, 0x74, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x20, 0x22, 0x53, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x22, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x22, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x6d, 0x69, 0x73, 0x63, 0x22, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x43, 0x51, 0x20, 0x6f, 0x72, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x22, 0x53, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x22, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2e, 0x20, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x3a, 0x20, 0x45, 0x72, 0x61, 0x6e, 0x0a, 0x5b, 0x32, 0x5d, 0x20, 0x43, 0x61, 0x6e, 0x27, 0x74, 0x20, 0x72, 0x65, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x77, 0x68, 0x61, 0x74, 0x20, 0x77, 0x61, 0x73, 0x20, 0x73, 0x61, 0x69, 0x64, 0x3f, 0x20, 0x20, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x2d, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x20, 0x6f, 0x6e, 0x20, 0x61, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x67, 0x65, 0x74, 0x20, 0x61, 0x20, 0x64, 0x69, 0x61, 0x6c, 0x6f, 0x67, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x20, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e }; ULONG CheckSum(UBYTE *pkt, ULONG size) { ULONG chk1, chk, ofs; UBYTE check[4]; check[3] = (UBYTE)(pkt[0x10]); check[2] = (UBYTE)(pkt[0x11]); check[1] = (UBYTE)(pkt[0x12]); check[0] = (UBYTE)(pkt[0x13]); chk=*((ULONG *)check); chk1=(*(pkt + 8) << 24) | (*(pkt + 4) << 16) | (*(pkt + 2) << 8 ) | (*(pkt + 6)); chk1^=chk; chk1^=0x00FF00FF; ofs=(chk1>>8) & 0x000000FF; printf("%08lx, %08lx (%ld)\n",icq_check_data[ofs], (chk1 & 0x000000FF), ofs); if(icq_check_data[ofs]==(chk1 & 0x000000FF)) { ofs=(chk1>>24) & 0x000000FF; if((*(pkt+ofs))==((chk1>>16) & 0x000000FF)) { printf("Checksum OK!\n"); return 0; } } printf("Checksum FAILED\n"); return 0; } ULONG ReverseLong(ULONG l) { UBYTE z[4]; z[3] = (UBYTE)((l)>>24)& 0x000000FF; z[2] = (UBYTE)((l)>>16)& 0x000000FF; z[1] = (UBYTE)((l)>>8)& 0x000000FF; z[0] = (UBYTE)(l) & 0x000000FF; return *((ULONG *)z); } ULONG Decrypt(UBYTE *pkt, ULONG size, ULONG key) { int count; int i; count =(size + 3) / 4; count+=3; count/=4; for(i=0;i