Rappid弹出框消除

前言

做工程总是需要绘制一些状态图、UML图之类的,在线比较好用的比如ProcessOn,Rappid的作用,就是方便开发这么一类的前端绘图框架,但是,免费试用的审批太慢了,然后,每次打开,都会有一个弹窗,所以就有Motivation,逆向源码,取消弹窗。

尝试

官网试用申请了两天没反应,从github上找到了别人上传的3.2.0的试用版。首先定位目标文件,惯例,rappid.js,这是这个项目的精华所在,别的地方都是明码,只有这里进行了js混淆压缩。

  1. window.alert,既然是浏览器弹窗,首先搜索这个方法,不出所料,没有;
  2. base64,既然搜不到,肯定是源码被加密了,然后通过反射调用的,那就查找加密后的字符串,前端加密常见的base64,特征就是结尾的“=”,还有atob方法,找到了;
    var El,
        Ll = ["TyfCoTnDj8Opw6A=", "wp5fA8Ouw48=", "w7zDnkvDnMObwq9aazrCvMK3CT0dMMOrHMKAwrPCgsKGDgfDo8K5EMKVZ8OrwpLCr8KgNgANCcKxw6vCrVHDtDrChl5fKMOwNBLDhMOaGcOuwodPwr3DmSrDjcO+cGzCrMK6w7HCt8KTwpVRwr0EwoHDsxx0W1TDmkA2DcKsDQLDg8KBw4BwwrjDsUlYwo0=", "Z2zDnlEQUEwSwqg=", "W0bDjgfCt8KTw4k=", "QMOgw5zDi8O+bMKuw6s7WQ==", "B8Oow6XDvgI2DUHDqcKJwrFDMw=="];
    El = Ll, function (t) {
        for (; --t;) El.push(El.shift())
    }(170);
    var Dl, Gl, zl, Bl = function (t, e) {
        var i = Ll[t -= 0];
        if (void 0 === Bl.JbcFeE) {
            !function () {
                var e;
                try {
                    e = Function('return (function() {}.constructor("return this")( ));')()
                } catch (t) {
                    e = window
                }
                e.atob || (e.atob = function (t) {
                    for (var e, i, n = String(t).replace(/=+$/, ""), r = "", o = 0, s = 0; i = n.charAt(s++); ~i && (e = o % 4 ? 64 * e + i : i, o++ % 4) && (r += String.fromCharCode(255 & e >> (-2 * o & 6)))) i = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(i);
                    return r
                })
            }();
            Bl.GdaSQk = function (t, e) {
                for (var i, n, r = [], o = 0, s = "", a = "", l = 0, h = (t = atob(t)).length; l < h; l++) a += "%" + ("00" + t.charCodeAt(l).toString(16)).slice(-2);
                for (t = decodeURIComponent(a), n = 0; n < 256; n++) r[n] = n;
                for (n = 0; n < 256; n++) o = (o + r[n] + e.charCodeAt(n % e.length)) % 256, i = r[n], r[n] = r[o], r[o] = i;
                for (var c = o = n = 0; c < t.length; c++) o = (o + r[n = (n + 1) % 256]) % 256, i = r[n], r[n] = r[o], r[o] = i, s += String.fromCharCode(t.charCodeAt(c) ^ r[(r[n] + r[o]) % 256]);
                return s
            }, Bl.dBQYqP = {}, Bl.JbcFeE = !0
        }
        var n = Bl.dBQYqP[t];
        return void 0 === n ? (void 0 === Bl.IYWyxg && (Bl.IYWyxg = !0), i = Bl.GdaSQk(i, e), Bl.dBQYqP[t] = i) : i = n, i
    };
    Dl = new Date(parseInt(Bl("0x5", "Rs^U"))), Gl = parseInt(Bl("0x4", "b@rV")), zl = Bl("0x1", "koGJ"), Bl("0x2", "Xmd8") != typeof window && Gl && !isNaN(Gl) && Dl && !isNaN(Dl[Bl("0x3", "#KwN")]()) && Dl[Bl("0x6", "KlGK")]() + Gl - (new Date).getTime() <= 0 && window[Bl("0x0", "u$Jv")](zl)

处理

对这串混淆压缩后得代码进行复原,主要功能是一个有效期得判定,超过有效期,弹出对话框提醒。

