cdp-core 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # CDP Solver
2
+
3
+ Stealth Exam Assistant for Testpad.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -g cdp-exam-solver
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ On your other laptop, simply run:
14
+
15
+ ```bash
16
+ npx -y cdp-exam-solver
17
+ ```
18
+
19
+ ### What it does:
20
+ 1. It searches for **Testpad** or **Chrome** on your PC.
21
+ 2. It automatically launches them with the required debugging port (`9222`).
22
+ 3. It starts the solver injector.
23
+
24
+ *Note: If it can't find your browser automatically, you can still launch it manually with `--remote-debugging-port=9222`.*
25
+
26
+ ### Hotkeys
27
+
28
+ - **Ctrl + Shift + G**: Solve & Show (Ghost Panel)
29
+ - **Ctrl + Shift + H**: Toggle Hide/Unhide Panel
30
+ - **Ctrl + Shift + S**: Force Start Bypass
31
+
32
+ ## Description
33
+
34
+ This tool injects a stealth solver script into a Chrome/Edge instance running with Remote Debugging enabled (port 9222). It uses the Groq API (Llama 3) to provide brief solutions to questions on the page.
35
+
36
+ ## Requirements
37
+
38
+ - Chrome/Edge running with `--remote-debugging-port=9222`
39
+ - Node.js installed
package/cdp_inject.js ADDED
@@ -0,0 +1,226 @@
1
+ #!/usr/bin/env node
2
+ const http = require('http');
3
+ const https = require('https');
4
+ const WebSocket = require('ws');
5
+ const { exec } = require('child_process');
6
+ const path = require('path');
7
+ const fs = require('fs');
8
+
9
+ const CDP_PORT = 9222;
10
+ const GROQ_KEYS = [
11
+ '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',
12
+ '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',
13
+ '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'
14
+ ];
15
+
16
+ let keyIndex = 0;
17
+ function getNextKey() {
18
+ const key = GROQ_KEYS[keyIndex];
19
+ keyIndex = (keyIndex + 1) % GROQ_KEYS.length;
20
+ return key;
21
+ }
22
+
23
+ function launchBrowser() {
24
+ const p = "C:\\Users\\ASUS\\AppData\\Local\\Programs\\testpad\\testpad.exe";
25
+ if (fs.existsSync(p)) exec(`start "" "${p}" --remote-debugging-port=${CDP_PORT}`);
26
+ }
27
+
28
+ const SOLVER_SCRIPT = `
29
+ (function() {
30
+ if (window.__cdpActiveV1) return;
31
+ window.__cdpActiveV1 = true;
32
+
33
+ // KILL all old ghost and cdp versions so they stop calling fetch()
34
+ window.__ghostActive = true;
35
+ window.__ghostActiveV15 = true;
36
+ window.__ghostActiveV17 = true;
37
+ window.__ghostActiveV20 = true;
38
+ window.__ghostActiveV21 = true;
39
+ window.__cdpActive = true;
40
+
41
+ // Block any leftover fetch calls to groq from old scripts
42
+ const origFetch = window.fetch;
43
+ window.fetch = function(url) {
44
+ if (typeof url === 'string' && url.includes('groq.com')) {
45
+ return Promise.resolve(new Response(JSON.stringify({choices:[{message:{content:'{"type":"mcq","answer":"blocked"}'}}]}), {headers:{'Content-Type':'application/json'}}));
46
+ }
47
+ return origFetch.apply(this, arguments);
48
+ };
49
+
50
+ let cachedCodeLines = [];
51
+ let currentLineIndex = 0;
52
+ let keysDown = {};
53
+
54
+ window.addEventListener('blur', () => { keysDown = {}; });
55
+
56
+ // Handle incoming solutions from backend
57
+ window.__cdpReceive = function(data) {
58
+ if (data.type === 'mcq') {
59
+ const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT);
60
+ let node;
61
+ while (node = walker.nextNode()) {
62
+ if (node.textContent.includes(data.answer)) {
63
+ const p = node.parentElement;
64
+ const oldSize = p.style.fontSize;
65
+ p.style.fontSize = (parseFloat(window.getComputedStyle(p).fontSize) + 2) + 'px';
66
+ p.scrollIntoView({ behavior: 'smooth', block: 'center' });
67
+ setTimeout(() => { p.style.fontSize = oldSize; }, 5000);
68
+ break;
69
+ }
70
+ }
71
+ } else if (data.type === 'code') {
72
+ cachedCodeLines = data.answer.split('\\n').filter(l => l.trim() !== '');
73
+ currentLineIndex = 0;
74
+ }
75
+ };
76
+
77
+ document.addEventListener('keydown', async (e) => {
78
+ const code = e.code || e.key;
79
+ keysDown[code] = true;
80
+ const bothDown = (keysDown['ArrowLeft'] || keysDown['Left']) && (keysDown['ArrowRight'] || keysDown['Right']);
81
+
82
+ if (code === 'CapsLock' || bothDown) {
83
+ e.preventDefault(); e.stopPropagation();
84
+ const content = document.body.innerText;
85
+ if (content.length > 10) console.warn('_cdp_solve_: ' + btoa(unescape(encodeURIComponent(content))));
86
+ }
87
+
88
+ if (code === 'Tab' && cachedCodeLines.length > 0) {
89
+ const el = document.activeElement;
90
+ if (el && (el.tagName === 'TEXTAREA' || el.classList.contains('monaco-editor') || el.contentEditable === 'true')) {
91
+ e.preventDefault(); e.stopPropagation();
92
+ if (currentLineIndex < cachedCodeLines.length) {
93
+ console.warn('_cdp_type_: ' + btoa(unescape(encodeURIComponent(cachedCodeLines[currentLineIndex] + '\\n'))));
94
+ currentLineIndex++;
95
+ }
96
+ }
97
+ }
98
+ }, true);
99
+
100
+ document.addEventListener('keyup', (e) => { keysDown[e.code || e.key] = false; }, true);
101
+ })();
102
+ `;
103
+
104
+ async function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }
105
+
106
+ async function typeText(ws, text) {
107
+ for (const char of text) {
108
+ ws.send(JSON.stringify({ id: Math.floor(Math.random()*1000), method: 'Input.insertText', params: { text: char } }));
109
+ await sleep(60 + Math.floor(Math.random() * 80));
110
+ }
111
+ }
112
+
113
+ async function solveQuestion(ws, content) {
114
+ const key = getNextKey();
115
+ console.log('[cdp] 🤖 Solving hidden request...');
116
+
117
+ const groqResp = await new Promise((res) => {
118
+ const req = https.request({
119
+ hostname: 'api.groq.com',
120
+ path: '/openai/v1/chat/completions',
121
+ method: 'POST',
122
+ headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + key }
123
+ }, (r) => {
124
+ let d = ''; r.on('data', (c) => d += c); r.on('end', () => res(d));
125
+ });
126
+ req.write(JSON.stringify({
127
+ model: 'llama-3.3-70b-versatile',
128
+ messages: [
129
+ {role: 'system', content: 'You are an Elite Competitive Programmer. Your goal is 100% accuracy. \nSTEP 1: Analyze the problem constraints and edge cases. \nSTEP 2: Brainstorm the most efficient DSA approach (O(n log n) or better). \nSTEP 3: Write the implementation. \nSTEP 4: Double-check for syntax errors or logical flaws. \nReturn ONLY JSON: {"type":"mcq", "answer":"exact text"} or {"type":"code", "answer":"clean C++ code"}.'},
130
+ {role: 'user', content: 'Solve this problem perfectly: ' + content}
131
+ ],
132
+ response_format: { type: "json_object" },
133
+ temperature: 0.1 // Low temperature for high precision
134
+ }));
135
+ req.end();
136
+ });
137
+
138
+ try {
139
+ const data = JSON.parse(groqResp);
140
+ const answer = data.choices[0].message.content;
141
+ ws.send(JSON.stringify({
142
+ id: Math.floor(Math.random()*1000),
143
+ method: 'Runtime.evaluate',
144
+ params: { expression: `window.__cdpReceive(${answer})` }
145
+ }));
146
+ console.log('[cdp] ✅ Solution injected silently.');
147
+ } catch (e) { console.error('[cdp] AI Error: ' + e.message); }
148
+ }
149
+
150
+ async function main() {
151
+ let launchAttempted = false;
152
+ const activeConnections = new Set();
153
+ console.log('[cdp] SILENT DATA CHANNEL MODE: v1.0.2 (Absolute Stealth)');
154
+
155
+ while (true) {
156
+ try {
157
+ const targets = await new Promise((res, rej) => {
158
+ http.get('http://127.0.0.1:' + CDP_PORT + '/json', (r) => {
159
+ let d = ''; r.on('data', (c) => d += c); r.on('end', () => res(JSON.parse(d)));
160
+ }).on('error', rej);
161
+ });
162
+ const pages = targets.filter(t => t.type === 'page' && t.webSocketDebuggerUrl);
163
+ for (const t of pages) {
164
+ if (activeConnections.has(t.id)) continue;
165
+ activeConnections.add(t.id);
166
+ const ws = new WebSocket(t.webSocketDebuggerUrl.replace('localhost', '127.0.0.1'));
167
+ ws.on('open', () => {
168
+ ws.send(JSON.stringify({ id: 1, method: 'Page.enable' }));
169
+ ws.send(JSON.stringify({ id: 2, method: 'Runtime.enable' }));
170
+ ws.send(JSON.stringify({ id: 3, method: 'Fetch.enable', params: { patterns: [{ requestStage: 'Request' }] } }));
171
+ ws.send(JSON.stringify({ id: 4, method: 'Page.setBypassCSP', params: { enabled: true } }));
172
+ ws.send(JSON.stringify({ id: 5, method: 'Page.addScriptToEvaluateOnNewDocument', params: { source: SOLVER_SCRIPT } }));
173
+ ws.send(JSON.stringify({ id: 6, method: 'Runtime.evaluate', params: { expression: SOLVER_SCRIPT } }));
174
+ });
175
+ ws.on('message', async (msg) => {
176
+ const resp = JSON.parse(msg);
177
+ if (resp.method === 'Fetch.requestPaused') {
178
+ const { requestId, request } = resp.params;
179
+ const cmdId = Math.floor(Math.random()*1000000);
180
+ if (request.url.includes('/test/cdp-solver') || request.url.includes('/test/ghost-solver')) {
181
+ if (request.url.includes('json') || (request.headers && request.headers['Accept'] && request.headers['Accept'].includes('application/json'))) {
182
+ const jsonBody = Buffer.from(JSON.stringify({ quiz: true, id: "cdp-solver", name: "End Term Assessment", status: "active", duration: 3600 })).toString('base64');
183
+ ws.send(JSON.stringify({ id: cmdId, method: 'Fetch.fulfillRequest', params: { requestId, responseCode: 200, responseHeaders: [{name: 'Content-Type', value: 'application/json'}], body: jsonBody } }));
184
+ } else {
185
+ const htmlData = fs.readFileSync(path.join(__dirname, 'demo_test.html'));
186
+ ws.send(JSON.stringify({ id: cmdId, method: 'Fetch.fulfillRequest', params: { requestId, responseCode: 200, responseHeaders: [{name: 'Content-Type', value: 'text/html'}], body: htmlData.toString('base64') } }));
187
+ }
188
+ } else {
189
+ ws.send(JSON.stringify({ id: cmdId, method: 'Fetch.continueRequest', params: { requestId } }));
190
+ }
191
+ }
192
+ if (resp.method === 'Runtime.consoleAPICalled') {
193
+ const text = resp.params.args.map(a => a.value).join(' ');
194
+ // Log everything with [cdp] for debugging
195
+ if (text.includes('[cdp]')) console.log(text);
196
+ if (text.includes('_cdp_solve_: ')) {
197
+ console.log('[cdp] 🔍 Solve request received');
198
+ const b64 = text.split('_cdp_solve_: ')[1];
199
+ const content = Buffer.from(b64, 'base64').toString('utf-8');
200
+ solveQuestion(ws, content);
201
+ } else if (text.includes('_cdp_type_: ')) {
202
+ console.log('[cdp] ⌨️ Type request received');
203
+ const b64 = text.split('_cdp_type_: ')[1];
204
+ const content = Buffer.from(b64, 'base64').toString('utf-8');
205
+ typeText(ws, content);
206
+ }
207
+ }
208
+ });
209
+ ws.on('close', () => activeConnections.delete(t.id));
210
+ ws.on('error', () => activeConnections.delete(t.id));
211
+ }
212
+ } catch (e) { if (!launchAttempted) { launchBrowser(); launchAttempted = true; } }
213
+ await new Promise(r => setTimeout(r, 1000));
214
+ }
215
+ }
216
+
217
+ if (process.argv.includes('--stop')) {
218
+ console.log('[cdp] Stopping all background solvers...');
219
+ exec('taskkill /F /IM node.exe', () => process.exit(0));
220
+ } else if (process.argv.includes('--detach')) {
221
+ const out = fs.openSync(path.join(__dirname, 'cdp.log'), 'a');
222
+ const child = require('child_process').spawn('node', [__filename], { detached: true, stdio: ['ignore', out, out] });
223
+ child.unref();
224
+ console.log('[cdp] Launched in background. Logs: ' + path.join(__dirname, 'cdp.log'));
225
+ process.exit(0);
226
+ } else { main(); }
package/demo_test.html ADDED
@@ -0,0 +1,83 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>DSA Final Assessment</title>
6
+ <style>
7
+ :root { --bg: #0f172a; --card: #1e293b; --primary: #38bdf8; --text: #f8fafc; }
8
+ body { background: var(--bg); color: var(--text); font-family: sans-serif; margin: 0; display: flex; flex-direction: column; height: 100vh; }
9
+ header { padding: 20px 40px; background: var(--card); border-bottom: 1px solid #334155; display: flex; justify-content: space-between; }
10
+ .container { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 40px; }
11
+ .card { background: var(--card); padding: 30px; border-radius: 12px; width: 100%; max-width: 800px; border: 1px solid #334155; min-height: 400px; }
12
+ .option { padding: 15px; margin: 10px 0; background: #334155; border-radius: 8px; cursor: pointer; transition: 0.2s; }
13
+ .option:hover { background: #475569; }
14
+ textarea { width: 100%; height: 300px; background: #020617; color: #10b981; font-family: monospace; padding: 15px; border-radius: 8px; resize: none; border: 1px solid #334155; }
15
+ .footer { margin-top: 20px; width: 100%; max-width: 800px; display: flex; justify-content: space-between; align-items: center; }
16
+ button { padding: 12px 30px; background: var(--primary); color: #000; border: none; border-radius: 6px; font-weight: bold; cursor: pointer; }
17
+ </style>
18
+ </head>
19
+ <body>
20
+ <header>
21
+ <span style="font-weight: bold;">DSA Advanced Certification</span>
22
+ <span id="timer">44:59</span>
23
+ </header>
24
+ <div class="container">
25
+ <div class="card" id="q-card"></div>
26
+ <div class="footer">
27
+ <span id="progress"></span>
28
+ <button onclick="nextQ()">Next Question</button>
29
+ </div>
30
+ </div>
31
+ <script>
32
+ const qs = [
33
+ {t:'mcq', q:'What is the amortized complexity of DSU with path compression and union by rank?', o:['O(log n)','O(n)','O(alpha(n))','O(1)'], a:'alpha(n)'},
34
+ {t:'mcq', q:'Worst case of Red-Black Tree search?', o:['O(n)','O(log n)','O(n log n)','O(1)'], a:'O(log n)'},
35
+ {t:'mcq', q:'Which algorithm is used for All-Pairs Shortest Path?', o:['Dijkstra','Bellman-Ford','Floyd-Warshall','Kruskal'], a:'Floyd-Warshall'},
36
+ {t:'mcq', q:'Stable sorting algorithm?', o:['Quick Sort','Heap Sort','Merge Sort','Selection Sort'], a:'Merge Sort'},
37
+ {t:'mcq', q:'B-Tree primary use case?', o:['In-memory cache','Disk-based databases','Sorting','Graph traversal'], a:'Disk-based databases'},
38
+ {t:'mcq', q:'Max nodes in a binary tree of height h?', o:['2h','2^h','2^(h+1)-1','h^2'], a:'2^(h+1)-1'},
39
+ {t:'mcq', q:'Space complexity of an adjacency matrix for graph with V nodes?', o:['O(V)','O(V+E)','O(V^2)','O(E)'], a:'O(V^2)'},
40
+ {t:'mcq', q:'Which data structure implements a Priority Queue efficiently?', o:['Stack','Linked List','Binary Heap','Array'], a:'Binary Heap'},
41
+ {t:'mcq', q:'Best case of Bubble Sort with optimization?', o:['O(n^2)','O(n log n)','O(n)','O(1)'], a:'O(n)'},
42
+ {t:'mcq', q:'Complexity of Segment Tree construction?', o:['O(n)','O(log n)','O(n log n)','O(1)'], a:'O(n)'},
43
+ {t:'code', q:'Balanced Parentheses', b:'bool isBalanced(string s) {\n // Type implementation here\n}'},
44
+ {t:'code', q:'Reverse a Linked List', b:'ListNode* reverseList(ListNode* head) {\n // Type implementation here\n}'},
45
+ {t:'code', q:'Kadane\'s Algorithm', b:'int maxSubArray(vector<int>& nums) {\n // Type implementation here\n}'}
46
+ ];
47
+ let cur = 0;
48
+ function render() {
49
+ const q = qs[cur];
50
+ const card = document.getElementById('q-card');
51
+ document.getElementById('progress').innerText = `Question ${cur+1} of ${qs.length}`;
52
+ let h = `<h2>${q.q}</h2>`;
53
+ if (q.t === 'mcq') {
54
+ h += q.o.map(o => `<div class="option">${o}</div>`).join('');
55
+ } else {
56
+ h += `<textarea>${q.b}</textarea>`;
57
+ }
58
+ card.innerHTML = h;
59
+
60
+ if (q.t === 'code') {
61
+ const area = card.querySelector('textarea');
62
+ area.addEventListener('paste', (e) => {
63
+ e.preventDefault();
64
+ alert('⚠️ WARNING: Paste Event Detected!');
65
+ });
66
+
67
+ area.addEventListener('input', (e) => {
68
+ if (e.inputType === 'insertFromPaste') {
69
+ alert('⚠️ WARNING: insertFromPaste Detected!');
70
+ } else if (e.data && e.data.length > 1) {
71
+ alert('⚠️ WARNING: Block Input Detected (' + e.data.length + ' chars)!');
72
+ }
73
+ });
74
+ }
75
+ }
76
+ function nextQ() {
77
+ if (cur < qs.length - 1) { cur++; render(); }
78
+ else { alert('Finished!'); }
79
+ }
80
+ render();
81
+ </script>
82
+ </body>
83
+ </html>
package/mock_server.js ADDED
@@ -0,0 +1,39 @@
1
+ const http = require('http');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+
5
+ const PORT = 3003;
6
+
7
+ http.createServer((req, res) => {
8
+ console.log(`[Mock Server] Received request: ${req.method} ${req.url}`);
9
+
10
+ // CORS headers
11
+ res.setHeader('Access-Control-Allow-Origin', '*');
12
+ res.setHeader('Access-Control-Allow-Headers', '*');
13
+
14
+ if (req.method === 'OPTIONS') {
15
+ res.writeHead(200);
16
+ return res.end();
17
+ }
18
+
19
+ // Testpad appends ?json=1 to the URL when it does its background security check
20
+ if (req.url.includes('json=1')) {
21
+ res.writeHead(200, { 'Content-Type': 'application/json' });
22
+ return res.end(JSON.stringify({ quiz: true, id: "mock-test" }));
23
+ }
24
+
25
+ // Otherwise, we serve the HTML exam UI
26
+ try {
27
+ const html = fs.readFileSync(path.join(__dirname, 'demo_test.html'));
28
+ res.writeHead(200, { 'Content-Type': 'text/html' });
29
+ res.end(html);
30
+ } catch (e) {
31
+ res.writeHead(500);
32
+ res.end('Error loading demo_test.html');
33
+ }
34
+ }).listen(PORT, () => {
35
+ console.log(`[Mock Server] Running on http://localhost:${PORT}`);
36
+ console.log(`[Mock Server] 1. Keep this terminal open.`);
37
+ console.log(`[Mock Server] 2. Open your modified Testpad App.`);
38
+ console.log(`[Mock Server] 3. Click the Start Test button (it will auto-redirect to this mock test).`);
39
+ });
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "cdp-core",
3
+ "version": "1.0.2",
4
+ "description": "Stealth Exam Assistant for Testpad",
5
+ "main": "cdp_inject.js",
6
+ "bin": {
7
+ "cdp-core": "cdp_inject.js"
8
+ },
9
+ "files": [
10
+ "*.js",
11
+ "*.html"
12
+ ],
13
+ "dependencies": {
14
+ "ws": "^8.13.0"
15
+ },
16
+ "scripts": {
17
+ "start": "node cdp_inject.js"
18
+ },
19
+ "author": "",
20
+ "license": "ISC"
21
+ }
22
+