[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-82782":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":15,"forks30d":15,"starsTrendScore":19,"compositeScore":20,"rankGlobal":9,"rankLanguage":9,"license":9,"archived":21,"fork":21,"defaultBranch":22,"hasWiki":23,"hasPages":21,"topics":24,"createdAt":9,"pushedAt":9,"updatedAt":25,"readmeContent":26,"aiSummary":27,"trendingCount":15,"starSnapshotCount":15,"syncStatus":13,"lastSyncTime":28,"discoverSource":29},82782,"MogVMP","eversinc33\u002FMogVMP","eversinc33","Static devirtualizer for VMProtect 3.0-3.5. Lifts virtualized code to LLVM using Remill and strips the VM layer through optimization.",null,"C++",253,18,2,4,0,1,41,149,12,72.84,false,"main",true,[],"2026-06-12 04:01:39","\u003Cp align=\"center\">\n  \u003Cimg src=\"img\u002Fmog.png\" width=\"400\"> \n\n  \u003Ch1 align=\"center\">MogVMP\u003C\u002Fh1>\n  \u003Cp align=\"center\">Devirtualizer for 32bit binaries protected by VMProtect 3.0-3.5.\u003C\u002Fp>\n\u003C\u002Fp>\n\nMogVMP lifts code to LLVM using [Remill](https:\u002F\u002Fgithub.com\u002Flifting-bits\u002Fremill) to recover the original semantics behind a virtualized function. Instead of modeling the VM specific handler semantics individually (like in my previous work on [byteshield](https:\u002F\u002Feversinc33.com\u002F2026\u002F05\u002F07\u002Fllvm-devirtualizer)), the whole x86 assembly code of each handler is lifted. Junk code, as well as the virtualization layer,  is subsequently optimized away by LLVMs built-in optimization passes and a custom pass that does aliasing-aware constant propagation and store forwarding over memory allocas.\n\nFor recovery of the CFG, the main goal of this project was to have it work fully statically, without needing any opcode traces or merging CFGs from traced runs. Instead, opcode handlers are lifted and optimized incrementally from VMENTER on. After each lifted handler, the next handler materializes as a constant. If it doesn't, VMP is branching: in this case, the two possible targets are extracted and the lifting process is forked. This approach works well on CFGs without jumptables, with a caveat of being rather slow. \n\nMogVMP runs on unpacked binaries and only attacks the virtualization of VMProtect. If a function uses multiple VMs, e.g. if it calls out to external APIs, you need to supply them to the commandline as well. The goal is not re-compilation but readable LLVM IR. In simple cases functions can be recompiled without change. In other cases, e.g. with external calls or argument buffers, manual adjustments to the IR are needed. \n\nThat being said, **MogVMP is a PoC I created to learn Remill** - do not expect production quality, handling of edge-cases, clean code or even that it works reliably beyond the complexity of the test examples. Theres issues and work in progress. See the examples below for what can be lifted already. \n\n \n## Examples\n\nA VMP 3.0.9 [DevirtualizeMe](https:\u002F\u002Fforum.tuts4you.com\u002Ftopic\u002F39481-devirtualizeme-vmprotect-309\u002F) from Tuts4You: \n\n![](.\u002Fimg\u002Fdevirtme.png)\n\nSimple Math function with a static CFG:\n\n![](.\u002Fimg\u002Flifted_math.png)\n\nBranching example:\n\n![](.\u002Fimg\u002Flifted_branch.png)\n\n## Usage\n\nRun the binary on the target executable, witha VMENTER address and an output path:\n\n```sh\nlifter [--save-intermediate-steps] [--continue \u003Cvmentry,...>] [--args \u003Ccount>] --vmenter \u003C0xADDR> [--imagebase \u003C0xADDR>] \u003Cpe> \u003Cout.ll>\n# e.g. for a simple example\nlifter --vmenter 0x004040ED .\u002Ftests\u002Fdata\u002FProject1.vmp.exe out.ll\n# function with multiple VMs\nlifter --vmenter 0x0040C890 --continue 0x4312d7,0x41F618 .\u002Ftests\u002Fdata\u002Fdevirtualizeme32_vmp_3.0.9_v1.exe devirt.ll\n```\n\n- `--vmenter \u003C0xADDR>` - address of the VMENTER to lift\n- `--args \u003Ccount>` - optional, number of args the function takes. infered from the caller if not supplied\n- `--imagebase \u003C0xADDR>` - optional address to rebase the PE to\n- `--continue\u003C0xADDR>,...` - optional addresses of additional VMENTERS if the virtualized code runs on multiple VMs\n\n### Finding VMENTERs\n\nThe PIN tool in `aux\u002Ftracer\u002F` can be used to trace a VMProtected binary and capture virtualized function's VMENTERs.\n\nBuild the tool with the Visual Studio project in `C:\\pin\\source\\tools\\MyPinTool`, then run it via PIN against the protected binary:\n\n```sh\npin.exe -t MyPinTool.dll -o trace.json -- target.vmp.exe [args]\n```\n\n## Build\n\n```sh\ngit clone --recurse-submodules https:\u002F\u002Fgithub.com\u002Feversinc33\u002FMogVMP && cd MogVMP\n# If already checked out:\n# git submodule update --init --recursive\ncmake --preset default\ncmake --build build\n```\n\nRun tests with:\n\n```sh\nctest --test-dir build --output-on-failure\n```\n\n### Shoutouts\n\n* [Ryan Weil](https:\u002F\u002Fryan-weil.github.io\u002F), who happened to work on a similar project, for great discussions\n* [Kyle Elliott](https:\u002F\u002Fgithub.com\u002Fkyle-elliott-tob), for motivation, telling me VMP 3.5 was an easy target\n* bakki, for giving the project its name:\n\n\u003Cp align=\"center\">\n  \u003Cimg src=\"img\u002Fbakki.png\" width=\"400\"> \n\u003C\u002Fp>\n\n\n","MogVMP 是一个针对 VMProtect 3.0-3.5 保护的 32 位二进制文件的静态去虚拟化工具。它使用 Remill 将虚拟化的代码提升到 LLVM，并通过优化移除虚拟机层。核心功能包括将 x86 汇编代码整体提升，去除垃圾代码和虚拟化层，并通过 LLVM 的内置优化以及自定义的别名感知常量传播和存储转发优化来恢复原始语义。该工具适用于需要静态分析和理解被 VMProtect 保护的代码场景，尤其适合逆向工程和安全研究。需要注意的是，MogVMP 是一个概念验证项目，可能不支持所有边缘情况或复杂代码，使用时需谨慎。","2026-06-11 04:09:13","CREATED_QUERY"]