1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
/* csstest.c - test program for libdvdcss
*
* Sam Hocevar <sam@zoy.org> - June 2001
* Updated on Nov 13th 2001 for libdvdcss version 1.0.0
* Additional error checks on Aug 9th 2002
* Aligned data reads on Jan 28th 2003
*
* This piece of code is public domain */
#include <stdio.h>
#include <stdlib.h>
#include <dvdcss/dvdcss.h>
static int isscrambled( unsigned char * );
static void dumpsector ( unsigned char * );
int main( int i_argc, char *ppsz_argv[] )
{
dvdcss_t dvdcss;
unsigned char p_data[ DVDCSS_BLOCK_SIZE * 2 ];
unsigned char *p_buffer;
unsigned int i_sector;
int i_ret;
/* Print version number */
printf( "cool, I found libdvdcss version %s\n", dvdcss_interface_2 );
/* Check for 2 arguments */
if( i_argc != 3 )
{
printf( "usage: %s <target> <sector>\n", ppsz_argv[0] );
printf( "examples:\n" );
printf( " %s /dev/hdc 1024\n", ppsz_argv[0] );
printf( " %s D: 1024\n", ppsz_argv[0] );
printf( " %s scrambledfile.vob 1024\n", ppsz_argv[0] );
return -1;
}
/* Save the requested sector */
i_sector = atoi( ppsz_argv[2] );
/* Initialize libdvdcss */
dvdcss = dvdcss_open( ppsz_argv[1] );
if( dvdcss == NULL )
{
printf( "argh ! couldn't open DVD (%s)\n", ppsz_argv[1] );
return -1;
}
/* Align our read buffer */
p_buffer = p_data + DVDCSS_BLOCK_SIZE
- ((long int)p_data & (DVDCSS_BLOCK_SIZE-1));
/* Set the file descriptor at sector i_sector and read one sector */
i_ret = dvdcss_seek( dvdcss, i_sector, DVDCSS_NOFLAGS );
if( i_ret != (int)i_sector )
{
printf( "seek failed (%s)\n", dvdcss_error( dvdcss ) );
dvdcss_close( dvdcss );
return i_ret;
}
i_ret = dvdcss_read( dvdcss, p_buffer, 1, DVDCSS_NOFLAGS );
if( i_ret != 1 )
{
printf( "read failed (%s)\n", dvdcss_error( dvdcss ) );
dvdcss_close( dvdcss );
return i_ret;
}
/* Print the sector */
printf( "requested sector: " );
dumpsector( p_buffer );
/* Check if sector was encrypted */
if( isscrambled( p_buffer ) )
{
/* Set the file descriptor position to the previous location */
/* ... and get the appropriate key for this sector */
i_ret = dvdcss_seek( dvdcss, i_sector, DVDCSS_SEEK_KEY );
if( i_ret != (int)i_sector )
{
printf( "seek failed (%s)\n", dvdcss_error( dvdcss ) );
dvdcss_close( dvdcss );
return i_ret;
}
/* Read sector again, and decrypt it on the fly */
i_ret = dvdcss_read( dvdcss, p_buffer, 1, DVDCSS_READ_DECRYPT );
if( i_ret != 1 )
{
printf( "read failed (%s)\n", dvdcss_error( dvdcss ) );
dvdcss_close( dvdcss );
return i_ret;
}
/* Print the decrypted sector */
printf( "unscrambled sector: " );
dumpsector( p_buffer );
}
else
{
printf( "sector is not scrambled\n" );
}
/* Close the device */
i_ret = dvdcss_close( dvdcss );
return i_ret;
}
/* Check if a sector is scrambled */
static int isscrambled( unsigned char *p_buffer )
{
return p_buffer[ 0x14 ] & 0x30;
}
/* Print parts of a 2048 bytes buffer */
static void dumpsector( unsigned char *p_buffer )
{
int i_amount = 4;
for( ; i_amount ; i_amount--, p_buffer++ ) printf( "%.2x", *p_buffer );
printf( "..." );
i_amount = 22;
p_buffer += 200;
for( ; i_amount ; i_amount--, p_buffer++ ) printf( "%.2x", *p_buffer );
printf( "...\n" );
}
|