Compare commits

...

48 Commits

Author SHA1 Message Date
761953e518 i love links 2025-10-17 03:32:37 -06:00
c00cf12b71 better compatibility table 2025-10-17 03:22:30 -06:00
ca94e59b53 MV_INLINE: more better limitations expressed 2025-10-13 01:41:44 -06:00
1adfca2a9f typos 2025-10-12 03:24:32 -06:00
0b2fc6f495 added performance guide 2025-10-12 03:03:18 -06:00
5065d5d788 minor improvements, typos, etc. 2025-09-18 00:10:25 -06:00
cae0341554 better phrasing 2025-09-14 20:37:49 -06:00
5d34ae2cd5 added MV_CFF, MV_OMIT_CFF & MV_OMIT_VM macros 2025-09-14 20:08:47 -06:00
2d15abca01 update dashboard
long overdue lol
2025-09-09 19:41:58 -05:00
fe88a4ec2f update MV_INLINE example 2025-09-09 19:37:27 -05:00
dcd0835e9e legal: typos 2025-09-08 17:09:19 -05:00
3f7045fce5 update example 2025-08-30 17:38:35 -05:00
3584b962fd more better 2025-08-19 13:43:31 -05:00
0a14bc975e added MV_INLINE 2025-08-19 13:23:41 -05:00
ef0440905d updated macro docs to provide example output 2025-08-16 21:03:51 -05:00
aa1d007ef9 more better wording 2025-08-15 13:30:20 -05:00
36d2aaba62 typo 2025-08-15 13:26:42 -05:00
6dcea53551 change alert type to info 2025-08-15 13:24:50 -05:00
b8fc134521 better macro documentation 2025-08-15 13:22:14 -05:00
4f06486bd9 rip 'Wrap CFF blocks' </3 2025-08-12 06:05:08 -05:00
e517aa2fbc added MV_OBFUSCATED 2025-08-07 16:38:35 -05:00
74f35b55ab added 'Lift Constants' option 2025-07-31 23:59:02 -05:00
6d4951c402 virtualization is free now 2025-07-28 17:42:24 -05:00
b2609d5d30 added MV_CRASH 2025-07-17 21:14:50 -05:00
8d4b8fdfca added MV_COMPRESS 2025-07-12 20:38:33 -05:00
9e7430f2ee added legal; added privacy 2025-07-08 18:42:05 -05:00
d723199014 added TOS 2025-07-08 18:30:37 -05:00
ed9685e77d added virtualization docs 2025-07-05 03:11:10 -05:00
b2c20a130e oops 2025-06-20 01:34:41 -05:00
8edde392f8 added virtualization docs 2025-06-20 01:30:36 -05:00
8fb73031b6 more css bullshit 2025-06-13 04:30:01 -05:00
31b7f040c2 fix response text color 2025-06-13 04:22:33 -05:00
150af4596b stale file 2025-06-13 03:57:36 -05:00
8c0156260b i like this more better 2025-06-13 03:52:00 -05:00
ffe82c0c0b 'api key' 2025-06-13 03:50:07 -05:00
53302ff29b added api docs 2025-06-13 03:33:07 -05:00
66aa62e624 clearer phrasing 2025-06-10 03:37:07 -05:00
57adc08610 more better cff docs 2025-06-09 19:15:12 -05:00
51b55b3d32 cff: added expression decomposition 2025-05-31 00:43:08 -05:00
33813e73b8 added MV_LINE 2025-05-24 22:31:35 -05:00
33e34edc13 added luraph aliases 2025-05-21 23:29:09 -05:00
3acba35fe9 no loop 2025-05-20 02:36:09 -05:00
07e151e4da deprecated MV_OMIT_FUNCTION, all hail MV_OMIT 2025-05-20 02:16:10 -05:00
944633407b added icons to docs :D 2025-05-14 21:55:06 -05:00
12a6f325e2 CFF supports break and continue now 2025-05-06 00:03:17 -05:00
6c07144978 specify key requirements 2025-05-04 18:08:25 -05:00
2d72f4e86d fix missing mark.svg 2025-05-02 21:03:30 -05:00
6388020b41 typos 2025-05-02 20:58:31 -05:00
32 changed files with 669 additions and 242 deletions

View File

@@ -0,0 +1,33 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="56 56 368 368" xmlns:bx="https://boxy-svg.com">
<defs>
<bx:grid x="0" y="0" width="32" height="32" divisions="4"></bx:grid>
<linearGradient gradientUnits="userSpaceOnUse" x1="273.624" y1="478.726" x2="273.624" y2="782.752" id="gradient-0" spreadMethod="pad" gradientTransform="matrix(0.652418, -0.740213, 0.236821, 0.368389, -19.889706, 290.182587)">
<stop offset="0" style="stop-color: rgb(19.608% 19.608% 19.608%)"></stop>
<stop offset="1" style="stop-color: rgb(16, 16, 16);"></stop>
</linearGradient>
<bx:export>
<bx:file format="svg" href="#object-0"></bx:file>
<bx:file format="svg" href="#object-0" path="Untitled 2.svg" excluded="true"></bx:file>
<bx:file format="svg" href="#object-1" path="Untitled 3.svg"></bx:file>
</bx:export>
<radialGradient gradientUnits="userSpaceOnUse" cx="-122.846" cy="182.09" r="176.849" id="gradient-1" gradientTransform="matrix(0.557382, 0.674632, -0.839369, 0.69349, 365.313098, 116.598059)">
<stop offset="0" style="stop-color: rgb(96.078% 96.078% 96.078%)"></stop>
<stop offset="1" style="stop-color: rgb(193, 193, 193);"></stop>
</radialGradient>
<filter id="drop-shadow-filter-0" bx:preset="drop-shadow 1 -6 -6 4 0.5 rgba(0,0,0,0.3)" color-interpolation-filters="sRGB" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceAlpha" stdDeviation="4"></feGaussianBlur>
<feOffset dx="-6" dy="-6"></feOffset>
<feComponentTransfer result="offsetblur">
<feFuncA id="spread-ctrl" type="linear" slope="1"></feFuncA>
</feComponentTransfer>
<feFlood flood-color="rgba(0,0,0,0.3)"></feFlood>
<feComposite in2="offsetblur" operator="in"></feComposite>
<feMerge>
<feMergeNode></feMergeNode>
<feMergeNode in="SourceGraphic"></feMergeNode>
</feMerge>
</filter>
</defs>
<ellipse style="fill: url(#gradient-1);" cx="240" cy="240" rx="176.849" ry="176.849" id="object-1"></ellipse>
<path style="stroke-linejoin: round; fill-rule: nonzero; fill: url(#gradient-0); paint-order: fill; filter: url(#drop-shadow-filter-0);" d="M 384 112 C 368 144 368 160 320 176 C 304 208 296 224 248 240 C 232 272 216 288 176 304 C 160 336 144 344 96 360 C 167.932 430.941 284.845 444.22 368 368 C 451.155 291.78 409.727 134.332 384 112 Z" id="object-0"></path>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -1,3 +1,3 @@
---
title: "MoonVeil Docs"
title: "MoonVeil Documentation"
---

