diff --git a/content.js b/content.js index aeebd03..ef0facd 100644 --- a/content.js +++ b/content.js @@ -26,7 +26,6 @@ window.addEventListener("message", function(event) { } if (event.data.type === "__GET_CDM_DEVICES__") { - console.log("Received request for CDM devices"); chrome.storage.local.get(["widevine_device", "playready_device"], (result) => { const widevine_device = result.widevine_device || null; @@ -44,7 +43,6 @@ window.addEventListener("message", function(event) { } if (event.data.type === "__GET_INJECTION_TYPE__") { - console.log("Received request for injection type"); chrome.storage.local.get("injection_type", (result) => { const injectionType = result.injection_type || "LICENSE"; @@ -59,7 +57,6 @@ window.addEventListener("message", function(event) { }); } if (event.data.type === "__GET_DRM_OVERRIDE__") { - console.log("Received request for DRM override"); chrome.storage.local.get("drm_override", (result) => { const drmOverride = result.drm_override || "DISABLED"; diff --git a/inject.js b/inject.js index d4fb687..6ba3c48 100644 --- a/inject.js +++ b/inject.js @@ -1,16 +1,16 @@ let widevineDeviceInfo = null; let playreadyDeviceInfo = null; -let originalMessage = null; let originalChallenge = null let serviceCertFound = false; let drmType = "NONE"; let psshFound = false; -let firstValidLicenseChallenge = false; let pssh = null; let drmOverride = "DISABLED"; let interceptType = "DISABLED"; let remoteCDM = null; - +let generateRequestCalled = false; +let remoteListenerMounted = false; +let injectionSuccess = false; // Post message to content.js to get DRM override window.postMessage({ type: "__GET_DRM_OVERRIDE__" }, "*"); @@ -426,4 +426,83 @@ function arrayBufferToBase64(uint8array) { } return window.btoa(binary); -} \ No newline at end of file +} + + +const generateRequestFunction = MediaKeySession.prototype.generateRequest; + +MediaKeySession.prototype.generateRequest = async function(initDataType, initData) { + if (!generateRequestCalled) { + generateRequestCalled = true; + const session = this; + let playReadyPssh = getPlayReadyPssh(initData); + if (playReadyPssh) { + // PlayReady Code + drmType = "PlayReady"; + window.postMessage({ type: "__DRM_TYPE__", data: "PlayReady" }, "*"); + console.log("[DRM Detected] PlayReady"); + pssh = playReadyPssh; + window.postMessage({ type: "__PSSH_DATA__", data: playReadyPssh }, "*"); + console.log("[PlayReady PSSH found] " + playReadyPssh) + } + let wideVinePssh = getWidevinePssh(initData) + if (wideVinePssh) { + // Widevine code + drmType = "Widevine"; + window.postMessage({ type: "__DRM_TYPE__", data: "Widevine" }, "*"); + console.log("[DRM Detected] Widevine"); + pssh = wideVinePssh; + window.postMessage({ type: "__PSSH_DATA__", data: wideVinePssh }, "*"); + console.log("[Widevine PSSH found] " + wideVinePssh) + } + if (!remoteListenerMounted) { + remoteListenerMounted = true; + session.addEventListener("message", async function messageInterceptor(event) { + event.stopImmediatePropagation(); + const uint8Array = new Uint8Array(event.message); + const base64challenge = arrayBufferToBase64(uint8Array); + if (base64challenge === "CAQ=") { + const { + device_type, system_id, security_level, host, secret, device_name + } = widevineDeviceInfo; + remoteCDM = new remoteWidevineCDM(device_type, system_id, security_level, host, secret, device_name); + await remoteCDM.openSession(); + } + if (base64challenge.startsWith("CAES") && !injectionSuccess) { + if (interceptType === "EME") { + injectionSuccess = true; + } + originalChallenge = base64challenge; + if (!remoteCDM) { + const { + device_type, system_id, security_level, host, secret, device_name + } = widevineDeviceInfo; + remoteCDM = new remoteWidevineCDM(device_type, system_id, security_level, host, secret, device_name); + await remoteCDM.openSession(); + } + await remoteCDM.getChallenge(pssh); + if (interceptType === "EME") { + const uint8challenge = base64ToUint8Array(remoteCDM.challenge); + const challengeBuffer = uint8challenge.buffer; + const syntheticEvent = new MessageEvent("message", { + data: event.data, + origin: event.origin, + lastEventId: event.lastEventId, + source: event.source, + ports: event.ports + }); + Object.defineProperty(syntheticEvent, "message", { + get: () => challengeBuffer + }); + session.dispatchEvent(syntheticEvent); + console.log("Intercepted EME Challenge and injected custom one.") + } + } + if (injectionSuccess) { + return; + } + }) + console.log("Message interceptor mounted."); + } + return generateRequestFunction.call(session, initDataType, initData); + }} \ No newline at end of file