All pastes #1734203 Raw Edit

Mine

public c v1 · immutable
#1734203 ·published 2010-01-01 18:10 UTC
rendered paste body
#include <stdio.h>#include <stdlib.h>#include <string.h>//#include <direct.h>#include <signal.h>#include <errno.h>struct pak_header_data{  unsigned char magic[4];  unsigned short flags;  unsigned short unknown1;  unsigned int block_sz;  unsigned int num_entries;};struct pak_entry_data{  unsigned int flags;  int startsector;		// byte offset = startsector * 2048  int filesize;  char ident[4];  unsigned int unknown2;  unsigned int crc;  int unknown4;  int unknown5;  unsigned char namelen;  unsigned char filepath[255];};unsigned char *p_tab1;unsigned char *p_tab2;static unsigned char init_parm[4] = { 0x36, 0x05, 0xbf, 0xce };unsigned char tab1[] = {  0xf8, 0x96, 0x54, 0x41,  0xc7, 0x04, 0xb8, 0x41,  0x7c, 0x5d, 0xbe, 0x07,  0x6b, 0x62, 0x54, 0xc1,};unsigned char tab2[] = {  0x15, 0xa0, 0x38, 0x25,  0x35, 0x1c, 0xad, 0x5b,  0x6d, 0x52, 0x7a, 0x36,  0xa8, 0x17, 0x1d, 0x20,};static struct _codec_parm{  unsigned int seed;  unsigned int variable;} codec_parm;unsigned intget_u32_be (unsigned char *p){  unsigned int ret = 0;  if (p)    {      ret |= p[3];      ret |= p[2] << 8;      ret |= p[1] << 16;      ret |= p[0] << 24;    }  return ret;}unsigned intget_u32_le (unsigned char *p){  return *(unsigned int *) p;}unsigned int (*get_u32) (unsigned char *p);#define SZ_KEYS (sizeof(tab1)/sizeof(unsigned int))unsigned intCal_KEY (unsigned int s_1, unsigned int s_2){  unsigned char i = 0;  for (; i < SZ_KEYS; i++)    {      unsigned int lo, hi, temp, seed = s_2;      temp = seed ^ get_u32 (p_tab1 + (i * 4));      hi = ((temp >> 16) & 0xffff);      lo = ((temp) & 0xffff);      temp = (lo * lo) + ~(hi * hi);      temp = (temp << 16) | (temp >> 16);      s_2 = temp ^ get_u32 (p_tab2 + (i * 4));      s_2 += lo * hi;      s_2 ^= s_1;      s_1 = seed;    }  return s_2;}voidcodec (unsigned char *buff, unsigned int size, struct _codec_parm *p_parm){  unsigned char *p_buff = buff;  unsigned int res, offset = 0;  unsigned char key[4];  struct _codec_parm temp;  temp.seed = ~(p_parm->seed - 1);  temp.variable = p_parm->variable;  while (size > offset)    {      if (!(offset & 3))	{	  res = Cal_KEY (temp.seed, temp.variable);	  key[3] = res;	  key[2] = res >>= 1;	  key[1] = res >>= 1;	  key[0] = res >>= 1;	  temp.variable += 1;	}      *p_buff++ ^= key[offset++ & 3];    };  p_parm->variable = temp.variable;}static unsigned int crc32_table[256];static __inline unsigned intcrc_reflect (unsigned int ref, unsigned int ch){  unsigned int value = 0, i;  for (i = 1; i < (ch + 1); i++)    {      if (ref & 1)	value |= 1 << (ch - i);      ref >>= 1;    }  return value;}voidcrc_init (){#define	  POLY (0x04c11db7)  unsigned int value = 0, i, j;  for (i = 0; i <= 256 - 1; i++)    {      crc32_table[i] = crc_reflect (i, 8) << 24;      for (j = 0; j < 8; j++)	crc32_table[i] =	  (crc32_table[i] << 1) ^ (crc32_table[i] & (1 << 31) ? POLY : 0);      crc32_table[i] = crc_reflect (crc32_table[i], 32);    }}static __inline unsigned intget_crc (unsigned char *p, unsigned int len, unsigned int crc){  while (len--)    crc = (crc >> 8) ^ crc32_table[(crc & 0xFF) ^ *p++];  return ~crc;}voidendian_init (void){  unsigned short endian = 1;  unsigned char *p_e = (unsigned char *) &endian;  if (!*p_e)    get_u32 = get_u32_be;  else    get_u32 = get_u32_le;}unsigned charinit (unsigned int variable){  unsigned char t_tab1[] = {    0xbc, 0x1f, 0x46, 0x64,    0x09, 0x99, 0x82, 0x34,    0xc0, 0x25, 0x4f, 0xe5,    0xb7, 0xdb, 0x26, 0x25,  };  unsigned char t_tab2[] = {    0x35, 0xe0, 0xb8, 0x25,    0x9d, 0x4d, 0x0e, 0x1d,    0xdc, 0x31, 0xbc, 0xbb,    0x78, 0xb6, 0x5e, 0xa7,  };  p_tab1 = t_tab1;  p_tab2 = t_tab2;  codec_parm.seed = 0x6C69746E;  codec_parm.variable = variable;  codec ((unsigned char *) init_parm, sizeof (unsigned int), &codec_parm);  codec (tab1, sizeof (tab1), &codec_parm);  codec (tab2, sizeof (tab2), &codec_parm);  p_tab1 = tab1;  p_tab2 = tab2;  codec_parm.seed = get_u32 (init_parm);  codec_parm.variable = 1;  if (get_crc (tab1, sizeof (tab1), 0 - 1) != 0x5CBE2D0F ||      get_crc (tab2, sizeof (tab2), 0 - 1) != 0x7BA1A34F)    return 0;  else    return 1;}#define _UC(p) ((unsigned char *)p)intmain (int argc, char **argv){  FILE *infp, *outfp;  struct pak_header_data h;  struct pak_entry_data e;  char *f_name = "FILES.PAK";  unsigned int i, crc_f = 0;  if (argc > 2)    {      printf ("Usage: codec_pak file.ext\n");      exit (1);    }  if (argc == 2)    f_name = argv[1];  if (!(infp = fopen (f_name, "rb")))    {      printf ("Error: cannot open %s : %s\n", f_name, strerror (errno), NULL);      exit (1);    }  fread (&h, sizeof (h), 1, infp);  crc_init ();  endian_init ();  if (!init (get_u32 ((unsigned char *) &h.magic)))    goto out;  if (h.flags >> 9)    {      codec ((unsigned char *) &h.unknown1, sizeof (h.unknown1), &codec_parm);      codec ((unsigned char *) &h.block_sz, sizeof (h.block_sz), &codec_parm);      codec ((unsigned char *) &h.num_entries, sizeof (h.num_entries),	     &codec_parm);    }  printf ("HDR: ID:%c%c%c%c, entries:%d\n", h.magic[0], h.magic[1],	  h.magic[2], h.magic[3], get_u32 (_UC (&h.num_entries)));  mkdir ("extracted",0777);  chdir ("extracted");  codec_parm.seed = get_u32 (_UC (&h.num_entries)) + (1 << 31);  codec_parm.variable = 1;#define entry_start(n) (sizeof(struct pak_header_data) + (sizeof(struct pak_entry_data) * n))  for (i = 0; i < get_u32 (_UC (&h.num_entries)); i++)    {      static unsigned char temp[4 * 1024];      unsigned int count, sz, crc;      struct _codec_parm t_parm;      fseek (infp, entry_start (i), SEEK_SET);      if (fread (&e, sizeof (struct pak_entry_data), 1, infp) != 1)	{	  printf ("failed reading file: %s\n", strerror (errno));	  break;	}      if (h.flags >> 8)	codec ((unsigned char *) &e, sizeof (struct pak_entry_data),	       &codec_parm);      printf ("E:%d: ID:%c%c%c%c, filepath:%s, size:%d, ", i + 1, e.ident[0],	      e.ident[1], e.ident[2], e.ident[3], e.filepath,	      get_u32 (_UC (&e.filesize)));      {	char *p_name = (char *) &e.filepath;	int ii = e.namelen - 1;	for (; ii > 0; ii--)	  {	    if ((p_name[ii] == '/') || (p_name[ii] == '\\'))	      {		int iii;		char slash = p_name[ii];		p_name[ii] = '\0';		for (iii = 0; ii > iii; iii++)		  {		    if ((p_name[iii] == '/') || (p_name[iii] == '\\'))		      {			p_name[iii] = '\0';			mkdir (e.filepath,0777);			p_name[iii] = slash;		      }		  }		mkdir (e.filepath,0777);		p_name[ii] = slash;		break;	      }	  }      }      /*       *     temp = (unsigned char *) calloc(1, get_u32(_UC(&e.filesize)));       *         fseek(infp, get_u32(_UC(&e.startsector)) * get_u32(_UC(&h.block_sz)), SEEK_SET);       *             fread(temp, get_u32(_UC(&e.filesize)), 1, infp);       *              */      fseek (infp,	     get_u32 (_UC (&e.startsector)) * get_u32 (_UC (&h.block_sz)),	     SEEK_SET);      if (get_u32 (_UC (&e.flags)) >> 31)	// coded	{	  t_parm.seed =	    get_u32 (_UC (&e.filesize)) + get_u32 (_UC (&e.flags));	  t_parm.variable = 1;	}      if (!(outfp = fopen (e.filepath, "wb")))	{	  printf ("Error: cannot open %s for writing: %s\n", e.filepath,		  strerror (errno));	  continue;	}      crc = 0 - 1;      for (count = get_u32 (_UC (&e.filesize)); count > 0;)	{	  sz =	    count >	    get_u32 (_UC (&h.block_sz)) ? get_u32 (_UC (&h.block_sz)) : count;	  fread (temp, sz, 1, infp);	  if (get_u32 (_UC (&e.flags)) >> 31)	// coded	    codec ((unsigned char *) temp, sz, &t_parm);	  crc = ~get_crc (temp, sz, crc);	  fwrite (temp, sz, 1, outfp);	  count -= sz;	}      fclose (outfp);      printf ("crc32:");      if (get_u32 (_UC (&e.crc)) == ~crc)	printf ("OK\n");      else	printf ("%s %0X != %0X\n", (crc_f++, "FAIL"), get_u32 (_UC (&e.crc)),		crc);    }  printf ("Files OK:%d, FAIL:%d\n", h.num_entries - crc_f, crc_f);out:  fclose (infp);  exit (0);}