This commit is contained in:
cilame 2023-01-31 18:38:38 +08:00
parent 35e5842b39
commit 93360e9c96

View File

@ -1,26 +1,34 @@
// makebytejs.js // makebytejs.js
const vm = require('vm'); var vm = require('vm');
const fs = require('fs').promises; var fs = require('fs');
const _module = require('module'); var _module = require('module');
const v8 = require('v8'); var v8 = require('v8');
v8.setFlagsFromString('--no-lazy'); v8.setFlagsFromString('--no-lazy');
async function compileFile(filePath) { function xor(buffer){
const code = await fs.readFile(filePath, 'utf-8'); var key = '123456789'.split('').map(function(e){return e.charCodeAt()})
const script = new vm.Script(_module.wrap(code)); for (var i = 0; i < buffer.length; i++) {
const bytecode = script.createCachedData(); buffer[i] ^= key[i % key.length]
await fs.writeFile(filePath.replace(/\.js$/i, '.bytecode'), bytecode); }
} }
compileFile('./test.js');
function compileFile(filePath) {
if (!fs.existsSync(filePath)) return
var code = fs.readFileSync(filePath, 'utf-8');
var script = new vm.Script(_module.wrap(code));
var bytecode = script.createCachedData();
xor(bytecode)
fs.writeFileSync('main.bytecode', bytecode);
}
compileFile('./main_.js');
// runbytejs.js // runbytejs.js
const _module = require('module'); var _module = require('module');
const path = require('path'); var path = require('path');
const fs = require('fs') var fs = require('fs')
const vm = require('vm'); var vm = require('vm');
const v8 = require('v8'); var v8 = require('v8');
v8.setFlagsFromString('--no-flush-bytecode'); v8.setFlagsFromString('--no-flush-bytecode');
function validateString(value, name) { function validateString(value, name) {
if (typeof value !== 'string') { if (typeof value !== 'string') {
@ -28,8 +36,8 @@ function validateString(value, name) {
} }
} }
function makeRequireFunction(mod) { function makeRequireFunction(mod) {
const Module = mod.constructor; var Module = mod.constructor;
const require = function require(path) { var require = function require(path) {
return mod.require(path); return mod.require(path);
}; };
require.resolve = function resolve(request, options) { require.resolve = function resolve(request, options) {
@ -45,22 +53,18 @@ function makeRequireFunction(mod) {
require.cache = Module._cache; require.cache = Module._cache;
return require; return require;
} }
const HeaderOffsetMap = { var HeaderOffsetMap = {
'magic': 0, 'magic': 0,
'version_hash': 4, 'version_hash': 4,
'source_hash': 8, 'source_hash': 8,
'flag_hash': 12 'flag_hash': 12
}; };
let _flag_buf;
function getFlagBuf() { function getFlagBuf() {
if (!_flag_buf) { var script = new vm.Script("");
const script = new vm.Script(""); return getHeader(script.createCachedData(), 'flag_hash');
_flag_buf = getHeader(script.createCachedData(), 'flag_hash');
}
return _flag_buf;
} }
function getHeader(buffer, type) { function getHeader(buffer, type) {
const offset = HeaderOffsetMap[type]; var offset = HeaderOffsetMap[type];
return buffer.slice(offset, offset + 4); return buffer.slice(offset, offset + 4);
} }
function setHeader(buffer, type, vBuffer) { function setHeader(buffer, type, vBuffer) {
@ -68,7 +72,7 @@ function setHeader(buffer, type, vBuffer) {
} }
function buf2num(buf) { function buf2num(buf) {
// 注意字节序问题 // 注意字节序问题
let ret = 0; var ret = 0;
ret |= buf[3] << 24; ret |= buf[3] << 24;
ret |= buf[2] << 16; ret |= buf[2] << 16;
ret |= buf[1] << 8; ret |= buf[1] << 8;
@ -76,11 +80,11 @@ function buf2num(buf) {
return ret; return ret;
} }
function loadBytecode(filePath) { function loadBytecode(filePath) {
const bytecode = fs.readFileSync(filePath, null); var bytecode = fs.readFileSync(filePath, null);
console.log(bytecode.toString('latin1')) xor(bytecode)
setHeader(bytecode, 'flag_hash', getFlagBuf()); setHeader(bytecode, 'flag_hash', getFlagBuf());
const sourceHash = buf2num(getHeader(bytecode, 'source_hash')); var sourceHash = buf2num(getHeader(bytecode, 'source_hash'));
const script = new vm.Script(' '.repeat(sourceHash), { var script = new vm.Script(' '.repeat(sourceHash), {
filename: filePath, filename: filePath,
cachedData: bytecode, cachedData: bytecode,
lineOffset: 0, lineOffset: 0,
@ -92,17 +96,15 @@ function loadBytecode(filePath) {
return script; return script;
} }
_module._extensions['.bytecode'] = function (module, filename) { _module._extensions['.bytecode'] = function (module, filename) {
const script = loadBytecode(filename, false); var script = loadBytecode(filename, false);
const wrapperFn = script.runInThisContext({ var wrapperFn = script.runInThisContext({
filename: filename, filename: filename,
displayErrors: true, displayErrors: true,
lineOffset: 0, lineOffset: 0,
columnOffset: 0, columnOffset: 0,
}); });
const require = makeRequireFunction(module); var require = makeRequireFunction(module);
wrapperFn.bind(module.exports)(module.exports, require, module, filename, path.dirname(filename)); wrapperFn.bind(module.exports)(module.exports, require, module, filename, path.dirname(filename));
} }
require('./test.bytecode') require('./main.bytecode')
console.log(window.top == window.self)