反编译抖音 a_bogus vmp

接上篇的继续 反编译 vmp 来进行学习

抖音的不太一样的点在于 他的vmp代码是分散的
好几段代码都是vmp的 然后指令对应的操作还不一样 就很蛋疼…
而且 指令对应的操作也是if else 还有三元表达式形式的 不太好找位置

第一步 看vmp代码结构

484e4f4a403f524300033604d6dbeab10000045d18187b
他通过一系列操作把这个长字符串转成了操作指令集

        for (var g = []; ;) try {
            var m = i[r++];
            // i 就是上面的长字符串处理后的结果
            if (m < 37) if (m < 18) if (m < 7) m < 3 ? p[++d] = 0 === m || null : 3 === m ? (c = i[r++], p[++d] = c << 24 >> 24) : (c = ((c = ((c = i[r++]) << 8) + i[r++]) << 8) + i[r++], p[++d] = (c << 8) + i[r++]); else if (m < 13) 7 === m ? (c = (i[r] << 8) + i[r + 1], r += 2, p[++d] = o[c]) : p[++d] = void 0; else if (m < 14) p[++d] = {}; else if (14 === m) c = (i[r] << 8) + i[r + 1], r += 2, s = o[c], u = p[d--], p[d][s] = u; else {
                for (s = i[r++], u = i[r++], b = v; s > 0; --s) b = b.p;
                p[++d] = b[u]
            } else if (m < 28) if (m < 20) 18 === m ? (c = (i[r] << 8) + i[r + 1], r += 2, s = o[c], p[d] = p[d][s]) : (s = p[d--], p[d] = p[d][s]); else if (m < 22) {
                for (s = i[r++], u = i[r++], b = v; s > 0; --s) b = b.p;
                b[u] = p[d--]
            } else if (22 === m) s = p[d--], u = p[d--], b = p[d--], u[s] = b; else {
                for (s = i[r++], u = i[r++], b = v, b = v; s > 0; --s) b = b.p;
                p[++d] = b, p[++d] = u
            } else m < 33 ? 28 === m ? (s = p[d--], p[d] %= s) : p[d] = -p[d] : m < 35 ? (s = p[d--], b = (u = p[d--])[s]++, p[++d] = b) : 35 === m ? (s = p[d--], p[d] = p[d] == s) : (s = p[d--], p[d] = p[d] != s); else if (m < 58) m < 51 ? m < 39 ? 37 === m ? (s = p[d--], p[d] = p[d] === s) : (s = p[d--], p[d] = p[d] !== s) : m < 44 ? (s = p[d--], p[d] = p[d] < s) : 44 === m ? (s = p[d--], p[d] = p[d] >> s) : p[d] = !p[d] : m < 53 ? 51 === m ? (c = (c = (i[r] << 8) + i[r + 1]) << 16 >> 16, r += 2, p[d] ? --d : r += c) : (c = (c = (i[r] << 8) + i[r + 1]) << 16 >> 16, r += 2, p[d] ? r += c : --d) : m < 54 ? (s = p[d--], (u = p[d--])[s] = p[d]) : 54 === m ? (s = p[d--], p[d] = p[d] in s) : p[d] = void 0; else if (m < 68) if (m < 64) 58 === m ? p[d] = typeof p[d] : (c = i[r++], s = p[d--], (u = function e() {
                var r = e._v;
                return (0, e._u)(r[0], arguments, r[1], r[2], this)
            })._v = [s, c, v], u._u = e, p[++d] = u); else {
                if (m < 66) throw s = p[d--];
                if (66 === m) {
                    for (s = p[d--], u = null; b = g.pop();) if (2 === b[0] || 3 === b[0]) {
                        u = b;
                        break
                    }
                    if (u) r = u[2], u[0] = 0, g.push(u); else {
                        if (!h) return s;
                        r = h[1], f = h[2], v = h[3], g = h[4], p[++d] = s, h = h[0]
                    }
                } else d -= c = i[r++], u = p.slice(d + 1, d + c + 1), s = p[d--], b = p[d--], s._u === e ? (s = s._v, h = [h, r, f, v, g], r = s[0], null == b && (b = function () {
                    return this
                }()), f = b, (v = [u].concat(u)).length = Math.min(s[1], c) + 1, v.p = s[2], g = []) : (l = s.apply(b, u), p[++d] = l)
            } else if (m < 71) if (68 === m) {
                for (c = i[r++], b = [void 0], l = c; l > 0; --l) b[l] = p[d--];
                u = p[d--], l = new (s = Function.bind.apply(u, b)), p[++d] = l
            } else r += 2 + (c = (c = (i[r] << 8) + i[r + 1]) << 16 >> 16); else m < 73 ? (c = (c = (i[r] << 8) + i[r + 1]) << 16 >> 16, r += 2, (s = p[d--]) || (r += c)) : 73 === m ? --d : (s = p[d], p[++d] = s)
        } catch (e) {
            for (; (c = g.pop()) && !c[0];) ;
            if (!c) {
                e:for (; h;) {
                    for (s = h[4]; c = s.pop();) if (c[0]) break e;
                    h = h[0]
                }
                if (!h) throw e;
                r = h[1], f = h[2], v = h[3], g = h[4], h = h[0]
            }
            1 === (s = c[0]) ? (r = c[2], c[0] = 0, g.push(c), p[++d] = e) : 2 === s ? (r = c[2], c[0] = 0, g.push(c)) : (r = c[3], c[0] = 2, g.push(c), p[++d] = e)

首先要简化 他那一大堆 if else 变成 switch case 方便后续的操作
在这里插入图片描述

变成这样就好了 方便后续的操作

第二步 看一些关键的变量

解释都在代码里了

var c, s, u, b, l, d = -1, p = [], h = null, v = [t];
// 这些变量分别代表了不同的含义 比如 栈 函数变量 函数入参 寄存器 等
// 需要注意反编译过程中的 变量作用域问题
for (s = Math.min(t.length, n), u = 0; u < s; ++u) v.push(t[u]);
v.p = a;

第三步 开始反编译

反编译函数

这是源代码中定义函数的地方

    i = r[f++];// i 是函数入参数量
    l = o[p--];// l是函数起点指令下标
    console.log('newFunc',now,l,i);
    (n = function e() {
        var f = e._v;
        return (0, e._u)(f[0], arguments, f[1], f[2], this);
    })._v = [l, i, h];
    n._u = e;
    o[++p] = n;
    console.log(p)

反编译成这样

i = r[f++];
l = o[p--];
let body63 = [];
// (n = function e() {
//     var f = e._v;
//     return (0, e._u)(f[0], arguments, f[1], f[2], this);
// })._v = [l, i, h];
// if (now === 1192)debugger
console.log('newFunc', l , i, h.idx, p+1) 
let func63 = types.identifier('func' + +l)
// if (s == 1582){
let hCopy = h.slice();
let args = types.identifier('arguments');
args.idx = h.idx+1
e(l, args, i, h, this,body63, -1) // 自己处理了一些东西
// h = hCopy.slice();
let v61 = types.functionDeclaration(func63, [], types.blockStatement(body63))
body.push(v61)
// func63._u = e;
func63._v = [l, i, h];
o[++p] = func63;
反编译判断
 i = (i = (r[f] << 8) + r[f + 1]) << 16 >> 16;
f += 2;
if (o[p]) {
    f += i; // 跳过一部分指令
} else {
    --p;
}
i = (i = (r[f] << 8) + r[f + 1]) << 16 >> 16;
f += 2;
let body52 = [];
// 这种不是函数的反编译 需要处理好作用域问题 否则会报错
e(f, h, c, b, a,body52, i-2-1, false, o,p) 
body.push(types.ifStatement(o[p], types.blockStatement(body52)))

最终结果

var tmp2248 = {};
    var tmp2249 = X["apply"](true, []);
    var tmp2250 = func618["apply"](true, [tmp2248, tmp2249]);
    var tmp2251 = {};
    var tmp2252 = {};
    var tmp2253 = navigator["platform"];
    tmp2252["platform"] = tmp2253;
    var tmp2254 = func618["apply"](true, [tmp2250, tmp2251, tmp2252]);
    tmp2018 = tmp2254;
    var tmp2255 = func1198["apply"](true, [tmp2254]);
    tmp2019 = tmp2255;
    var tmp2256 = func1086["apply"](true, [tmp2255]);
    tmp2020 = tmp2256;
    var tmp2257 = tmp2256["length"];
    tmp2021 = tmp2257;
    var tmp2258 = 255;
    var tmp2259 = tmp2257 & tmp2258;
    tmp2023 = tmp2259;
    var tmp2260 = 8;
    var tmp2261 = tmp2257 >> tmp2260;
    var tmp2262 = 255;
    var tmp2263 = tmp2261 & tmp2262;
    tmp2027 = tmp2263;
    var tmp2264 = "";
    tmp2028 = tmp2264;
    var tmp2265 = func1086["apply"](true, [tmp2264]);
    tmp2029 = tmp2265;
    var tmp2266 = tmp2265["length"];
    tmp2030 = tmp2266;
    var tmp2267 = 255;
    var tmp2268 = tmp2266 & tmp2267;
    tmp2032 = tmp2268;
    var tmp2269 = 8;
    var tmp2270 = tmp2266 >> tmp2269;
    var tmp2271 = 255;
    var tmp2272 = tmp2270 & tmp2271;
    tmp2036 = tmp2272;
    var tmp2273 = tmp2100 ^ tmp2112;
    var tmp2274 = tmp2273 ^ tmp2139;
    var tmp2275 = tmp2274 ^ tmp2152;
    var tmp2276 = tmp2275 ^ tmp2168;
    var tmp2277 = tmp2276 ^ tmp2180;
    var tmp2278 = tmp2277 ^ tmp2184;
    var tmp2279 = tmp2278 ^ tmp2188;
    var tmp2280 = tmp2279 ^ tmp2116;
    var tmp2281 = tmp2280 ^ tmp2143;
    var tmp2282 = tmp2281 ^ tmp2156;
    var tmp2283 = tmp2282 ^ tmp2172;
    var tmp2284 = tmp2283 ^ tmp2182;
    var tmp2285 = tmp2284 ^ tmp2186;
    var tmp2286 = tmp2285 ^ tmp2190;
    var tmp2287 = tmp2286 ^ tmp2120;
    var tmp2288 = tmp2287 ^ tmp2147;
    var tmp2289 = tmp2288 ^ tmp2160;
    var tmp2290 = tmp2289 ^ tmp2176;
    var tmp2291 = tmp2290 ^ tmp2122;
    var tmp2292 = tmp2291 ^ tmp2149;
    var tmp2293 = tmp2292 ^ tmp2164;
    var tmp2294 = tmp2293 ^ tmp2178;
    var tmp2295 = tmp2294 ^ tmp2194;
    var tmp2296 = tmp2295 ^ tmp2198;
    var tmp2297 = tmp2296 ^ tmp2202;
    var tmp2298 = tmp2297 ^ tmp2204;
    var tmp2299 = tmp2298 ^ tmp377;
    var tmp2300 = tmp2299 ^ tmp2210;
    var tmp2301 = tmp2300 ^ tmp2217;
    var tmp2302 = tmp2301 ^ tmp2128;
    var tmp2303 = tmp2302 ^ tmp2135;
    var tmp2304 = tmp2303 ^ tmp2222;
    var tmp2305 = tmp2304 ^ tmp2226;
    var tmp2306 = tmp2305 ^ tmp2230;
    var tmp2307 = tmp2306 ^ tmp2232;
    var tmp2308 = tmp2307 ^ tmp2235;
    var tmp2309 = tmp2308 ^ tmp2239;
    var tmp2310 = tmp2309 ^ tmp2243;
    var tmp2311 = tmp2310 ^ tmp2247;
    var tmp2312 = tmp2311 ^ tmp2259;
    var tmp2313 = tmp2312 ^ tmp2263;
    var tmp2314 = tmp2313 ^ tmp2268;
    var tmp2315 = tmp2314 ^ tmp2272;
    tmp2079 = tmp2315;
    var tmp2316 = [tmp2100, tmp2112, tmp2222, tmp2139, tmp2152, tmp2168, tmp2239, tmp2180, tmp2184, tmp2226, tmp2188, tmp2116, tmp2143, tmp2230, tmp2232, tmp2156, tmp2172, tmp2235, tmp2182, tmp2186, tmp2190, tmp2120, tmp2147, tmp2160, tmp2247, tmp2176, tmp2122, tmp2149, tmp2164, tmp2178, tmp2194, tmp2198, tmp2243, tmp2202, tmp2204, tmp377, tmp2210, tmp2217, tmp2128, tmp2135, tmp2259, tmp2263, tmp2268, tmp2272];
    var tmp2317 = tmp2316["concat"];
    var tmp2318 = func120["apply"](true, [tmp2256]);
    var tmp2319 = func120["apply"](true, [tmp2265]);
    var tmp2320 = [tmp2315];
    var tmp2321 = tmp2317["apply"](tmp2316, [tmp2318, tmp2319, tmp2320]);
    tmp2085 = tmp2321;
    var tmp2322 = func1382["apply"](true, [tmp2099]);
    var tmp2323 = func1538["apply"](true, [tmp2108]);
    tmp2322 += tmp2323;
    var tmp2324 = String["fromCharCode"];
    var tmp2325 = 121;
    var tmp2326 = tmp2324["apply"](String, [tmp2325]);
    var tmp2327 = String["fromCharCode"];
    var tmp2328 = tmp2327["apply"];
    var tmp2329 = tmp2328["apply"](tmp2327, [true, tmp2321]);
    var tmp2330 = ee["apply"](true, [tmp2326, tmp2329]);
    tmp2322 += tmp2330;
    tmp2086 = tmp2322;
    var tmp2331 = "s4";
    var tmp2332 = re["apply"](true, [tmp2322, tmp2331]);
    return tmp2332;

大概就是这样 一共三千多行 可以很明白的看到他的执行逻辑了

总结

他的麻烦点就是变量作用域问题 其他的按部就班的按照他的代码逻辑去改成ast节点的操作就行了

欢迎关注我的公众号 谢谢大家

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/636744.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

kafka监控配置和告警配置——筑梦之路

kafka_exporter项目地址&#xff1a;https://github.com/danielqsj/kafka_exporter docker-compose部署kafka_exporter # docker-compose部署多个kafka_exporter&#xff0c;每个exporter对接一个kafka# cat docker-compose.ymlversion: 3.1 services:kafka-exporter-opslogs…

30.标签实现动画

SVG的<set>标签是一个非常有用的工具&#xff0c;它允许开发者在SVG图形中创建简单的动画效果。这个标签主要用于在一段时间内改变一个属性到一个新值。以下是关于如何使用<set>标签的一些详细说明和示例。 <set>标签的基本用法 <set>标签用于在SVG动…

【代码随想录】【算法训练营】【第17天】 [110]平衡二叉树 [257]二叉树的所有路径 [404]左叶子之和

前言 思路及算法思维&#xff0c;指路 代码随想录。 题目来自 LeetCode。 day 17&#xff0c;又是一个令人愉快的周五~ 题目详情 [110] 平衡二叉树 题目描述 110 平衡二叉树 解题思路 前提&#xff1a;平衡二叉树&#xff1a;左右子树高度差不超过1, 思路&#xff1a;…

Fastjson漏洞之CVE-2017-18349

前言&#xff1a; 要想理解漏洞原理&#xff0c;首先看看Fastjson是什么&#xff0c;具体用来做什么才能更好的找到可以利用的场景&#xff1a; Fastjson 是一个由阿里巴巴开发的 Java 语言实现的高性能 JSON 解析器和生成器。它具有以下特点: 快速&#xff1a;Fastjson 在序列…

【区块链】caliper压力测试

本文上接postman接口测试 参照工程项目使用Caliper测试工具对食品安全溯源系统智能合约生成新食品(newFood)功能进行压力测试 首先启动webase python3 deploy.py startAll vim /opt/bencahmark/caliper-benchmark/networks/fisco-bcos/test-nw/fisco-bcos.json 命令便捷查…

LLama3 | 一. 本地 Web Demo 部署

前置工作 课程文档&#xff1a;Llama3-Tutorial/docs/hello_world.md at main SmartFlowAI/Llama3-Tutorial GitHub 1.安装vscode 2.安装vscode插件 Remote SSH 3.配置 VSCode 远程连接开发机 ssh连接开发机 进行端口映射 在开发机控制台中点击自定义服务&#xff0c;复…

Python编程之旅:从错误到精通的奇妙探险

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、初识Python编程的陷阱与解决方案 1. 语法错误&#xff1a;防范于未然 2. 逻辑错误&…

java+Angular+Nginx+原生HTML+JS+CSS+Jquery融合B/S版电子病历系统云HIS系统源码

javaAngularNginx原生HTMLJSCSSJquery融合B/S版电子病历系统云HIS系统源码 Java版云HIS系统融合电子病历系统&#xff0c;是医学专用软件。医院通过电子病历以电子化方式记录患者就诊的信息&#xff0c;包括&#xff1a;首页、病程记录、检查检验结果、医嘱、手术记录、护理记录…

Day24:Leetcode:235. 二叉搜索树的最近公共祖先 + 701.二叉搜索树中的插入操作 + 450.删除二叉搜索树中的节点

LeetCode&#xff1a;235. 二叉搜索树的最近公共祖先 解决方案&#xff1a; 1.思路 对于当前节点x&#xff0c;如果x比p和q的值都大&#xff0c;说明&#xff0c;p和q在x的右子树里面&#xff0c;那么去x的右子树里面去寻找&#xff1b;对于当前节点x&#xff0c;如果x比p和…

VMware Ubuntu虚拟机开机黑屏的解决方法

由于不知名原因&#xff0c;我的VMware虚拟机隔三差五会出现开机即黑屏的现象。经过查阅资料和摸索&#xff0c;发现其中一种方法可以很好地解决我虚拟机的问题。 &#xff08;1&#xff09;打开虚拟机 &#xff08;2&#xff09;在虚拟机还在读条状态时&#xff0c;鼠标左键进…

数字营销:以大数据作引擎,推动企业全面数字化升级

数字营销本质乃是以大数据为核之心&#xff0c;促使营销活动高效运作&#xff0c;消费者线上线下数据的无缝衔接、企业内外部数据的贯通、公域引流私域运营等&#xff0c;皆已成为企业运营的标准配置。 数据即等同于市场&#xff0c;市场即等同于用户&#xff0c;用户乃是企…

【hive和spark】hive on spark和spark读取hive metastore配置

HIVE ON SPARK 和 SPARK READ HIVE METASTORE 具体hadoop 和 hive单机版本安装请参考单节点搭建hadoop和hive 此文是基与这篇基础上升级而来。 零、版本说明&#xff1a; 本例使用的版本&#xff0c;hive和spark版本对标Cloudera 公司的 cdh6.2.0 版本&#xff0c;hdfs图省事…

Android应用URI调起百度地图、高德地图 和 腾讯地图

1、百度地图 地图调起API | 百度地图API SDKhttps://lbs.baidu.com/faq/api?titlewebapi/uri/andriod例&#xff1a;反向地址解析 //反向地址解析URI private final String BAIDU_MAP_NAVI_URI "baidumap://map/geocoder?location";/*** 跳转百度地图*/ private…

消息号 KI261 成本中心 XXXX/123123 冻结而不能直接对 2020.10.08 收入记帐

做AR凭证遇到如上图所示的报错&#xff0c;检查之后发现是科目的成本要素类别与成本中心的控制面板-锁定中的类型不匹配&#xff0c;现在科目的成本要素类别是11&#xff0c;控制面板中锁定了“实际销售收入”与“计划收入”。 成本要素类别“11”代表主营收入或者库存收入&…

新手第一次做抖店,应该注意什么?知道这些技巧让你更快拿到结果

大家好&#xff0c;我是电商花花。 新手第一次刚开始接触抖音小店&#xff0c;都会担心自己做不好&#xff0c;操作不到位的想法&#xff0c;怕自己做店长时间不出单。 其实做店担心不出单是很正常的&#xff0c;但是只要我们掌握正确的做店方法和技巧也能很快就做好抖音小店…

大语言模型下的JSON数据格式交互

插&#xff1a; AI时代&#xff0c;程序员或多或少要了解些人工智能&#xff0c;前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家(前言 – 人工智能教程 ) 坚持不懈&#xff0c;越努力越幸运&#xff0c;大家…

【动态规划七】背包问题

目录 0/1背包问题 一、【模板】01背包 二、分割等和子集 三、目标和 四、最后一块石头的重量 II 完全背包问题 一、【模板】完全背包 二、零钱兑换 三、零钱兑换 II 四、完全平方数 二维费用的背包问题 一、一和零 二、盈利计划 似包非包 组合总和 卡特兰数 不…

“Excel+中文编程”衍生新型软件,WPS用户:自家孩子

你知道吗&#xff0c;我们中国人有时候真的挺有创新精神的。 你可能熟悉Excel表格&#xff0c;也可能听说过中文编程&#xff0c;但你有没有脑洞大开&#xff0c;想过如果把这两者结合起来&#xff0c;会碰撞出什么样的火花呢&#xff1f; 别不信&#xff0c;跟着我来看看吧&a…

惠普电脑怎么进入bios?图文教程助你轻松上手!

进入BIOS&#xff08;基本输入/输出系统&#xff09;是在电脑启动时进行硬件初始化和设置的重要步骤之一。对于惠普&#xff08;HP&#xff09;电脑用户来说&#xff0c;了解如何进入BIOS是解决一些硬件和系统问题的关键。本文将介绍惠普电脑怎么进入bios的三种方法&#xff0c…

Wireshark抓取PROFINET包问题总结

1.如何导入GSD文件 ? 打开Wireshark在【编辑】->【首选项】->【Protocols】->【PNIO】&#xff0c;设置GSD文件的路径。 添加完成后&#xff0c;就可以解析报文了 2.Frame check sequence和FCS Status显示 unverified ? 【编辑】->【首选项】->【Protocols】…