let encrypt_list = ["TyfCoTnDj8Opw6A=",
    "wp5fA8Ouw48=",
    "w7zDnkvDnMObwq9aazrCvMK3CT0dMMOrHMKAwrPCgsKGDgfDo8K5EMKVZ8OrwpLCr8KgNgANCcKxw6vCrVHDtDrChl5fKMOwNBLDhMOaGcOuwodPwr3DmSrDjcO+cGzCrMK6w7HCt8KTwpVRwr0EwoHDsxx0W1TDmkA2DcKsDQLDg8KBw4BwwrjDsUlYwo0=",
    "Z2zDnlEQUEwSwqg=",
    "W0bDjgfCt8KTw4k=",
    "QMOgw5zDi8O+bMKuw6s7WQ==",
    "B8Oow6XDvgI2DUHDqcKJwrFDMw=="];
for (let i = 1; i > 0; i--) {
    encrypt_list.push(encrypt_list.shift())
}
decoder = {
    result: {},
    atob: function (input) {
        const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
        let str = String(input).replace(/=+$/, ""), output = "", bs, buffer;
        for (let bc = 0, idx = 0; idx < str.length; idx++) {
            buffer = chars.indexOf(str.charAt(idx));
            if (~buffer) {
                bs = bc % 4 ? 64 * bs + buffer : buffer;
                if (bc++ % 4) {
                    output += String.fromCharCode(255 & bs >> (-2 * bc & 6))
                }
            }
        }
        return output;
    },
    decode: function (input, e) {
        input = this.atob(input);//base64解码
        let t = "", result = "";
        for (let i = 0; i < input.length; i++) {
            t += "%" + ("00" + input.charCodeAt(i).toString(16)).slice(-2);
        }
        input = decodeURIComponent(t);
        let table = [];
        for (let i = 0; i < 256; i++) {
            table[i] = i;
        }
        for (let i = 0, j = 0; i < 256; i++) {
            j = (j + table[i] + e.charCodeAt(i % e.length)) % 256;
            const tmp = table[i];
            table[i] = table[j];
            table[j] = tmp;
        }
        for (let i = 0, j = 0, k = 1; i < input.length; i++, k = (k + 1) % 256) {
            j = (j + table[k]) % 256;
            const tmp = table[k];
            table[k] = table[j];
            table[j] = tmp;
            result += String.fromCharCode(input.charCodeAt(i) ^ table[(table[k] + table[j]) % 256]);
        }
        return result
    },
    get: function (id, key) {
        id -= 0;
        if (undefined === this.result[id]) {
            this.result[id] = this.decode(encrypt_list[id], key);
        }
        return this.result[id];
    }
};
const record_date = new Date(parseInt(decoder.get("0x5", "Rs^U")));
const m_alert = decoder.get("0x0", "u$Jv"),
    message = decoder.get("0x1", "koGJ"),
    m_getTime1 = decoder.get("0x3", "#KwN"),
    trial_time = parseInt(decoder.get("0x4", "b@rV")),
    m_getTime2 = decoder.get("0x6", "KlGK");
console.log(trial_time);
decoder.get("0x2", "Xmd8") != typeof window &&
trial_time &&
!isNaN(trial_time) &&
record_date &&
!isNaN(record_date[m_getTime1]()) &&
record_date[m_getTime2]() + trial_time - (new Date).getTime() <= 0 &&
window[m_alert](message);

在rappid.js中,将这段代码全注释掉,就不会再出现提醒啦。

总结

总体,rappid的加密还不是很复杂,也许rappid的厂商和大多数软件公司一样,卖的不是产品,而是维护,以及计算资源。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,978评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,954评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,623评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,324评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,390评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,741评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,892评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,655评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,104评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,569评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,254评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,834评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,725评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,950评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,260评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,446评论 2 348

推荐阅读更多精彩内容

  • 深入浅出Nodejs 模块机制 Commonjs规范 node的模块实现步骤:路径分析文件定位编译执行核心模块在n...
    lmmy123阅读 422评论 0 1
  • 日常学习知识点总结(JS篇) 1、闭包: 闭包就是函数中的函数,里面的函数可以访问外面函数的变量,外面的变量是内部...
    依稀_Sting阅读 2,056评论 0 1
  • 一:web前端页面优化: 1.web页面的具体是什么?前身? web前端页面作为呈现给用户看的页面,也就是浏览器可...
    々烽火戏诸侯阅读 1,051评论 0 2
  • yahoo军规一共分8个部分共35条: 内容部分: 1. 尽量减少HTTP请求数 80%的终端用户响应时间都花在了...
    revert阅读 4,700评论 0 2
  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 7,512评论 16 22