/* * Copyright (C) 2000 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include #include static unsigned char _reverse[0x100]; static unsigned char _table[0x100] = { 0x33, 0x73, 0x3B, 0x26, 0x63, 0x23, 0x6B, 0x76, 0x3E, 0x7E, 0x36, 0x2B, 0x6E, 0x2E, 0x66, 0x7B, 0xD3, 0x93, 0xDB, 0x06, 0x43, 0x03, 0x4B, 0x96, 0xDE, 0x9E, 0xD6, 0x0B, 0x4E, 0x0E, 0x46, 0x9B, 0x57, 0x17, 0x5F, 0x82, 0xC7, 0x87, 0xCF, 0x12, 0x5A, 0x1A, 0x52, 0x8F, 0xCA, 0x8A, 0xC2, 0x1F, 0xD9, 0x99, 0xD1, 0x00, 0x49, 0x09, 0x41, 0x90, 0xD8, 0x98, 0xD0, 0x01, 0x48, 0x08, 0x40, 0x91, 0x3D, 0x7D, 0x35, 0x24, 0x6D, 0x2D, 0x65, 0x74, 0x3C, 0x7C, 0x34, 0x25, 0x6C, 0x2C, 0x64, 0x75, 0xDD, 0x9D, 0xD5, 0x04, 0x4D, 0x0D, 0x45, 0x94, 0xDC, 0x9C, 0xD4, 0x05, 0x4C, 0x0C, 0x44, 0x95, 0x59, 0x19, 0x51, 0x80, 0xC9, 0x89, 0xC1, 0x10, 0x58, 0x18, 0x50, 0x81, 0xC8, 0x88, 0xC0, 0x11, 0xD7, 0x97, 0xDF, 0x02, 0x47, 0x07, 0x4F, 0x92, 0xDA, 0x9A, 0xD2, 0x0F, 0x4A, 0x0A, 0x42, 0x9F, 0x53, 0x13, 0x5B, 0x86, 0xC3, 0x83, 0xCB, 0x16, 0x5E, 0x1E, 0x56, 0x8B, 0xCE, 0x8E, 0xC6, 0x1B, 0xB3, 0xF3, 0xBB, 0xA6, 0xE3, 0xA3, 0xEB, 0xF6, 0xBE, 0xFE, 0xB6, 0xAB, 0xEE, 0xAE, 0xE6, 0xFB, 0x37, 0x77, 0x3F, 0x22, 0x67, 0x27, 0x6F, 0x72, 0x3A, 0x7A, 0x32, 0x2F, 0x6A, 0x2A, 0x62, 0x7F, 0xB9, 0xF9, 0xB1, 0xA0, 0xE9, 0xA9, 0xE1, 0xF0, 0xB8, 0xF8, 0xB0, 0xA1, 0xE8, 0xA8, 0xE0, 0xF1, 0x5D, 0x1D, 0x55, 0x84, 0xCD, 0x8D, 0xC5, 0x14, 0x5C, 0x1C, 0x54, 0x85, 0xCC, 0x8C, 0xC4, 0x15, 0xBD, 0xFD, 0xB5, 0xA4, 0xED, 0xAD, 0xE5, 0xF4, 0xBC, 0xFC, 0xB4, 0xA5, 0xEC, 0xAC, 0xE4, 0xF5, 0x39, 0x79, 0x31, 0x20, 0x69, 0x29, 0x61, 0x70, 0x38, 0x78, 0x30, 0x21, 0x68, 0x28, 0x60, 0x71, 0xB7, 0xF7, 0xBF, 0xA2, 0xE7, 0xA7, 0xEF, 0xF2, 0xBA, 0xFA, 0xB2, 0xAF, 0xEA, 0xAA, 0xE2, 0xFF, }; //---------------------------------------------------------------------------------------------------------- inline void _ClockLfsr0Forward(int &lfsr0) { int temp; temp = (lfsr0 << 3) | (lfsr0>> 14); lfsr0 = (lfsr0>> 8) | ((((((temp << 3) ^ temp) << 3) ^ temp ^ lfsr0) & 0xFF) << 9); } inline void _ClockLfsr1Forward(int &lfsr1) { lfsr1 = (lfsr1>> 8) | ((((((((lfsr1>> 8) ^ lfsr1)>> 1) ^ lfsr1)>> 3) ^ lfsr1) & 0xFF) << 17); } inline void _ClockBackward(int &lfsr0, int &lfsr1) { int temp0, temp1; lfsr0 = ((lfsr0 << 8) ^ ((((lfsr0>> 3) ^ lfsr0)>> 6) & 0xFF)) & ((1 << 17) - 1); temp0 = ((lfsr1>> 17) ^ (lfsr1>> 4)) & 0xFF; temp1 = (lfsr1 << 5) | (temp0>> 3); temp1 = ((temp1>> 1) ^ temp1) & 0xFF; lfsr1 = ((lfsr1 << 8) | ((((((temp1>> 2) ^ temp1)>> 1) ^ temp1)>> 3) ^ temp1 ^ temp0)) & ((1 << 25) - 1); } static void _Salt(int &lfsr0, int &lfsr1, const unsigned char salt[5]) { lfsr0 ^= (_reverse[salt[0]] << 9) | _reverse[salt[1]]; lfsr1 ^= ((_reverse[salt[2]] & 0xE0) << 17) | ((_reverse[salt[2]] & 0x1F) << 16) | (_reverse[salt[3]] << 8) | _reverse[salt[4]]; } static void _PrintKey(int lfsr0, int lfsr1) { printf("key:"); printf(" %02X", _reverse[lfsr0>> 9]); printf(" %02X", _reverse[lfsr0 & 0xFF]); printf(" %02X", _reverse[((lfsr1>> 16) & 0x1F) | ((lfsr1>> 17) & 0xE0)]); printf(" %02X", _reverse[(lfsr1>> 8) & 0xFF]); printf(" %02X", _reverse[lfsr1 & 0xFF]); } static int _FindLfsr(const unsigned char *crypt, int offset, const unsigned char *plain, int &result0, int &result1) { int loop0, loop1, lfsr0, lfsr1, carry, count; for(loop0 = count = 0; loop0 != (1 << 18); loop0++) { lfsr0 = loop0>> 1; carry = loop0 & 0x01; for(loop1 = lfsr1 = 0; loop1 != 4; loop1++) { _ClockLfsr0Forward(lfsr0); carry = (_table[crypt[offset + loop1]] ^ plain[loop1]) - ((lfsr0>> 9) ^ 0xFF) - carry; lfsr1 = (lfsr1>> 8) | ((carry & 0xFF) << 17); carry = (carry>> 8) & 0x01; } for(; loop1 != 7; loop1++) { _ClockLfsr0Forward(lfsr0); _ClockLfsr1Forward(lfsr1); carry += ((lfsr0>> 9) ^ 0xFF) + (lfsr1>> 17); if((carry & 0xFF) != (_table[crypt[offset + loop1]] ^ plain[loop1])) { break; } carry>>= 8; } if(loop1 == 7) { for(loop1 = 0; loop1 != 6; loop1++) { _ClockBackward(lfsr0, lfsr1); } carry = ((lfsr0>> 9) ^ 0xFF) + (lfsr1>> 17) + (loop0 & 0x01); if((carry & 0xFF) == (_table[crypt[offset]] ^ plain[0])) { for(loop1 = 0; loop1 != offset + 1; loop1++) { _ClockBackward(lfsr0, lfsr1); } if(lfsr0 & 0x100 && lfsr1 & 0x200000) { result0 = lfsr0; result1 = lfsr1; count++; } } } } return count; } int quit_check(void) { int i; if ( kbhit() ) { i = getch(); if (i == 'q' || i == 'Q') { return (1); } } return(0); } void _checkWinver() { DWORD dwVersion; dwVersion = GetVersion(); if (dwVersion < 0x80000000) { printf("\nautomatic authenticate won't work with WinNT/Win2000, yet - sorry"); printf("\n\nplay your DVD with a player to do this"); exit(1); } } static int _FindKey(char *filename, int &lfsr0, int &lfsr1) { unsigned char buffer[0x800], plain[7] = { 0x00, 0x00, 0x01, 0xBE, 0x00, 0x00, 0xFF }; char authstring[80]; int result, offset, left, flag, block, count, abort,i; FILE *file; result = 1; printf("\rscanning %s for key now ...\t\t \n",filename); if((file = fopen(filename, "rb")) == 0) { printf("error: can't open input file '%s'\n", filename); exit (1); } else { for(flag = block = 0; fread(buffer, 1, sizeof buffer, file) == sizeof buffer; block++) { if ((block % 100)==0) { printf("\rscanning, block %d", block); fflush(stdout); if ( kbhit() ) { i = getch(); switch(i) { case 'q': case 'Q': fclose(file); exit (1); case 'n': case 'N': // printf("\rsearching key on next vobfile "); fclose(file); return (2); case 's': case 'S': printf("\n\nskipping keysearch...(ignoring key)\n\n"); fclose(file); return (0); } } } if(buffer[0x14] & 0x10) { flag |= 0x01; if(buffer[0x00] == 0x00 && buffer[0x01] == 0x00 && buffer[0x02] == 0x01 && buffer[0x03] == 0xBA && buffer[0x0E] == 0x00 && buffer[0x0F] == 0x00 && buffer[0x10] == 0x01) { offset = 0x14 + (buffer[0x12] << 8) + buffer[0x13]; if(0x80 <= offset && offset <= 0x7F9) { flag |= 0x02; left = 0x800 - offset - 6; plain[4] = (char) (left>> 8); plain[5] = (char) left; if((count = _FindLfsr(buffer + 0x80, offset - 0x80, plain, lfsr0, lfsr1)) == 1) { _Salt(lfsr0, lfsr1, buffer + 0x54); result = 0; break; } else if(count) { printf("\rblock %d reported %d possible keys, skipping\n", block, count); } } } } } fclose(file); if(block < 250 && result ) { return (3); } if(result && feof(file)==0 ) { printf("\ncould not retrieve key from file '%s'\n", filename); return (1); } else { printf("\rscanning, done \n"); if(result) { printf("error: unable to deduce key from input file (%s)\n", flag & 0x02 ? "the algorithm failed" : flag & 0x01 ? "there were no vulnerable blocks" : "there were no encrypted blocks"); } } fclose(file); } return result; } static void _Decrypt(unsigned char *buffer, int lfsr0, int lfsr1) { int loop0, carry; _Salt(lfsr0, lfsr1, buffer + 0x54); for(loop0 = carry = 0, buffer += 0x80; loop0 != 0x800 - 0x80; loop0++, buffer++) { _ClockLfsr0Forward(lfsr0); _ClockLfsr1Forward(lfsr1); carry += ((lfsr0>> 9) ^ 0xFF) + (lfsr1>> 17); *buffer = (unsigned char) (_table[*buffer] ^ carry); carry>>= 8; } } static int _DecryptFile(const char *filename0, const char *filename1, int lfsr0, int lfsr1, int option,int vob_flag,int *ac3rip, int &skip_vobid) { unsigned char buffer[0x800],ac3buffer[0x800]; int result, block, choice,display_message_id=0,loop,loop1,ac3_flag=0, ac3buffsize, ac3str_info; int tmin, tsec; float filesize; FILE *file0,*file1; HANDLE input_file,ac3file1,ac3file2,ac3file3,ac3file4; DWORD dwRead = 0; time_t t1, t2; char ac3filename[80]; loop=0; while (ac3rip[loop]!=0) { sprintf(ac3filename,"audio_%i.ac3",ac3rip[loop]); switch (loop) { case 0: ac3_flag=1; ac3file1 = CreateFile(ac3filename,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_RANDOM_ACCESS,NULL); SetFilePointer(ac3file1,NULL,NULL,FILE_END); break; case 1: ac3_flag=1; ac3file2 = CreateFile(ac3filename,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_RANDOM_ACCESS,NULL); SetFilePointer(ac3file2,NULL,NULL,FILE_END); break; case 2: ac3_flag=1; ac3file3 = CreateFile(ac3filename,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_RANDOM_ACCESS,NULL); SetFilePointer(ac3file3,NULL,NULL,FILE_END); break; case 3: ac3_flag=1; ac3file4 = CreateFile(ac3filename,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_RANDOM_ACCESS,NULL); SetFilePointer(ac3file4,NULL,NULL,FILE_END); } loop++; } if((file0 = fopen(filename0, "rb")) == 0) { printf("error: can't open input file '%s'\n", filename0); exit (1); } fseek(file0,0,SEEK_END); filesize=ftell(file0)/2048; if (filesize == 0 ) { printf("\nfile has no data\n"); exit(1); } fseek(file0,0,SEEK_SET); if (option == 1) { // unnecessary - no option 1 passed // input_file = CreateFile(filename1,OPEN_ALWAYS,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_RANDOM_ACCESS,NULL); } else { if (option == 2) { input_file = CreateFile(filename1,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_RANDOM_ACCESS,NULL); SetFilePointer(input_file,NULL,NULL,FILE_END); } else { if((file1 = fopen(filename1, "rb")) != 0) { fclose(file1); printf("\n'%s' already exists: (O)verwrite,(A)ppend, (Q)uit?\n\n", filename1); while (1) { choice=getch(); switch (choice) { case 'o': case 'O': input_file = CreateFile(filename1,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_RANDOM_ACCESS,NULL); choice = 'q'; break; case 'a': case 'A': input_file = CreateFile(filename1,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_RANDOM_ACCESS,NULL); SetFilePointer(input_file,NULL,NULL,FILE_END); choice = 'q'; break; case 'Q': case 'q': choice = 'q'; exit (1); } if (choice == 'q' ) break; } } else { input_file = CreateFile(filename1,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_RANDOM_ACCESS,NULL); } } } t1 = time(NULL); for(block = 0;; block++) { if(block % 100 == 0) { t2 = time(NULL); tsec = difftime(t2,t1); tmin = (tsec/60); tsec = tsec - (tmin*60); printf("\rdecrypting, %.2f%% done\t %i:%02i",100-((filesize-block)/filesize)*100,tmin,tsec); fflush(stdout); if (quit_check() == 1) { CloseHandle (input_file); CloseHandle(ac3file1);CloseHandle(ac3file2);CloseHandle(ac3file3);CloseHandle(ac3file4); fclose(file0); exit (1); } } if(fread(buffer, 1, sizeof buffer, file0) != sizeof buffer) { result = 0; break; } if(buffer[0x14] & 0x10) { _Decrypt(buffer, lfsr0, lfsr1); buffer[0x14] &= ~0x10; } if (vob_flag>0) { if (buffer[38]==0x00 && buffer[39]==0x00 && buffer[40]==0x01 && buffer[41]==0xBF && buffer[42]==0x03 && buffer[43]==0xD4) { // search for VOB_ID vob_flag=1 //search for multiangle info and skip movie according to first found info // skip current vob_id if bytes detected if (vob_flag==1) { if ((buffer[1071]!=0x00) || (buffer[1072]!=0x00) ) { // skip_vobid=0; // } else { if (buffer[1056]!=skip_vobid ) { skip_vobid=buffer[1056]+1; if (buffer[1056]!=display_message_id) { printf("\r Multiangle detected, skipping vob-id %2i now\n",skip_vobid); display_message_id=buffer[1056]; } } //while in multiangle part, skip next vob_id while (buffer[1056]==skip_vobid) { if(fread(buffer, 1, sizeof buffer, file0) != sizeof buffer) { break; } if(buffer[0x14] & 0x10) { _Decrypt(buffer, lfsr0, lfsr1); buffer[0x14] &= ~0x10; } if (buffer[38]==0x00 && buffer[39]==0x00 && buffer[40]==0x01 && buffer[41]==0xBF && buffer[42]==0x03 && buffer[43]==0xD4) { if (buffer[1056]!=skip_vobid) break; } buffer[1056]=skip_vobid; } } buffer[1071]=0x00; buffer[1072]=0x00; } } } if (ac3_flag==1) { if (buffer[14]==0x00 && buffer[15]==0x00 && buffer[16]==0x01 && buffer[17]==0xBD) { loop1=0; ac3str_info=buffer[22]+23; ac3buffsize=2044-ac3str_info; while (ac3rip[loop1]!=0) { if (ac3rip[loop1]+48==buffer[ac3str_info]) { break; } loop1++; } if (buffer[ac3str_info] == ac3rip[loop1]+48 && ac3rip[loop1]!=0) { for (loop=0;loop<(2048-(ac3str_info));loop++) { ac3buffer[loop]=buffer[ac3str_info+4+loop]; // check for bad audio buffer streams (matrix workaround) if ((loop>8) && ac3buffer[loop-8]==0x00 && ac3buffer[loop-7]==0x00 && ac3buffer[loop-6]==0x01 && ac3buffer[loop-5]==0xBE && ac3buffer[loop-2]==0xFF && ac3buffer[loop-1]==0xFF && ac3buffer[loop]==0xFF ) { ac3buffsize=loop-8; break; } } switch(loop1) { case 0: if ( WriteFile(ac3file1,ac3buffer,ac3buffsize,&dwRead,NULL) == 0) { printf("\nerror: can't write %s \n",ac3file2); CloseHandle(ac3file1);CloseHandle(ac3file2);CloseHandle(ac3file3);CloseHandle(ac3file4); fclose(file0); exit(1); } break; case 1: if ( WriteFile(ac3file2,ac3buffer,ac3buffsize,&dwRead,NULL) == 0) { printf("\nerror: can't write to %s \n",ac3file2); CloseHandle(ac3file1);CloseHandle(ac3file2);CloseHandle(ac3file3);CloseHandle(ac3file4); fclose(file0); exit(1); } break; case 2: if ( WriteFile(ac3file3,ac3buffer,ac3buffsize,&dwRead,NULL) == 0) { printf("\nerror: can't write to %s \n",ac3file2); CloseHandle(ac3file1);CloseHandle(ac3file2);CloseHandle(ac3file3);CloseHandle(ac3file4); fclose(file0); exit(1); } break; case 3: if ( WriteFile(ac3file4,ac3buffer,ac3buffsize,&dwRead,NULL) == 0) { printf("\nerror: can't write to %s \n",ac3file2); CloseHandle(ac3file1);CloseHandle(ac3file2);CloseHandle(ac3file3);CloseHandle(ac3file4); fclose(file0); exit(1); } } } } } if (option != 1) { if ( WriteFile(input_file,buffer,sizeof buffer,&dwRead,NULL) == 0) { printf("\nerror: can't write to output file\n"); CloseHandle (input_file); CloseHandle(ac3file1);CloseHandle(ac3file2);CloseHandle(ac3file3);CloseHandle(ac3file4); fclose(file0); exit(1); } } } printf("\rdecrypting, %i%% done\t %i:%02i \n", 100,tmin,tsec); CloseHandle (input_file); CloseHandle(ac3file1);CloseHandle(ac3file2);CloseHandle(ac3file3);CloseHandle(ac3file4); fclose(file0); return result; } void patch_region (void){ int buffer; char filename1[80]="Video_ts.ifo"; char filename2[80]="Video_ts.bup"; FILE *file; if((file = fopen(filename1, "r+")) == 0) { printf("\nerror: can't open file '%s'\n", filename1); printf("\nrun vobdec from same directory as %s",filename1); printf("\nand make sure write protection is disabled"); exit(1); } fseek(file,35,0); buffer = 192; (buffer,file); fclose(file); if((file = fopen(filename2, "r+b")) == 0) { printf("\nerror: can't open file '%s'\n", filename2); printf("\nrun vobdec from same directory as %s",filename2); printf("\nand make sure write protection is disabled"); exit(1); } fseek(file,35,0); fputc(buffer,file); fclose(file); printf("\npatched files %s and %s successfully",filename1,filename2); } void disable_macrovision (char *filename){ int buffer,loop,j,correct,i; FILE *file; unsigned char fbuffer[6]; int fstreamfind[6]={0,0,1,191,3,212}; printf("\npatching macrovision on file '%s'\n",filename); printf("\npress 'y' to confirm\nany other key to abort..."); i=getch(); if (i!='y' && i!='Y') exit(1); printf("\n\npatching file..."); if((file = fopen(filename, "r+b")) == 0) { printf("\nerror: can't open file '%s' for patching\n", filename); printf("\nmake sure write protection is disabled"); exit(1); } fseek(file,0,0); while(!feof(file)) { j++; if ((j % 100) == 0) { if (quit_check() == 1) { fclose(file); exit (1); } } fseek(file,38,SEEK_CUR); if(fread(fbuffer,1,sizeof fbuffer, file) == 0) { printf("\end of file reached"); fclose(file); exit(1); } correct = 1; for (loop=0;loop<6;loop++) { if ( fbuffer[loop] != fstreamfind[loop] ) { correct = 0; } } if ( correct == 1 ) { fseek(file,5,SEEK_CUR); fputc(0,file); } else{ fseek(file,6,SEEK_CUR); } fseek(file,1998,SEEK_CUR); } printf("\npatched file %s successfully",filename); } int region_free_check(char *drive,char *vtsfilename) { int buffer,i,max_aud,lang_known=0,reg_flag=0; char dir[70] =":\\video_ts\\Video_ts.ifo"; char dir2[70] =":\\video_ts\\Vts_01_0.ifo"; char language[80]; unsigned char lang_flag[3]; char in_filename[80]; char DVDname[80]; FILE *file; dir2[15]=vtsfilename[16]; dir2[16]=vtsfilename[17]; strcpy (in_filename,drive); strcat (in_filename,dir); sprintf(DVDname,"%c:\\",drive[0]); GetVolumeInformation(DVDname,DVDname,80,NULL,0,0,0,0); for (i=0;i 10000) { printf("could not find AC3 in file"); exit(1); } if ((j % 100) == 0) { if (quit_check() == 1) { fclose(file); exit (1); } } if(fread(fbuffer, 1, sizeof fbuffer, file) == 0) { printf("\nend of file reached "); fclose(file); exit(1); } //search for audio stream correct = 1; for (loop=0;loop<4;loop++) { if ( fbuffer[(loop+14)] != fstreamfind[loop] ) { correct = 0; } } //search for language if ( correct == 1 ) { if (fbuffer[28] == 0x80) { if (found_flag==1) { fclose(file); exit(1); } printf("\nfound AC3 stream 0x80 (most likely english)"); found_flag=1; i=1; } else { if (fbuffer[28]== ac3flag[0]+i) { i++; printf("\nfound AC3 stream 0x%x", fbuffer[28]); } } } } } void info() { printf("\nfull DVD RIP : vobdec x merge DVD into 1 file\n"); printf("full DVD RIP : vobdec s separate files\n"); printf("single .vob file : vobdec [1..99] rip single files only\n"); printf("rip multiple VOB files : vobdec [1] [99] rip VOBs [1-99], [x] for merging\n"); printf("regular decryption : vobdec [infile] [outfile] [K0 K1 K2 K3 K4]\n"); printf(" optional: 'vobdec vts# [...]' use other # than default vts1 \n"); printf(" 'key #####' pass key (10 digits) to program\n"); printf(" '-0' disables multiangle detection\n"); printf(" '-ac3 [80] [81]..' parallel ac3-stream rip from DVD\n"); printf(" '+ac3 [80] [81]..' get only ac3-stream from DVD\n"); printf(" '-a' authenticate DVD\n"); printf("\nstrip file from LBA # : vobdec strip [#LBA] [infile] [outfile]\n"); printf("search Cell-IDs #LBA : vobdec lba [infile] \n"); printf("search + filedump : vobdec lba [infile] [outfile]\n"); printf("truncate file : vobdec trunc [#LBA] [infile]\n"); printf("show AC3 file info : vobdec ac3 [vobfile]\n"); printf("merge files : vobdec merge [file1]...[file2]...[targetfile]\n"); printf("rip ac3 streams : vobdec ac3 [vobfile] [ac3file] [ac3 number]\n"); printf("remove region info : vobdec regionfree (only for .ifo, .bup files)\n"); printf("remove macrovision : vobdec demacro [vobfile]\n"); printf("show DVD/AC3 info : vobdec info"); } void def_name(char *filename,char *drive,char *part1,char *part2,char *part3) { strcpy (filename,drive); strcat (filename,part1); strcat (filename,part2); strcat (filename,part3); } void truncate_file(double trunc_point,char *filename) { long trunc_long; int i; double filesize; HANDLE input_file; input_file = CreateFile(filename,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_WRITE_THROUGH,NULL); // test if file exits if (GetLastError()==2) { printf("couldn't open file %s",filename); exit(1); } filesize = GetFileSize(input_file,NULL); if (trunc_point>= filesize) { printf("\ntruncpoint %.0lf bytes / filesize %.0lf bytes",trunc_point,filesize); printf("\n\ntruncpoint out of filesize - aborting truncation"); exit(1); } printf("\ntruncating %s at %.0lf bytes / LBA # %.0lf (y)?",filename,trunc_point,trunc_point/2048); printf("\nany other key will abort"); i = getch(); if (i != 'y' && i != 'Y') exit(1); SetFilePointer(input_file,0,NULL,FILE_BEGIN); // 2GB limit due to long input - work around it if (trunc_point < 2147483646) { trunc_long=trunc_point; SetFilePointer(input_file,trunc_long,NULL,FILE_CURRENT); } else { while (trunc_point> 2147483646) { SetFilePointer(input_file,2147483646,NULL,FILE_CURRENT); trunc_point -= 2147483646; } trunc_long=trunc_point; SetFilePointer(input_file,trunc_long,NULL,FILE_CURRENT); } if (SetEndOfFile(input_file)==0) { printf("\ntruncation failed"); } else { printf("\nfile truncated"); } CloseHandle (input_file); } void append_file (char *sourcefile,char *targetfile) { int ibuffer,counter,i; FILE *infile,*outfile; double filesize,filesize2,filesize3; DWORD dwRead,dwWrite; HANDLE input_file,output_file; char buffer[2048]; input_file = CreateFile(sourcefile,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if (GetLastError()==2) { printf("\ncouldn't open file %s",sourcefile); exit(1); } output_file = CreateFile(targetfile,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_RANDOM_ACCESS,NULL); if (GetLastError()==2) { printf("\ncouldn't open file %s",targetfile); exit(1); } filesize = GetFileSize(output_file,NULL); filesize2 = GetFileSize(input_file,NULL); printf("\ntargetfile %20s: %13.0lf bytes",targetfile,filesize); printf("\nsourcefile %20s: %13.0lf bytes",sourcefile,filesize2); printf("\n\nmerging...\n"); SetFilePointer(input_file,0,NULL,FILE_BEGIN); SetFilePointer(output_file,0,NULL,FILE_END); while ( (ReadFile(input_file,buffer,2048,&dwRead,NULL) != 0) ) { if (dwRead == 0) { break; } if ( WriteFile(output_file,buffer,dwRead,&dwWrite,NULL)== 0 || (dwWrite==0)){ CloseHandle (input_file); CloseHandle (output_file); printf("\nerror writing to file"); printf("\n\ntry to truncate file %s to original size? (y)\nany other key will abort",targetfile); i = getch(); if (i == 'y' || i == 'Y') { if (filesize==0) { remove(targetfile); } else { truncate_file(filesize,targetfile); } } exit(1); } counter++; if (counter % 100 == 0) { counter=0; if (quit_check() == 1) { CloseHandle (input_file); CloseHandle (output_file); exit (1); } } } CloseHandle (input_file); CloseHandle (output_file); input_file = CreateFile(targetfile,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); filesize3 = GetFileSize(input_file,NULL); CloseHandle (input_file); printf("\n\nmerged %s: %5.0lf bytes",targetfile,filesize3); if (filesize3-filesize2-filesize ==0) { printf("\n\nmerging of files was succesful"); // merge multiple, limit, filesize check in stripping, too printf("\ndo you want to delete original file %s now? (y/n)",sourcefile); i = getch(); if (i == 'y' || i == 'Y') { remove (sourcefile); } } else { printf("\nmerging of files failed"); // undo change by resetting filepointer printf("\n\ntry to truncate file %s to original size? (y)\nany other key will abort",targetfile); i = getch(); if (i == 'y' || i == 'Y') { if (filesize==0) { remove(targetfile); } else { truncate_file(filesize,targetfile); } } } } void strip_file(long lba,char *in_filename,char *out_filename) { int i; unsigned char buffer[204800]; double split_byte,filesize,filesize2,lbadouble; long byte_shift; unsigned long counter=0; DWORD dwRead; FILE *infile,*outfile; HANDLE input_file; input_file = CreateFile(in_filename,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); filesize = GetFileSize(input_file,NULL); //in LBA CloseHandle (input_file); if (lba>= filesize/2048) { printf("\nLBA is out of files range (max LBA is %.0lf)",filesize/2048); exit(1); } // workaround 2 GB limit split_byte = lba; split_byte = split_byte * 2048; printf("\ndumping %s to %s @ LBA %li\n",in_filename,out_filename,lba); if ((infile = fopen(in_filename,"rb")) == NULL) { printf("couldn't open %s abort process",in_filename); exit(1); } fseek(infile,0,SEEK_SET); while (split_byte> 2147483646) { fseek(infile,2147483646,SEEK_CUR); split_byte -= 2147483646; } byte_shift = split_byte; fseek(infile,byte_shift,SEEK_CUR); if ((outfile = fopen(out_filename,"wb")) == NULL) { printf("\ncouldn't open %s abort process",out_filename); exit(1); } while ((i=(fread(buffer, 1, sizeof buffer, infile))) != 0) { fwrite(buffer,i,1,outfile); counter++; // if (counter % 10 == 0) { printf("\r %.0lf00 blocks left",(filesize/2048-lba-counter*100)/100 ); if (quit_check() == 1) { fclose(infile); fclose(outfile); exit (1); } // } } fclose(infile);fclose(outfile); input_file = CreateFile(out_filename,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); filesize2 = GetFileSize(input_file,NULL); CloseHandle (input_file); lbadouble= lba; lbadouble *= 2048; printf("\r %8.0lf blocks left",0); printf("\n\n%s has %15.0lf bytes", in_filename,filesize); printf("\n%s has %15.0lf bytes", out_filename,filesize2); printf("\nsplitting point was at %3.0lf bytes / LBA #%.0lf", lbadouble,lbadouble/2048); if ((filesize2 == filesize-lbadouble) && filesize2 != 0) { printf("\nsuccesully dumped file...\n"); } else { printf("\nerror: could not dump file correct"); printf("\n%s should be %.0lf bytes, is %.0lf bytes",out_filename,filesize-lbadouble, filesize2); printf("\n\nremove file %s (y)",out_filename); printf("\nany other key will preserve file"); i=getch(); if ( i=='y' || i=='Y') { if (remove(out_filename) == 0) { printf("\nfile deleted"); } else { printf("\n\ndelete failed"); } } // option to remove file exit(1); } printf("\norginal file will be truncated now"); printf("\n (c) to continue, any other key to abort process"); i = getch(); if ( (i != 'c') && (i != 'C') ) { exit(1); } split_byte = lba; split_byte = split_byte * 2048; truncate_file(split_byte,in_filename); } void check_valid_id (char *filename,int *first_cell,int *last_cell) { int dir_flag=0,buffer,j,i,correct; int streamfind[6]={0,0,1,191,3,212}; FILE *file; double filesize; long lbasize; DWORD dwRead; HANDLE input_file; if((file = fopen(filename, "rb")) == 0) { printf("\nerror: can't open file '%s'\n", filename); exit(1); } fclose(file); input_file = CreateFile(filename,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); filesize = GetFileSize(input_file,NULL); //in LBA CloseHandle (input_file); lbasize=filesize/2048; if (lbasize != filesize/2048) { printf("\nincorrect filesize - run 'vobdec trunc %li %s' first", lbasize,filename); exit(1); } if((file = fopen(filename, "rb")) == 0) { printf("\nerror: can't open file '%s'\n", filename); exit(1); } fseek(file,-2048,SEEK_END); printf("\nopening file '%s for CELL-ID detection'\n\n", filename); while (*last_cell == 0 || *first_cell == 0) { j++; if ((j % 100) == 0) { j=0; if (quit_check() == 1) { fclose(file); exit (1); } } fseek(file,38,SEEK_CUR); correct = 1; for (i=0;i<6;i++) { buffer = fgetc(file); if ( buffer != streamfind[i] ) { correct = 0; } } if ( correct == 1 ) { fseek(file,1014,SEEK_CUR); buffer = fgetc(file); if (dir_flag == 0) { *last_cell=buffer; dir_flag = 1; fseek(file,0,SEEK_SET); } else { *first_cell=buffer; } } else { fseek(file,2004,SEEK_CUR); } if (dir_flag == 0) { fseek(file,-4096,SEEK_CUR);//this is going back 2048 bytes overall actually } } if (*last_cell == *first_cell) { printf("\nonly CELL-ID %i found - no clean truncation possible",*first_cell); fclose(file); exit(1); } else { if (*last_cell < *first_cell) { printf("\nfound cell-IDs %i to %i in wrong order - make sure, you merged VOB correctly",*first_cell,*last_cell); fclose(file); exit(1); } } printf("\nfound cell-IDs %i to %i, searching lba positions now\n",*first_cell,*last_cell); fclose(file); } void scan_foraudio (char *filename,char *outfilename,int *ac3rip) { int buffer,i,j=0,correct,loop,loop1,loop2; long ac3str_info,ac3buffsize,read_data; unsigned char fbuffer[204800]; unsigned char audiobuffer[2048]; unsigned char ac3flag[1]; char ac3filename[80]; unsigned char fstreamfind[4]={0x00,0x00,0x01,0xBD}; FILE *file; DWORD dwRead; HANDLE ac3file1,ac3file2,ac3file3,ac3file4; for (loop=0;loop8) && audiobuffer[loop-8]==0x00 && audiobuffer[loop-7]==0x00 && audiobuffer[loop-6]==0x01 && audiobuffer[loop-5]==0xBE && audiobuffer[loop-2]==0xFF && audiobuffer[loop-1]==0xFF && audiobuffer[loop]==0xFF ) { ac3buffsize=loop-8; break; } } switch(loop1) { case 0: if ( WriteFile(ac3file1,audiobuffer,ac3buffsize,&dwRead,NULL) == 0) { printf("\nerror: can't write %s \n",ac3file2); CloseHandle(ac3file1);CloseHandle(ac3file2);CloseHandle(ac3file3);CloseHandle(ac3file4); fclose(file); exit(1); } break; case 1: if ( WriteFile(ac3file2,audiobuffer,ac3buffsize,&dwRead,NULL) == 0) { printf("\nerror: can't write to %s \n",ac3file2); CloseHandle(ac3file1);CloseHandle(ac3file2);CloseHandle(ac3file3);CloseHandle(ac3file4); fclose(file); exit(1); } break; case 2: if ( WriteFile(ac3file3,audiobuffer,ac3buffsize,&dwRead,NULL) == 0) { printf("\nerror: can't write to %s \n",ac3file2); CloseHandle(ac3file1);CloseHandle(ac3file2);CloseHandle(ac3file3);CloseHandle(ac3file4); fclose(file); exit(1); } break; case 3: if ( WriteFile(ac3file4,audiobuffer,ac3buffsize,&dwRead,NULL) == 0) { printf("\nerror: can't write to %s \n",ac3file2); CloseHandle(ac3file1);CloseHandle(ac3file2);CloseHandle(ac3file3);CloseHandle(ac3file4); fclose(file); exit(1); } } } } } } printf("\ndone."); CloseHandle(ac3file1);CloseHandle(ac3file2);CloseHandle(ac3file3);CloseHandle(ac3file4); fclose(file); } // forward search is about 3 times faster than backwards(why?), so I won't dump this function void search_cell_ids (char *filename) { int buffer,i,j,cell_id,loop,correct,last_cell=0,first_cell=0,search_cell; unsigned char fbuffer[6]; long lbajump,filepos,curr_pos,cell_size,last_lba; unsigned char fstreamfind[6]={0x00,0x00,0x01,0xBF,0x03,0xD4}; FILE *file; double filesize; DWORD dwRead; double free; HANDLE input_file; // function could be optimized, but runs at ok speed, now input_file = CreateFile(filename,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); filesize = GetFileSize(input_file,NULL); CloseHandle (input_file); //search for first and last cell-id first for fast abort+loop input check_valid_id (filename,&first_cell,&last_cell); if((file = fopen(filename, "rb")) == 0) { printf("\nerror: can't open file '%s'\n", filename); exit(1); } //now search fully fseek(file,0,SEEK_SET); search_cell = first_cell+1; curr_pos=0; for (loop=first_cell;loop2000 ) { // jump 2000 lba could be optimized according to filesize/cell_id number fseek(file,4094941,SEEK_CUR); curr_pos += 2000; // last_lba=curr_pos; } else { //search each LBA backwards now - part could be optimized fseek(file,-1059,SEEK_CUR); last_lba=curr_pos; while (cell_id == 0) { fseek(file,38,SEEK_CUR); if(fread(fbuffer, 1, sizeof fstreamfind, file) != sizeof fstreamfind) { printf("\nerror reading LBA from file "); fclose(file); exit(1); } correct = 1; for (i=0;i<6;i++) { if ( fbuffer[i] != fstreamfind[i] ) { correct = 0; } } if ( correct == 1 ) { fseek(file,1014,SEEK_CUR); buffer = fgetc(file); if (buffer == search_cell-1) { printf("\nCELL-ID %3i found at LBA #%li ",buffer+1,last_lba); cell_id=buffer+1; search_cell++; fseek(file,-1059,SEEK_CUR); break;//exit loop+search next } else { fseek(file,-1015,SEEK_CUR); last_lba=curr_pos; } } //jump to previous lba fseek(file,-2092,SEEK_CUR); curr_pos --; } } } else { fseek(file,2004,SEEK_CUR); curr_pos++; } } } printf("\ndone."); fclose(file); } void search_back_cell_ids (char *filename, char *outfilename) { int buffer,i,j,cell_id,loop,correct,last_cell=0,first_cell=0,search_cell,fpos; long lbajump,filepos,curr_pos,cell_size,strip_lba,lbasize; unsigned char fstreamfind[6]={0x00,0x00,0x01,0xBF,0x03,0xD4}; unsigned char fbuffer[6]; FILE *file; double filesize; DWORD dwRead; HANDLE input_file; input_file = CreateFile(filename,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); filesize = GetFileSize(input_file,NULL); //in LBA CloseHandle (input_file); lbasize=filesize/2048; check_valid_id (filename,&first_cell,&last_cell); if((file = fopen(filename, "rb")) == 0) { printf("\nerror: can't open file '%s'\n", filename); exit(1); } fseek(file,-2048,SEEK_END); search_cell = last_cell; curr_pos=lbasize-1; for (loop=first_cell;loop search_cell-1 && curr_pos>2000 ) { // jump 2000 lba could be optimized according to filesize/cell_id number fseek(file,-4097059,SEEK_CUR); curr_pos -= 2000; } else { //search each LBA forward now - part could be optimized fseek(file,-1059,SEEK_CUR); while (cell_id == 0) { fseek(file,38,SEEK_CUR); if(fread(fbuffer, 1, sizeof fstreamfind, file) != sizeof fstreamfind) { printf("\error reading LBA for streaminfo"); } correct = 1; for (i=0;i<6;i++) { if ( fbuffer[i] != fstreamfind[i] ) { correct = 0; } } if ( correct == 1 ) { fseek(file,1014,SEEK_CUR); buffer = fgetc(file); if (buffer == search_cell) { printf("\nCELL-ID %3i found at LBA #%li ",buffer,curr_pos); strip_lba= curr_pos; cell_id=buffer+1; search_cell--; fseek(file,989,SEEK_CUR); curr_pos++; break;//exit loop+search next } else { fseek(file,-1015,SEEK_CUR); } //jump to next lba } fseek(file,2004,SEEK_CUR); curr_pos ++; } } } else { fseek(file,-2092,SEEK_CUR); curr_pos--; } } printf("\n\n(d)ump cell-id %i LBA %li to file %s?",search_cell+1,strip_lba,outfilename); printf("\n(c)ontinue search\n...any other key will abort"); i=getch(); if (i=='d' || i=='D') { fclose(file); strip_file(strip_lba,filename,outfilename); exit(1); } else { if (i != 'c' && i != 'C') { exit(1); } printf("\n\ncontinuing search...\n"); } } printf("\ndone."); fclose(file); } void _authenticateDVD(int drive,int *drive_id) { int i,j; char authstring[80]; DWORD dwVersion; FILE *_tmpfile; dwVersion = GetVersion(); printf("\rAuthentication of DVD drive ..."); //--- _checkWinversion; if (searchpath("dodsrip.exe") == NULL) { printf("\n\nerror: can't open dodsrip.exe"); printf("\nMake sure dodsrip.exe is in same directory as vobdec.exe\n"); exit(1); } if ( dwVersion < 0x80000000 && drive_id[0] == 1000 ) { for (i='0';i<'5';i++) { for (j='0';j<'5';j++) { sprintf(authstring,"dodsrip /h %c /t %c /l %c g 0 1 _tmp.vob>NUL",i,j,drive_id[2]); remove("_tmp.vob"); system(authstring); if ((_tmpfile=fopen("_tmp.vob","rb")) != NULL) { printf("\tDVD successfully authenticated"); printf("\nuse '-a%c%c' for next authentication run \n\n",i,j); fclose(_tmpfile); remove("_tmp.vob"); return; } } } printf("\n\n error: could not authenticate DVD drive !!! "); printf("\n\n start DVD with a DVD-player to do this, or:"); printf("\n\n see ctrl pan->system->device man->open cdrom->properties->settings"); printf("\n enter HOST-ID as first value, Target-ID as second value"); printf("\n e.g. 'vobdec -a01' for Host:0, Target-ID:1\n"); exit(1); } if (drive_id[0] == 1000 ) { sprintf(authstring,"dodsrip /d %c g 0 1 _tmp.vob>NUL",drive); remove("_tmp.vob"); system(authstring); if ((_tmpfile=fopen("_tmp.vob","rb")) != NULL) { fclose(_tmpfile); remove("_tmp.vob"); printf("\t DVD successfully authenticated \n"); } else { printf("\n\nerror: DVD authentication failed "); printf("\n\n try using a DVD player to do this \n"); exit(1); } } else { sprintf(authstring,"dodsrip /h %c /t %c /l %c g 0 1 _tmp.vob>NUL",drive_id[0],drive_id[1],drive_id[2]); system(authstring); if ((_tmpfile=fopen("_tmp.vob","rb")) == NULL) { printf("\n\n error: use different values to authenticate DVD!!! "); printf("\n\n see ctrl pan->system->device man->open cdrom->properties->settings"); printf("\n enter HOST-ID as first value, Target-ID as second value\n"); printf("\n or try 'vobdec -a' to auto detect IDs\n"); exit (1); } else { printf("\t DVD successfully authenticated "); fclose(_tmpfile); remove("_tmp.vob"); } } } int _loopkeysearch(char *filename,int &lfsr0,int &lfsr1) { int i, loop=0; int _dummy[3]={1000,'0','0'}; char authstring[80]; printf("\n'Q': Quit, 'N': scan Next vobfile, 'S': Skip key scan (undecrypted DVDs only)\n\n"); while (fopen(filename,"rb") != 0) { i=(_FindKey(filename,lfsr0, lfsr1)); if (i==0) { return 0; } if ( i==3 && loop<1 ) { printf("\n"); _authenticateDVD(filename[0], _dummy); printf("\n"); i=(_FindKey(filename,lfsr0, lfsr1)); if (i==0) { return 0; } } loop++; filename[strlen(filename)-5]++; } if (loop==0) { printf("\nerror: could not find file %s on DVD", filename); } else { printf("\nerror: could not retrieve any key, DVD seems to be not encrypted"); } return 1; } int main(int argc, char **argv) { unsigned char key[5], dummy; int loop0, loop1, value, lfsr0, lfsr1, option=0,i,j,skip_vobid=0,region_flag,keyflag=0,vob_flag=1,auth_flag=0; char filename[40] = "x:\\video_ts\\vts_01_1.vob", ac3name[40]; int ac3rip[8]={0,0,0,0,0,0,0,0}; int DVD_info[3]={1000,'0','0'}; char drive[3] = "x"; char part1[20] = ":\\video_ts\\vts_01_"; char part2[3] ="1"; char part3[12] = ".vob"; char authstring[80]; unsigned char char2hex[3]="0円"; char outfile[80]="x.vob"; double byte_number; FILE *file; clrscr(); printf("\nVobDec+ 0.311 - VOB Decryption Utility\t\t('Q' to Quit)\n"); for(loop0 = 0; loop0 != 0x100; loop0++) { for(loop1 = value = 0; loop1 != 8; loop1++) { value |= ((loop0>> loop1) & 0x01) << (7 - loop1); } _reverse[loop0] = (unsigned char) value; } if (argc == 1) { info (); exit (1); } if ( (argc == 2) && ((strcmp(argv[1],"info")==0) || (strcmp(argv[1],"INFO")==0) )) { for(loop0 = 99; loop0 < 123; loop0++) { drive[0]=loop0; def_name(filename,drive,":\\","",""); if(GetDriveType(filename)==DRIVE_CDROM) { def_name(filename,drive,part1,part2,part3); if ((fopen(filename,"rb")) != 0) { printf ("\nfound DVD on drive %c:\n",drive[0]); region_flag = (region_free_check(drive,filename)); } } } exit(1); } for (loop1=1;loop1loop1+1) ) { if (strlen(argv[loop1+1])==10 ) { printf("\nusing "); for(loop0 = 0; loop0 < 5; loop0++) { char2hex[0]=argv[loop1+1] [loop0*2]; char2hex[1]= argv[loop1+1] [loop0*2+1]; if(sscanf(char2hex, "%X%c", &value, &dummy) != 1) { printf("error: can't parse '%s' as a hex key byte\n",char2hex); exit(1); } key[loop0] = (unsigned char) value; printf("%x",key[loop0]); } keyflag=1; _Salt(lfsr0 = 0x100, lfsr1 = 0x200000, key); printf(" as key now\n"); for (loop0=loop1;loop03) { printf("\nonly up to 4 audio streams allowed"); exit(1); } ac3rip[i-loop1]=atoi(argv[i+1]); if (ac3rip[i-loop1]<80 || ac3rip[i-loop1]>88) { break; } sprintf(ac3name,"audio_%i.ac3",ac3rip[i-loop1]); if((file=fopen(ac3name, "rb")) != 0) { printf("\n'%s' already exists:\ntype 'd' to delete file, any other key to append to this ac3 file\n", ac3name); j = getch(); if ( j == 'd' || j == 'D' ) { fclose(file); remove(ac3name); } } } if (ac3rip[0]<80 || ac3rip[0]>88) { printf("\nwrong entry for ac3stream"); exit(1); } for (loop0=loop1;loop0 4) && (argc < 9) && ((strcmp(argv[1],"ac3")==0) || (strcmp(argv[1],"AC3")==0) )) { for (i=4;i89) { printf("\nwrong audio paratmeter entered"); exit(1); } } scan_foraudio (argv[2],argv[3],ac3rip); exit(1); } if ( (argc == 4 ) && ((strcmp(argv[1],"trunc")==0) || (strcmp(argv[1],"TRUNC")==0)) ) { byte_number=atof(argv[2]); if (byte_number ==0) { info(); exit(1); } byte_number *=2048; truncate_file(byte_number,argv[3]); exit(1); } if ( (strcmp(argv[1],"trunc")==0) || (strcmp(argv[1],"TRUNC")==0) ) { if (argc == 5 && (strcmp(argv[2],"-b")==0)) { byte_number=atof(argv[3]); if (byte_number==0) { info(); exit(1); } truncate_file(byte_number,argv[4]); } else { printf("\nerror: file truncation failed\n"); printf("\nwrong parameters entered: run 'vobdec' to get commands info"); } exit(1); } if ( (argc> 3) && ((strcmp(argv[1],"merge")==0) || (strcmp(argv[1],"MERGE")==0)) ) { for (loop0=2;loop0 99 ) { info(); exit (1); } loop1 = 1; for(loop0 = 99; loop0 < 123; loop0++) { drive[0]=loop0; def_name(filename,drive,":\\","",""); if(GetDriveType(filename)==DRIVE_CDROM) { def_name(filename,drive,part1,part2,part3); if ((fopen(filename,"rb")) != 0) { loop0 = 1000; if (auth_flag==1) { printf("\n"); _authenticateDVD(filename[0],DVD_info); if (argc==1) exit(1); } printf ("\nfound DVD on drive %c:\n",drive[0]); region_flag = (region_free_check(drive,filename)); if (keyflag==1) break; if (region_flag == 0) { printf("\nDVD most likely not encrypted"); printf("\n press 's' to skip key search, any other key will start key search now"); region_flag = getch(); } if ( region_flag != 'S' && region_flag != 's' ) { printf ("\nretrieving key...\n"); if( _loopkeysearch(filename,lfsr0, lfsr1)) return 1; _PrintKey(lfsr0, lfsr1); } break; } } } if (loop0 != 1000) { printf("\ncouldn't find a DVD/file - make sure disk is accessible\n\n"); exit(1); } if ( i> 0 || argv[1] [0] == '0') { // encode files from file_x to file_y counting up if (argc == 4 || argc == 3 || argc == 2) { if (argc == 2) { j = i; } else { j = atoi(argv[2]); } if (j < i) { printf("\nwrong input parameter"); exit (1); } for (loop0=i;loop0<=j;loop0++) { itoa(loop0,part2,10); def_name(filename,drive,part1,part2,part3); if ( argv [argc-1] [0] == 'x' || argv [argc-1] [0] == 'X') { def_name(outfile,"","","x",".vob"); if (loop0-i> 0) option = 2; } else { for (loop1=0;loop1<12;loop1++) { outfile[loop1]=filename[loop1+12]; } } if ( region_flag != 1 ) { printf ("\ncopying file %s ---> %s\n",filename,outfile); } else { printf ("\ndecrypting file %s ---> %s\n",filename,outfile); } if ( _DecryptFile(filename, outfile, lfsr0, lfsr1, option,vob_flag,ac3rip,skip_vobid)) return 1; } exit(1); } } if ( argv[1] [0] == 'x' || argv[1] [0] == 'X' || argv[1] [0] == 's' || argv[1] [0] == 'S') { filename[strlen(filename)-5] = '1'; do { if ( argv[1] [0] == 's' || argv[1] [0] == 'S') { for (loop0=0;loop0<12;loop0++) { outfile[loop0]=filename[loop0+12]; } } if ( ( argv[1] [0] == 'x' || argv[1] [0] == 'X' ) && (loop1> 1) ) { option = 2; } if ( region_flag != 1 ) { printf ("\ncopying file %s ---> %s\n",filename,outfile); } else { printf ("\ndecrypting file %s ---> %s\n",filename,outfile); } if ( _DecryptFile(filename, outfile, lfsr0, lfsr1, option,vob_flag,ac3rip,skip_vobid)) return 1; loop1++; itoa(loop1,part2,10); def_name(filename,drive,part1,part2,part3); } while ((fopen(filename,"rb")) != 0); exit (1); } } printf("\nwrong input parameter"); exit (1); }

AltStyle によって変換されたページ (->オリジナル) /