阅读视图

发现新文章,点击刷新页面。

js中如何隐藏eval关键字?

本文介绍了JavaScript中隐藏eval关键字的多种方法,从简单的字符串拼接和Function构造函数,到使用字符编码动态生成字符串。更复杂的方案包括通过JS混淆工具(如JShaman)将代码转换为难以辨识的格式,甚至模拟虚拟机执行字节码来重构eval。这些技术通过层层包装,使原始eval调用在代码审计中难以被发现。

JavaScript中隐藏eval关键字的技巧

某些情况下,我们在进行JS编程时,可能想要用eval执行一些特殊的代码,但想不想让他人轻易看出是使用了eval。那么,就得想办法隐藏eval关键字了。

简单的隐藏方法

// 方法1:使用字符串分割
const ev = "ev";
const al = "al";
const hiddenEval = window[ev + al];

// 使用
hiddenEval('console.log("隐藏的eval执行")');

// 方法2:通过Function构造函数
const executeCode = new Function('code', 'return eval(code)');
executeCode('2 + 2'); // 返回4

复杂的隐藏方法

// 使用字符编码
const encodedEval = () => {
    const chars = [101, 118, 97, 108];
    const str = String.fromCharCode(...chars);
    return window[str];
};

const myEval = encodedEval();

更更更复杂的隐藏方法

如果还想隐藏的更深,可以再用JShaman进行JS代码混淆加密,上面代码会变成:

const encodedEval = () => {
  const _0x35ea38 = {
    "\u006d\u004f\u0067\u006c\u0048": function (_0x55d02e, _0x5cdb2b) {
      return _0x55d02e ^ _0x5cdb2b;
    },
    "\u0076\u006a\u0048\u0044\u0073": function (_0x4c98c3, _0xa2b4f0) {
      return _0x4c98c3 ^ _0xa2b4f0;
    }
  };
  const _0x2cd5ff = [0x47a4d ^ 0x47a28, _0x35ea38["\u006d\u004f\u0067\u006c\u0048"](0xd8290, 0xd82e6), _0x35ea38['vjHDs'](0xb9759, 0xb9738), _0x35ea38["\u0076\u006a\u0048\u0044\u0073"](0x7b450, 0x7b43c)];

  const _0x3d45d7 = String['fromCharCode'](..._0x2cd5ff);

  return window[_0x3d45d7];
};

const myEval = encodedEval();

或:

function _0x927a(opcode) {
  var op = {
    push: 32,
    add: 33,
    sub: 34,
    mul: 35,
    div: 36,
    pop: 37,
    xor: 38
  };
  var stack = [];
  var ip = -1;
  var sp = -1;

  while (ip < opcode.length) {
    ip++;

    switch (opcode[ip]) {
      case op.push:
        {
          ip++;
          stack.push(opcode[ip]);
          sp++;
          break;
        }

      case op.add:
        {
          stack.push(stack[sp - 1] + stack[sp]);
          sp++;
          break;
        }

      case op.sub:
        {
          stack.push(stack[sp - 1] - stack[sp]);
          sp++;
          break;
        }

      case op.mul:
        {
          stack.push(stack[sp - 1] * stack[sp]);
          sp++;
          break;
        }

      case op.div:
        {
          stack.push(stack[sp - 1] / stack[sp]);
          sp++;
          break;
        }

      case op.xor:
        {
          stack.push(stack[sp - 1] ^ stack[sp]);
          sp++;
          break;
        }

      case op.pop:
        {
          return stack[sp];
        }
    }
  }
}

const encodedEval = () => {
  const chars = [_0x927a([32, 865932, 32, 866025, 38, 37]), _0x927a([32, 625917, 32, 625803, 38, 37]), _0x927a([32, 750963, 32, 750866, 38, 37]), _0x927a([32, 753540, 32, 753640, 38, 37])];
  const str = String['\x66\x72\x6f\x6d\x43\x68\x61\x72\x43\x6f\x64\x65'](...chars);
  return window[str];
};

const myEval = encodedEval();

怎么样,还能找到eval关键字吗?

10个JavaScript编程实用技巧

JavaScript编程10个实用技巧

1. 箭头函数简化

// 传统写法
setTimeout(function() {
    console.log('Hello');
}, 1000);

// 箭头函数
setTimeout(() => console.log('Hello'), 1000);

2. 解构赋值

const config = {apiUrl: 'https://api.example.com', timeout: 5000};
const {apiUrl, timeout} = config;

3. 模板字符串

const name = '李四';
console.log(`欢迎 ${name} 使用我们的服务!`);

4. 可选链操作符

// 安全访问嵌套属性
const userCity = user?.address?.city ?? '未知';

5. 空值合并

const port = process.env.PORT ?? 3000;

6. 展开运算符

const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5]; // [1,2,3,4,5]

7. Promise简化

// 使用async/await替代.then()
async function fetchData() {
    try {
        const data = await fetch('/api/data');
        return data.json();
    } catch (error) {
        console.error('请求失败', error);
    }
}

8. 数组方法链式调用

const result = array
    .filter(item => item.active)
    .map(item => item.name)
    .slice(0, 10);

9. 短路求值

// 条件赋值
const isAdmin = user.role === 'admin';
isAdmin && showAdminPanel();

10. 事件委托

// 避免为每个子元素绑定事件
document.getElementById('list').addEventListener('click', (e) => {
    if (e.target.tagName === 'LI') {
        console.log('点击了:', e.target.textContent);
    }
});

掌握这些实用技巧能让你的JavaScript代码更加简洁、高效且易于维护。

另外,值得注意的是:JavaScript代码是公开透明的代码,容易在执行环境中被查看、复制、盗用,如果有重要的代码,建议使用JShaman进行JS代码混淆加密,使代码变的不可读、不可分析,以保护代码安全。

JavaScript数据类型

一、原始类型

JavaScript中的原始类型是不可变的数据类型,它们直接存储在栈内存中。

1. Undefined类型

let notDefined;
console.log(notDefined); // undefined
console.log(typeof notDefined); // "undefined"

// 未声明的变量与undefined的区别
// console.log(neverDeclared); // ReferenceError

2. Null类型

let emptyValue = null;
console.log(emptyValue); // null
console.log(typeof emptyValue); // "object" (这是JavaScript的历史遗留问题)

// null与undefined的区别
console.log(null == undefined); // true
console.log(null === undefined); // false

3. Boolean类型

let isActive = true;
let isCompleted = false;

//  truthy和falsy值
console.log(Boolean('')); // false
console.log(Boolean('hello')); // true
console.log(Boolean(0)); // false
console.log(Boolean(1)); // true

4. Number类型

let integer = 42;
let float = 3.14;
let scientific = 2.5e3; // 2500
let hex = 0xFF; // 255
let binary = 0b1010; // 10
let octal = 0o744; // 484

// 特殊数值
let infinity = Infinity;
let negativeInfinity = -Infinity;
let notANumber = NaN;

console.log(typeof NaN); // "number"

5. BigInt类型

// 超过Number安全整数范围的数字
const bigNumber = 9007199254740991n;
const huge = BigInt(123456789012345678901234567890);

console.log(bigNumber + 1n); // 9007199254740992n

6. String类型

let singleQuote = 'Hello';
let doubleQuote = "World";
let templateLiteral = `Hello ${doubleQuote}`;

console.log(templateLiteral); // "Hello World"

// 字符串方法
let message = "JavaScript数据类型";
console.log(message.length); // 11
console.log(message.includes('数据类型')); // true

7. Symbol类型

const uniqueKey = Symbol('description');
const anotherKey = Symbol('description');

console.log(uniqueKey === anotherKey); // false

// 全局Symbol注册表
const globalSymbol = Symbol.for('globalKey');
const sameGlobalSymbol = Symbol.for('globalKey');
console.log(globalSymbol === sameGlobalSymbol); // true

二、引用数据类型

1.Object类型

对象是JavaScript中最复杂的数据类型,用于存储键值对集合。

// 对象字面量
let person = {
    name: '张三',
    age: 25,
    isStudent: true,
    greet: function() {
        return `你好,我是${this.name}`;
    }
};

console.log(person.name); // "张三"
console.log(person.greet()); // "你好,我是张三"

// 动态添加属性
person.country = '中国';
delete person.isStudent;

2.Array类型

数组是特殊的对象,用于存储有序的数据集合。

let numbers = [1, 2, 3, 4, 5];
let mixed = [1, 'hello', true, { name: '李四' }];

// 数组方法
numbers.push(6); // 末尾添加
numbers.pop();   // 末尾删除
numbers.unshift(0); // 开头添加
numbers.shift(); // 开头删除

// 遍历数组
numbers.forEach((item, index) => {
    console.log(`索引${index}: ${item}`);
});

3.Function类型

函数在JavaScript中也是一等公民,可以作为参数传递和返回值。

// 函数声明
function add(a, b) {
    return a + b;
}

// 函数表达式
const multiply = function(a, b) {
    return a * b;
};

// 箭头函数
const divide = (a, b) => a / b;

// 高阶函数
function createCalculator(operation) {
    return function(a, b) {
        return operation(a, b);
    };
}
❌