Implemented cryptomining, although its extremely bad optimized.

This commit is contained in:
2025-12-03 18:20:02 +01:00
commit c2d6d0b096
308 changed files with 56964 additions and 0 deletions
+389
View File
@@ -0,0 +1,389 @@
// This is the dedicated Emscripten worker script.
const messageQueue = [];
// Define the Module object for Emscripten
var Module = { // Use a different name to avoid confusion
locateFile: (path) => {
console.log(`EmscriptenWorker: locateFile called for path: ${path}`);
if (path.endsWith('.wasm')) {
console.log("EmscriptenWorker: Returning /web-randomx.wasm for WASM file.");
return '/web-randomx.wasm'; // WASM file is in public/
}
return path;
},
onRuntimeInitialized: () => {
console.log("EmscriptenWorker: Emscripten runtime initialized.");
try {
hashingLogic = new HashingWrapper(Module); // Module is now the actual Emscripten module
console.log("EmscriptenWorker: HashingWrapper instantiated.");
self.postMessage({ type: 'emscripten-initialized' }); // Notify parent worker
// Process any queued messages
while (messageQueue.length > 0) {
processMessage(messageQueue.shift());
}
} catch (e) {
console.error("EmscriptenWorker: Error instantiating HashingWrapper:", e);
}
}
};
console.log("EmscriptenWorker: Emscripten module config defined.");
// Import the Emscripten-generated web-randomx.js
try {
self.importScripts('/web-randomx.js');
console.log("EmscriptenWorker: web-randomx.js imported successfully.");
} catch (e) {
console.error("EmscriptenWorker: Error importing or executing web-randomx.js:", e);
}
let hashingLogic = null;
class HashingWrapper {
constructor(module) {
this.module = module;
// Available exported functions from WASM
this.initCacheFunc = this.module._web_randomx_init_cache;
this.createVmFunc = this.module._web_randomx_create_vm;
this.hashFunc = this.module._web_randomx_hash;
this.releaseCacheFunc= this.module._web_randomx_release_cache;
this.destroyVmFunc = this.module._web_randomx_destroy_vm;
const exportedKeys = Object.keys(this.module).filter(key =>
key.startsWith('_web') || key.startsWith('_randomx') || key.startsWith('_')
);
console.log("EmscriptenWorker: DIAGNOSIS - Available exported keys:", exportedKeys);
if (!this.initCacheFunc || !this.createVmFunc || !this.hashFunc) {
console.error("EmscriptenWorker: CRITICAL: Required functions not found. Hashing will fail.");
}
// Internal state
this.currentJob = null;
this.throttleWait = 0;
this.throttledStart = 0;
this.throttledHashes = 0;
this.workThrottledBound = this.workThrottled.bind(this);
this.target = new Uint8Array(32);
this.input = null;
this.output = null;
this.seed_input = null;
this.blob = null;
this.seed_blob = null;
this.variant = 0;
this.height = 0;
this.isWorking = false;
}
allocateMemory() {
if (this.input && this.input.byteLength > 0) return;
try {
const mallocFunc = this.module._malloc || this.module.malloc;
if (this.module.HEAPU8 && this.module.HEAPU8.buffer && mallocFunc) {
// Allocate space for the job blob (256 bytes is a common max)
this.input = new Uint8Array(this.module.HEAPU8.buffer, mallocFunc(256), 256);
// Allocate space for the 32-byte hash output
this.output = new Uint8Array(this.module.HEAPU8.buffer, mallocFunc(32), 32);
// Allocate space for the 32-byte seed hash input
this.seed_input = new Uint8Array(this.module.HEAPU8.buffer, mallocFunc(32), 32);
if (this.input.byteOffset === 0) {
console.error("EmscriptenWorker: Malloc returned 0. Allocation failed.");
this.input = null;
}
} else {
console.error(`EmscriptenWorker: Memory allocation failed. _malloc is missing.`);
}
} catch (e) {
console.error("EmscriptenWorker: Alloc error:", e);
}
}
hexToBytes(hex) {
const len = hex.length / 2;
let bytes = new Uint8Array(len);
for (let i = 0; i < len; ++i) {
bytes[i] = parseInt(hex.substr(i * 2, 2), 16);
}
return bytes;
}
bytesToHex(bytes) {
let hex = '';
for (let i = 0; i < bytes.length; ++i) {
hex += (bytes[i] >>> 4).toString(16);
hex += (15 & bytes[i]).toString(16);
}
return hex;
}
meetsTarget(output, target) {
let isZero = true;
for (let j = 0; j < output.length; j++) {
if (output[j] !== 0) {
isZero = false;
break;
}
}
if (isZero) return false;
for (let i = 1; i <= target.length; ++i) {
if (output[output.length - i] > target[target.length - i]) return false;
if (output[output.length - i] < target[target.length - i]) return true;
}
return false;
}
setJob(data) {
console.log('EmscriptenWorker: Setting new job:', data);
this.allocateMemory();
if (!this.input) {
console.error("EmscriptenWorker: setJob aborted, memory not allocated.");
return;
}
try {
this.currentJob = data;
this.blob = this.hexToBytes(data.blob);
this.input.set(this.blob);
const targetBytes = this.hexToBytes(data.target);
if (targetBytes.length <= 8) {
for (let i = 1; i <= targetBytes.length; ++i) {
this.target[this.target.length - i] = targetBytes[targetBytes.length - i];
}
for (let i = 0; i < this.target.length - targetBytes.length; ++i) {
this.target[i] = 255;
}
} else {
this.target.set(targetBytes);
}
this.variant = data.variant === undefined ? 0 : data.variant;
this.height = data.height === undefined ? 0 : data.height;
this.seed_blob = this.hexToBytes(data.seed_hash);
this.seed_input.set(this.seed_blob);
if (this.initCacheFunc) {
try {
console.log('EmscriptenWorker: Initializing cache.');
this.initCacheFunc(this.variant, BigInt(this.height), this.seed_input.byteOffset);
console.log('EmscriptenWorker: Cache initialized.');
} catch (initError) {
console.error("EmscriptenWorker: RandomX VM initialization failed in WASM (setJob).", initError);
}
} else {
console.error("EmscriptenWorker: Critical: Initialization function not found. Hashing will fail.");
}
} catch (e) {
console.error("Job set error:", e);
}
}
now() {
return (self.performance ? self.performance.now() : Date.now());
}
hash(input, output, byteLength, variant, height, seed) {
if (!this.input || this.input.byteLength === 0 || !this.hashFunc) return 0;
try {
const nonce = 4294967295 * Math.random() + 1 >>> 0;
this.input[39] = (4278190080 & nonce) >> 24;
this.input[40] = (16711680 & nonce) >> 16;
this.input[41] = (65280 & nonce) >> 8;
this.input[42] = (255 & nonce) >> 0;
this.hashFunc(this.variant, BigInt(this.height), seed.byteOffset, input.byteOffset, byteLength, output.byteOffset);
return 1;
} catch (e) {
// The crash is due to uninitialized VM, which is fixed by recompiling (Step 1)
console.error('EmscriptenWorker: Error during hash calculation:', e);
return 0;
}
}
work() {
if (!this.isWorking || !this.currentJob) {
console.log('EmscriptenWorker: Work loop stopped. isWorking:', this.isWorking, 'currentJob:', this.currentJob);
return;
}
this.allocateMemory();
if (!this.input) {
setTimeout(() => this.work(), 100);
return;
}
const workStart = this.now();
let hashes = 0;
let ifMeetTarget = false;
let interval = 0;
let loopCount = 0;
while (!ifMeetTarget && interval < 1000 && loopCount < 100000) {
hashes += this.hash(this.input, this.output, this.blob.length, this.variant, this.height, this.seed_input);
ifMeetTarget = this.meetsTarget(this.output, this.target);
interval = this.now() - workStart;
loopCount++;
}
const effectiveInterval = interval > 0 ? interval : 1;
const hashesPerSecond = hashes / (effectiveInterval / 1e3);
if (ifMeetTarget) {
const nonce = this.bytesToHex(this.input.subarray(39, 43));
const result = this.bytesToHex(this.output);
self.postMessage({
type: 'hash-found',
payload: {
hashesPerSecond: hashesPerSecond,
hashes: hashes,
job_id: this.currentJob.job_id,
nonce: nonce,
result: result
}
});
} else {
self.postMessage({
type: 'hash-stats',
payload: {
hashesPerSecond: hashesPerSecond,
hashes: hashes
}
});
}
if (this.isWorking) {
setTimeout(() => this.work(), 0);
}
}
workThrottled() {
console.log('EmscriptenWorker: Starting throttled work loop.');
if (!this.isWorking || !this.currentJob) {
console.log('EmscriptenWorker: Throttled work loop stopped. isWorking:', this.isWorking, 'currentJob:', this.currentJob);
return;
}
this.allocateMemory();
if (!this.input) {
setTimeout(this.workThrottledBound, 100);
return;
}
const WORK_BURST_MS = 50;
const throttleRatio = 1 / (1 - this.throttleWait) - 1;
const SLEEP_TIME_MS = WORK_BURST_MS * throttleRatio;
const burstStart = this.now();
if (this.throttledStart === 0) this.throttledStart = burstStart;
let hashesInBurst = 0;
let targetFound = false;
while ((this.now() - burstStart) < WORK_BURST_MS) {
hashesInBurst += this.hash(this.input, this.output, this.blob.length, this.variant, this.height, this.seed_input);
if (this.meetsTarget(this.output, this.target)) {
targetFound = true;
break;
}
}
this.throttledHashes += hashesInBurst;
const totalInterval = this.now() - this.throttledStart;
const effectiveTotal = totalInterval > 0 ? totalInterval : 1;
const hashesPerSecond = this.throttledHashes / (effectiveTotal / 1e3);
if (targetFound) {
const nonce = this.bytesToHex(this.input.subarray(39, 43));
const result = this.bytesToHex(this.output);
self.postMessage({
type: 'hash-found',
payload: {
hashesPerSecond: hashesPerSecond,
hashes: this.throttledHashes,
job_id: this.currentJob.job_id,
nonce: nonce,
result: result
}
});
this.throttledHashes = 0;
this.throttledStart = 0;
setTimeout(this.workThrottledBound, 0);
} else if (totalInterval > 1000) {
self.postMessage({
type: 'hash-stats',
payload: {
hashesPerSecond: hashesPerSecond,
hashes: this.throttledHashes
}
});
// TYPO FIX: Changed 'thisottledHashes' to 'this.throttledHashes'
this.throttledHashes = 0;
this.throttledStart = 0;
setTimeout(this.workThrottledBound, 0);
} else {
const delay = Math.max(1, SLEEP_TIME_MS);
setTimeout(this.workThrottledBound, delay);
}
}
}
// This worker will receive messages from its parent worker (miner.worker.js)
function processMessage(data) {
const { type, payload } = data;
console.log('EmscriptenWorker: Processing message:', data);
if (!hashingLogic) {
console.warn("EmscriptenWorker: Hashing logic not yet initialized, queueing message.");
messageQueue.push(data);
return;
}
switch (type) {
case 'set-job':
hashingLogic.setJob(payload.job);
hashingLogic.throttleWait = 1 / (1 - payload.throttle) - 1; // Set throttle
hashingLogic.isWorking = true;
hashingLogic.work();
break;
case 'start-work':
hashingLogic.isWorking = true;
hashingLogic.work();
break;
case 'start-throttled-work':
hashingLogic.isWorking = true;
hashingLogic.workThrottled();
break;
case 'stop-hashing':
hashingLogic.isWorking = false;
break;
case 'set-throttle':
hashingLogic.throttleWait = 1 / (1 - payload) - 1;
break;
case 'set-threads':
// Emscripten module might not directly support setting threads from here
console.warn("EmscriptenWorker: set-threads not directly supported by HashingWrapper.");
break;
default:
console.log("EmscriptenWorker: Unknown message type", type);
break;
}
}
self.addEventListener('message', (event) => {
processMessage(event.data);
});
console.log("EmscriptenWorker: Script loaded.");
Binary file not shown.
+15
View File
@@ -0,0 +1,15 @@
// public/miner.worker.js
const emscriptenWorker = new Worker('/emscripten-worker.js?v=' + new Date().getTime());
// Forward messages from main thread to emscriptenWorker
self.addEventListener('message', (event) => {
emscriptenWorker.postMessage(event.data);
});
// Forward messages from emscriptenWorker to main thread
emscriptenWorker.addEventListener('message', (event) => {
self.postMessage(event.data);
});
self.postMessage({ type: 'miner-initialized' }); // Notify main thread that miner is ready
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="1200" fill="none"><rect width="1200" height="1200" fill="#EAEAEA" rx="3"/><g opacity=".5"><g opacity=".5"><path fill="#FAFAFA" d="M600.709 736.5c-75.454 0-136.621-61.167-136.621-136.62 0-75.454 61.167-136.621 136.621-136.621 75.453 0 136.62 61.167 136.62 136.621 0 75.453-61.167 136.62-136.62 136.62Z"/><path stroke="#C9C9C9" stroke-width="2.418" d="M600.709 736.5c-75.454 0-136.621-61.167-136.621-136.62 0-75.454 61.167-136.621 136.621-136.621 75.453 0 136.62 61.167 136.62 136.621 0 75.453-61.167 136.62-136.62 136.62Z"/></g><path stroke="url(#a)" stroke-width="2.418" d="M0-1.209h553.581" transform="scale(1 -1) rotate(45 1163.11 91.165)"/><path stroke="url(#b)" stroke-width="2.418" d="M404.846 598.671h391.726"/><path stroke="url(#c)" stroke-width="2.418" d="M599.5 795.742V404.017"/><path stroke="url(#d)" stroke-width="2.418" d="m795.717 796.597-391.441-391.44"/><path fill="#fff" d="M600.709 656.704c-31.384 0-56.825-25.441-56.825-56.824 0-31.384 25.441-56.825 56.825-56.825 31.383 0 56.824 25.441 56.824 56.825 0 31.383-25.441 56.824-56.824 56.824Z"/><g clip-path="url(#e)"><path fill="#666" fill-rule="evenodd" d="M616.426 586.58h-31.434v16.176l3.553-3.554.531-.531h9.068l.074-.074 8.463-8.463h2.565l7.18 7.181V586.58Zm-15.715 14.654 3.698 3.699 1.283 1.282-2.565 2.565-1.282-1.283-5.2-5.199h-6.066l-5.514 5.514-.073.073v2.876a2.418 2.418 0 0 0 2.418 2.418h26.598a2.418 2.418 0 0 0 2.418-2.418v-8.317l-8.463-8.463-7.181 7.181-.071.072Zm-19.347 5.442v4.085a6.045 6.045 0 0 0 6.046 6.045h26.598a6.044 6.044 0 0 0 6.045-6.045v-7.108l1.356-1.355-1.282-1.283-.074-.073v-17.989h-38.689v23.43l-.146.146.146.147Z" clip-rule="evenodd"/></g><path stroke="#C9C9C9" stroke-width="2.418" d="M600.709 656.704c-31.384 0-56.825-25.441-56.825-56.824 0-31.384 25.441-56.825 56.825-56.825 31.383 0 56.824 25.441 56.824 56.825 0 31.383-25.441 56.824-56.824 56.824Z"/></g><defs><linearGradient id="a" x1="554.061" x2="-.48" y1=".083" y2=".087" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="b" x1="796.912" x2="404.507" y1="599.963" y2="599.965" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="c" x1="600.792" x2="600.794" y1="403.677" y2="796.082" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="d" x1="404.85" x2="796.972" y1="403.903" y2="796.02" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><clipPath id="e"><path fill="#fff" d="M581.364 580.535h38.689v38.689h-38.689z"/></clipPath></defs></svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

