PublishSingleFile=true for .NET

Issues related to VMProtect
Admin
Site Admin
Posts: 2761
Joined: Mon Aug 21, 2006 8:19 pm
Location: Russia, E-burg
Contact:

PublishSingleFile=true for .NET

Post by Admin »

The build 1932 supports self-contained executables.

Here is simple example of .csproj to protect compiled assembly before publishing in a single file:

Code: Select all

<Project Sdk="Microsoft.NET.Sdk">

...

<Target Name="VMProtectCompile" BeforeTargets="GenerateSingleFileBundle">
  <PropertyGroup>
    <VMProtectCon>"C:\Program Files\VMProtect Demo\VMProtect_Con.exe"</VMProtectCon>
    <VMProtectInputFile>"$(IntermediateOutputPath)$(AssemblyName).dll"</VMProtectInputFile>
  </PropertyGroup>
  <Exec Command="$(VMProtectCon) $(VMProtectInputFile) $(VMProtectInputFile)" />
</Target>

<Target Name="VMProtectDelete" AfterTargets="GenerateSingleFileBundle">
  <Delete Files="$(IntermediateOutputPath)$(AssemblyName).dll" />
</Target>

</Project>
howze
Posts: 11
Joined: Thu Dec 07, 2023 9:55 am

Re: PublishSingleFile=true for .NET

Post by howze »

Admin wrote: Wed Dec 27, 2023 11:17 am The build 1932 supports self-contained executables.

Here is simple example of .csproj to protect compiled assembly before publishing in a single file:

Code: Select all

<Project Sdk="Microsoft.NET.Sdk">

...

<Target Name="VMProtectCompile" BeforeTargets="GenerateSingleFileBundle">
  <PropertyGroup>
    <VMProtectCon>"C:\Program Files\VMProtect Demo\VMProtect_Con.exe"</VMProtectCon>
    <VMProtectInputFile>$(IntermediateOutputPath)$(AssemblyName).dll</VMProtectInputFile>
  </PropertyGroup>
  <Exec Command="$(VMProtectCon) $(VMProtectInputFile) $(VMProtectInputFile)" />
</Target>

<Target Name="VMProtectDelete" AfterTargets="GenerateSingleFileBundle">
  <Delete Files="$(IntermediateOutputPath)$(AssemblyName).dll" />
</Target>

</Project>
1、When I was testing this feature, I found that if the name of the project contains a space, it will report an error when publishing, please check, thank you.

pic.png
pic.png (50.85 KiB) Viewed 9449 times


2、At the same time, how to use functions such as 'Memory Protection', 'Debugger', 'Virtualization Tools Found' message, etc., which can be directly used in the gui?
Admin
Site Admin
Posts: 2761
Joined: Mon Aug 21, 2006 8:19 pm
Location: Russia, E-burg
Contact:

Re: PublishSingleFile=true for .NET

Post by Admin »

Just change PATH_TO_VMP_FILE to the full name of ".vmp" file created by VMProtect's GUI:

Code: Select all

<Target Name="VMProtectCompile" BeforeTargets="GenerateSingleFileBundle">
  <PropertyGroup>
    <VMProtectCon>"C:\Program Files\VMProtect Demo\VMProtect_Con.exe"</VMProtectCon>
    <VMProtectInputFile>"$(IntermediateOutputPath)$(AssemblyName).dll"</VMProtectInputFile>
    <VMProtectProjectFile>-pf "PATH_TO_VMP_FILE"</VMProtectProjectFile>
  </PropertyGroup>
  <Exec Command="$(VMProtectCon) $(VMProtectInputFile) $(VMProtectInputFile) $(VMProtectProjectFile)" />
</Target>
About available parameters for the console version you can read here.

P.S. Don't forget to use the code virtualization for all critical methods with ObfuscationAttribute:

Code: Select all

