#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "DeCSS.h"
#define MaxKeys 1000
typedef struct
{
int occ;
DVD40bitKey key;
} KeyOcc;
void Syntax(void)
{
printf("SYNTAX ERROR: Wrong number of parameters.\n");
printf(" DeCSSplus VOBInputFile [VOBOutputFile] [/p[ause]] [/v{0..9}] [/o[utput]] [/s]\n");
printf(" /p : Pause at the end of execution\n");
printf(" /v : Verbosity level 0..9\n");
printf(" /o : Use VOBInputFile as output if no output file given\n");
printf(" /s : Scan entier file. Default is to stop after having found 20 times the same key.\n\n");
printf(" Please make sure the file is _readable_. Use a DVD-player to\n");
printf(" remove the sector protection\n\n");
}
int main( int argc, char* argv[] ) {
int paramPause = 0;
int paramVerbose = 1;
int paramOutput = 0;
int paramScanAll = 0;
char *paramInputFile = NULL;
char *paramOutputFile = NULL;
FILE *in,*out;
unsigned char buf[0x800];
DVD40bitKey MyKey;
int pos,BytesRead,BytesWritten,BestPLen,BestP,i,j,k,encrypted=0,filsize;
KeyOcc PosKey[MaxKeys];
int RegisteredKeys = 0, TotalKeysFound = 0, StopScanning = 0;
if (paramVerbose>=1)
{
printf(" DeCSSplus v1.0 - Decrypt without knowing the key - (c) 2000 Ethan Hawke\n");
printf("-------------------------------------------------------------------------\n");
}
if (argc<2)
{
Syntax();
if (paramPause)
{
printf("Press ENTER key to continue ...\n");
getchar();
}
return(1);
}
i=1;
while (i<argc)
{
if (strncmp(argv[i],"/",1)==0)
{
if (strncmp(argv[i],"/p",2)==0) paramPause = 1;
else if (strncmp(argv[i],"/v",2)==0) paramVerbose = atoi((argv[i])+2);
else if (strncmp(argv[i],"/s",2)==0) paramScanAll = 1;
else if (strncmp(argv[i],"/o",2)==0) paramOutput = 1;
else
{
Syntax();
if (paramPause)
{
printf("Press ENTER key to continue ...\n");
getchar();
}
return(1);
}
}
else
{
if (!paramInputFile) paramInputFile = argv[i];
else if (!paramOutputFile) { paramOutputFile = argv[i]; paramOutput = 1; }
else
{
Syntax();
if (paramPause)
{
printf("Press ENTER key to continue ...\n");
getchar();
}
return(1);
}
}
i++;
}
if (in = fopen(paramInputFile,"rb"))
{
pos = 0;
fseek(in,0,SEEK_END);
filsize = ftell(in);
fseek(in,0,SEEK_SET);
do
{
if (paramVerbose>=1 && filsize>1024*1024) printf("%.2f of file read & found %i keys...\r",pos*100.0/filsize,TotalKeysFound);
BytesRead = fread(buf,1,0x800,in);
if (buf[0x14] & 0x30) // PES_scrambling_control
{
encrypted = 1;
BestPLen = 0;
BestP = 0;
for(i=2;i<0x30;i++)
{
for(j=i;(j<0x80) && (buf[0x7F-(j%i)]==buf[0x7F-j]);j++);
if ((j>BestPLen) && (j>i))
{
BestPLen = j;
BestP = i;
}
}
if ((BestPLen>20) && (BestPLen/BestP>=2))
{
i = CSScrackerDVD(0,&buf[0x80],&buf[0x80-(BestPLen/BestP)*BestP],(DVD40bitKey*)&buf[0x54],&MyKey);
while (i>=0)
{
k = 0;
for(j=0;j<RegisteredKeys;j++)
if (memcmp(&(PosKey[j].key),&MyKey,sizeof(DVD40bitKey))==0)
{
PosKey[j].occ++;
TotalKeysFound++;
k = 1;
}
if (k==0)
{
memcpy(&(PosKey[RegisteredKeys].key),&MyKey,sizeof(DVD40bitKey));
PosKey[RegisteredKeys++].occ = 1;
TotalKeysFound++;
}
if (paramVerbose>=2) printf("\nOfs:%08X - Key: %02X %02X %02X %02X %02X\n",pos,MyKey[0],MyKey[1],MyKey[2],MyKey[3],MyKey[4]);
i = CSScrackerDVD(i,&buf[0x80],&buf[0x80-(BestPLen/BestP)*BestP],(DVD40bitKey*)&buf[0x54],&MyKey);
}
if (RegisteredKeys==1 && PosKey[0].occ>=20) StopScanning = 1;
}
}
pos += BytesRead;
} while (BytesRead==0x800 && !StopScanning);
fclose(in);
if (paramVerbose>=1 && StopScanning) printf("Found enough occurancies of the same key. Scan stopped.");
if (paramVerbose>=1) printf("\n\n");
}
else
{
printf("FILE ERROR: File could not be opened. [Check if file is readable]\n");
if (paramPause)
{
printf("Press ENTER key to continue ...\n");
getchar();
}
return(1);
}
if (!encrypted)
{
printf("This file was _NOT_ encrypted!\n");
if (paramPause)
{
printf("Press ENTER key to continue ...\n");
getchar();
}
return(0);
}
if (encrypted && RegisteredKeys==0)
{
printf("Sorry... No keys found to this encrypted file.\n");
if (paramPause)
{
printf("Press ENTER key to continue ...\n");
getchar();
}
return(1);
}
for(i=0;i<RegisteredKeys-1;i++)
for(j=i+1;j<RegisteredKeys;j++)
if (PosKey[j].occ>PosKey[i].occ)
{
memcpy(&MyKey,&(PosKey[j].key),sizeof(DVD40bitKey));
k = PosKey[j].occ;
memcpy(&(PosKey[j].key),&(PosKey[i].key),sizeof(DVD40bitKey));
PosKey[j].occ = PosKey[i].occ;
memcpy(&(PosKey[i].key),&MyKey,sizeof(DVD40bitKey));
PosKey[i].occ = k;
}
if (paramVerbose>=1)
{
printf(" Key(s) & key probability\n--------------------------\n");
for(i=0;i<RegisteredKeys;i++)
printf(" %02X %02X %02X %02X %02X - %3.2f%%\n",PosKey[i].key[0],PosKey[i].key[1],PosKey[i].key[2],PosKey[i].key[3],PosKey[i].key[4],PosKey[i].occ*100.0/TotalKeysFound);
printf("\n");
}
if (paramOutput)
{
if (RegisteredKeys>1)
{
printf(" Which stream key do you want to use (ex. 13 47 8A BC EF): ");
if (scanf("%2X %2X %2X %2X %2X",&(MyKey[0]),&(MyKey[1]),&(MyKey[2]),&(MyKey[3]),&(MyKey[4]))!=5)
{
printf("\nNot a valid key.\n");
if (paramPause)
{
printf("Press ENTER key to continue ...\n");
getchar();
}
return(1);
}
if (paramVerbose>=2) printf("Using key %02X %02X %02X %02X %02X\n",MyKey[0],MyKey[1],MyKey[2],MyKey[3],MyKey[4]);
}
else
memcpy(&(MyKey),&(PosKey[0].key),sizeof(DVD40bitKey));
if (paramOutputFile)
{
if (in = fopen(paramInputFile,"rb"))
{
if (out = fopen(paramOutputFile,"wb"))
{
pos = 0;
do
{
if (paramVerbose>=1 && filsize>1024*1024) printf("%.2f of file read/written...\r",pos*100.0/filsize);
BytesRead = fread(&buf,1,0x800,in);
if (buf[0x14] & 0x30) // PES_scrambling_control
{
CSSdescrambleSector(&MyKey,(unsigned char*)&buf);
buf[0x14] &= 0x8F;
}
BytesWritten = fwrite(&buf,1,BytesRead,out);
if (BytesWritten!=BytesRead)
{
printf("Could not write to output file.\n");
if (paramPause)
{
printf("Press ENTER key to continue ...\n");
getchar();
}
return(1);
}
pos += BytesRead;
} while (BytesRead==0x800);
}
else
{
printf("\n File could not be opened for Write.\n");
if (paramPause)
{
printf("Press ENTER key to continue ...\n");
getchar();
}
return(1);
}
}
else
{
printf("\n File could not be opened for Read/Write.\n");
if (paramPause)
{
printf("Press ENTER key to continue ...\n");
getchar();
}
return(1);
}
}
else
{
if (in = fopen(paramInputFile,"r+b"))
{
pos = 0;
do
{
if (paramVerbose>=1 && filsize>1024*1024) printf("%.2f of file read/written...\r",pos*100.0/filsize);
fseek(in,pos,SEEK_SET);
BytesRead = fread(&buf,1,0x800,in);
if (buf[0x14] & 0x30) // PES_scrambling_control
{
CSSdescrambleSector(&MyKey,(unsigned char*)&buf);
buf[0x14] &= 0x8F;
}
fseek(in,pos,SEEK_SET);
fwrite(&buf,1,BytesRead,in);
pos += BytesRead;
} while (BytesRead==0x800);
}
else
{
printf("\n File could not be opened for Read/Write.\n");
if (paramPause)
{
printf("Press ENTER key to continue ...\n");
getchar();
}
return(1);
}
}
}
if (paramPause)
{
printf("Press ENTER key to continue ...\n");
getchar();
}
return(0);
}
TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2025 AOH