18
content/docs/api.md Normal file
View File

@@ -0,0 +1,18 @@
---
weight: 100
title: "Web API"
description: "Perform obfuscations programmatically"
icon: "article"
date: "2025-05-01T18:47:58-05:00"
lastmod: "2025-05-01T18:47:58-05:00"
---
MoonVeil is available to be used programmatically via it's web API if you'd like. Start by [creating an API key](/account).
## Authorization
Each API request expects an `Authorization` header in the format of `Authorization: Bearer mv-secret-...` where `mv-secret-...` is the API key you just created.
{{% alert context="warning" text="**DO NOT** share this key with anyone else!" /%}}
{{< swagger >}}

View File

@@ -0,0 +1,35 @@
---
weight: 999
title: "Luraph Compatibility Guide"
description: "Compatibility guide for Luraph"
icon: "article"
date: "2025-05-01T18:47:58-05:00"
lastmod: "2025-05-01T18:47:58-05:00"
---
MoonVeil provides a compatibility layer to support users which already use Luraph's suite of Macros.
Many of Luraph's macros do features or optimizations that are already built into MoonVeil. Though MoonVeil will still accept scripts which try to use these macros, they will have no effect. Below is a table of compatibility between Luraph and MoonVeil.
{{% table %}}
| Luraph Macro | MoonVeil Alias | Description |
| ----- | ----- | ----- |
| `LPH_ENCFUNC` | [MV_ENC_FUNC](/docs/macros/mv_enc_func) | Virtualizes and encrypts functions |
| `LPH_ENCSTR` | `MV_NO_OP` | Not applicable |
| `LPH_ENCNUM` | `MV_NO_OP` | Not applicable |
| `LPH_CRASH` | [MV_CRASH](/docs/macros/mv_crash) | Crashes the VM |
| `LPH_NO_VIRTUALIZE` | [MV_OMIT](/docs/macros/mv_omit) | Omits a function from all obfuscation steps |
| `LPH_JIT` | `MV_NO_OP` | MoonVeil provides built-in optimizations |
| `LPH_JIT_MAX` | `MV_NO_OP` | MoonVeil provides built-in optimizations |
| `LPH_NO_UPVALUES` | `MV_NO_OP` | Not applicable |
| `LPH_LINE` | [MV_LINE](/docs/macros/mv_line) | Current line number |
| `LPH_OBFUSCATED` | [MV_OBFUSCATED](/docs/macros/mv_obfuscated) | Detects obfuscation |
{{% /table %}}
{{% alert context="info" text="`MV_NO_OP` isn't user accessible, and is only used to provide source compatibility." /%}}
A minor difference between Luraph and MoonVeil is that MoonVeil does not automatically virtualize your script (outside of the [Virtualize Script](/docs/options/virtualization/) option). Instead, you can selectively virtualize blocks using the [MV_VM](/docs/macros/mv_vm) or [MV_ENC_FUNC](/docs/macros/mv_enc_func) macros. This gives you much more control over the obfuscation process, enabling you to have much better performance.
Though you can use Luraph's macros in MoonVeil, MoonVeil additionally provides many other [macros](/docs/macros) which are not available in Luraph.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 258 KiB

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 316 KiB

After

Width:  |  Height:  |  Size: 198 KiB

View File

@@ -11,9 +11,7 @@ Once you've signed in, you'll be taken to the dashboard. This can also be naviga
{{< figure src="/img/dashboard-1.png" alt="Dashboard" width="auto" >}}
The Dashboard is the main interface for the obfuscator. You simply type the script you'd like to obfuscate into the left-side code editor and your obfuscated script will appear on the right-side as you make changes.
In the bottom right corner you'll see a Plus icon which will open the options menu.
The Dashboard is the main interface for the obfuscator. You simply type the script you'd like to obfuscate into the left-side code editor and use the target icon in the bottom right to obfuscate it. Additionally on the bottom right corner you'll see a Plus icon which will open the options menu.
{{< figure src="/img/dashboard-options.png" alt="Dashboard Options" width="auto" >}}

View File

@@ -0,0 +1,3 @@
---
title: "Legal"
---

View File

