| 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197. 198. 199. 200. 201. 202. 203. 204. 205. 206. 207. 208. 209. 210. 211. 212. 213. 214. 215. 216. 217. 218. 219. 220. 221. 222. 223. 224. 225. 226. 227. 228. 229. 230. 231. 232. 233. 234. 235. 236. 237. 238. 239. 240. 241. 242. 243. 244. 245. 246. 247. 248. 249. 250. 251. 252. 253. 254. 255. 256. 257. 258. 259. 260. 261. 262. 263. 264. 265. | //
// 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 <exec/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
void HexDump(UBYTE *data, LONG size)
{
LONG i;
LONG x;
BOOL r=TRUE;
UBYTE bfr[64];
for(i=0, x=0;;i++) {
if(i<size) {
if(x==0) printf("%04lx: ", i);
printf("%02x ", data[i]);
bfr[x]=data[i];
if(bfr[x]<0x20) bfr[x]='.';
if(bfr[x]>0x7f) 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<count;i++) {
ULONG *r;
if(i!=4) { // checksum is not encrypted
r=(ULONG *)(pkt + (i*4));
*r^=ReverseLong((key + icq_check_data[i*4]));
}
}
pkt[0]=0x04;
pkt[1]=0x00;
}
ULONG GetKey(char *bfr, ULONG size)
{
ULONG key;
UBYTE check[4];
check[3] = (UBYTE)(bfr[0x10]);
check[2] = (UBYTE)(bfr[0x11]);
check[1] = (UBYTE)(bfr[0x12]);
check[0] = (UBYTE)(bfr[0x13]);
printf("Check: %lx\n", *((ULONG *)check));
key=0x66756B65 * size;
key+=*((ULONG *)check);
return key;
}
void main(int ac, char *av[])
{
FILE *fp;
if(ac!=2) {
printf("Argument missing\n");
exit(0);
}
fp=fopen(av[1], "r");
if(fp) {
UBYTE bfr[512];
int size;
ULONG key;
if(LoadBlock(fp, bfr, 512, &size)) {
printf("Loaded packet:\n");
HexDump(bfr, size);
key=GetKey(bfr, size);
printf("Key: %08lx\n", key);
Decrypt(bfr, size, key);
printf("Decrypted packet:\n");
HexDump(bfr, size);
CheckSum(bfr, size);
} else printf("Error interpreting file. (%ld)\n", size);
fclose(fp);
} else printf("Could not open file\n");
}
|