11Plugins
22=======
33
4- BitMono can load **plugins ** - external assemblies that contribute your own protections - without
5- rebuilding BitMono. Drop a plugin DLL into the plugins directory and BitMono discovers and runs the
6- protections inside it, exactly like the built-in ones. (`#227 <https://github.com/sunnamed434/BitMono/issues/227 >`_)
4+ BitMono can load **plugins **, external assemblies that add your own protections, without rebuilding
5+ BitMono. Drop a plugin DLL into the plugins directory and BitMono finds the protections inside it and
6+ runs them exactly like the built-in ones. (`#227 <https://github.com/sunnamed434/BitMono/issues/227 >`_)
77
88.. warning ::
99
10- Plugins are loaded into the BitMono process with full trust - .NET cannot sandbox them. Only drop
11- in plugins from sources you trust, just as you would with any other executable.
10+ Plugins run inside the BitMono process with full trust, .NET can't sandbox them. Only drop in
11+ plugins from sources you trust, same as you would with any other executable.
1212
1313
1414Where plugins live
1515------------------
1616
17- By default BitMono scans a ``plugins `` directory next to the BitMono executable. You can change the
18- directory name (or point it at an absolute path) with ``PluginsDirectoryName `` in ``obfuscation.json ``:
17+ By default BitMono scans a ``plugins `` directory next to the BitMono executable. You can rename it (or
18+ point it at an absolute path) with ``PluginsDirectoryName `` in ``obfuscation.json ``:
1919
2020.. code-block :: json
2121
2222 {
2323 "PluginsDirectoryName" : " plugins"
2424 }
2525
26- Two layouts are supported :
26+ or override it for a single run from the CLI with `` --plugins `` :
2727
28- - **Flat ** - drop the DLL straight into the directory: ``plugins/MyProtections.dll ``.
29- - **Per-plugin folder ** - give each plugin its own folder: ``plugins/MyProtections/MyProtections.dll ``.
30- Put any extra dependencies in a nested folder (for example ``plugins/MyProtections/libs/ ``); they are
31- resolved on demand and are not themselves treated as plugins.
28+ .. code-block :: bash
29+
30+ BitMono.CLI -f MyApp.dll --plugins " C:\path\to\my-plugins" -p HelloPlugin
31+
32+ Two layouts work:
3233
33- If the directory does not exist, BitMono simply skips plugin loading.
34+ - **Flat **, drop the DLL straight in: ``plugins/MyProtections.dll ``.
35+ - **Per-plugin folder **, give each plugin its own folder: ``plugins/MyProtections/MyProtections.dll ``.
36+ Put any extra dependencies in a nested folder (say ``plugins/MyProtections/libs/ ``), they're resolved
37+ on demand and aren't treated as plugins themselves.
38+
39+ If the directory doesn't exist, BitMono just skips plugin loading.
3440
3541
3642Writing a plugin
3743----------------
3844
3945A plugin is an ordinary class library that references ``BitMono.API `` (and usually ``BitMono.Core `` for
40- the ``Protection `` base class) and exposes one or more public protections. Writing a protection is the
41- same as :doc: `creating a built-in one <first-protection >`:
46+ the ``Protection `` base class) and exposes one or more public protections. Writing the protection itself
47+ is the same as writing a :doc: `built-in one <first-protection >`:
4248
4349.. code-block :: csharp
4450
@@ -66,46 +72,58 @@ same as :doc:`creating a built-in one <first-protection>`:
6672
6773 .. note ::
6874
69- The container builds your protection by calling its **first ** constructor and resolving each
70- parameter. Take ``IBitMonoServiceProvider `` (as above) to reach BitMono's services. If a parameter
71- cannot be resolved the protection is skipped and the error is logged - it never aborts the run.
75+ The container builds your protection through its **first ** constructor, resolving each parameter.
76+ Take ``IBitMonoServiceProvider `` (like above) to reach BitMono's services. If a parameter can't be
77+ resolved the protection is skipped and the error is logged, it never aborts the run.
7278
7379
7480.. _plugins-reference-the-host :
7581
7682Reference BitMono, don't ship it
7783--------------------------------
7884
79- Reference the BitMono assemblies with ``Private="false" `` so they are **not ** copied next to your
80- plugin. Your plugin must bind to the *same * ``BitMono.API `` the host is running; if you ship your own
81- copy, your protection implements a *different * ``IProtection `` type and BitMono will ignore it (and warn
82- you in the log).
85+ Reference BitMono from NuGet and mark it ``ExcludeAssets="runtime" `` so its assemblies are **not ** copied
86+ into your build output (BitMono itself provides them at runtime). Your plugin has to bind to the *same *
87+ ``BitMono.API `` the host is running. Ship your own copy and your protection implements a *different *
88+ ``IProtection `` type, so BitMono ignores it (and warns you in the log).
89+
90+ ``BitMono.Core `` pulls in ``BitMono.API ``, ``BitMono.Shared `` and ``AsmResolver `` for you, and
91+ ``ExcludeAssets="runtime" `` keeps the whole graph out of your output, so a successful build leaves just
92+ your own plugin DLL behind.
8393
8494.. code-block :: xml
8595
8696 <ItemGroup >
87- <Reference Include =" BitMono.API" >
88- <HintPath >path\to\BitMono.API.dll</HintPath >
89- <Private >false</Private >
90- </Reference >
91- <Reference Include =" BitMono.Core" >
92- <HintPath >path\to\BitMono.Core.dll</HintPath >
93- <Private >false</Private >
94- </Reference >
95- <Reference Include =" BitMono.Shared" >
96- <HintPath >path\to\BitMono.Shared.dll</HintPath >
97- <Private >false</Private >
98- </Reference >
97+ <!-- Use the version that matches the BitMono you run the plugin against. -->
98+ <PackageReference Include =" BitMono.Core" Version =" 0.40.1" >
99+ <ExcludeAssets >runtime</ExcludeAssets >
100+ </PackageReference >
99101 </ItemGroup >
100102
101103
104+ Versioning and compatibility
105+ ----------------------------
106+
107+ There's no special "plugin version" attribute - your plugin's own assembly version is its version, and
108+ BitMono prints it when it loads it (``Loaded plugin: MyPlugin v1.2.0.0 ``).
109+
110+ What actually matters is the ``BitMono.API `` version you build against (``BitMono.Core `` pulls it in). It's
111+ the contract, and it follows `semver <https://semver.org >`_: a new minor only adds things, a new major can
112+ break ``IProtection ``/``Protection ``. If a plugin is built against a *newer * ``BitMono.API `` than the
113+ BitMono you drop it into, it'd probably call something that isn't there - so BitMono skips it and logs a
114+ warning telling you to rebuild against the version you're running. Same or older builds load fine.
115+
116+ So pin ``BitMono.Core `` to the version you ship against and bump it when you move to a newer BitMono.
117+
118+
102119External dependencies
103120---------------------
104121
105- If your plugin uses external libraries (NuGet packages, your own helpers), ship those DLLs alongside the
106- plugin - either next to it or in a nested folder such as ``libs ``. BitMono installs an
107- ``AppDomain.AssemblyResolve `` handler that probes the plugin directories and loads dependencies on
108- demand, so they don't have to sit in BitMono's own folder.
122+ If your plugin uses external libraries (other NuGet packages, your own helpers), reference them
123+ **normally ** (without ``ExcludeAssets `` - that switch is only for BitMono itself) so they're copied next
124+ to your plugin, then ship those DLLs next to the plugin or in a nested folder like ``libs ``. BitMono
125+ installs an ``AppDomain.AssemblyResolve `` handler that probes the plugin directories and loads
126+ dependencies on demand, so they don't have to sit in BitMono's own folder.
109127
110128A typical per-plugin layout::
111129
@@ -119,7 +137,7 @@ A typical per-plugin layout::
119137Enabling a plugin protection
120138----------------------------
121139
122- Plugin protections are configured exactly like the built-in ones - by name (the class name, or the
140+ Plugin protections are configured exactly like the built-in ones, by name (the class name, or the
123141``[ProtectionName("...")] `` value). Add them to ``protections.json ``:
124142
125143.. code-block :: json
@@ -139,5 +157,5 @@ or pass them on the command line:
139157
140158 BitMono.CLI -f MyApp.dll -p HelloPlugin
141159
142- Execution order follows the configuration order, the same as built-in protections. See
160+ Execution order follows the configuration order, same as built-in protections. See
143161:doc: `obfuscation-execution-order ` for details.
0 commit comments