Can't protect .Net assembly on Linux

The same assembly .dll, built on Linux (Ubuntu or WSL2) and targeting either .net 6.0 or .net 8.0 (haven’t tried other versions) is protected just fine using VMProtect for Windows, while VMProtect for Linux (v3.10.2 build 2510) exits with an error “Can’t resolve assembly System.Runtime…”

This behavior can be reproduced even for a generic console .net app:

dotnet new console -f net6.0



namespace test;
using System.Reflection;

[Obfuscation(Feature = "virtualization", Exclude = false)]
public class Test {
  [Obfuscation(Feature = "virtualization", Exclude = false)]
  public void Foo(){
    Console.WriteLine("Foo");
  }
}

class Program
{
  public static void Main(string[] args){
    var obj = new Test();
    obj.Foo();
  }
}

then publish and try to protect:

dotnet publish -c Release -r linux-x64 --self-contained true -o pub
cd pub
vmprotect_con test.dll test.vmp.dll

exits with:
[Error] Can’t resolve assembly “System.Runtime, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”

Also notice the System.Runtime version 4.2.1.0 when using –self-contained true. When building with –self-contained false - it shows the correct target version 6.0.0.0 or 8.0.0.0 but still can’t resolve it.

I tried disabling “Strip Debug Information” in the project file and then calling

vmprotect_con test.dll.vmp

with no difference.

The error "Can’t resolve assembly “System.Runtime” means that VMProtect didn’t find required assembly in “/usr/lib/dotnet/shared”.

Thank you for the prompt reply. I was able to get it working using a symlink.

When installed via downloaded Microsoft packages on Debian/Ubuntu/WSL - it lives in /usr/share/dotnet/shared by default.

I just checked “sudo apt-get install dotnet-runtime-8.0” on Ubuntu 24.04 and it was installed in “/usr/lib/dotnet/shared/Microsoft.NETCore.App”

Yes, you are correct regarding apt-get on Ubuntu, however, the difference is between Ubuntu-provided and Microsoft-provided packages.

if you install it from MS repo (see Linux Software Repository for Microsoft Products | Microsoft Learn) like this:

wget https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt update
sudo apt install dotnet-sdk-6.0
sudo apt install dotnet-sdk-8.0

It goes to “/usr/share/dotnet/shared”

From the Docs:

The default location on Linux varies depending on distro and installment method. The default location on Ubuntu 22.04 is /usr/share/dotnet (when installed from packages.microsoft.com) or /usr/lib/dotnet (when installed from Jammy feed).

I’d suggest to simply take it from DOTNET_ROOT environment variable.

Microsoft как обычно в своем репертуаре решила устроить разработчикам геморрой на пустом месте. Причем DOTNET_ROOT-а нет ни после первого ни после второго способа, а есть еще третий - это установка через dotnet-install.sh, который ставит все свое барахло вообще в папку пользователя.

И в какую директорию в итоге смотреть?

Fixed in the 2525 build.

Еще в случае с self-contained рантайм будет лежать рядом со входным файлом. Это была моя первая попытка победить ошибку - положить все рядом с assembly.

Вторая попытка была найти аргумент для vmprotect_con, чтобы указать search-path)