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

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

View File

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

File diff suppressed because one or more lines are too long

View File

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

View File

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

View File

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

File diff suppressed because one or more lines are too long

View File

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