[Obfuscation(Feature = "virtualization", Exclude = false)]
void MethodForProtection()
{
...
howze
Posts: 11
Joined: Thu Dec 07, 2023 9:55 am

Re: PublishSingleFile=true for .NET

Post by howze »

Admin wrote: Fri Dec 29, 2023 12:21 pm Just change PATH_TO_VMP_FILE to the full name of ".vmp" file created by GUI:

Code: Select all

<Target Name="VMProtectCompile" BeforeTargets="GenerateSingleFileBundle">
  <PropertyGroup>
    <VMProtectCon>"C:\Program Files\VMProtect Demo\VMProtect_Con.exe"</VMProtectCon>
    <VMProtectInputFile>"$(IntermediateOutputPath)$(AssemblyName).dll"</VMProtectInputFile>
    <VMProtectProjectFile>-pf "PATH_TO_VMP_FILE"</VMProtectProjectFile>
  </PropertyGroup>
  <Exec Command="$(VMProtectCon) $(VMProtectInputFile) $(VMProtectInputFile) $(VMProtectProjectFile)" />
</Target>
About available parameters for the console version you can read here.

P.S. Don't forget to use the code virtualization for all critical methods with ObfuscationAttribute:

Code: Select all

[Obfuscation(Feature = "virtualization", Exclude = false)]
void MethodForProtection()
{
...

I don’t know if I understand it correctly, but I still get an error.

Code: Select all

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net8.0-windows</TargetFramework>
    <RootNamespace>Wpf_App</RootNamespace>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <UseWPF>true</UseWPF>
  </PropertyGroup>

<Target Name="VMProtectCompile" BeforeTargets="GenerateSingleFileBundle">
  <PropertyGroup>
    <VMProtectCon>"D:\VMProtect Demo\VMProtect_Con.exe"</VMProtectCon>
    <VMProtectInputFile>$(IntermediateOutputPath)$(AssemblyName).dll</VMProtectInputFile>
	<VMProtectProjectFile>-pf "C:\Users\Hao\Desktop\Wpf App\bin\Release\net8.0-windows\publish\win-x64\Wpf App.exe"</VMProtectProjectFile>
  </PropertyGroup>
  <Exec Command="$(VMProtectCon) $(VMProtectInputFile) $(VMProtectInputFile) $(VMProtectProjectFile)" />
</Target>

<Target Name="VMProtectDelete" AfterTargets="GenerateSingleFileBundle">
  <Delete Files="$(IntermediateOutputPath)$(AssemblyName).dll" />
</Target>

</Project>
pic.png
pic.png (24.27 KiB) Viewed 9421 times
Admin
Site Admin
Posts: 2761
Joined: Mon Aug 21, 2006 8:19 pm
Location: Russia, E-burg
Contact:

Re: PublishSingleFile=true for .NET

Post by Admin »

It seems you don't need our software, because you can't even solve such a "simple problem" by yourself. I don't understand why you think that "Wpf App.exe" is a VMProtect project file.

P.S. You still use wrong code here:

Code: Select all

<VMProtectInputFile>$(IntermediateOutputPath)$(AssemblyName).dll</VMProtectInputFile>
howze
Posts: 11
Joined: Thu Dec 07, 2023 9:55 am

Re: PublishSingleFile=true for .NET

Post by howze »

Admin wrote: Fri Dec 29, 2023 2:29 pm It seems you don't need our software, because you can't even solve such a "simple problem" by yourself. I don't understand why you think that "Wpf App.exe" is a VMProtect project file.

P.S. You still use wrong code here:

Code: Select all

<VMProtectInputFile>$(IntermediateOutputPath)$(AssemblyName).dll</VMProtectInputFile>
Thank you very much, I successfully solved the problem, it was indeed that I used the wrong code.
ps. My English is not good, and I am not very familiar with this software, but now I understand what VMProtect project file is. Anyway, thank you again for your patient answer.
AuDim
Posts: 5
Joined: Thu Oct 16, 2025 4:26 pm

Re: PublishSingleFile=true for .NET

Post by AuDim »

I have two questions about PublishSingleFile=true.

1. Am I correct in assuming the console version is being used here?
And it won't work with a Lite license?

2. I get the error:
[Error] Can't resolve assembly "Avalonia.Controls, Version=11.3.7.0, Culture=neutral, PublicKeyToken=c8d484a7012f9a8b"
namespae Avalonia.Controls is located in the Avalonia.dll assembly, which was added to the package as a NuGet package.
What should I do to make VMProtect see it?
Admin
Site Admin
Posts: 2761
Joined: Mon Aug 21, 2006 8:19 pm
Location: Russia, E-burg
Contact:

Re: PublishSingleFile=true for .NET

Post by Admin »

Please notice that the latest version of VMProtect supports self-contained EXE, so you don't need to modify .csproj anymore.
AuDim
Posts: 5
Joined: Thu Oct 16, 2025 4:26 pm

Re: PublishSingleFile=true for .NET

Post by AuDim »

I have the following structure in the .exe container:
cnc.dll - executable code with "main" function.
com.dll - assembly - where the main code is, included from cnc.dll
It's com.dll that needs to be protected.

I can't protect it even without linking to SingleFile.
Now I'm trying it on a regular Net application (without SingleFile).

And if I run VMProtect.exe on cnc.dll, everything is fine.
But if VMProtect.exe tries to protect com.dll, I get the error:
Can't resolve type "System.Byte[], System.Runtime, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" (token: 0xc0000eb)

So, it turns out that included assemblies can't be protected?
Only the executable assembly can?
Is there a way out of this situation?

I hope I've explained everything clearly.
Admin
Site Admin
Posts: 2761
Joined: Mon Aug 21, 2006 8:19 pm
Location: Russia, E-burg
Contact:

Re: PublishSingleFile=true for .NET

Post by Admin »

Please send us an example (original DLLs + .VMP files) that shows your problem.
AuDim
Posts: 5
Joined: Thu Oct 16, 2025 4:26 pm

Re: PublishSingleFile=true for .NET

Post by AuDim »

I rebuilt the application to use a single executable DLL, but it didn't help.
The error persists:
Can't resolve type "System.Byte[], System.Runtime, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" (token: 0xc0000eb)

Here's the assembly's bin directory:
https://drive.google.com/file/d/1gpPhPm ... sp=sharing
The assembly needs to be protected: JupiterCNC.dll

Have a look?
Admin
Site Admin
Posts: 2761
Joined: Mon Aug 21, 2006 8:19 pm
Location: Russia, E-burg
Contact:

Re: PublishSingleFile=true for .NET

Post by Admin »

AuDim wrote: Fri Oct 17, 2025 3:45 pm Can't resolve type "System.Byte[], System.Runtime, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" (token: 0xc0000eb)
Fixed in the 2503 build.
AuDim
Posts: 5
Joined: Thu Oct 16, 2025 4:26 pm

Re: PublishSingleFile=true for .NET

Post by AuDim »

Thank you so much!

On the GUI on SinglFile:
Now the same thing, but with "CommunityToolkit.Mvvm".
And this assembly is in "Imports" too.
???

If I run a simple application (not a SinglFile) from the GUI, compilation succeeds.
But the application won't launch.
PS: In the code, I only set:
[Obfuscation(Feature = "strings", Exclude = false)].
And I didn't enable virtualization.

What could be causing it not to launch?

PS: In the Windows logs:

Application: JupiterCNC.exe
CoreCLR Version: 9.0.1025.47515
.NET Version: 9.0.10
Description: The process was terminated due to an unhandled exception.
Exception Info: System.TypeLoadException: Could not load type 'System.DoubleNumerics.Vector3' from assembly 'JupiterCNC, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' due to value type mismatch.
at System.Signature.GetSignature(Void* pCorSig, Int32 cCorSig, RuntimeFieldHandleInternal fieldHandle, IRuntimeMethodInfo methodHandle, RuntimeType declaringType)
at System.Reflection.RuntimeMethodInfo.<get_Signature>g__LazyCreateSignature|25_0()
at System.Reflection.RuntimeMethodInfo.FetchNonReturnParameters()
at System.Reflection.RuntimeMethodInfo.GetParameters()
at InvokeStub_(Object, Span`1)
at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.Emit.DynamicMethod.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at 563F5FA9.0FB29B3A()
at 563F5FA9.2EA869A8(Object 578EBD3D, Int32 7C01B93D)
--- End of stack trace from previous location ---
at 563F5FA9.4AB1E91F.F3333F1E(Object DFADEC00)
at 563F5FA9.2EA869A8(Object 578EBD3D, Int32 7C01B93D)
at 563F5FA9.DA17ED05()
at 563F5FA9.2EA869A8(Object 578EBD3D, Int32 7C01B93D)
--- End of stack trace from previous location ---
at 563F5FA9.4AB1E91F.F3333F1E(Object DFADEC00)
at 563F5FA9.2EA869A8(Object 578EBD3D, Int32 7C01B93D)
at .cctor()

PS: System.DoubleNumerics.dll is located in the bin directory, where 'System.DoubleNumerics.Vector3' is defined.
Admin
Site Admin
Posts: 2761
Joined: Mon Aug 21, 2006 8:19 pm
Location: Russia, E-burg
Contact:

Re: PublishSingleFile=true for .NET

Post by Admin »

You should exclude renaming for all classes that used in reflection or switch off the option "Strip debug information".
AuDim
Posts: 5
Joined: Thu Oct 16, 2025 4:26 pm

Re: PublishSingleFile=true for .NET

Post by AuDim »

Thanks, but:

You wrote: >You should exclude renaming for all classes used in reflection

I don't use Reflection anywhere in my code.
But I tried adding the tag to the project file:
<AutoGenerateBindingRedirects>false</AutoGenerateBindingRedirects>
But it didn't work, the error was the same: Could not load type 'System.DoubleNumerics.Vector3'
And the docs for "AutoGenerateBindingRedirects" say: It doesn't apply to newer implementations of .NET, including .NET 6 and later versions.
So, you can no longer disable it in .NET projects.
Or did you mean something else, not "AutoGenerateBindingRedirects"?

You wrote: >or switch off the "Strip debug information" option

Disabled in the GUI.
This also didn't work, the same error: Could not load type 'System.DoubleNumerics.Vector3'
I checked with the following debug information types:
<DebugType>portable</DebugType>
<DebugType>full</DebugType>-
<DebugType>embedded</DebugType>
Post Reply