This commit is contained in:
TPD94 2025-06-19 22:42:40 -04:00
parent b4de9c6d61
commit 046d64bbc5
8 changed files with 82 additions and 114 deletions

View File

@ -28,6 +28,11 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
chrome.storage.local.set({ latestKeys: data }); chrome.storage.local.set({ latestKeys: data });
break; break;
case "LICENSE_URL":
console.log("Storling License URL " + data);
chrome.storage.local.set({licenseURL: data});
break;
default: default:
console.warn("Unknown message type received:", type); console.warn("Unknown message type received:", type);
} }

View File

@ -1,24 +1,18 @@
// Inject `inject.js` into the page context // Inject `inject.js` into the page context
(function injectScript() { (function injectScript() {
function append() { const script = document.createElement('script');
const container = document.head || document.documentElement; script.src = chrome.runtime.getURL('inject.js');
if (!container) { script.type = 'text/javascript';
return requestAnimationFrame(append); // Wait for DOM to exist script.onload = () => script.remove(); // Clean up
} // Inject directly into <html> or <head>
const script = document.createElement('script'); (document.documentElement || document.head || document.body).appendChild(script);
script.src = chrome.runtime.getURL('inject.js');
script.type = 'text/javascript';
script.onload = () => script.remove(); // Clean up after injecting
container.appendChild(script);
}
append();
})(); })();
// Listen for messages from the injected script // Listen for messages from the injected script
window.addEventListener("message", function(event) { window.addEventListener("message", function(event) {
if (event.source !== window) return; if (event.source !== window) return;
if (["__DRM_TYPE__", "__PSSH_DATA__", "__KEYS_DATA__"].includes(event.data?.type)) { if (["__DRM_TYPE__", "__PSSH_DATA__", "__KEYS_DATA__", "__LICENSE_URL__"].includes(event.data?.type)) {
chrome.runtime.sendMessage({ chrome.runtime.sendMessage({
type: event.data.type.replace("__", "").replace("__", ""), type: event.data.type.replace("__", "").replace("__", ""),
data: event.data.data data: event.data.data

File diff suppressed because one or more lines are too long

View File

@ -4,7 +4,7 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>CDRM Decryption Extension</title> <title>CDRM Decryption Extension</title>
<script type="module" crossorigin src="./assets/index-CN3ssfBX.js"></script> <script type="module" crossorigin src="./assets/index-TiKBTYa_.js"></script>
<link rel="stylesheet" crossorigin href="./assets/index-UaipKa9p.css"> <link rel="stylesheet" crossorigin href="./assets/index-UaipKa9p.css">
</head> </head>
<body class="min-w-full min-h-full w-full h-full"> <body class="min-w-full min-h-full w-full h-full">

View File

@ -4,16 +4,21 @@ function Results() {
const [drmType, setDrmType] = useState(""); const [drmType, setDrmType] = useState("");
const [pssh, setPssh] = useState(""); const [pssh, setPssh] = useState("");
const [licenseUrl, setLicenseUrl] = useState(""); const [licenseUrl, setLicenseUrl] = useState("");
const [keys, setKeys] = useState(""); const [keys, setKeys] = useState([]);
useEffect(() => { useEffect(() => {
chrome.storage.local.get( chrome.storage.local.get(
["drmType", "latestPSSH", "latestLicenseRequest", "latestKeys"], [
"drmType",
"latestPSSH",
"latestLicenseRequest",
"latestKeys",
"licenseURL",
],
(result) => { (result) => {
if (result.drmType) setDrmType(result.drmType); if (result.drmType) setDrmType(result.drmType);
if (result.latestPSSH) setPssh(result.latestPSSH); if (result.latestPSSH) setPssh(result.latestPSSH);
if (result.latestLicenseRequest?.url) if (result.licenseURL) setLicenseUrl(result.licenseURL);
setLicenseUrl(result.latestLicenseRequest.url);
if (result.latestKeys) { if (result.latestKeys) {
try { try {
const parsed = Array.isArray(result.latestKeys) const parsed = Array.isArray(result.latestKeys)
@ -36,8 +41,8 @@ function Results() {
if (changes.latestPSSH) { if (changes.latestPSSH) {
setPssh(changes.latestPSSH.newValue); setPssh(changes.latestPSSH.newValue);
} }
if (changes.latestLicenseRequest) { if (changes.licenseURL) {
setLicenseUrl(changes.latestLicenseRequest.newValue.url); setLicenseUrl(changes.licenseURL.newValue);
} }
if (changes.latestKeys) { if (changes.latestKeys) {
setKeys(changes.latestKeys.newValue); setKeys(changes.latestKeys.newValue);
@ -54,7 +59,7 @@ function Results() {
chrome.storage.local.set({ chrome.storage.local.set({
drmType: "None", drmType: "None",
latestPSSH: "None", latestPSSH: "None",
latestLicenseRequest: { url: "None" }, licenseURL: "None",
latestKeys: [], latestKeys: [],
}); });

View File

@ -307,11 +307,11 @@ const u8ToHexStr = bytes =>
const b64ToHexStr = b64 => const b64ToHexStr = b64 =>
[...atob(b64)].map(c => c.charCodeAt(0).toString(16).padStart(2, '0')).join``; [...atob(b64)].map(c => c.charCodeAt(0).toString(16).padStart(2, '0')).join``;
function jsonContainsValue(obj, target) { function jsonContainsValue(obj, prefix = "CAES") {
if (typeof obj === "string") return obj === target; if (typeof obj === "string") return obj.startsWith(prefix);
if (Array.isArray(obj)) return obj.some(val => jsonContainsValue(val, target)); if (Array.isArray(obj)) return obj.some(val => jsonContainsValue(val, prefix));
if (typeof obj === "object" && obj !== null) { if (typeof obj === "object" && obj !== null) {
return Object.values(obj).some(val => jsonContainsValue(val, target)); return Object.values(obj).some(val => jsonContainsValue(val, prefix));
} }
return false; return false;
} }
@ -418,7 +418,7 @@ MediaKeySession.prototype.generateRequest = function(initDataType, initData) {
console.log("[PlayReady PSSH found] " + playReadyPssh) console.log("[PlayReady PSSH found] " + playReadyPssh)
} }
let wideVinePssh = getWidevinePssh(initData) let wideVinePssh = getWidevinePssh(initData)
if (wideVinePssh && !playReadyPssh && drmOverride !== "PLAYREADY") { if (wideVinePssh && drmOverride !== "PLAYREADY") {
// Widevine code // Widevine code
drmType = "Widevine"; drmType = "Widevine";
window.postMessage({ type: "__DRM_TYPE__", data: "Widevine" }, "*"); window.postMessage({ type: "__DRM_TYPE__", data: "Widevine" }, "*");
@ -489,7 +489,6 @@ MediaKeySession.prototype.generateRequest = function(initDataType, initData) {
} }
}; };
// Message update interceptors // Message update interceptors
const originalUpdate = MediaKeySession.prototype.update; const originalUpdate = MediaKeySession.prototype.update;
MediaKeySession.prototype.update = function(response) { MediaKeySession.prototype.update = function(response) {
@ -509,7 +508,7 @@ MediaKeySession.prototype.update = function(response) {
licenseResponseCounter++; licenseResponseCounter++;
} }
const updatePromise = originalUpdate.call(this, response); const updatePromise = originalUpdate.call(this, response);
if (!pssh && interceptType !== "DISABLED") { if (!pssh && (drmOverride !== "WIDEVINE" && drmOverride !== "PLAYREADY")) {
updatePromise updatePromise
.then(() => { .then(() => {
let clearKeys = getClearkey(response); let clearKeys = getClearkey(response);
@ -543,9 +542,17 @@ MediaKeySession.prototype.update = function(response) {
const method = (config.method || 'GET').toUpperCase(); const method = (config.method || 'GET').toUpperCase();
if (method === 'POST') { if (method === 'POST') {
console.log('Intercepted POST fetch request:'); if (config.body) {
console.log('URL:', resource); if (config.body instanceof ArrayBuffer || body instanceof Uint8Array) {
console.log('Options:', config); const buffer = body instanceof Uint8Array ? body : new Uint8Array(body);
const base64Body = window.btoa(String.fromCharCode(...buffer));
if (base64Body.startsWith("CAES") && base64Body !== remoteCDM.challenge && interceptType === "EME") {
foundChallengeInBody = true;
window.postMessage({ type: "__LICENSE_URL__", data: this._url }, "*");
return;
}
}
}
} }
return originalFetch(resource, config); return originalFetch(resource, config);
@ -571,16 +578,25 @@ MediaKeySession.prototype.update = function(response) {
const base64Body = window.btoa(String.fromCharCode(...buffer)); const base64Body = window.btoa(String.fromCharCode(...buffer));
if (base64Body.startsWith("CAES") && base64Body !== remoteCDM.challenge && interceptType === "EME") { if (base64Body.startsWith("CAES") && base64Body !== remoteCDM.challenge && interceptType === "EME") {
foundChallengeInBody = true; foundChallengeInBody = true;
window.postMessage({ type: "__LICENSE_URL__", data: this._url }, "*");
// Block the request // Block the request
return; return;
} }
if (base64Body.startsWith("CAES") && interceptType == "LICENSE") { if (base64Body.startsWith("CAES") && interceptType == "LICENSE") {
foundChallengeInBody = true; foundChallengeInBody = true;
window.postMessage({ type: "__LICENSE_URL__", data: this._url }, "*");
remoteCDM.getChallenge(pssh) remoteCDM.getChallenge(pssh)
const injectedBody = base64ToUint8Array(remoteCDM.challenge); const injectedBody = base64ToUint8Array(remoteCDM.challenge);
return originalSend.call(this, injectedBody); return originalSend.call(this, injectedBody);
} }
} }
if (isJson(body)) {
if (jsonContainsValue(body) && !jsonContainsValue(body, remoteCDM.challenge)) {
foundChallengeInBody = true;
window.postMessage({ type: "__LICENSE_URL__", data: this._url }, "*");
return;
}
}
} }
} }
return originalSend.apply(this, arguments); return originalSend.apply(this, arguments);

File diff suppressed because one or more lines are too long

View File

@ -4,7 +4,7 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>CDRM Decryption Extension</title> <title>CDRM Decryption Extension</title>
<script type="module" crossorigin src="./assets/index-CN3ssfBX.js"></script> <script type="module" crossorigin src="./assets/index-TiKBTYa_.js"></script>
<link rel="stylesheet" crossorigin href="./assets/index-UaipKa9p.css"> <link rel="stylesheet" crossorigin href="./assets/index-UaipKa9p.css">
</head> </head>
<body class="min-w-full min-h-full w-full h-full"> <body class="min-w-full min-h-full w-full h-full">