Release v1.0.1

Added support for non-standard versions
This commit is contained in:
hyugogirubato 2024-03-31 10:23:19 +02:00
parent b5a2b726b2
commit a02e3b0daa
4 changed files with 38 additions and 17 deletions

View File

@ -1,4 +1,4 @@
from .cdm import * from .cdm import *
from .vendor import * from .vendor import *
__version__ = '1.0.0' __version__ = '1.0.1'

View File

@ -33,8 +33,8 @@ class Cdm:
self.logger.info('ABI CPU: %s', self.properties['ro.product.cpu.abi']) self.logger.info('ABI CPU: %s', self.properties['ro.product.cpu.abi'])
# Determine vendor based on SDK API # Determine vendor based on SDK API
self.vendor = Vendor.from_sdk_api(self.sdk_api) self.script = self._prepare_hook_script()
self.script: str = self._prepare_hook_script() self.vendor = self._prepare_vendor()
def _fetch_device_properties(self) -> dict: def _fetch_device_properties(self) -> dict:
""" """
@ -132,6 +132,36 @@ class Cdm:
else: else:
self.logger.warning('Failed to intercept the private key') self.logger.warning('Failed to intercept the private key')
def _prepare_vendor(self) -> Vendor:
"""
Prepares and selects the most compatible vendor version based on the device's processes.
"""
details: [int] = []
for p in self.device.enumerate_processes():
for k, v in Vendor.SDK_VERSIONS.items():
if p.name == v[2]:
session: Session = self.device.attach(p.name)
script: Script = session.create_script(self.script)
script.load()
try:
script.exports_sync.getlibrary(v[3])
details.append(k)
except RPCException:
pass
session.detach()
if not details:
return Vendor.from_sdk_api(self.sdk_api)
# Find the closest SDK version to the current one, preferring lower matches in case of a tie.
sdk_api = min(details, key=lambda x: abs(x - self.sdk_api))
if sdk_api == Vendor.SDK_MAX and self.sdk_api > Vendor.SDK_MAX:
sdk_api = self.sdk_api
elif sdk_api != self.sdk_api:
self.logger.warning('Non-default Widevine version for SDK %s', sdk_api)
return Vendor.from_sdk_api(sdk_api)
def hook_process(self, process: Process) -> bool: def hook_process(self, process: Process) -> bool:
""" """
Hooks into the specified process to intercept DRM keys. Hooks into the specified process to intercept DRM keys.

View File

@ -7,19 +7,9 @@
const SDK_API = '${SDK_API}'; // Dynamically replaced with the actual SDK API level. const SDK_API = '${SDK_API}'; // Dynamically replaced with the actual SDK API level.
const OEM_CRYPTO_API = [ const OEM_CRYPTO_API = [
// Mapping of function names across different API levels (obfuscated names may vary). // Mapping of function names across different API levels (obfuscated names may vary).
'rnmsglvj', 'rnmsglvj', 'polorucp', 'kqzqahjq', 'pldrclfq', 'kgaitijd',
'polorucp', 'cwkfcplc', 'crhqcdet', 'ulns', 'dnvffnze', 'ygjiljer',
'kqzqahjq', 'qbjxtubz', 'qkfrcjtw', 'rbhjspoh'
'pldrclfq',
'kgaitijd',
'cwkfcplc',
'crhqcdet',
'ulns', // 11, 13
'dnvffnze', // 15
'ygjiljer', // 15
'qbjxtubz', // 16
'qkfrcjtw', // 16
'rbhjspoh' // 17
// Add more as needed for different versions. // Add more as needed for different versions.
]; ];

View File

@ -24,6 +24,7 @@ class Vendor:
24: (11, '1.0', 'mediadrmserver', 'libwvdrmengine.so'), 24: (11, '1.0', 'mediadrmserver', 'libwvdrmengine.so'),
23: (11, '1.0', 'mediaserver', 'libwvdrmengine.so') 23: (11, '1.0', 'mediaserver', 'libwvdrmengine.so')
} }
SDK_MAX = max(SDK_VERSIONS.keys())
def __init__(self, oem: int, version: str, process: str, library: str): def __init__(self, oem: int, version: str, process: str, library: str):
""" """
@ -51,7 +52,7 @@ class Vendor:
vendor_details = cls.SDK_VERSIONS.get(sdk_api) vendor_details = cls.SDK_VERSIONS.get(sdk_api)
if not vendor_details: if not vendor_details:
vendor_details = cls.SDK_VERSIONS[max(cls.SDK_VERSIONS.keys())] vendor_details = cls.SDK_VERSIONS[cls.SDK_MAX]
logger.warning('CMD version is not yet implemented') logger.warning('CMD version is not yet implemented')
logger.warning('Using closest supported CDM version: %s', vendor_details[1]) logger.warning('Using closest supported CDM version: %s', vendor_details[1])
else: else: