ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

VMP d.protected 自定义字节码还原实战

VMP d.protected 自定义字节码还原实战 样本d.protected.lua自定义 Lua VM 字节码保护文件头自称「神秘人加密」。五层结构层层套娃最终静态还原出一个 MQTT 消息队列推送任务21 个加密页面、100 条指令、38 个常量全部解开。本文用到的所有解密还原工具已在文章末尾打包提供。一、保护结构解剖自顶向下五层1. 位运算兼容层文件头先手写一整套 32 位整数/位运算mCnMLgHBhb/qTl6QngWEF等混淆名——目标运行环境没有 bit 库VM 自带全套 bit32。2. XOR 字符串字符串常量是(function(e,k) ... end)(bytes, key)立即调用形态单字节 XOR。3. VM 数据表顶层 Lua 表存 VM 全部参数——常量池、页面映射、密钥材料、模块元数据。4. 页面加密核心字节码切成若干「页面」每页先Base64 变种自定义索引表偏移再PRNG 流密码密钥推导: key (w - tok - fk - pid*97 - bid) % 2147483647 -- 每页密钥不同 PRNG: state (state * 1103515245 12345) 0x7fffffff -- 经典 glibc LCG 流字节: (state 16) 0xff 与密文 XOR页面还带 Tag 完整性校验解完再过 codec 还原成标准字节码。5. 自定义字节码格式头部魔数HV\x01\x02 指令计数每条指令32 字节 8 个 uint32 字段字段含义经 F 表映射编码/pc/next/A/B/C/BX/SBX操作码本身也加密oid (encoded - (fk pc*131 pid)) % 2147483647 -- 依赖 pc 和页面 id 再查 OM 表 → 真实 opcode二、还原思路纯静态全程不跑样本。两个 Python 脚本打穿五层parse_and_decrypt.py (20KB) Lua 表解析 → XOR 字符串 → 逐页推导密钥 → LCG 流解密 → Tag 校验 → codec 解码 → 指令字段按 F 表拆解 → opcode 反推 OM 表映射 → 反汇编 full_disasm.py 合并所有页面、按 pc 排序输出完整指令流 ↓ d.protected_deobfuscated.lua人工归纳解页面的顺序很关键密钥依赖pid页号和bid模块 id而页号藏在已解密部分里——所以从外层模块参数表入手先拿fk/bid/tok0/stride/bias一组常量再逐页递推。两套模块参数全部提取外层页面 757350772 子模块 53539021 页 / 100 条指令。三、还原结果剥到最后是个物联网 MQTT 推送任务sys.taskInit(function()whiletruedoifnext(msg_queue)nilthensys.waitUntil(NEW_MQTT_MSG,10000)-- 空队列等消息elseifnotutil_mqtt.isReady()thensys.waitUntil(MQTT_READY,5000)-- 断线等重连elselocalmsgmsg_queue[1]table.remove(msg_queue,1)ifmsg.retryconfig.MSG_RETRY_MAXthen-- 超次丢弃清缓存fskv.del(msg.id)elseifutil_mqtt.publish(...)then-- 推送成功清缓存fskv.del(msg.id)else-- 失败重入队退避msg.retrymsg.retry1table.insert(msg_queue,msg)sys.wait(config.MSG_RETRY_INTERVAL)endendsys.wait(100)endend)100 条 VM 指令对应的全部语义零残留。四、关键点每页密钥独立依赖页号/模块号不能一把梭——必须从外层参数表推出常量再逐页解。opcode 依赖 pcencoded - (fk pc*131 pid)指令换个位置编码就不同直接静态映射表会错必须模拟解码流程。Tag 校验是最好的调试器解密对不对校验值立刻告诉你不用猜。五、小结这是五个样本里结构最工整的一个加密链路长Base64→LCG→codec→字段映射→opcode 反推但每一环都是确定性算法只要参数表拿到整条链多米诺式解开。难在找到第一块骨牌——VM 数据表里的那组密钥常量。工具附件解密工具包括样本.zip
返回列表