演示网址
aHR0cHM6Ly93d3cudmlhZ29nby5jb20vQ29uY2VydC1UaWNrZXRzL1BvcC1NdXNpYy9TYWJyaW5hLUNhcnBlbnRlci1UaWNrZXRzL0UtMTU3NDEyOTgwP3F1YW50aXR5PTE=
从堆栈下断点找到加密位置
本文不谈别的,只谈ckj里这个s123和s146(一大串数据,几乎都是固定值,没啥讲的)
接着跟着堆栈找s123的生成位置
经过几次刷新,发现在断点位置1的时候,s123还未生成,经过代码
Q6j[Af(typeof RE()[gH(qk)], 'undefined') ? RE()[gH(k7)](Hq, MS, Hjj) : RE()[gH(ZS)].apply(null, [FS, Ad, GB])](Anj, R7()[Kn(Zk)](nr, hf), B9j);
之后,出现s123,如图:
所以在第一个断点处单步跟入
进入函数
代码如下(动态js,你的js代码跟我的不一样非常正常):
function lM(nP, nh) {
var A0 = lM;
switch (nP) {
case T3:
{
var WN = nh[vP];
WN[WN[x6](lq)] = function() {
var RM = this[pP]();
var zG = this[GG]();
var WZ = this[GG]();
var bM = this[kM](WZ, zG);
if (t3(RM)) {
var Ev = this;
var l6 = {
get(FP) {
Ev[xz] = FP;
return WZ;
}
};
this[xz] = new Proxy(this[xz],l6);
}
this[UN].push(bM);
}
;
lM(qN, [WN]);
}
break;
case WJ:
{
var bq = nh[vP];
bq[bq[x6](tz)] = function() {
this[UN].push(Wh(this[GG](), this[GG]()));
}
;
}
break;
case YJ:
{
var EG = nh[vP];
var nN = nh[vN];
return this[UN][DB(this[UN].length, sB)][EG] = nN;
}
break;
case rN:
{
var xq = nh[vP];
xq[xq[x6](rB)] = function() {
this[UN].push(this[dN](undefined));
}
;
lM(WJ, [xq]);
}
break;
case qN:
{
var CP = nh[vP];
CP[CP[x6](n6)] = function() {
this[UN].push(Lz(this[GG](), this[GG]()));
}
;
lM(mB, [CP]);
}
break;
case jq:
{
var pV = nh[vP];
var NV = nh[vN];
for (var sJ of [...this[UN]].reverse()) {
if (U0(pV, sJ)) {
return NV[kM](sJ, pV);
}
}
throw RG()[KN(sN)](XB, dv(Nh));
}
break;
case mB:
{
var mP = nh[vP];
mP[mP[x6](zh)] = function() {
this[UN].push(this[Vv](this[mq]()));
}
;
lM(rN, [mP]);
}
break;
case MN:
{
var A = nh[vP];
var Zq = nh[vN];
var QZ = nh[cx];
this[t] = this[TJ](Zq, QZ);
this[xz] = this[dN](A);
this[Aq] = new LJ(this);
this[bV](W5.m, lB);
try {
while (gP(this[G6][W5.m], this[t].length)) {
var IB = this[pP]();
this[IB](this);
}
} catch (v) {}
}
break;
case CZ:
{
rJ = function() {
return Ch.apply(this, [Q3, arguments]);
}
;
hv = function() {
return Ch.apply(this, [RJ, arguments]);
}
;
LJ = function(Vh) {
this[UN] = [Vh[xz].e];
}
;
Wq = function(EG, nN) {
return lM.apply(this, [YJ, arguments]);
}
;
D = function(pV, NV) {
return lM.apply(this, [jq, arguments]);
}
;
gh = function() {
this[UN][this[UN].length] = {};
}
;
ph = function() {
this[UN].pop();
}
;
Av = function() {
return [...this[UN]];
}
;
v0 = function(K0) {
return lM.apply(this, [OV, arguments]);
}
;
Az = function() {
this[UN] = [];
}
;
f5 = function() {
return Ch.apply(this, [T3, arguments]);
}
;
jB = function(KB, b6, ch, GV) {
return Ch.apply(this, [vN, arguments]);
}
;
cN = function() {
return E5.apply(this, [r3, arguments]);
}
;
z = function() {
return E5.apply(this, [WJ, arguments]);
}
;
f6 = function(A, Zq, QZ) {
return lM.apply(this, [MN, arguments]);
}
;
IJ(U6, []);
Ez = qh();
nz();
IJ.call(this, Q3, [KM()]);
b = AJ();
IJ.call(this, dh, [KM()]);
HN = dZ();
VV.call(this, cz, [KM()]);
MZ();
IJ.call(this, zx, [KM()]);
r0();
VV.call(this, sP, [KM()]);
L5 = VV(H3, [['$W$', '888', '8$', '$F88hFFFFFF', '$F8ShFFFFFF'], t3({})]);
W5 = {
m: L5[lB],
t: L5[sB],
W: L5[XB]
};
;z3 = class z3 {
constructor() {
this[G6] = [];
this[t] = [];
this[UN] = [];
this[Lx] = lB;
sh(Xh, [this]);
this[Yx()[G(XB)](hV, lB, xJ, O6)] = f6;
}
}
;
return z3;
}
break;
case OV:
{
var K0 = nh[vP];
if (jP(this[UN].length, lB))
this[UN] = Object.assign(this[UN], K0);
}
break;
}
}
观察一下代码,找到插桩位置:this[IB](this);(小技巧,经过几次调试sbsd发现,可以直接搜](this);
可以快速定位!
输出代码有几万行,从开头简单分析一下
这是一个简单的jsvmp,找到插桩位置之后,很容易就能算出来,具体代码就不上了。给各位看官练练手!
一步一步的写就行了,这个VPM我逆向过来大概写了几十行。
s123和s146均能在输出中找到,根据找到的位置,一点点往上推导,找到开头就行了
akamai/kasada/incapsula 交流地址:https://discord.gg/TCWWpH2Gy2
如果不想动手一点点扣的老板也可以找我(已经封装成api,供调用,不免费),交流地址需要科技上网才能打开