最近也是入手了蔡老板的AST课程 跟着蔡老板一步一步学 下面是学习的例题(笔记)做完了趁着不困梳理一下
function _u() {
var n = r(v(980, 817));
return (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = (n = n["replace"](/px_width/g, qu))["replace"](/px_cnt_width/g, hu))["replace"](/px_height/g, Iu))["replace"](/px_background/g, su))["replace"](/pxcntId/g, Uc))["replace"](/pxcId/g, Mc))["replace"](/pxdc/g, Bc))["replace"](/pxcd/g, Hc))["replace"](/pxcac/g, Ec))["replace"](/pxifc/g, Rc))["replace"](/pxbbwof/g, Uu))["replace"](/pxba/g, Zc))["replace"](/pxtc/g, jc))["replace"](/px_bar_height/g, wu))["replace"](/pxtId/g, bc))["replace"](/pxbtnwarpper/g, xc))["replace"](/px_border_width/g, tu))["replace"](/px_border_color/g, vu))["replace"](/px_border_radius/g, cu))["replace"](/px_fill_color/g, uu))["replace"](/px_text_color/g, iu))["replace"](/px_text_size/g, fu))["replace"](/px_text_font/g, ou))["replace"](/px_inner_height/g, eu))["replace"](/px_target_color/g, Cu))["replace"](/px_font_weight/g, zu))["replace"](/px_btn_padding/g, Lu))["replace"](/px_pressable_area_padding/g, ku))["replace"](/px_pressable_area_width/g, lu))["replace"](/px_pressable_area_top/g, du))["replace"](/px_text_transform/g, yu))["replace"](/px_checkmark_thickness/g, Du))["replace"](/px_checkmark_height/g, au))["replace"](/px_checkmark_width/g, Au))["replace"](/px_acc_text/g, Wc))["replace"](/px_acc_email_input/g, Tc))["replace"](/px_acc_value_box/g, Yc))["replace"](/px_acc_value_hyphen/g, Nc))["replace"](/px_acc_step_two_continue_btn/g, Jc))["replace"](/px_value_box_container/g, pc))["replace"](/px_acc_img/g, _c))["replace"](/px_acc_tooltip/g, Fc))["replace"](/pxvisuallyhidden/g, ru);
}
混淆后的代码
先用exit方法 exit方法:在退出某个节点时执行的操作。当 AST 遍历器完成访问该节点及其子节点后,会调用该节点类型对应的 exit
方法。 也就是从最后往前遍历
最里面的replace节点以及父节点
let {parentPath, node} = path;
if (!parentPath.isMemberExpression()){
return;
}
判断一下最里面那一层的节点是不是MemberExpression 不是返回
左节点类型
右节点类型
let {left, operator, right} = node;
if (!types.isIdentifier(left) || !types.isCallExpression(right) || operator != "=")
{
return;
}
判断一下左右节点类型还有中间操作符是否为= 如果不是 返回
return类型
let returnPath = path.findParent(p => p.isReturnStatement()); //获取祖先节点(return)
if (!returnPath){
return;
}
判断一下是不是ReturnStatement 如果不是返回
上边三个判断用来去除无用的代码
然后遍历即可
function _u() {
var n = r(v(980, 817));
n = n["replace"](/px_width/g, qu);
n = n["replace"](/px_cnt_width/g, hu);
n = n["replace"](/px_height/g, Iu);
n = n["replace"](/px_background/g, su);
n = n["replace"](/pxcntId/g, Uc);
n = n["replace"](/pxcId/g, Mc);
n = n["replace"](/pxdc/g, Bc);
n = n["replace"](/pxcd/g, Hc);
n = n["replace"](/pxcac/g, Ec);
n = n["replace"](/pxifc/g, Rc);
n = n["replace"](/pxbbwof/g, Uu);
n = n["replace"](/pxba/g, Zc);
n = n["replace"](/pxtc/g, jc);
n = n["replace"](/px_bar_height/g, wu);
n = n["replace"](/pxtId/g, bc);
n = n["replace"](/pxbtnwarpper/g, xc);
n = n["replace"](/px_border_width/g, tu);
n = n["replace"](/px_border_color/g, vu);
n = n["replace"](/px_border_radius/g, cu);
n = n["replace"](/px_fill_color/g, uu);
n = n["replace"](/px_text_color/g, iu);
n = n["replace"](/px_text_size/g, fu);
n = n["replace"](/px_text_font/g, ou);
n = n["replace"](/px_inner_height/g, eu);
n = n["replace"](/px_target_color/g, Cu);
n = n["replace"](/px_font_weight/g, zu);
n = n["replace"](/px_btn_padding/g, Lu);
n = n["replace"](/px_pressable_area_padding/g, ku);
n = n["replace"](/px_pressable_area_width/g, lu);
n = n["replace"](/px_pressable_area_top/g, du);
n = n["replace"](/px_text_transform/g, yu);
n = n["replace"](/px_checkmark_thickness/g, Du);
n = n["replace"](/px_checkmark_height/g, au);
n = n["replace"](/px_checkmark_width/g, Au);
n = n["replace"](/px_acc_text/g, Wc);
n = n["replace"](/px_acc_email_input/g, Tc);
n = n["replace"](/px_acc_value_box/g, Yc);
n = n["replace"](/px_acc_value_hyphen/g, Nc);
n = n["replace"](/px_acc_step_two_continue_btn/g, Jc);
n = n["replace"](/px_value_box_container/g, pc);
n = n["replace"](/px_acc_img/g, _c);
n = n["replace"](/px_acc_tooltip/g, Fc);
return n["replace"](/pxvisuallyhidden/g, ru);
}
解完混淆代码效果
enter类型:在进入某个节点时执行的操作。当 AST 遍历器首次访问该节点时,会调用该节点类型对应的 enter
方法。也就是从最开始往后遍历
改为enter类型试一下
结果是这样 显然出现了错误 原因是他是从开始往后遍历 改变了祖先节点的类型 可以看到祖先节点类型从被上边的代码过滤掉 return掉了。
第一次循环
第二次循环:
然后我们把祖先节点判断那改一下即可,这里要说一下isStatement包含isReturnStatement,isStatement包含很多函数自己查吧。
最后效果是一样的。