mirror of
https://cdm-project.com/Deja/DVDFabServerEmulator.git
synced 2024-10-22 07:02:59 +00:00
v1.1.3 (2)
We're back!
This commit is contained in:
parent
8beaf72323
commit
eaa47803bf
132
.gitignore
vendored
Normal file
132
.gitignore
vendored
Normal file
@ -0,0 +1,132 @@
|
||||
# ---> Node
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional stylelint cache
|
||||
.stylelintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variable files
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# vuepress v2.x temp and cache directory
|
||||
.temp
|
||||
.cache
|
||||
|
||||
# Docusaurus cache and generated files
|
||||
.docusaurus
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
198
index.js
Normal file
198
index.js
Normal file
@ -0,0 +1,198 @@
|
||||
/*
|
||||
DVDFab Server Emulator v1.1.3
|
||||
*/
|
||||
|
||||
// Libraries
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const crypto = require('crypto');
|
||||
const mockttp = require('mockttp');
|
||||
|
||||
// Classes
|
||||
class Session {
|
||||
constructor() {
|
||||
this.currentMachineId = null;
|
||||
this.usage = 0;
|
||||
this.generateNewIdentity();
|
||||
}
|
||||
|
||||
generateMacAddress() {
|
||||
const macBytes = Array.from({ length: 12 }, () => Math.floor(Math.random() * 256));
|
||||
const firstMac = macBytes.slice(0, 6).map(_ => _.toString(16).padStart(2, '0')).join('-');
|
||||
const secondMac = macBytes.slice(6).map(_ => _.toString(16).padStart(2, '0')).join('-');
|
||||
return `${firstMac}:${secondMac}`;
|
||||
}
|
||||
|
||||
generateNewIdentity() {
|
||||
this.currentMachineId = this.generateMacAddress();
|
||||
}
|
||||
|
||||
patchBoundary(data) {
|
||||
if (this.usage === 3) {
|
||||
this.usage = 0;
|
||||
this.generateNewIdentity();
|
||||
}
|
||||
|
||||
const macRegex = /^([0-9a-f]{2}-){5}[0-9a-f]{2}(:([0-9a-f]{2}-){5}[0-9a-f]{2})?/;
|
||||
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
|
||||
const subscriptionRegex = /^365$/;
|
||||
|
||||
for (const key in data) {
|
||||
const value = data[key];
|
||||
if (macRegex.test(value)) {
|
||||
data[key] = this.currentMachineId;
|
||||
} else if (emailRegex.test(value)) {
|
||||
data[key] = this.currentMachineId;
|
||||
} else if (subscriptionRegex.test(value)) {
|
||||
data[key] = 'trial';
|
||||
}
|
||||
}
|
||||
|
||||
this.usage++;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
// Constants
|
||||
const productList = fs.readFileSync(path.join(__dirname, 'products.txt'), 'utf8').trim().split('\n').map(Number);
|
||||
const daysLeft = Math.floor((new Date('9999-12-31T23:59:59.999Z') - new Date()) / 1000 / 60 / 60 / 24);
|
||||
const currentDate = new Date();
|
||||
const currentVersion = fs.readFileSync(path.join(__dirname, 'version.txt'), 'utf8').trim();
|
||||
const randomToken = crypto.randomBytes(16).toString('hex');
|
||||
|
||||
// Functions
|
||||
function parseBoundary(data, boundary) {
|
||||
const parts = data.split(`--${boundary}`).filter(part => part.trim() && part !== '--');
|
||||
const formData = {};
|
||||
|
||||
parts.forEach(part => {
|
||||
const match = /Content-Disposition: form-data; name="([^"]+)"\r\n\r\n([\s\S]+)/.exec(part);
|
||||
if (match) {
|
||||
formData[match[1]] = match[2].trim();
|
||||
}
|
||||
});
|
||||
|
||||
return formData;
|
||||
}
|
||||
|
||||
function buildMultipartBody(data, boundary) {
|
||||
let body = '';
|
||||
for (const [key, value] of Object.entries(data)) {
|
||||
body += `--${boundary}\r\nContent-Disposition: form-data; name="${key}"\r\n\r\n${value}\r\n`;
|
||||
}
|
||||
body += `--${boundary}--\r\n`;
|
||||
return body;
|
||||
}
|
||||
|
||||
function modifyDRMRequest(session, request) {
|
||||
if (request.headers['content-type'] && request.headers['content-type'].includes('multipart/form-data')) {
|
||||
const boundaryMatch = /boundary=(.+)/.exec(request.headers['content-type']);
|
||||
if (boundaryMatch) {
|
||||
const boundary = boundaryMatch[1];
|
||||
const formData = parseBoundary(request.body.buffer.toString(), boundary);
|
||||
const patchedData = session.patchBoundary(formData);
|
||||
const newBody = buildMultipartBody(patchedData, boundary);
|
||||
|
||||
request.body = Buffer.from(newBody);
|
||||
request.headers['content-length'] = Buffer.byteLength(newBody).toString();
|
||||
}
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
// Runtime
|
||||
const ticket = ['1'];
|
||||
productList.forEach((product) => {
|
||||
ticket.push(`${product}:${253402300799}`);
|
||||
});
|
||||
ticket.push(`VP:${daysLeft}`);
|
||||
ticket.push(`OV:${currentVersion}`);
|
||||
ticket.push('BV:');
|
||||
ticket.push(`AD:1`);
|
||||
ticket.push('SUB:');
|
||||
ticket.push('UT:0');
|
||||
ticket.push('ML:1-11-1');
|
||||
ticket.push(`S:${randomToken}`);
|
||||
ticket.push(`TI:${Math.floor(currentDate.getTime() / 1000)}`);
|
||||
ticket.push('TM:0');
|
||||
|
||||
// Proxy
|
||||
(async () => {
|
||||
const https = await mockttp.generateCACertificate();
|
||||
const proxyServer = mockttp.getLocal({ https });
|
||||
const session = new Session();
|
||||
|
||||
proxyServer.forPost(/https:\/\/.+\/auth\/v[0-5]+\//).thenReply(200,
|
||||
ticket.join('|')
|
||||
);
|
||||
|
||||
proxyServer.forPost(/https:\/\/.+\/ak\/uc_v[0-9]+\//).thenPassThrough({
|
||||
beforeRequest: async (request) => {
|
||||
modifyDRMRequest(session, request);
|
||||
}
|
||||
});
|
||||
|
||||
proxyServer.forPost(/http:\/\/ssl\.dvdfab\.cn\/auth\/trial_disc.php/).thenPassThrough({
|
||||
beforeRequest: async (request) => {
|
||||
modifyDRMRequest(session, request);
|
||||
}
|
||||
});
|
||||
|
||||
proxyServer.forPost(/https:\/\/ssl.dvdfab.cn\/update\/recommend.php/).thenReply(200,
|
||||
'{"cscode":0,"version":1,"enable":true,"data":[]}',
|
||||
{ 'content-type': 'text/html' }
|
||||
);
|
||||
|
||||
proxyServer.forPost(/https:\/\/ssl-jp.dvdfab.cn\/ak\/v[0-9]+\/st\//).thenPassThrough({
|
||||
beforeRequest: async (request) => {
|
||||
modifyDRMRequest(session, request);
|
||||
}
|
||||
});
|
||||
|
||||
proxyServer.forPost(/https:\/\/.+\/client\/command/).thenCloseConnection();
|
||||
|
||||
proxyServer.forPost(/https:\/\/servo-slave-.+\.dvdfab\.cn\/recommend\/client\/best\/list/).thenReply(200,
|
||||
'{"cscode":200,"version":"1.0.0","data":[]}',
|
||||
{ 'content-type': 'application/json' }
|
||||
);
|
||||
|
||||
proxyServer.forPost(/https:\/\/app-api-c[0-9]+\.dvdfab\.cn\/api\/info_control\//).thenReply(200,
|
||||
'{"result":{"res":"true","msg":"ok","data":[]}}',
|
||||
{ 'content-type': 'text/html; charset=UTF-8' }
|
||||
);
|
||||
|
||||
proxyServer.forPost(/https:\/\/drm-u[0-9]+\.dvdfab\.cn\/ak\/re\/downloadex\//).thenReply(200,
|
||||
'{"R":"0","num":100,"count":"100"}',
|
||||
{ 'content-type': 'text/html; charset=UTF-8' }
|
||||
);
|
||||
|
||||
proxyServer.forPost(/https:\/\/drm-u[0-9]+\.dvdfab\.cn\/ak\/re\/keycheck\//).thenReply(200,
|
||||
'{"R":"0","ret":"success"}',
|
||||
{ 'content-type': 'text/html; charset=UTF-8' }
|
||||
);
|
||||
|
||||
proxyServer.forPost(/https:\/\/app-api-c[0-9]+\.dvdfab\.cn\/api\/common_json_post\//).thenReply(200,
|
||||
'{"result":{"res":true,"msg":"NO_ERROR"}}'
|
||||
);
|
||||
|
||||
proxyServer.forPost(/https:\/\/.+\/\/products\/client_upgrade_license_v2/).thenCloseConnection();
|
||||
|
||||
await proxyServer.forUnmatchedRequest().thenPassThrough();
|
||||
|
||||
proxyServer.start(8000)
|
||||
|
||||
console.log();
|
||||
console.log(' +=============================================================+');
|
||||
console.log(' | DVDFab Server Emulator has started... |');
|
||||
console.log(' | You may now use any DVDFab software. |');
|
||||
console.log(' +=============================================================+');
|
||||
console.log(' | If you got this script from anywhere apart from |');
|
||||
console.log(' | The CDM-Project, you likely have a malicious copy. |');
|
||||
console.log(' +=============================================================+');
|
||||
console.log(' | ONCE YOU ARE READY, DO NOT JUST CLOSE THE EMULATOR! |');
|
||||
console.log(' | Using CTRL-C will properly disconnect you from the proxy. |');
|
||||
console.log(' | If you used the CLOSE BUTTON, run the \'stop.bat\' script. |');
|
||||
console.log(' +=============================================================+');
|
||||
console.log();
|
||||
})();
|
5
stop.bat
Normal file
5
stop.bat
Normal file
@ -0,0 +1,5 @@
|
||||
@echo off
|
||||
taskkill /f /im "node.exe*"
|
||||
setx http_proxy ""
|
||||
setx https_proxy ""
|
||||
exit /b 0
|
1
version.txt
Normal file
1
version.txt
Normal file
@ -0,0 +1 @@
|
||||
6197
|
Loading…
Reference in New Issue
Block a user