- Added persistent injection for sites that use polyfill

- Fix overflow on top bar
This commit is contained in:
TPD94 2025-06-02 12:17:03 -04:00
parent 358be057bb
commit 67e2a11258
7 changed files with 119 additions and 27 deletions

1
frontend/.gitignore vendored
View File

@ -8,7 +8,6 @@ pnpm-debug.log*
lerna-debug.log* lerna-debug.log*
node_modules node_modules
dist
dist-ssr dist-ssr
*.local *.local

52
frontend/dist/assets/index-BFZJq4X0.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

13
frontend/dist/index.html vendored Normal file
View File

@ -0,0 +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-BFZJq4X0.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>

View File

@ -42,7 +42,7 @@ function TopNav({ onMenuClick }) {
}; };
return ( return (
<div className="w-full h-full flex flex-row"> <div className="w-full h-full flex flex-row overflow-x-hidden">
<img <img
src={hamburgerIcon} src={hamburgerIcon}
alt="Menu" alt="Menu"

View File

@ -11,6 +11,8 @@ let originalChallenge = null;
let widevineDeviceInfo = null; let widevineDeviceInfo = null;
let playreadyDeviceInfo = null; let playreadyDeviceInfo = null;
let drmOveride = "DISABLED" let drmOveride = "DISABLED"
let serviceCertificate = null;
window.postMessage({ type: "__GET_DRM_OVERRIDE__" }, "*"); window.postMessage({ type: "__GET_DRM_OVERRIDE__" }, "*");
@ -626,29 +628,45 @@ MediaKeySession.prototype.generateRequest = async function(initDataType, initDat
// === Intercept License or EME Messages === // === Intercept License or EME Messages ===
if (!messageSuppressed && interceptType === 'EME') { if (!messageSuppressed && interceptType === 'EME') {
session.addEventListener("message", function originalMessageInterceptor(event) { let intercepted = false;
event.stopImmediatePropagation();
console.log("[Intercepted EME Message] Injecting custom message.");
console.log(event.data);
const uint8 = base64ToUint8Array(customBase64); const messageInterceptor = function(event) {
const arrayBuffer = uint8.buffer; const uint8View = new Uint8Array(event.message);
const base64String = btoa(String.fromCharCode(...uint8View));
const syntheticEvent = new MessageEvent("message", { if (base64String === "CAQ=") {
data: event.data, console.log("[CAQ] Detected - letting original message through.");
origin: event.origin, return; // Allow original message
lastEventId: event.lastEventId, }
source: event.source,
ports: event.ports
});
Object.defineProperty(syntheticEvent, "message", { if (!intercepted) {
get: () => arrayBuffer intercepted = true;
}); event.stopImmediatePropagation();
console.log(syntheticEvent); console.log("[Intercepted EME Message] Injecting custom message.");
setTimeout(() => session.dispatchEvent(syntheticEvent), 0);
}, { once: true });
const uint8 = base64ToUint8Array(customBase64);
const arrayBuffer = uint8.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: () => arrayBuffer
});
setTimeout(() => session.dispatchEvent(syntheticEvent), 0);
// Remove after interception
session.removeEventListener("message", messageInterceptor);
}
};
session.addEventListener("message", messageInterceptor);
messageSuppressed = true; messageSuppressed = true;
} }
@ -692,6 +710,8 @@ MediaKeySession.prototype.update = function(response) {
// Handle Service Certificate // Handle Service Certificate
if (base64Response.startsWith("CAUS") && !firstValidServiceCertificate) { if (base64Response.startsWith("CAUS") && !firstValidServiceCertificate) {
console.log("[Service Certificate] Found:", base64Response);
serviceCertificate = base64Response;
const base64ServiceCertificateData = { const base64ServiceCertificateData = {
type: "__CERTIFICATE_DATA__", type: "__CERTIFICATE_DATA__",
data: base64Response data: base64Response
@ -785,6 +805,7 @@ window.fetch = async function(input, init = {}) {
if (method === "POST") { if (method === "POST") {
const url = typeof input === "string" ? input : input.url; const url = typeof input === "string" ? input : input.url;
let body = init.body; let body = init.body;
// If the body is FormData, convert it to an object (or JSON) // If the body is FormData, convert it to an object (or JSON)
if (body instanceof FormData) { if (body instanceof FormData) {
@ -807,6 +828,7 @@ window.fetch = async function(input, init = {}) {
// Handle body based on its type // Handle body based on its type
if (typeof body === 'string') { if (typeof body === 'string') {
if (isJson(body)) { if (isJson(body)) {
const parsed = JSON.parse(body); const parsed = JSON.parse(body);
if (jsonContainsValue(parsed, customBase64)) { if (jsonContainsValue(parsed, customBase64)) {
@ -834,6 +856,7 @@ window.fetch = async function(input, init = {}) {
sendToBackground({ url, method, headers, body: modifiedBody }); sendToBackground({ url, method, headers, body: modifiedBody });
} }
} }
// Ensure the modified body is used and passed to the original fetch call // Ensure the modified body is used and passed to the original fetch call
init.body = modifiedBody; init.body = modifiedBody;

View File

@ -4,24 +4,28 @@
"version": "2.0", "version": "2.0",
"description": "Decrypt DRM Protected content", "description": "Decrypt DRM Protected content",
"permissions": [ "permissions": [
"storage",
"tabs",
"activeTab",
"webRequest", "webRequest",
"webRequestBlocking", "webRequestBlocking",
"<all_urls>" "<all_urls>",
"activeTab",
"storage",
"tabs",
"contextMenus"
], ],
"background": { "background": {
"scripts": ["background.js"] "scripts": ["background.js"],
"persistent": true
}, },
"content_scripts": [ "content_scripts": [
{ {
"matches": ["<all_urls>"], "matches": ["<all_urls>"],
"js": ["content.js"], "js": ["content.js"],
"run_at": "document_start" "run_at": "document_start",
"all_frames": true
} }
], ],
"web_accessible_resources": ["inject.js"], "web_accessible_resources": ["inject.js"],
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
"browser_action": { "browser_action": {
"default_icon": { "default_icon": {
"16": "icons/icon16.png", "16": "icons/icon16.png",