BoxedApp Blog

BoxedApp: Tips'n'Tricks, Examples, Use Cases etc.

.NET Applications: How to Hide Assemblies And Unmanaged DLLs


Share this post Bookmark and Share

One interesting task I’ve heard from one of our first customers is hidding assemblies and unmanaged DLLs. The target language is C#. Let’s explore how to solve this task with BoxedApp SDK.

At the first, decide how to store an assembly. In this example, I keep an assembly in static array. To create C# code with such array, I use the following code:

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace ConvertBinToSharpCode
{
    class Program
    {
        static void Main(string[] args)
        {
            byte[] data = File.ReadAllBytes(args[0]);

            Console.Write("namespace BinData\n{\n\tpublic class Data1\n\t\t{\n\n\t\tpublic static byte[] data = \n{\n");

            foreach (byte b in data)
            {
                Console.Write(b.ToString() + ",");
            }

            Console.Write("};\n}\n}\n");
        }
    }
}

It takes one argument (path to an assembly) and outputs C# code, save it as data.cs, for example:

namespace BinData
{
	public class Data1
		{

		public static byte[] data = 
{
77,90,144,0,3,0 .......
}
}

Include it to the main solution.

Now, how to create a virtual file with assembly and fill it from the BinData.Data1.data:

static void CreateAssemblyInMemory(
   string strVirtualPath, 
   byte[] data)
{
   IntPtr hHandle =
      BoxedAppSDK.NativeMethods.BoxedAppSDK_CreateVirtualFile(
         strVirtualPath,
         BoxedAppSDK.NativeMethods.EFileAccess.GenericWrite,
         BoxedAppSDK.NativeMethods.EFileShare.Read,
         IntPtr.Zero,
         BoxedAppSDK.NativeMethods.ECreationDisposition.New,
         BoxedAppSDK.NativeMethods.EFileAttributes.Normal,
         IntPtr.Zero);
   CloseHandle(hHandle);

   using (FileStream VirtualFileStream = 
            new FileStream(strVirtualPath, FileMode.Open))
   {
      VirtualFileStream.Write(data, 0, (int)data.Length);
   }
}

Now how to create an assembly into memory:

CreateAssemblyInMemory(@"Z:\myclass.dll", BinData.Data1.data);

Assembly assembly = Assembly.LoadFrom(@"Z:\myclass.dll");
object o = assembly.CreateInstance("myclass.Class1");
o.GetType().GetMethod("SomeMethod").Invoke(o, null);

Another option, when your application uses some assembly and you would like to keep this assembly in memory. In this case, you write:

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        BoxedAppSDK.NativeMethods.BoxedAppSDK_Init();

        // Creates a virtual file with assembly
        // before using the assembly, in 
        // other words, the assembly is not 
        // loaded yet
        CreateAssemblyInMemory(
           Application.StartupPath + @"\\Assembly1.dll", 
           BinData.Data1.data);

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        // The Form1 will be created, 
        // Form1 loads the assembly Assembly1.dll, 
        // BoxedApp SDK provides it from memory
        Application.Run(new Form1());

        BoxedAppSDK.NativeMethods.BoxedAppSDK_Exit();
   }
...
}
Share this post Bookmark and Share






Write a Comment

You must be logged in to post a comment. Log in