本文介绍了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')
复杂的隐藏方法
// 使用字符编码
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关键字吗?
转自https://juejin.cn/post/7566171225708068864
该文章在 2025/11/6 16:05:11 编辑过