Limitations on Use of Methods in .NET Applications
This topic describes limitations on the use of methods in .NET applications that you protect using Sentinel LDK Envelope.
Methods that cannot be selected for protection
The methods that follow cannot be selected for protection:
>Methods with a code size of 0 (for example, pure virtual functions).
>Methods with a name that starts with “?A0x”, “ATL” or “<CrtImplementationDetails”. These are system methods from the ATL library and should not be modified by Envelope.
>A method with one of the following names is ignored: initterm, .cctor, initatexbit
>Global methods (methods that do not belong to any type).
Methods that cannot be obfuscated or encryted
For the methods that follow, Envelope can only check for the presence of a Sentinel protection key. However, Envelope cannot apply code obfuscation or code encryption.
>Generic methods (template method inside casual or template class).
>Any method that has pointers in arguments or as local variables - ptr itself, fnptr (function pointer), and by ref (parameters passed by reference).
>Any static method in a generic method (template type with a static method inside it).
>Any method inside a value type (special type, similar to struct in C++).
Methods for which the retrieved file name case is altered
When the protection type is set to Only Windows shell or Method level & Windows shell, the case of the application file name that is retrieved by the methods listed below is sometimes different from the actual file name on the hard drive.
For example:
Path on disk: |
E:\Applications\CGD_pro\bin\SBE.exe |
Path used by the calling function: |
E:\Applications\CGD_pro\bin\SBE.EXE |
This issue occurs when the following methods are used:
>System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName
>System.Windows.Forms.Application.ExecutablePath
>System.IO.Directory.GetCurrentDirectory()
>System.Environment.CurrentDirectory
>Assembly.GetExecutingAssembly().Location
Use of Union fields
Envelope does not support Union fields when these are passed as a function parameter. Instead, you can use Unions as global variables or as internal variables of Classes or Methods.
Sample 1
This sample demonstrates a supported code segment. This mechanism will work because the union fields are used inside a function within a method of the same class, but they are not passed as an argument
using System; using System.Runtime.InteropServices; namespace Test { [StructLayout(LayoutKind.Explicit)] public struct SampleUnion { [FieldOffset(0)] public byte[] bytes; [FieldOffset(0)] public float[] floats; } public class TestClass { SampleUnion foo; public TestClass() { foo.bytes = new byte[10]; foo.floats[0] = 3.1415926F; } public void TestUnion() { Console.WriteLine("Type for 'float[] floats' : {0}", foo.floats.GetType()); Console.WriteLine(foo.floats[0]); } public static void Main() { TestClass test = new TestClass(); test.TestUnion(); } } }
Sample 2
This sample demonstrates an unsupported mechanism. The protected application will fail when executed. This occurs because Envelope cannot handle union fields that are passed as parameters to functions.
using System; using System.Runtime.InteropServices; namespace Test { [StructLayout(LayoutKind.Explicit)] public struct SampleUnion { [FieldOffset(0)] public byte[] bytes; [FieldOffset(0)] public float[] floats; } public class TestClass { public SampleUnion foo; public TestClass() { foo.bytes = new byte[10]; foo.floats[0] = 3.1415926F; } public void TestUnion(float[] floats) { Console.WriteLine("Type for 'float[] floats' : {0}", floats.GetType()); Console.WriteLine(floats[0]); } public static void Main() { TestClass test = new TestClass(); test.TestUnion(test.foo.floats); } } }