@@ -0,0 +1,22 @@
---
weight: 100
title: "Privacy Policy"
icon: "article"
date: "2025-05-01T18:47:58-05:00"
lastmod: "2025-05-01T18:47:58-05:00"
---
We store various information about your usage of MoonVeil. This information includes:
- Discord user ID, email, and username
- Usage patterns of the Services
We do NOT log (or otherwise 'temporarily store') any request or data passed through MoonVeil.
## Third-Party Consent
We also use various third party service providers to keep MoonVeil up and running. Each service, along with their respective privacy policy can be found below:
- [Cloudflare](https://www.cloudflare.com/privacypolicy/)
- [Stripe](https://stripe.com/privacy)

View File

@@ -0,0 +1,29 @@
---
weight: 100
title: "Terms of Service"
icon: "article"
date: "2025-05-01T18:47:58-05:00"
lastmod: "2025-05-01T18:47:58-05:00"
---
These Terms of Service, entered into between you, and MoonVeil ("we", "us"), govern your usage of the MoonVeil website, and all content and information provided on, from, or through the website (the "Services"). By creating an account on the Services, you agree that all interactions you make with this website will be governed under these Terms of Service.
## Purchases & Refund Policy
Upon purchase of a membership (the "Products") on the Services, your account will be upgraded instantly. The Products are non-refundable, and no refunds will be issued without cause. In special circumstances, you may receive a good-faith refund at our sole discretion.
## Prohibited Activities
You agree that while using the Services, you will not attempt to reverse engineer into the Services, or use the Services for any purpose prohibited by law. You also agree that you will not duplicate, distribute, or sublicense any of the Services for any reason without prior written approval. You also agree that you will not attempt to use the Services in any automated manner, except the documented Application Programming Interface (the "API"). We reserve the right to end your plan without refund, if we reasonably believe you are engaged in prohibited activities at our sole discretion.
## Disclaimer of Warranty
MOONVEIL PROVIDES THESE SERVICES AS-IS. YOUR USE OF THESE SERVICES IS AT YOUR OWN RISK, AND MOONVEIL AND ALL AFFILIATES DISCLAIM ALL WARRANTIES IN RELATION WITH THE SERVICES AND YOUR USAGE OF THE SERVICES. MOONVEIL DOES NOT WARRANT THAT THE CONTENT AVAILABLE FOR DOWNLOAD WILL BE FREE OF VIRUSES, MALWARE, CONTANMINATION, OR DESTRUCTIVE QUALITIES. YOU AGREE THAT YOU ASSUME ALL RISK AS TO THE CHARACTERISTICS OF THE DOWNLOADED CONTENT. MOONVEIL IS NOT RESPONSIBLE FOR ANY DAMAGES FACED DUE TO CONTENT PROVIDED ON THE SERVICES.
## Limitation of Liability
IN NO EVENT SHALL MOONVEIL BE LIABLE FOR ANY UNAVAILABILITY OR INOPERABILITY OF THE WEBSITE, TECHNICAL MALFUNCTION, COMPUTER ERROR, CORRUPTION OR LOSS OF INFORMATION, OR OTHER INJURY, DAMAGE OR DISRUPTION OF ANY KIND BEYOND THE REASONABLE CONTROL OF MOONVEIL. IN NO EVENT WILL MOONVEIL BE LIABLE FOR ANY INDIRECT, INCIDENTAL, CONSEQUENTIAL, SPECIAL OR EXEMPLARY DAMAGES, INCLUDING BUT NOT LIMITED TO, LOSS OF PROFITS OR LOSS OF BUSINESS OPPORTUNITY, EVEN IF SUCH DAMAGES ARE FORESEEABLE AND WHETHER OR NOT MOONVEIL HAS BEEN ADVISED OF THE POSSIBILITY THEREOF. MOONVEIL ASSUMES NO LIABILITY FOR ANY SERVICES PROVIDED ON THE WEBSITE. YOU AGREE TO INDEMNIFY MOONVEIL AND ALL MEMBERS, OFFICERS, DIRECTORS, AGENTS, AND SUCCESSORS FROM AND AGAINST ANY AND ALL LIABILITIES, OBLIGATIONS, LOSSES, DAMAGES, TAXES, CLAIMS, ACTIONS AND SUITES FOR ANY AND ALL REASONABLE COSTS, EXPENSES, AND DISBURSEMENTS OF ANY KIND AND NATURE WHATSOEVER.
## Governing Law and Severability
If any term or condition of this Agreement is deemed void or invalid, or for any reason unenforceable, it shall be given effect to the greatest extent possible or if impossible, shall be severed from the remainder of this Agreement, and will not affect the enforceability of the remaining terms and conditions of this Agreement. You hereby represent and warrant that this Agreement constitutes your legally binding obligation to abide by the terms and conditions and that you have the authority to enter into this Agreement.

View File

@@ -0,0 +1,31 @@
---
weight: 100
title: "MV_CFF"
description: "Force a CFF pass"
icon: "code_blocks"
date: "2025-05-01T18:47:58-05:00"
lastmod: "2025-05-01T18:47:58-05:00"
---
`declare function MV_CFF<A..., R...>(vmFunction: (A...) -> R..., enableExpressionDecomposition?: boolean): (A...) -> R...`
will force the [CFF](/docs/options/flatten-control-flow) pass onto the passed function. Expression decomposition is enabled by default, but can be disabled with the second argument.
## Valid Usage
```lua
MV_CFF(function()
for i = 0, 10 do
print('this is flattened!', i)
end
MV_OMIT_CFF(function() print('this isnt') end)()
end)()
-- passing false as a second argument will disable expression decomposition, leading to much smaller output
MV_CFF(function()
for i = 0, 10 do
print('this is flattened!', i)
end
MV_OMIT_CFF(function() print('this isnt') end)()
end, false)()
```

View File

@@ -0,0 +1,26 @@
---
weight: 100
title: "MV_COMPRESS"
description: "Compresses strings"
icon: "code_blocks"
date: "2025-05-01T18:47:58-05:00"
lastmod: "2025-05-01T18:47:58-05:00"
---
`declare function MV_COMPRESS(data: string): string`
will compress the passed string and decompress at runtime.
{{% alert context="info" text="**Note**: `LPH_ENCSTR` is an available alias, although not a direct replacement." /%}}
## Valid Usage
```lua
return MV_COMPRESS([[Lorem ipsum odor amet, consectetuer adipiscing elit. Ipsum curae senectus ut tempor rhoncus sed aliquam fermentum. Luctus consectetur consectetur vitae parturient risus enim. Justo venenatis dictumst eget tincidunt eu fermentum. Erat elementum molestie ad aliquam donec mauris tempor. Justo dictumst dapibus ultricies potenti scelerisque class sociosqu vivamus. Dignissim lobortis tristique nullam placerat lectus maximus class dolor.
Class eros ligula facilisis viverra adipiscing. Convallis penatibus lacinia hac pretium tempor mauris risus. Aliquet sagittis quisque dignissim duis volutpat eleifend sagittis. Mollis duis congue non auctor duis sapien senectus. Magna aptent ac nostra nisl; penatibus sagittis dis. Tempus sapien porta dolor luctus tempus felis habitant phasellus.
Volutpat quam senectus tristique egestas dui risus praesent maecenas adipiscing. Ante est platea cursus consequat quisque curabitur euismod. Himenaeos blandit augue; sed condimentum curae curabitur aliquam. Hac hendrerit arcu maecenas nisi iaculis donec natoque gravida. Sapien pretium nascetur, nisl in feugiat ultricies. Pretium ipsum ultricies et non blandit accumsan arcu. Egestas enim litora tortor nisi aenean posuere. Tortor posuere purus facilisi augue ipsum.
Metus ultrices netus rhoncus sed mi et neque ex. Tincidunt commodo metus quisque hendrerit tristique nostra amet sociosqu. Curae egestas feugiat massa torquent a vel faucibus faucibus. Euismod posuere cubilia penatibus class molestie torquent tristique commodo nam. Nullam rhoncus ad sem, habitasse euismod porta gravida. Ut curabitur tristique orci vestibulum rhoncus. Habitasse pulvinar risus congue dis cras consequat inceptos. Nulla hac interdum commodo enim magna; habitant id? Lacus pretium per accumsan praesent rutrum vestibulum.]])
```

View File

@@ -0,0 +1,25 @@
---
weight: 100
title: "MV_CRASH"
description: "Crashes the VM"
icon: "code_blocks"
date: "2025-05-01T18:47:58-05:00"
lastmod: "2025-05-01T18:47:58-05:00"
---
`declare function MV_CRASH(void): void`
crashes the VM and corrupts the state.
{{% alert context="info" text="**Note**: `LPH_CRASH` is an available alias" /%}}
## Valid Usage
```lua
MV_VM(function() MV_CRASH() end)()
MV_VM(function()
local a = MV_CRASH()
end)()
```
{{% alert context="warning" text="**Note**: This macro can only be used in virtualized blocks." /%}}

View File

@@ -2,18 +2,20 @@
weight: 100
title: "MV_ENC_FUNC"
description: "Encrypts functions"
icon: "article"
icon: "code_blocks"
date: "2025-05-01T18:47:58-05:00"
lastmod: "2025-05-01T18:47:58-05:00"
---
`declare function MV_ENC_FUNC<A..., R...>(vmFunction: (A...) -> R..., encryptKey: string, decryptKey: string): (A...) -> R...`
will virtualize and encrypt the passed function constant with the provided `encryptKey`. Then `decryptKey` is evaluated at runtime to grab the key.
will virtualize and encrypt the passed function constant with the provided `encryptKey`. Then `decryptKey` is evaluated at runtime to grab the key. There are no restrictions on the length or the allowed characters of the keys, only that they are the same.
{{% alert context="info" text="**Note**: `LPH_ENCFUNC` is an available alias." /%}}
## Valid Usage
```lua
local foo = 'ok'
local total = 0
local getKey = MV_VM(function()
@@ -31,5 +33,4 @@ end
return total
```
{{% alert context="warning" text="**Note**: if your plan doesn't include virtualization support, `MV_ENC_FUNC` is a no-op where the passed function is mangled normally and not virtualized or encrypted!" /%}}

View File

@@ -2,14 +2,14 @@
weight: 100
title: "MV_ENC_STR"
description: "Encrypts strings"
icon: "article"
icon: "code_blocks"
date: "2025-05-01T18:47:58-05:00"
lastmod: "2025-05-01T18:47:58-05:00"
---
`declare function MV_ENC_STR(str: string, encryptKey: string, decryptKey: string): string`
will encrypt the passed string constant with the provided `encryptKey`. Then `decryptKey` is evaluated at runtime to grab the key.
will encrypt the passed string constant with the provided `encryptKey`. Then `decryptKey` is evaluated at runtime to grab the key. There are no restrictions on the length or the allowed characters of the keys, only that they are the same.
## Valid Usage
```lua

View File

@@ -2,7 +2,7 @@
weight: 100
title: "MV_INDEX_TO_NUM"
description: "Obfuscates named indexes"
icon: "article"
icon: "code_blocks"
date: "2025-05-01T18:47:58-05:00"
lastmod: "2025-05-01T18:47:58-05:00"
---
@@ -14,9 +14,20 @@ will replace all instances of named indexes with a unique number constant.
## Valid Usage
```lua
local foo = MV_INDEX_TO_NUM({total = 0})
local foo = MV_INDEX_TO_NUM({total = 0, b = 2})
for i = 1, 10 do
foo.total = foo.total + i
end
return foo.total
return foo.total + foo.b
```
turns into:
```lua
-- note that the order of the indexes has been changed as well
local a={[24453]=2,[19314]=0}
for b=1,10 do
a[19314]=a[19314]+b
end
return a[19314] + a[24453]
```

View File

@@ -0,0 +1,52 @@
---
weight: 100
title: "MV_INLINE"
description: "Make preprocessor macros"
icon: "code_blocks"
date: "2025-05-01T18:47:58-05:00"
lastmod: "2025-05-01T18:47:58-05:00"
---
`declare function MV_INLINE<A..., R...>(inlineFunction: (A...) -> R...): (A...) -> R...`
will mark the passed function to be inlined where used.
Some limitations apply:
- The passed function cannot be variadic (i.e. no ... usage)
- The passed function cannot tailcall or otherwise recursively call itself.
- You must use this macro in it's specific form, i.e. `local <var> = MV_INLINE(function() ... end)`
Note that this pass acts more like a preprocessor that replaces the function calls with the results of the function (if any), and can have strange effects in some cases.
For example, when an inlined function is called, its function body is inserted right before the statement the call is in. This can lead to some unexpected behavior when used in `or` or `if` expressions:
```lua
local called = false
local testFunc = MV_INLINE(function()
called = true
return 'hi'
end)
local foo = 'bar' or testFunc()
print(foo, called)
```
Will print `bar true`, where under normal circumstances testFunc should not be executed. This is because the `or` expression is evaluated after the inserted body.
## Valid Usage
```lua
local testFunc = MV_INLINE(function(start, endn)
local total = 0
for i = start, endn do
total = total + i
end
return total
end)
local testFunc2 = MV_INLINE(function()
return testFunc(1, 10), testFunc(11, 20), testFunc(1, 15)
end)
print(testFunc2())
```

View File

@@ -0,0 +1,29 @@
---
weight: 100
title: "MV_LINE"
description: "Get current line"
icon: "code_blocks"
date: "2025-05-01T18:47:58-05:00"
lastmod: "2025-05-01T18:47:58-05:00"
---
`declare MV_LINE: number`
will be replaced with a number constant representing the current line.
{{% alert context="info" text="**Note**: `LPH_LINE` is an available alias." /%}}
## Valid Usage
```lua
local a = MV_LINE
print(a, MV_LINE)
```
turns into:
```lua
print(1,2)
```
{{% alert context="info" text="**Note**: the 'a' local got folded yet retains the original line number" /%}}

View File

@@ -0,0 +1,40 @@
---
weight: 100
title: "MV_OBFUSCATED"
description: "Detect if script is obfuscated"
icon: "code_blocks"
date: "2025-05-01T18:47:58-05:00"
lastmod: "2025-05-01T18:47:58-05:00"
---
`declare MV_OBFUSCATED: boolean`
This macro is a constant value that is set as true during obfuscation, which can allow certain code paths to only run in an obfuscated or unobfuscated context. MoonVeil will optimize out the blocks which should not run.
{{% alert context="info" text="**Note**: `LPH_OBFUSCATED` is an available alias." /%}}
## Valid Usage
```lua
if MV_OBFUSCATED then
validateWhitelist() -- This code will only if the script has been obfuscated.
else
skipWhitelist()
-- This code will only run when the script is not obfuscated.
-- Additionally, there will be no traces of this code in the obfuscated code.
end
return if MV_OBFUSCATED then runWithoutDebugging() else runWithDebugging()
```
turns into:
```lua
do
validateWhitelist()
end
return runWithoutDebugging()
```

View File

@@ -0,0 +1,24 @@
---
weight: 100
title: "MV_OMIT_CFF"
description: "Omit from CFF"
icon: "code_blocks"
date: "2025-05-01T18:47:58-05:00"
lastmod: "2025-05-01T18:47:58-05:00"
---
`declare function MV_OMIT_CFF<A..., R...>(cffFunction: (A...) -> R...): (A...) -> R...`
Similar to [MV_OMIT](/docs/macros/MV_OMIT), this will omit only the [CFF](/docs/options/flatten-control-flow) steps from the passed function. This can be useful to keep performance-critical sections unobfuscated but still have other AST passes applied to them.
## Valid Usage
```lua
MV_CFF(function()
for i = 0, 10 do
print('this is flattened!', i)
end
MV_OMIT_CFF(function() print('this isnt') end)()
end)()
```
> Make sure to call the macro result!

View File

@@ -1,22 +1,46 @@
---
weight: 100
title: "MV_OMIT_FUNCTION"
description: "Omit all mangling steps"
icon: "article"
title: "MV_OMIT"
description: "Omit from all steps"
icon: "code_blocks"
date: "2025-05-01T18:47:58-05:00"
lastmod: "2025-05-01T18:47:58-05:00"
---
`declare function MV_OMIT_FUNCTION<A..., R...>(omit: (A...) -> R...): (A...) -> R...`
`declare function MV_OMIT(omit: any): any`
will omit all mangling steps from the passed function, will also disregard any indexes set by `MV_INDEX_TO_NUM`
will omit all obfuscation steps from the passed expression, will also disregard any indexes set by `MV_INDEX_TO_NUM`. Passing a function to this can be useful to keep performance-critical sections unobfuscated.
When used in a virtualized block (using the [MV_VM](./MV_VM) or [MV_ENC_FUNC](./MV_ENC_FUNC) macros), this will lift the function from the virtualized block as a separate standalone minified function in plaintext.
{{% alert context="info" text="**Note**: `MV_OMIT_FUNCTION` && `LPH_NO_VIRTUALIZE` are also available aliases." /%}}
Additionally if you'd like to only omit the function from certain AST passes, you can use the [MV_OMIT_CFF](./MV_OMIT_CFF) or [MV_OMIT_VM](./MV_OMIT_VM) macros.
## Valid Usage
```lua
local dontMangleMe = MV_OMIT_FUNCTION(function()
print("im in plaintext!")
local dontMangleMe = MV_OMIT(function()
print("this whole function is in plaintext!")
end)
donMangleMe()
dontMangleMe()
local a = MV_OMIT("plaintext string")
print(a .. "im obfuscated")
local foo = 'hello'
MV_ENC_FUNC(function()
MV_OMIT(function(aa)
if aa == "lol" then
foo = "OK"
else
foo = "NO"
end
end)("lol")
print(foo)
end, "abc", "abc")()
-- will print "OK"
```

View File

@@ -0,0 +1,24 @@
---
weight: 100
title: "MV_OMIT_VM"
description: "Omit from VM"
icon: "code_blocks"
date: "2025-05-01T18:47:58-05:00"
lastmod: "2025-05-01T18:47:58-05:00"
---
`declare function MV_OMIT_VM<A..., R...>(vmFunction: (A...) -> R...): (A...) -> R...`
Similar to [MV_OMIT](/docs/macros/MV_OMIT), this will only omit the passed function from the VM. This can be useful to keep performance-critical sections unobfuscated but still have other AST passes applied to them.
## Valid Usage
```lua
MV_VM(function()
for i = 0, 10 do
print('this is virtualized!', i)
end
MV_OMIT_VM(function() print('this isnt') end)()
end)()
```
> Make sure to call the macro result!

View File

@@ -2,7 +2,7 @@
weight: 100
title: "MV_VM"
description: "Virtualize function"
icon: "article"
icon: "code_blocks"
date: "2025-05-01T18:47:58-05:00"
lastmod: "2025-05-01T18:47:58-05:00"
---
@@ -20,4 +20,3 @@ end)
virtualizedFunction("1", "2", "3")
```
{{% alert context="info" text="**Note**: if your plan doesn't include virtualization support, `MV_VM` is a no-op where the passed function is mangled normally and not virtualized." /%}}

View File

@@ -2,7 +2,7 @@
weight: 100
title: "Macros"
description: "Obfuscator API"
icon: "article"
icon: "code_blocks"
date: "2025-05-01T18:47:58-05:00"
lastmod: "2025-05-01T18:47:58-05:00"
---

View File

@@ -2,7 +2,7 @@
weight: 200
title: "Options"
description: "Options for the obfuscator"
icon: "article"
icon: "settings"
date: "2025-05-01T18:47:58-05:00"
lastmod: "2025-05-01T18:47:58-05:00"
---

View File

@@ -7,15 +7,16 @@ date: "2025-05-01T18:47:58-05:00"
lastmod: "2025-05-01T18:47:58-05:00"
---
This option will enable the Control Flow Flattener (CFF). This feature is conservative in it's estimates of what can be flattened, if a block can't be flattened without side effects, it will be discarded from the flattening queue. CFF is applied recursively to failed blocks, meaning if a block is discarded from the flattening queue, its children may be flattened individually.
This option enables Control Flow Flattening (CFF), restructuring control flow and statements into a dispatch-like state machine. The flattener prioritizes correctness; if flattening a block could cause side effects, it either skips that block or only partially flattens it.
The control flow flattener supports the following branching syntaxes:
- `if` statements
- `while` and `repeat` loops
- numeric `for` loops
- `break` and `continue` statements
- `for-in` loops and even support for [Luau's generalized iteration](https://luau.org/syntax#generalized-iteration)
The following child options are available:
- `Wrap CFF blocks`: This will move some CFF blocks into their own closure in a lookup table.
- `Hoist locals`: Will move local storage into a lookup table for CFF blocks. Useful to cut down on the number of used locals.
- `Expression Decomposition`: Breaks apart expressions into CFF blocks and temporaries, can kill performance.
- `Hoist locals`: Will move local storage into a lookup table. Useful to cut down on the number of used locals.

View File

@@ -11,6 +11,7 @@ This option will enable non-destructive constant decomposition and various state
The following child options are available:
- `Lift Constants`: Percentage of function constants to lift into a lookup table. 0 is disabled while 100 is all constants.
- `Mangle Numbers`: Replaces number constants with a randomized binary expression which evaluates to that number.
- `Mangle Strings`: Performs light obfuscation of string constants.
- `Mangle Self-calls`: Replaces `x:foo()` with `x.foo(x)`.

View File

@@ -0,0 +1,16 @@
---
weight: 100
title: "Virtualization"
description: "Compilation and VM Generation"
icon: "article"
date: "2025-05-01T18:47:58-05:00"
lastmod: "2025-05-01T18:47:58-05:00"
---
The MoonVeil virtualization pass handles lifting and compiling selected virtualized blocks using the [MV_VM](/docs/macros/mv_vm) or [MV_ENC_FUNC](/docs/macros/mv_enc_func) macros. The virtualizer handles the generation of a uniquely hardened luau interpreter implemented in luau and transpiles virtualized blocks to it. Each script has a completely unique instruction set with hot-patching mnemonics, shuffled opcode encoding and behavior.
The following child options are available:
- `Virtualize Script`: Wrap the entire script in an `MV_VM` macro, effectively marking the entire script (excluding [MV_OMIT](/docs/macros/mv_omit_function) blocks).
- `Environment check`: Will perform some basic anti-tamper checks, can break some environments
- `Debug VM`: Enables VM error debugging; DO NOT USE FOR SHARED SCRIPTS

View File

@@ -0,0 +1,67 @@
---
weight: 999
title: "Performance Guide"
description: "Performance guide for MoonVeil"
icon: "article"
date: "2025-05-01T18:47:58-05:00"
lastmod: "2025-05-01T18:47:58-05:00"
---
MoonVeil provides multiple solutions to improve and optimize the performance of your scripts.
## Using the 'Fast VM' preset
This preset is available in [your dashboard's settings](/docs/dashboard/). If you're still having performance issues, continue reading.
## Omitting Obfuscation from blocks
Not all code needs to be obfuscated. Large libraries that deal with unimportant code such as UI libraries, data serialization libraries, etc. can be left unobfuscated.
MoonVeil allows you to omit obfuscation from specific blocks of your script, by wrapping the block in an [MV_OMIT](/docs/macros/mv_omit_function) macro:
```lua
MV_OMIT(function()
for i = 0, 10 do
print(i)
end
end)()
```
Code that runs frequently (e.g. per game tick, render frame, or otherwise multiple times per second) may cause application freezes, drop FPS, reduce throughput, and increase latency even if optimized properly. Most of the time obfuscation is not necessary on these functions. For example:
```lua
game:GetService("RunService").RenderStepped:Connect(MV_OMIT(function()
Label.Text = "FPS: " .. game:GetService("Stats").FramesPerSecond
-- or whatever
end))
```
## Obfuscation only through macros
Who says you need to obfuscate your whole script? If you know what you're doing, you can selectively tell MoonVeil to **only** obfuscate certain parts of your script using the [MV_VM](/docs/macros/mv_vm), [MV_ENC_FUNC](/docs/macros/mv_enc_func), and [MV_CFF](/docs/macros/mv_cff) macros. This gives you much more control over the obfuscation process, you simply tell MoonVeil what parts of your script you want to obfuscate:
```lua
local getThing = MV_VM(function()
for i = 0, 10 do
print(i)
end
-- this will be SO slow, but does work!
MV_CFF(function()
for i = 0, 10 do
print(i)
end
end)()
return "hello world"
end)
MV_ENC_FUNC(function()
print('yay function unencrypted')
for i = 0, 10 do
print(i)
end
end, "hello world", getThing())()
```
Then using the `Minify` preset will only run the passes you've specified. For a full list of macros, see the [documentation](/docs/macros).

View File

@@ -1,12 +0,0 @@
---
weight: 999
title: "Using Macros"
description: "Guide to using macros"
icon: "article"
date: "2025-05-01T18:47:58-05:00"
lastmod: "2025-05-01T18:47:58-05:00"
---
[Macros](./macros/) are a collection of reserved global functions available for use in your scripts. These are only available at obfuscation-time and are not available at runtime, meaning trying to access these functions dynamically will fail.
They can be used in any script in [your dashboard](./dashboard/) and provide many useful tools for obfuscation.

View File

@@ -1,202 +0,0 @@
# Note: Template blocks require a 'weight' parameter so they're correctly ordered on the landing page
# Hero
hero:
enable: true
weight: 10
template: hero
backgroundImage:
path: "images/templates/hero"
filename:
desktop: "gradient-desktop.webp"
mobile: "gradient-mobile.webp"
badge:
text: v0.1.0
color: primary # primary, secondary, success, danger, warning, info, light, dark
pill: false # boolean
soft: true # boolean
# titleLogo:
# path: "images/logos"
# filename: "title_logo.png"
# alt: "Lotus Docs Logo"
# height: 80px
title: "MoonVeil Obfuscator"
subtitle: A lightweight, **modern documentation** theme for Hugo. Easily customised for building **fast**, **secure**, and **SEO-friendly** documentation sites.
ctaButton:
icon: rocket_launch
btnText: "Get Started"
url: "/docs/quickstart/#create-a-new-lotus-docs-site"
cta2Button:
icon: construction
btnText: "In Development"
url: "https://github.com/colinwilson/lotusdocs"
info: "**Open Source** MIT Licensed."
# Feature Grid
featureGrid:
enable: true
weight: 20
template: feature grid
title: Why choose Lotus Docs?
subtitle: Lotus Docs is a highly configurable Hugo documentation theme. Yet, with the default configuration you can deploy and publish your documentation site in a matter of minutes. Check out some core features below.
items:
- title: Fast
icon: speed
description: 4 x 100's score on Google Lighthouse by default. Lotus Docs removes unused CSS, prefetches asset links, and lazy loads content images.
ctaLink:
text: learn more
url: /docs/
- title: SEO Friendly
icon: trending_up
description: Data is automatically structured to be SEO friendly. Includes Meta tags, Opengraph, and Twitter cards. Choose the settings that best suit you.
ctaLink:
text: learn more
url: /docs/
- title: Secure by default
icon: lock
description: Lotus Docs' default configuration scores A+ on Mozilla Observatory. You can update the default Security Headers to suit your requirements.
ctaLink:
text: learn more
url: /docs/
- title: Optional Features
icon: settings
description: Many Lotus Docs features are configurable via optional parameters. Require DocSearch for your site? Then enable it via a single setting.
ctaLink:
text: learn more
url: /docs/
- title: Deploy to Vercel
icon: change_history
description: Deploy to Vercel in seconds. Vercel Functions, Vercel Redirects/Rewrites, and Vercel Headers are all configurable for an enriched experience.
ctaLink:
text: learn more
url: /docs/
- title: Dark Mode
icon: dark_mode
description: Prefer not to be blasted by the sun while reading? Switch to a low-light UI with the click of a button. Modify colour variables to match your branding.
ctaLink:
text: learn more
url: /docs/
- title: Search by DocSearch
icon: search
description: Search your docs with DocSearch. A powerful, efficient and accessible search solution built on Algolia Crawler & Autocomplete. TBC.
ctaLink:
text: learn more
url: /docs/
- title: Multilingual Support
icon: translate
description: Lotus Docs supports Hugo's Multilingual Mode. Create documentation in multiple languages side by side with i18n support.
ctaLink:
text: learn more
url: /docs/
- title: Bootstrap v5
icon: palette
description: Built on Bootstrap 5, Lotus Docs allows for a familiar, flexible, and intuitive developer experience. Easily customise your site via SCSS variables and files.
ctaLink:
text: learn more
url: /docs/
imageText:
enable: false
weight: 25
template: image text
title: Built with performance and accessability in mind. Top scores on Google's Lighthouse
subtitle: A default Lotus Docs deployment is capable of achieving 4 x 100 scores on Google's Lighthouse performance analysis tool.
list:
- text: Blazing fast page loads
icon: speed
- text: Sensible default SEO friendly settings
icon: area_chart
- text: Designed to be accessible
icon: accessibility
image:
path: "images/templates/single"
filename: "google_lighthouse_circle_v1.0.svg"
alt: "Google LightHouse 100% Illustration" # Optional but recommended
imgOrder:
desktop: 2
mobile: 1
ctaButton:
text: Learn more
url: "/docs/"
# Image compare
imageCompare:
enable: false
weight: 30
template: image compare
title: Customise The Lotus Docs Appearance
subtitle: Much of Lotus Docs' appearance can be customised. Dark mode is optional (enabled by default) and you can choose a Google font that suites you via the config parameters.
items:
- title: Dark Mode
config: {
startingPoint: 50,
addCircle: true,
addCircleBlur: false,
showLabels: true,
labelOptions: {
before: 'Dark',
after: 'Light',
onHover: false
}
}
imagePath: "images/screenshots"
imageBefore: "lotusdocs_dark_v0.8.webp"
imageAfter: "lotusdocs_light_v0.8.webp"
- title: Custom Fonts
config: {
controlColor: "#3C4257",
startingPoint: 25,
addCircle: true,
addCircleBlur: false,
showLabels: true,
labelOptions: {
before: 'Inter',
after: 'Life Saver',
onHover: false
}
}
imagePath: "images/screenshots"
imageBefore: "lotusdocs_google_font_demo_inter_screenshot.webp"
imageAfter: "lotusdocs_google_font_demo_lifesavers_screenshot.webp"
- title: Accent Color
config: {
startingPoint: 25,
addCircle: true,
addCircleBlur: true,
showLabels: true,
labelOptions: {
before: 'Blue',
after: 'Cardinal',
onHover: false
}
}
imagePath: "images/screenshots"
imageBefore: "lotusdocs_blue_theme_colour.webp"
imageAfter: "lotusdocs_cardinal_theme_colour.webp"

View File

@@ -0,0 +1,132 @@
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5.11.0/swagger-ui.css" />
<script src="https://unpkg.com/swagger-ui-dist@5.11.0/swagger-ui-bundle.js" crossorigin></script>
<style>
/* TODO: i just threw shit in here until it semi fit the theme, im so sorry */
.information-container,
.servers,
.models {
display: none !important;
}
.swagger-ui {
fill: var(--body-color);
color: var(--body-color);
}
.swagger-ui .btn {
background: var(--primary);
border: none;
border-radius: 4px;
box-shadow: 0 1px 2px rgba(0,0,0,.1);
color: var(--body-color);
font-family: sans-serif;
font-size: 14px;
font-weight: 700;
padding: 5px 23px;
transition: all .3s;
}
.swagger-ui .body-param-options {
display: none;
}
.swagger-ui .btn.cancel {
background: var(--danger);
color: var(--body-color);
}
.swagger-ui .prop-type {
color: var(--primary);
}
.swagger-ui .opblock-description-wrapper p, .swagger-ui .opblock .opblock-section-header h4, .swagger-ui table thead tr td, .swagger-ui table thead tr th, .swagger-ui .parameter__name {
fill: var(--body-color);
color: var(--body-color);
}
.swagger-ui .model, .swagger-ui .model-title, .swagger-ui .parameter__type, .swagger-ui .tab li, .swagger-ui label, .swagger-ui .opblock .opblock-section-header > label {
fill: var(--body-color);
color: var(--body-color);
}
.swagger-ui .response-col_status, .swagger-ui .response-col_description, .swagger-ui .responses-inner h4, .swagger-ui .responses-inner h5, .swagger-ui .model-toggle {
fill: var(--body-color);
color: var(--body-color);
}
.swagger-ui textarea {
background: var(--code-block-bg);
color: var(--body-color);
}
.swagger-ui .parameters-col_description, .swagger-ui .response-col_description, .swagger-ui table th, .swagger-ui table td {
padding-left: 10px;
}
.docs-content .main-content ul > li::before, .swagger-ui .opblock .opblock-section-header > label {
display: none;
}
.docs-content .main-content ul > li {
padding-left: 0px;
}
.swagger-ui .opblock-summary {
background-color: var(--primary-color);
color: var(--body-color);
fill: var(--body-color);
align-items: center;
cursor: pointer;
display: flex;
padding: 5px;
}
.swagger-ui .opblock-summary .opblock-summary-path {
color: var(--body-color);
}
.swagger-ui .opblock .opblock-summary-description {
color: var(--body-color);
}
.swagger-ui .opblock .opblock-section-header {
align-items: center;
background: var(--primary-color);
box-shadow: 0 1px 2px rgba(0,0,0,.1);
display: flex;
min-height: 50px;
padding: 8px 20px;
}
.swagger-ui .wrapper {
padding: 0;
}
.swagger-ui .scheme-container, .title {
display: none;
}
</style>
<div id="swagger-ui"></div>
<script>
window.onload = () => {
// Build a system
const ui = SwaggerUIBundle({
url: "https://moonveil.cc/api/doc.json",
deepLinking: false,
dom_id: "#swagger-ui",
persistAuthorization: true,
validatorUrl: null,
presets: [
SwaggerUIBundle.presets.apis,
],
plugins: [
],
layout: "BaseLayout",
})
window.ui = ui
};
</script>