function mdaxPLm(STyJVMq) {
function IeePmW8(STyJVMq) {
return Nf4JzBj[STyJVMq < -42 ? STyJVMq - 54 : STyJVMq > -42 ? STyJVMq < 124 ? STyJVMq < 124 ? STyJVMq < -42 ? STyJVMq - 22 : STyJVMq + 41 : STyJVMq + 70 : STyJVMq + 65 : STyJVMq + 83]
}
var y52kFT, kgy7r5t, HKwckJV, aW6xTd = {}, TaDTniI = STyJVMq.split(''), y1D8QT = kgy7r5t = TaDTniI[Z_BwhsN(22)],
MA0iwVM = [y1D8QT], F39IZQO = y52kFT = 256;
for (STyJVMq = IeePmW8(-35); STyJVMq < TaDTniI.length; STyJVMq++) HKwckJV = TaDTniI[STyJVMq].charCodeAt(Z_BwhsN(22)), HKwckJV = F39IZQO > HKwckJV ? TaDTniI[STyJVMq] : aW6xTd[HKwckJV] ? aW6xTd[HKwckJV] : kgy7r5t + y1D8QT, MA0iwVM.push(HKwckJV), y1D8QT = HKwckJV.charAt(Z_BwhsN(22)), aW6xTd[y52kFT] = kgy7r5t + y1D8QT, y52kFT++, kgy7r5t = HKwckJV;
return MA0iwVM.join('').split('|')
}
关键点逐步解释
- 内部函数 IeePmW8
• 这是一个条件嵌套非常深的函数,逻辑上通过比较 STyJVMq 的值来访问 Nf4JzBj 中的元素。
• Nf4JzBj 是一个未定义的数组(或对象),可能在外部代码中定义。
• IeePmW8 的作用可能是动态计算索引,并从 Nf4JzBj 中取值。
初始化部分
• aW6xTd 是一个空对象,用于记录某种映射。
• TaDTniI 是输入字符串 STyJVMq 分割为字符数组。
• y1D8QT 和 kgy7r5t 被初始化为第一个字符,变量名混淆但逻辑清晰。
• MA0iwVM 是一个结果数组,初始值为第一个字符。
• F39IZQO 和 y52kFT 被初始化为 256,暗示可能与 ASCII 表或字符编码相关。
循环逻辑
• for (STyJVMq = IeePmW8(-35); STyJVMq < TaDTniI.length; STyJVMq++):
• 初始值是 IeePmW8(-35) 的返回值。
• 循环遍历输入字符串的每个字符。
• 获取当前字符的 Unicode 编码。
• 判断是否小于 F39IZQO,如果是,直接取字符本身。
• 如果大于,则查找 aW6xTd 对应映射,或者构造新的映射值。
• 映射逻辑
• 将当前构造的字符组合映射到 y52kFT,然后自增。
结果返回
• 拼接 MA0iwVM 数组为字符串。
• 通过 split('|') 分割为数组返回。
功能推测
函数解密的关键一环,功能性函数。
STyJVMq = kYggzY(function () {
var __p_8319535701;
var Nf4JzBj,
__p_2387872652 = (__p_8319535701 = Array.prototype.slice.call(arguments), Nf4JzBj = __p_8319535701.slice(0));
void (Nf4JzBj[Z_BwhsN(19)] = Z_BwhsN(21), Nf4JzBj[Z_BwhsN(20)] = Nf4JzBj[Z_BwhsN(25)]);
return Nf4JzBj[Z_BwhsN(20)](Nf4JzBj[Z_BwhsN(22)]())
}, Z_BwhsN(21))(hiBvTib, mdaxPLm);
• kYggzY 是一个高阶函数,接受两个参数:
• 一个匿名函数 function () { ... }。
• 一个返回值为 Z_BwhsN(21) 的常量。
• kYggzY 的返回值是一个新函数。随后,这个新函数被调用,传入参数 hiBvTib 和 mdaxPLm。
功能推测
-
通过调用 kYggzY 和匿名函数的组合,这段代码似乎是为 STyJVMq 创建一个动态函数。
-
函数的行为可能与动态键名映射 (Z_BwhsN) 和参数注入有关。
-
STyJVMq 最终可能是某种动态计算或字符串处理逻辑的核心。
function ZNeCP5() {
var __p_2995048044;
var IeePmW8,
__p_6991082740 = (__p_2995048044 = Array.prototype.slice.call(arguments), IeePmW8 = __p_2995048044.slice(0));
function y52kFT(IeePmW8) {
return Nf4JzBj[IeePmW8 > 114 ? IeePmW8 + 59 : IeePmW8 > 114 ? IeePmW8 + 44 : IeePmW8 > -52 ? IeePmW8 > -52 ? IeePmW8 > 114 ? IeePmW8 + 80 : IeePmW8 < 114 ? IeePmW8 > 114 ? IeePmW8 + 100 : IeePmW8 + 51 : IeePmW8 + 49 : IeePmW8 - 20 : IeePmW8 - 18]
}
typeof (IeePmW8[Z_BwhsN(19)] = Z_BwhsN(25), IeePmW8[y52kFT(113)] = Z_BwhsN(105));
if (IeePmW8[IeePmW8[y52kFT(113)] + y52kFT(72)] > 210) {
function kgy7r5t(IeePmW8) {
return Nf4JzBj[IeePmW8 > 166 ? IeePmW8 + 59 : IeePmW8 > 0 ? IeePmW8 < 166 ? IeePmW8 > 166 ? IeePmW8 - 24 : IeePmW8 > 166 ? IeePmW8 - 80 : IeePmW8 > 166 ? IeePmW8 + 10 : IeePmW8 < 166 ? IeePmW8 < 166 ? IeePmW8 - 1 : IeePmW8 + 58 : IeePmW8 - 31 : IeePmW8 + 42 : IeePmW8 - 26]
}
return IeePmW8[-kgy7r5t(6)]
} else {
return niubisa[IeePmW8[Z_BwhsN(22)]]
}
}
• 将传入的 arguments 转为数组,并赋值给 __p_2995048044 和 IeePmW8。
• IeePmW8 是核心数组变量,用于后续计算。
• 复杂的嵌套三元运算符动态计算索引值。
• 根据输入参数 IeePmW8 返回 Nf4JzBj 的某一项。
• 核心逻辑混淆严重,但大致可归纳为:
• 根据 IeePmW8 的值范围进行分支,最终返回一个动态计算的索引。
功能总结
- 动态计算与混淆:
• 通过动态索引和复杂的条件嵌套,生成和操作键值对,返回动态结果。
• 函数内部逻辑被高度混淆,增加了逆向难度。
- 可能的用途:
• 字符串映射、解密、或动态生成索引。
• 根据分支条件,分别返回从数组或全局对象中提取的数据。
function C7CMe4S() {
try {
return global || window || new Function(ZNeCP5(Z_BwhsN(83)))()
} catch (e) {
try {
return this
} catch (e) {
return {}
}
}
}
ZNeCP5 和 Z_BwhsN 是混淆的辅助函数,这部分需要解混淆代码才能确定其作用。从参数 83 看,可能是 ASCII 转换或者索引查找的一部分。
假设它们的功能如下:
• Z_BwhsN(83) 可能返回 'return this' 的内容或其他表示全局对象的代码片段。
• ZNeCP5 可能是对字符串进行简单处理的函数。
该函数的目的是确保在任何 JavaScript 运行环境中返回全局对象,即:
• 浏览器中的 window
• Node.js 中的 global
• 若无法访问全局对象,则退而求其次,返回空对象 {}。
相对于_0x类型的JS加密
(function(d,m){var c=h,y=d();while(!![]){try{var Y=parseInt(c('0x126'))/0x1*(parseInt(c('0x123'))/0x2)+parseInt(c('0x11d'))/0x3+-parseInt(c('0x11a'))/0x4+-parseInt(c('0x11c'))/0x5*(-parseInt(c('0x121'))/0x6)+parseInt(c('0x122'))/0x7*(parseInt(c('0x124'))/0x8)+parseInt(c('0x125'))/0x9*(-parseInt(c('0x11e'))/0xa)+-parseInt(c('0x11b'))/0xb*(parseInt(c('0x11f'))/0xc);if(Y===m)break;else y['push'](y['shift']());}catch(z){y['push'](y['shift']());}}}(t,0xbc435));function h(d,m){var y=t();return h=function(Y,z){Y=Y-0x11a;var c=y[Y];return c;},h(d,m);}function t(){var s=['8932292ldEdPK','wdGpl','492KWzeyd','70FISaKH','708OlwoUq','1191464LcSdCY','10095606MvwKUd','1911wgYmpH','2007548ASTMfJ','11kunUAS','5160erdTDy','2666967KbzQaC','10aMDorw'];t=function(){return s;};return t();}function hi(){var n=h,d={'wUGpl':'Hello\x20World!'};console['log'](d[n('0x120')]);}hi();
在大类上都属于同一类加密,都是可逆的。
以上都是新款加密的一些特征点。
好奇还原后的代码是什么样 可以看看上一篇文章。