./c0de/c/icqdecrypt.txt

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");
}
 

Back