{"id":22663652,"url":"https://github.com/dmaivel/covirt","last_synced_at":"2025-04-06T02:07:18.082Z","repository":{"id":266403748,"uuid":"897614741","full_name":"dmaivel/covirt","owner":"dmaivel","description":"An x86-64 code virtualizer for VM based obfuscation","archived":false,"fork":false,"pushed_at":"2024-12-21T23:34:19.000Z","size":395,"stargazers_count":109,"open_issues_count":0,"forks_count":26,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-03-30T01:05:32.993Z","etag":null,"topics":["code-virtualizer","compiler","mba","mixed-boolean-arithmetic","obfuscation","obfuscator","reverse-engineering","self-modifying-code","virtual-machine","virtualization","virtualizer","vm","vmp","vmprotect"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dmaivel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-12-02T23:47:38.000Z","updated_at":"2025-03-18T16:48:18.000Z","dependencies_parsed_at":"2025-01-06T03:09:15.656Z","dependency_job_id":"c8e0b94d-32f9-4f9b-86ab-9b49d2557925","html_url":"https://github.com/dmaivel/covirt","commit_stats":null,"previous_names":["dmaivel/covirt"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmaivel%2Fcovirt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmaivel%2Fcovirt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmaivel%2Fcovirt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmaivel%2Fcovirt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dmaivel","download_url":"https://codeload.github.com/dmaivel/covirt/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247423512,"owners_count":20936626,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["code-virtualizer","compiler","mba","mixed-boolean-arithmetic","obfuscation","obfuscator","reverse-engineering","self-modifying-code","virtual-machine","virtualization","virtualizer","vm","vmp","vmprotect"],"created_at":"2024-12-09T12:31:53.731Z","updated_at":"2025-04-06T02:07:18.055Z","avatar_url":"https://github.com/dmaivel.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg align=\"right\" width=\"35%\" src=\"media/covirt.png\"\u003e\n\n# covirt ![license](https://img.shields.io/badge/license-MIT-blue)\n\nAn x86-64 code virtualizer for VM based obfuscation.\n\n## Features\n\n- Stack-based virtual machine architecture\n- MBA, self-modifying code obfuscation\n- Support for both PE* and ELF binaries\n- Code markers to define protected regions\n\n*\\*PE support only tested on binaries compiled via MinGW-w64*\n\n# Getting started\n\n## Dependencies\n\n`CMake` will fetch all these dependencies, so installing them yourself is not necessary.\n\n| Name | Version |\n| ---- | ------- |\n| [CMake](https://cmake.org/) | 3.25+ |\n| [Zydis](https://github.com/zyantific/zydis) | 4.1.0+ |\n| [zasm](https://github.com/zyantific/zasm) | Latest |\n| [LIEF](https://github.com/lief-project/LIEF) | 0.15.1+ |\n\n## Building\n\nA `C++23` compatible compiler is required in order to build.\n\n```bash\ngit clone https://github.com/dmaivel/covirt.git\ncd covirt\nmkdir build\ncd build\ncmake ..\ncmake --build . --config Release\n```\n\nIf you are compiling on Windows via Visual Studio, you must use `clang-cl`: `cmake .. -T ClangCL -A x64`.\n\n# Usage\n\n```bash\nUsage: covirt [--help] [--version] [--output OUTPUT_PATH] [--vm_code_size MAX] [--vm_stack_size SIZE] [--no_self_modifying_code] [--no_mixed_boolean_arith] [--show_dump_table] INPUT_PATH\n\nCode virtualizer for x86-64 ELF \u0026 PE binaries\n\nPositional arguments:\n  INPUT_PATH                         path to input binary to virtualize \n\nOptional arguments:\n  -h, --help                         shows help message and exits \n  -v, --version                      prints version information and exits \n  -o, --output OUTPUT_PATH           specify the output file [default: INPUT_PATH.covirt] \n  -vcode, --vm_code_size MAX         specify the maximum allowed total lifted bytes [default: 2048]\n  -vstack, --vm_stack_size SIZE      specify the size of the virtual stack [default: 2048]\n  -no_smc, --no_self_modifying_code  disable smc pass \n  -no_mba, --no_mixed_boolean_arith  disable mba pass \n  -d, --show_dump_table              show disassembly of the vm instructions\n```\n\n## Code markers\n\nFor `covirt` to know which functions need to be virtualized, you must add the start and end markers into your source code, like so:\n\n```c\n#include \"covirt_stub.h\"\n\nint my_function(...)\n{\n    int result = 0;\n  \n    __covirt_vm_start();\n    // ...\n    __covirt_vm_end();\n\n    return result;\n}\n```\n\n\u003e [!IMPORTANT]\n\u003e  - Do not place `__covirt_vm_end` in unreachable locations (i.e. after a return), as it will prevent the end stub from emitting\n\u003e  - `__covirt_vm_...();` stubs won't work using `MSVC` because they use inline assembly\n\u003e  - `SSE4` support is required\n\n## Demo\n\n\u003cimg align=\"right\" width=\"55%\" src=\"media/ss.png\"\u003e\n\n```c\n#include \u003ccovirt_stub.h\u003e\n#include \u003cstdio.h\u003e\n\nint calculate(int a, int b)\n{\n    int result = 0;\n\n    __covirt_vm_start();\n    \n    for (int i = 0; i \u003c 10; i++)\n        if (i \u003e 5)\n            result += result + a;\n        else\n            result += (result \u003e\u003e 1) + b;\n    printf(\"result = %d\\n\", result);\n\n    __covirt_vm_end();\n\n    return result;\n}\n\nint main()\n{\n    calculate(5, 12);\n}\n\n```\n\nThe example application above was virtualized using `covirt a.out -d`, which outputs a dump of the VM instructions following obfuscation and virtualization. The current VM implementation pushes most operands onto the stack to process them, reducing the complexity of encoding the VM instructions. For instructions that don't have a defined VM handler, they will be executed natively (`vm_exit` -\u003e `native instruction` -\u003e `vm_enter`). Calling functions follows the same pipeline, in which we exit, call the function, and reenter the VM. All together, the transformations make the binaries grow significantly in size:\n - `a.out` as an `ELF`: 15.5 kB -\u003e 1.0 MB\n - `a.out` as a `PE`: 259.3 kB -\u003e 1.3 MB\n\n## Obfuscation\n\n| Description | IDA |\n|-|-----------------|\nIDA decompilation of `vm_entry`, which has been obfuscated via the MBA pass only. Over 27k LOC were generated by the decompiler. | ![cpp](media/ss2.png)\nIDA disassembly of `vm_entry`, which has been obfuscated via the MBA \u0026 SMC passes. Decompilation doesn't work. | ![cpp](media/ss3.png)\n\n## Known issues\n- **Can't call another VM protected function from within a protected region**\n  - Causes segfault if VM is obfuscated\n  - No return value if VM isn't obfuscated \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdmaivel%2Fcovirt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdmaivel%2Fcovirt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdmaivel%2Fcovirt/lists"}