📄 drms.c
字号:
p_bordel[ 1 ] += 0x20E; p_bordel[ 5 ] += 0x223D; p_bordel[ 13 ] -= 0x576; p_bordel[ 15 ] += 0x576; return; case 91: p_bordel[ 2 ] -= 0x64; p_bordel[ 3 ] += 0x64; p_bordel[ 12 ] -= 1; p_bordel[ 13 ] += 1; break; case 99: p_bordel[ 0 ] += 1; p_bordel[ j ] += p_bordel[ 13 ]; break; } TinyShuffle8( p_bordel );}/***************************************************************************** * TinyShuffle[12345678]: tiny shuffle subroutines ***************************************************************************** * These standalone functions are little helpers for the shuffling process. *****************************************************************************/static void TinyShuffle1( uint32_t * p_bordel ){ uint32_t i_cmd = (p_bordel[ 5 ] + 10) >> 2; if( p_bordel[ 5 ] > 0x7D0 ) { i_cmd -= 0x305; } switch( i_cmd & 3 ) { case 0: p_bordel[ 5 ] += 5; break; case 1: p_bordel[ 4 ] -= 1; break; case 2: if( p_bordel[ 4 ] & 5 ) { p_bordel[ 1 ] ^= 0x4D; } /* no break */ case 3: p_bordel[ 12 ] += 5; break; }}static void TinyShuffle2( uint32_t * p_bordel ){ uint32_t i, j; for( i = 0, j = 0; i < 16; i++ ) { if( (p_bordel[ i ] & 0x777) > (p_bordel[ j ] & 0x777) ) { j = i; } } if( j > 5 ) { for( ; j < 15; j++ ) { p_bordel[ j ] += p_bordel[ j + 1 ]; } } else { p_bordel[ 2 ] &= 0xB62FC; }}static void TinyShuffle3( uint32_t * p_bordel ){ uint32_t i_cmd = p_bordel[ 6 ] + 0x194B; if( p_bordel[ 6 ] > 0x2710 ) { i_cmd >>= 1; } switch( i_cmd & 3 ) { case 1: p_bordel[ 3 ] += 0x19FE; break; case 2: p_bordel[ 7 ] -= p_bordel[ 3 ] >> 2; /* no break */ case 0: p_bordel[ 5 ] ^= 0x248A; break; }}static void TinyShuffle4( uint32_t * p_bordel ){ uint32_t i, j; for( i = 0, j = 0; i < 16; i++ ) { if( p_bordel[ i ] < p_bordel[ j ] ) { j = i; } } if( (p_bordel[ j ] % (j + 1)) > 10 ) { p_bordel[ 1 ] -= 1; p_bordel[ 2 ] += 0x13; p_bordel[ 12 ] += 1; }}static void TinyShuffle5( uint32_t * p_bordel ){ uint32_t i; p_bordel[ 2 ] &= 0x7F3F; for( i = 0; i < 5; i++ ) { switch( ( p_bordel[ 2 ] + 10 + i ) % 5 ) { case 0: p_bordel[ 12 ] &= p_bordel[ 2 ]; /* no break */ case 1: p_bordel[ 3 ] ^= p_bordel[ 15 ]; break; case 2: p_bordel[ 15 ] += 0x576; /* no break */ case 3: p_bordel[ 7 ] -= 0x2D; /* no break */ case 4: p_bordel[ 1 ] <<= 1; break; } }}static void TinyShuffle6( uint32_t * p_bordel ){ uint32_t i, j; for( i = 0; i < 8; i++ ) { j = p_bordel[ 3 ] & 0x7514 ? 5 : 7; SWAP( p_bordel[ i ], p_bordel[ i + j ] ); }}static void TinyShuffle7( uint32_t * p_bordel ){ uint32_t i; i = (((p_bordel[ 9 ] + p_bordel[ 15 ] + 12) >> 2) - p_bordel[ 4 ]) & 7; while( i-- ) { SWAP( p_bordel[ i ], p_bordel[ i + 3 ] ); } SWAP( p_bordel[ 1 ], p_bordel[ 10 ] );}static void TinyShuffle8( uint32_t * p_bordel ){ uint32_t i; i = (p_bordel[ 0 ] & p_bordel[ 6 ]) & 0xF; switch( p_bordel[ i ] % 1000 ) { case 7: if( (p_bordel[ i ] & 0x777) > (p_bordel[ 7 ] & 0x5555) ) { p_bordel[ i ] ^= p_bordel[ 5 ] & p_bordel[ 3 ]; } break; case 19: p_bordel[ 15 ] &= 0x5555; break; case 93: p_bordel[ i ] ^= p_bordel[ 15 ]; break; case 100: SWAP( p_bordel[ 0 ], p_bordel[ 3 ] ); SWAP( p_bordel[ 1 ], p_bordel[ 6 ] ); SWAP( p_bordel[ 3 ], p_bordel[ 6 ] ); SWAP( p_bordel[ 4 ], p_bordel[ 9 ] ); SWAP( p_bordel[ 5 ], p_bordel[ 8 ] ); SWAP( p_bordel[ 6 ], p_bordel[ 7 ] ); SWAP( p_bordel[ 13 ], p_bordel[ 14 ] ); break; case 329: p_bordel[ i ] += p_bordel[ 1 ] ^ 0x80080011; p_bordel[ i ] += p_bordel[ 2 ] ^ 0xBEEFDEAD; p_bordel[ i ] += p_bordel[ 3 ] ^ 0x8765F444; p_bordel[ i ] += p_bordel[ 4 ] ^ 0x78145326; break; case 567: p_bordel[ 12 ] -= p_bordel[ i ]; p_bordel[ 13 ] += p_bordel[ i ]; break; case 612: p_bordel[ i ] += p_bordel[ 1 ]; p_bordel[ i ] -= p_bordel[ 7 ]; p_bordel[ i ] -= p_bordel[ 8 ]; p_bordel[ i ] += p_bordel[ 9 ]; p_bordel[ i ] += p_bordel[ 13 ]; break; case 754: i = __MIN( i, 12 ); p_bordel[ i + 1 ] >>= 1; p_bordel[ i + 2 ] <<= 4; p_bordel[ i + 3 ] >>= 3; break; case 777: p_bordel[ 1 ] += 0x20E; p_bordel[ 5 ] += 0x223D; p_bordel[ 13 ] -= 0x576; p_bordel[ 15 ] += 0x576; break; case 981: if( (p_bordel[ i ] ^ 0x8765F441) < 0x2710 ) { SWAP( p_bordel[ 0 ], p_bordel[ 1 ] ); } else { SWAP( p_bordel[ 1 ], p_bordel[ 11 ] ); } break; }}/***************************************************************************** * GetSystemKey: get the system key ***************************************************************************** * Compute the system key from various system information, see HashSystemInfo. *****************************************************************************/static int GetSystemKey( uint32_t *p_sys_key, vlc_bool_t b_ipod ){ static char const p_secret5[ 8 ] = "YuaFlafu"; static char const p_secret6[ 8 ] = "zPif98ga"; struct md5_s md5; int64_t i_ipod_id; uint32_t p_system_hash[ 4 ]; /* Compute the MD5 hash of our system info */ if( ( !b_ipod && HashSystemInfo( p_system_hash ) ) || ( b_ipod && GetiPodID( &i_ipod_id ) ) ) { return -1; } /* Combine our system info hash with additional secret data. The resulting * MD5 hash will be our system key. */ InitMD5( &md5 ); AddMD5( &md5, (const uint8_t*)p_secret5, 8 ); if( !b_ipod ) { AddMD5( &md5, (const uint8_t *)p_system_hash, 6 ); AddMD5( &md5, (const uint8_t *)p_system_hash, 6 ); AddMD5( &md5, (const uint8_t *)p_system_hash, 6 ); AddMD5( &md5, (const uint8_t*)p_secret6, 8 ); } else { i_ipod_id = U64_AT(&i_ipod_id); AddMD5( &md5, (const uint8_t *)&i_ipod_id, sizeof(i_ipod_id) ); AddMD5( &md5, (const uint8_t *)&i_ipod_id, sizeof(i_ipod_id) ); AddMD5( &md5, (const uint8_t *)&i_ipod_id, sizeof(i_ipod_id) ); } EndMD5( &md5 ); memcpy( p_sys_key, md5.p_digest, 16 ); return 0;}#ifdef WIN32# define DRMS_DIRNAME "drms"#else# define DRMS_DIRNAME ".drms"#endif/***************************************************************************** * WriteUserKey: write the user key to hard disk ***************************************************************************** * Write the user key to the hard disk so that it can be reused later or used * on operating systems other than Win32. *****************************************************************************/static int WriteUserKey( void *_p_drms, uint32_t *p_user_key ){ struct drms_s *p_drms = (struct drms_s *)_p_drms; FILE *file; int i_ret = -1; char psz_path[ PATH_MAX ]; snprintf( psz_path, PATH_MAX - 1, "%s/" DRMS_DIRNAME, p_drms->psz_homedir );#if defined( HAVE_ERRNO_H )# if defined( WIN32 ) if( !mkdir( psz_path ) || errno == EEXIST )# else if( !mkdir( psz_path, 0755 ) || errno == EEXIST )# endif#else if( !mkdir( psz_path ) )#endif { snprintf( psz_path, PATH_MAX - 1, "%s/" DRMS_DIRNAME "/%08X.%03d", p_drms->psz_homedir, p_drms->i_user, p_drms->i_key ); file = utf8_fopen( psz_path, "wb" ); if( file != NULL ) { i_ret = fwrite( p_user_key, sizeof(uint32_t), 4, file ) == 4 ? 0 : -1; fclose( file ); } } return i_ret;}/***************************************************************************** * ReadUserKey: read the user key from hard disk ***************************************************************************** * Retrieve the user key from the hard disk if available. *****************************************************************************/static int ReadUserKey( void *_p_drms, uint32_t *p_user_key ){ struct drms_s *p_drms = (struct drms_s *)_p_drms; FILE *file; int i_ret = -1; char psz_path[ PATH_MAX ]; snprintf( psz_path, PATH_MAX - 1, "%s/" DRMS_DIRNAME "/%08X.%03d", p_drms->psz_homedir, p_drms->i_user, p_drms->i_key ); file = utf8_fopen( psz_path, "rb" ); if( file != NULL ) { i_ret = fread( p_user_key, sizeof(uint32_t), 4, file ) == 4 ? 0 : -1; fclose( file ); } return i_ret;}/***************************************************************************** * GetUserKey: get the user key ***************************************************************************** * Retrieve the user key from the hard disk if available, otherwise generate * it from the system key. If the key could be successfully generated, write * it to the hard disk for future use. *****************************************************************************/static int GetUserKey( void *_p_drms, uint32_t *p_user_key ){ static char const p_secret7[] = "mUfnpognadfgf873"; struct drms_s *p_drms = (struct drms_s *)_p_drms; struct aes_s aes; struct shuffle_s shuffle; uint32_t i, y; uint32_t *p_sci_data = NULL; uint32_t i_user, i_key; uint32_t p_sys_key[ 4 ]; uint32_t i_sci_size = 0, i_blocks, i_remaining; uint32_t *p_sci0, *p_sci1, *p_buffer; uint32_t p_sci_key[ 4 ]; char *psz_ipod; int i_ret = -5; if( ReadUserKey( p_drms, p_user_key ) == 0 ) { REVERSE( p_user_key, 4 ); return 0; } psz_ipod = getenv( "IPOD" ); if( GetSystemKey( p_sys_key, psz_ipod ? VLC_TRUE : VLC_FALSE ) ) { return -3; } if( GetSCIData( psz_ipod, &p_sci_data, &i_sci_size ) ) { return -4; } /* Phase 1: unscramble the SCI data using the system key and shuffle * it using DoShuffle(). */ /* Skip the first 4 bytes (some sort of header). Decrypt the rest. */ i_blocks = (i_sci_size - 4) / 16; i_remaining = (i_sci_size - 4) - (i_blocks * 16); p_buffer = p_sci_data + 1; /* Decrypt and shuffle our data at the same time */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -