⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drms.c

📁 WINCE mp4 format source
💻 C
📖 第 1 页 / 共 3 页
字号:
static int GetUserKey( void *_p_drms, uint32_t *p_user_key )
{
    static char const p_secret[] = "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;
    uint32_t i_user, i_key;
    uint32_t p_sys_key[ 4 ];
    uint32_t i_sci_size, i_blocks, i_remaining;
    uint32_t *p_sci0, *p_sci1, *p_buffer;
    uint32_t p_sci_key[ 4 ];
    char *psz_ipod;
    int i_ret = -1;

    if( !ReadUserKey( p_drms, p_user_key ) )
    {
        REVERSE( p_user_key, 4 );
        return 0;
    }

    psz_ipod = getenv( "IPOD" );

    if( GetSystemKey( p_sys_key, psz_ipod ? 1 : 0 ) )
    {
        return -1;
    }

    if( GetSCIData( psz_ipod, &p_sci_data, &i_sci_size ) )
    {
        return -1;
    }

    /* 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 */
    InitAES( &aes, p_sys_key );
    REVERSE( p_sys_key, 4 );
    InitShuffle( &shuffle, p_sys_key );

    memcpy( p_sci_key, p_secret, 16 );
    REVERSE( p_sci_key, 4 );

    while( i_blocks-- )
    {
        uint32_t p_tmp[ 4 ];

        REVERSE( p_buffer, 4 );
        DecryptAES( &aes, p_tmp, p_buffer );
        BlockXOR( p_tmp, p_sci_key, p_tmp );

        /* Use the previous scrambled data as the key for next block */
        memcpy( p_sci_key, p_buffer, 16 );

        /* Shuffle the decrypted data using a custom routine */
        DoShuffle( &shuffle, p_tmp, 4 );

        /* Copy this block back to p_buffer */
        memcpy( p_buffer, p_tmp, 16 );

        p_buffer += 4;
    }

    if( i_remaining >= 4 )
    {
        i_remaining /= 4;
        REVERSE( p_buffer, i_remaining );
        DoShuffle( &shuffle, p_buffer, i_remaining );
    }

    /* Phase 2: look for the user key in the generated data. I must admit I
     *          do not understand what is going on here, because it almost
     *          looks like we are browsing data that makes sense, even though
     *          the DoShuffle() part made it completely meaningless. */

    y = 0;
    REVERSE( p_sci_data + 5, 1 );
    i = U32_AT( p_sci_data + 5 );
    i_sci_size -= 22 * sizeof(uint32_t);
    p_sci1 = p_sci_data + 22;
    p_sci0 = NULL;

    while( i_sci_size >= 20 && i > 0 )
    {
        if( p_sci0 == NULL )
        {
            i_sci_size -= 18 * sizeof(uint32_t);
            if( i_sci_size < 20 )
            {
                break;
            }

            p_sci0 = p_sci1;
            REVERSE( p_sci1 + 17, 1 );
            y = U32_AT( p_sci1 + 17 );
            p_sci1 += 18;
        }

        if( !y )
        {
            i--;
            p_sci0 = NULL;
            continue;
        }

        i_user = U32_AT( p_sci0 );
        i_key = U32_AT( p_sci1 );
        REVERSE( &i_user, 1 );
        REVERSE( &i_key, 1 );
        if( i_user == p_drms->i_user && ( ( i_key == p_drms->i_key ) ||
            ( !p_drms->i_key && ( p_sci1 == (p_sci0 + 18) ) ) ) )
        {
            memcpy( p_user_key, p_sci1 + 1, 16 );
            REVERSE( p_sci1 + 1, 4 );
            WriteUserKey( p_drms, p_sci1 + 1 );
            i_ret = 0;
            break;
        }

        y--;
        p_sci1 += 5;
        i_sci_size -= 5 * sizeof(uint32_t);
    }

    free( p_sci_data );

    return i_ret;
}

/*****************************************************************************
 * GetSCIData: get SCI data from "SC Info.sidb"
 *****************************************************************************
 * Read SCI data from "\Apple Computer\iTunes\SC Info\SC Info.sidb"
 *****************************************************************************/
static int GetSCIData( char *psz_ipod, uint32_t **pp_sci,
                       uint32_t *pi_sci_size )
{
    FILE *file;
    char *psz_path = NULL;
    char p_tmp[ PATH_MAX ];
    int i_ret = -1;

    if( psz_ipod == NULL )
    {
#ifdef _WIN32
        char *p_filename = "\\Apple Computer\\iTunes\\SC Info\\SC Info.sidb";
        typedef HRESULT (WINAPI *SHGETFOLDERPATH)( HWND, int, HANDLE, DWORD,
                                                   LPSTR );
        HINSTANCE shfolder_dll = NULL;
        SHGETFOLDERPATH dSHGetFolderPath = NULL;

        if( ( shfolder_dll = LoadLibrary( _T("SHFolder.dll") ) ) != NULL )
        {
            dSHGetFolderPath =
                (SHGETFOLDERPATH)GetProcAddress( shfolder_dll,
                                                 _T("SHGetFolderPathA") );
        }

        if( dSHGetFolderPath != NULL &&
            SUCCEEDED( dSHGetFolderPath( NULL, /*CSIDL_COMMON_APPDATA*/ 0x0023,
                                         NULL, 0, p_tmp ) ) )
        {
            strncat( p_tmp, p_filename, min( strlen( p_filename ),
                     (sizeof(p_tmp)/sizeof(p_tmp[0]) - 1) -
                     strlen( p_tmp ) ) );
            psz_path = p_tmp;
        }

        if( shfolder_dll != NULL )
        {
            FreeLibrary( shfolder_dll );
        }
#endif
    }
    else
    {
#define ISCINFO "iSCInfo"
        if( strstr( psz_ipod, ISCINFO ) == NULL )
        {
            sprintf( p_tmp, /*sizeof(p_tmp)/sizeof(p_tmp[0]) - 1,*/
                      "%s/iPod_Control/iTunes/" ISCINFO, psz_ipod );
            psz_path = p_tmp;
        }
        else
        {
            psz_path = psz_ipod;
        }
    }

    if( psz_path == NULL )
    {
        return -1;
    }

    file = fopen( psz_path, "r" );
    if( file != NULL )
    {
        struct stat st;

        if( !fstat( fileno( file ), &st ) )
        {
            *pp_sci = malloc( st.st_size );
            if( *pp_sci != NULL )
            {
                if( fread( *pp_sci, 1, st.st_size,
                           file ) == (size_t)st.st_size )
                {
                    *pi_sci_size = st.st_size;
                    i_ret = 0;
                }
                else
                {
                    free( (void *)*pp_sci );
                    *pp_sci = NULL;
                }
            }
        }

        fclose( file );
    }

    return i_ret;
}

/*****************************************************************************
 * HashSystemInfo: hash system information
 *****************************************************************************
 * This function computes the MD5 hash of the C: hard drive serial number,
 * BIOS version, CPU type and Windows version.
 *****************************************************************************/
static int HashSystemInfo( uint32_t *p_system_hash )
{
    struct md5_s md5;
    int i_ret = 0;

#ifdef _WIN32
    HKEY i_key;
    unsigned int i;
    DWORD i_size;
    DWORD i_serial;
    LPBYTE p_reg_buf;

    static LPCTSTR p_reg_keys[ 3 ][ 2 ] =
    {
        {
            _T("HARDWARE\\DESCRIPTION\\System"),
            _T("SystemBiosVersion")
        },

        {
            _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"),
            _T("ProcessorNameString")
        },

        {
            _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion"),
            _T("ProductId")
        }
    };

    InitMD5( &md5 );

    AddMD5( &md5, "cache-control", 13 );
    AddMD5( &md5, "Ethernet", 8 );

    GetVolumeInformation( _T("C:\\"), NULL, 0, &i_serial,
                          NULL, NULL, NULL, 0 );
    AddMD5( &md5, (uint8_t *)&i_serial, 4 );

    for( i = 0; i < sizeof(p_reg_keys) / sizeof(p_reg_keys[ 0 ]); i++ )
    {
        if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, p_reg_keys[ i ][ 0 ],
                          0, KEY_READ, &i_key ) != ERROR_SUCCESS )
        {
            continue;
        }

        if( RegQueryValueEx( i_key, p_reg_keys[ i ][ 1 ],
                             NULL, NULL, NULL, &i_size ) != ERROR_SUCCESS )
        {
            RegCloseKey( i_key );
            continue;
        }

        p_reg_buf = malloc( i_size );

        if( p_reg_buf != NULL )
        {
            if( RegQueryValueEx( i_key, p_reg_keys[ i ][ 1 ],
                                 NULL, NULL, p_reg_buf,
                                 &i_size ) == ERROR_SUCCESS )
            {
                AddMD5( &md5, (uint8_t *)p_reg_buf, i_size );
            }

            free( p_reg_buf );
        }

        RegCloseKey( i_key );
    }

