KeyDive/keydive.py

63 lines
2.6 KiB
Python
Raw Permalink Normal View History

2024-03-30 19:03:15 +00:00
import argparse
import logging
2024-04-01 10:24:00 +00:00
import subprocess
2024-03-30 19:03:15 +00:00
import time
import coloredlogs
2024-03-31 13:27:10 +00:00
from pathlib import Path
2024-03-30 19:03:15 +00:00
import extractor
2024-03-30 19:03:15 +00:00
from extractor.cdm import Cdm
coloredlogs.install(
fmt='%(asctime)s [%(levelname).1s] %(name)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
level=logging.DEBUG)
if __name__ == '__main__':
logger = logging.getLogger('KeyDive')
# Parse command line arguments for device ID
parser = argparse.ArgumentParser(description='Extract Widevine L3 keys from an Android device.')
2024-05-20 03:12:24 +00:00
parser.add_argument('-a', '--auto', required=False, action='store_true', help='Open Bitmovin\'s demo automatically.')
parser.add_argument('-d', '--device', required=False, type=str, help='Target Android device ID.')
2024-04-06 13:24:58 +00:00
parser.add_argument('-f', '--functions', required=False, type=Path, help='Path to Ghidra XML functions file.')
2024-05-22 16:36:36 +00:00
parser.add_argument('-w', '--wvd', required=False, action='store_true', help='Generate WVD.')
2024-04-06 13:24:58 +00:00
parser.add_argument('--force', required=False, action='store_true', help='Force using the default vendor (skipping analysis).')
2024-03-30 19:03:15 +00:00
args = parser.parse_args()
try:
logger.info('Version: %s', extractor.__version__)
2024-04-06 13:24:58 +00:00
# Ensure the ADB server is running
2024-05-19 13:41:42 +00:00
sp = subprocess.run(['adb', 'start-server'], capture_output=True)
2024-04-19 19:52:59 +00:00
if sp.returncode != 0:
2024-04-06 13:24:58 +00:00
raise EnvironmentError('ADB is not recognized as an environment variable, see https://github.com/hyugogirubato/KeyDive/blob/main/docs/PACKAGE.md#adb-android-debug-bridge')
2024-03-31 13:27:10 +00:00
2024-04-06 13:24:58 +00:00
# Initialize the CDM handler with the specified or default device
2024-05-21 12:26:31 +00:00
cdm = Cdm(device=args.device, functions=args.functions, force=args.force, wvd=args.wvd)
2024-03-30 19:03:15 +00:00
2024-04-06 13:24:58 +00:00
# Attempt to locate and identify the Widevine process on the target device
pid = cdm.enumerate_processes().get(cdm.vendor.process)
if not pid:
raise EnvironmentError('Widevine process not found on the device')
logger.info('Process: %s (%s)', pid, cdm.vendor.process)
2024-03-30 19:03:15 +00:00
2024-04-06 13:24:58 +00:00
# Hook into the identified process for DRM key extraction
if not cdm.hook_process(pid=pid):
raise Exception('Failed to hook into the Widevine process')
2024-03-30 19:03:15 +00:00
logger.info('Successfully hooked. To test, play a DRM-protected video: https://bitmovin.com/demos/drm')
2024-05-20 03:12:24 +00:00
if args.auto:
2024-05-22 16:36:36 +00:00
subprocess.run(['adb', '-s', cdm.device.id, 'shell', 'am', 'start', '-a', 'android.intent.action.VIEW', '-d', 'https://bitmovin.com/demos/drm'])
2024-05-20 03:12:24 +00:00
2024-03-30 19:03:15 +00:00
# Keep script running while extracting keys
while cdm.running:
time.sleep(1)
except KeyboardInterrupt:
pass
except Exception as e:
logger.critical(e)
logger.info('Exiting')