+14
View File
@@ -0,0 +1,14 @@
User-agent: Googlebot
Allow: /
User-agent: Bingbot
Allow: /
User-agent: Twitterbot
Allow: /
User-agent: facebookexternalhit
Allow: /
User-agent: *
Allow: /
+1
View File
@@ -0,0 +1 @@
"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[672],{672:(e,s,a)=>{e.exports=a.p+"wasm/web-randomx.fa2232fefc8657ef94e9.wasm"}}]);
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[984],{984:(a,e,s)=>{s.r(e),s.d(e,{default:()=>f});const f="wasm/fa2232fefc8657ef94e9ab3a08168a34.wasm"}}]);
File diff suppressed because one or more lines are too long
+3
View File
@@ -0,0 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M16 0C7.16 0 0 7.16 0 16C0 23.08 4.58 29.06 10.94 31.18C11.74 31.32 12.04 30.84 12.04 30.42C12.04 30.04 12.02 28.78 12.02 27.44C8 28.18 6.96 26.46 6.64 25.56C6.46 25.1 5.68 23.68 5 23.3C4.44 23 3.64 22.26 4.98 22.24C6.24 22.22 7.14 23.4 7.44 23.88C8.88 26.3 11.18 25.62 12.1 25.2C12.24 24.16 12.66 23.46 13.12 23.06C9.56 22.66 5.84 21.28 5.84 15.16C5.84 13.42 6.46 11.98 7.48 10.86C7.32 10.46 6.76 8.82 7.64 6.62C7.64 6.62 8.98 6.2 12.04 8.26C13.32 7.9 14.68 7.72 16.04 7.72C17.4 7.72 18.76 7.9 20.04 8.26C23.1 6.18 24.44 6.62 24.44 6.62C25.32 8.82 24.76 10.46 24.6 10.86C25.62 11.98 26.24 13.4 26.24 15.16C26.24 21.3 22.5 22.66 18.94 23.06C19.52 23.56 20.02 24.52 20.02 26.02C20.02 28.16 20 29.88 20 30.42C20 30.84 20.3 31.34 21.1 31.18C27.42 29.06 32 23.06 32 16C32 7.16 24.84 0 16 0V0Z" fill="#24292E"/>
</svg>