#else
    InitMD5( &md5 );
    i_ret = -1;
#endif

    EndMD5( &md5 );
    memcpy( p_system_hash, md5.p_digest, 16 );

    return i_ret;
}

/*****************************************************************************
 * GetiPodID: Get iPod ID
 *****************************************************************************
 * This function gets the iPod ID.
 *****************************************************************************/
static int GetiPodID( int64_t *p_ipod_id )
{
    int i_ret = -1;

#define PROD_NAME   "iPod"
#define VENDOR_NAME "Apple Computer, Inc."

    char *psz_ipod_id = getenv( "IPODID" );
    if( psz_ipod_id != NULL )
    {
#ifndef _WIN32
        *p_ipod_id = strtoll( psz_ipod_id, NULL, 16 );
#else
        *p_ipod_id = strtol( psz_ipod_id, NULL, 16 );
#endif
        return 0;
    }

#ifdef HAVE_IOKIT_IOKITLIB_H
    CFTypeRef value;
    mach_port_t port;
    io_object_t device;
    io_iterator_t iterator;
    CFMutableDictionaryRef matching_dic;

    if( IOMasterPort( MACH_PORT_NULL, &port ) == KERN_SUCCESS )
    {
        if( ( matching_dic = IOServiceMatching( "IOFireWireUnit" ) ) != NULL )
        {
            CFDictionarySetValue( matching_dic,
                                  CFSTR("FireWire Vendor Name"),
                                  CFSTR(VENDOR_NAME) );
            CFDictionarySetValue( matching_dic,
                                  CFSTR("FireWire Product Name"),
                                  CFSTR(PROD_NAME) );

            if( IOServiceGetMatchingServices( port, matching_dic,
                                              &iterator ) == KERN_SUCCESS )
            {
                while( ( device = IOIteratorNext( iterator ) ) != NULL )
                {
                    value = IORegistryEntryCreateCFProperty( device,
                        CFSTR("GUID"), kCFAllocatorDefault, kNilOptions );

                    if( value != NULL )
                    {
                        if( CFGetTypeID( value ) == CFNumberGetTypeID() )
                        {
                            int64_t i_ipod_id;
                            CFNumberGetValue( (CFNumberRef)value,
                                              kCFNumberLongLongType,
                                              &i_ipod_id );
                            *p_ipod_id = i_ipod_id;
                            i_ret = 0;
                        }

                        CFRelease( value );
                    }

                    IOObjectRelease( device );

                    if( !i_ret ) break;
                }

                IOObjectRelease( iterator );
            }
        }

        mach_port_deallocate( mach_task_self(), port );
    }

#elif HAVE_SYSFS_LIBSYSFS_H
    struct sysfs_bus *bus = NULL;
    struct dlist *devlist = NULL;
    struct dlist *attributes = NULL;
    struct sysfs_device *curdev = NULL;
    struct sysfs_attribute *curattr = NULL;

    bus = sysfs_open_bus( "ieee1394" );
    if( bus != NULL )
    {
        devlist = sysfs_get_bus_devices( bus );
        if( devlist != NULL )
        {
            dlist_for_each_data( devlist, curdev, struct sysfs_device )
            {
                attributes = sysfs_get_device_attributes( curdev );
                if( attributes != NULL )
                {
                    dlist_for_each_data( attributes, curattr,
                                         struct sysfs_attribute )
                    {
                        if( ( strcmp( curattr->name, "model_name" ) == 0 ) &&
                            ( strncmp( curattr->value, PROD_NAME,
                                       sizeof(PROD_NAME) ) == 0 ) )
                        {
                            *p_ipod_id = strtoll( curdev->name, NULL, 16 );
                            i_ret = 0;
                            break;
                        }
                    }
                }

                if( !i_ret ) break;
            }
        }

        sysfs_close_bus( bus );
    }
#endif

    return i_ret;
}

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -