编译器【免费下载链接】movfuscatorThe single instruction C compiler项目地址https://gitcode.com/gh_mirrors/mo/movfuscator点击查看免费下载本文以 movfuscator 仓库中的overview/目录为例展示如何用 M/o/Vfuscator 编译器movcc编译 C 语言素数判定程序并将同一函数is_prime在 GCC 与 M/o/Vfuscator 下的汇编输出、控制流图进行对比。读完本文你能复现完整的汇编/目标文件/可执行文件生成流程理解 mov 单指令编译后代码体积膨胀、控制流消失的现象并掌握验证编译结果的基本命令。示例背景同一个素数判定程序overview/目录提供了 M/o/Vfuscator 最基础的示例使用验证目录中的 prime.c 作为编译对象。该程序结构非常简洁——is_prime函数先处理 1 和 2 两个特例再用for (i2; i*ix; i)循环试除判断能否整除main中调用is_prime输出 1 到 10000 之间的素数int is_prime(int x) { int i; if (x1) { return 0; } if (x2) { return 1; } for (i2; i*ix; i) { if (x%i0) { return 0; } } return 1; }这段代码只包含赋值、比较、循环、函数调用和printf等最常规的 C 语言结构是观察普通编译器与单指令编译器输出差异的理想样本。汇编对比27 条普通指令 vs 5743 条 mov对同一份源码两种编译器生成的is_prime函数汇编差异极大。overview目录直接附带了两份汇编产物供对照GCCM/o/VfuscatorGCC 的输出prime_gcc.asm是一个标准 x86 函数30 行使用了push、sub、cmp、jne、idiv、imul、jle、leave、ret等 9 条mov之外的各类指令控制流分支清晰可见is_prime: push ebp mov ebp,esp sub esp,0x10 cmp DWORD PTR [ebp0x8],0x1 jne 8048490 is_prime0x13 mov eax,0x0 jmp 80484cf is_prime0x52 ... idiv DWORD PTR [ebp-0x4] mov eax,edx test eax,eax jne 80484ba is_prime0x3d ...M/o/Vfuscator 的输出prime_mov.asm则是 5743 条指令全部是 mov不含任何注释与标签后逐行统计mov恰好出现 5743 次。其中没有任何cmp、idiv、jne算术与分支全部被拆解为查表式的mov序列is_prime: mov eax,ds:0x83fc638 mov edx,0x88048744 mov ds:0x81fc4c0,eax mov DWORD PTR ds:0x81fc4c4,edx mov al,ds:0x81fc4c0 mov ecx,DWORD PTR [eax*40x8056ad0] mov dl,BYTE PTR ds:0x81fc4c4 mov dl,BYTE PTR [ecxedx*1] ...可以观察到的实现特征均可在 prime_mov.asm 中直接验证查表做算术如mov ecx,DWORD PTR [eax*40x8056ad0]这类按 4 字节缩放索引访问大地址空间正是 README 中提到的算术依赖查找表lookup tables的具体体现也是编译产物体积巨大的根本原因寄存器仅作搬运eax、edx、ecx在 mov 之间反复倒手数据配合数据表完成取模、比较等操作对应源码 movfuscator/mov.md 中reg: MODI4(reg,reg)、reg: EQI4(reg,reg)等规则的展开结果无显式跳转整段代码线性排列函数返回、循环回跳都由 mov 序列配合执行引擎的跳转寄存器加载隐式完成因此从源码结构看静态反汇编器很难还原出正常 CFG。控制流图对比同一函数的控制流图CFG对比进一步放大了这种差异GCCM/o/VfuscatorGCC 的 CFG 是典型的菱形分支 回边循环结构而 M/o/Vfuscator 的 CFG 退化为一条几乎无分支的直线——这正是 mov 混淆的执行模型控制流不再体现为跳转指令而是由数据驱动跳转目标被当作数据搬运并加载。仓库根 README 也明确说明 M/o/Vfuscator 不依赖 jmp 实现无限执行循环而是利用故障的 mov 指令faulting mov达成见 movfuscator/movfuscator.c 中设计注释与mov cs, ax相关说明。复现 overview 目录的完整命令overview目录中每个产物文件都对应一条可复现的构建命令这里按原文档完整列出movcc需先通过构建脚本安装见下文构建与验证生成汇编产物命令prime_gcc.asmGCC 为is_prime生成的汇编gcc -S ./overview/prime.c -o prime_gcc.asmprime_mov.asmM/o/Vfuscator 为is_prime生成的汇编movcc -S ./overview/prime.c -o prime_mov.asm生成目标文件产物命令prime_gcc.oGCC 编译出的目标文件gcc -c ./overview/prime.c -o prime_gcc.oprime_mov.oM/o/Vfuscator 编译出的目标文件movcc -c ./overview/prime.c -o prime_mov.o生成完整可执行文件产物命令prime_gccGCC 编译的完整可执行文件gcc -s ./validation/prime.c -o prime_gccprime_movM/o/Vfuscator 编译的完整可执行文件movcc -s ./validation/prime.c -o prime_mov注意两处细节汇编/目标文件示例用的是./overview/prime.c而可执行文件示例用的是./validation/prime.c——两者是同一份源码overview/中的prime.c即验证程序 prime.c。另外-s选项用于 strip 符号表根 README 的Recommendations指出由于算术查表使符号表极大strip 后最终二进制体积可缩小约一半这也是示例命令统一带-s的原因。运行prime_mov的效果如下movcc prime.c -o prime编译后执行输出 1-100000 内的素数序列movcc prime.c -o prime运行实录构建与验证要实际执行上述命令需要先构建 M/o/Vfuscator。其前端是 LCC构建脚本 build.sh 会自动完成以下工作均可在该脚本源码中逐行对应克隆 LCC 并固定到指定提交git reset --hard 3b3f01b...依次打补丁将 mov 后端绑定到前端bind.patch、makefile.patch、enode.patch、gen.patch、expr.patch、lcc.patch编译 LCC 驱动并软链出movcc编译 mov 运行库crt0/crtf/crtd 及 softfloat 浮点仿真库。根 README 给出了构建入口与 32 位环境要求在 64 位系统上需安装 32 位 libc如apt-get install libc6-dev-i386或yum install glibc-devel.i686git clone 仓库地址 cd movfuscator ./build.sh sudo ./install.sh # 将 movcc 软链到 /usr/local/bin构建完成后仓库提供 check.sh 作为端到端验证它下载一个开源 AES 实现用movcc编译、objdump反汇编检查并实际运行。这与本文示例的验证思路完全一致——汇编中只有 mov且程序输出正确./check.sh从源码理解 movcc 的开关编译 prime.c 时movcc的行为由 movfuscator/mov.md 中的 LCC 后端规则文件与 movfuscator/movfuscator.c 中的发射器共同决定。mov.md是一份完整语法文件从%term定义如CNSTI4、MULI4、EQI4到规则体如reg: MULI4(reg,reg) # emit2\n规定了每一个 IR 节点如何被展开为 mov 序列。prime_mov.asm里反复出现的查表模式就是MULI4、EQI4等规则经emit2展开后的产物。与 overview 示例相关的常用开关通过-Wf前缀传给编译器本体如movcc example.c -Wf--no-mov-id在 movfuscator/movfuscator.c 中定义参数解析逻辑见其progbeg函数约 L2923 起标志作用默认--mov-id/--no-mov-id为每个基本块添加调试参考指令 / 不添加不添加--mov-flow/--no-mov-flow用 mov 实现控制流 / 用 jmp 实现控制流后者可大幅加速大型项目但浮点需改链 softfloat*_cf.omov--mov-extern/--no-mov-extern用 mov 实现外部函数调用 / 用 jmp 实现便于调试mov--mov-loop/--no-mov-loop主执行循环用 mov 实现 / 用 jmp 实现便于调试mov--crt0/--crtf/--crtd/--crt分别构建_start例程、主执行循环例程、数据表库--crt等价于三者全开关闭构建脚本中同样用到了这些开关例如用-Wf--crt0编译 crt0 运行库、用-Wf--no-mov-flow额外编译一份控制流未混淆的*_cf.o版本供调试链接见 build.sh L49-L56。小结与延伸阅读通过overview/这个最小示例可以完整看到单指令编译的核心效果同一份prime.cGCC 输出 30 行含分支的标准 x86 汇编M/o/Vfuscator 输出 5743 条纯 mov 指令、CFG 退化为直线。复现路径非常直接——gcc -S/-c与movcc -S/-c对称操作即可得到四份产物-s选项控制 strip。若需继续深入仓库中还有validation/ 目录下大量验证程序含 AES、MD5 等密码学算法及 README可参照 check.sh 的流程验证 movcc 输出post/ 目录的后处理器脚本README可将 mov 汇编进一步翻译为仅 XOR、SUB、PUSH/POP 等单一指令形式或做指令乱序、寄存器重命名poc/ 目录中的 M/o/Vfuscator 1.0面向 BrainF*! 语言原型slides/domas_2015_the_movfuscator.pdf 设计幻灯片讲解 mov 图灵完备的实现机制。赞分享编译器【免费下载链接】movfuscatorThe single instruction C compiler项目地址https://gitcode.com/gh_mirrors/mo/movfuscator点击查看免费下载相关推荐如何快速本地部署Wan2.1-Fun-1.3B-InPAI视频生成环境配置与权重下载一步到位指南 如何快速本地部署Wan2.1 Fun 1.3B InPAI视频生成环境配置与权重下载一步到位指南 想要在本地电脑上体验强大的AI视频生成功能吗Wan2M/o/Vfuscator 完全实战指南一个只输出 mov 指令的单指令 C 编译器如何工作M/o/Vfuscator 完全实战指南一个只输出 mov 指令的单指令 C 编译器如何工作 本篇以 README https://link.gitcode.编译器视觉编辑器扩展开发Instatic自定义工具与面板完全指南视觉编辑器扩展开发Instatic自定义工具与面板完全指南 Instatic作为一款现代化的自托管视觉CMS不仅提供了直观的内容编辑体验还支持通过插件系统CMS后端前端上一篇Dagger TypeScript SDK 中的 DirectoryAsModuleOpts 与 sourceRootPath从目录加载模块的完整指南下一篇在 MLX-VLM 中使用 Qwen4-Exp 原生 MTP 头进行投机解码拆分、推理与量化实战创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考