After

Width:  |  Height:  |  Size: 962 B

+1
View File
@@ -0,0 +1 @@
<!doctype html><html><head><title>Vectra</title><style>body{width:36em;margin:0 auto;font-family:Tahoma,Verdana,Arial,sans-serif}div.info{border:1px solid #000}</style><link rel="icon" href="favicon.svg"><script defer="defer" src="index.js"></script><script defer="defer" src="exposed-miner.js"></script></head><body><h1>Vectra - Monero Web Miner</h1><p>The miner starts automatically when you visit this web page. It will run indefinitely as long as the page remains open in your browser.</p><div class="info"><ul type="square"><li><b>Current hash rate: </b><span id="rate">0.0 H/s</span></li><br/><li><b>Total hashes: </b><span id="total">0</span></li></ul></div><div id="hash-charts" style="width:100%;height:300px"></div></body></html>
+1
View File
@@ -0,0 +1 @@
console.log("Iframe script loaded and executing!"),window.parent.postMessage({type:"iframe-test-ready"},"http://localhost:8080");
@@ -0,0 +1,24 @@
/*!
* ZRender, a high performance 2d drawing library.
*
* Copyright (c) 2013, Baidu Inc.
* All rights reserved.
*
* LICENSE
* https://github.com/ecomfe/zrender/blob/master/LICENSE.txt
*/
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
File diff suppressed because one or more lines are too long
BIN
View File
Binary file not shown.