Salamander .NET Linker and mini-deployment tool allows you to link .NET assemblies together into a single file, and to deploy your application without installation of the whole Microsoft .NET Framework. The linker links MSIL code on demand putting together only the required classes and methods, and it is capable of linking into the Microsoft .NET framework class libraries. The mini-deployment tool then builds a minimum set of the Microsoft .NET runtime to ship with your .NET programs. This usually results in installation file size of a few mega bytes, rather than tens of mega bytes, and the installation takes much less time without rebooting machines.
Although the linking and mini-deployment are provided from the same command line utility, they are actually independent in the sense that you can use only the linking without using the mini-deployment, or use only the mini-deployment without any linking. The linking is usually performed before mini-deployment in order to shrink the whole package size.
Although .NET solves the DLL hell problem in quite a good manner, but there are still too many dependent assemblies (managed DLL files) to manage. It is quite often that you may need to distribute more than 10 assemblies to your customers. In this case, it makes sense to consolidate dependent DLLs into a single assembly.
There are still many low-end machines that are not suitable for .NET framework installation, and some users may not be willing to install the framework at all, this tool helps you to reach more customers as it silently deploys a trimmed down version of the framework without any noticeable effects and conflicts. The framework appears as an integrated part of your own application.
Even when one day all machines have Microsoft .NET Framework installed, such a tool will be still useful. Five years from now, there will be many versions of framework available, and thus it is going to be a difficult task to make sure that your customers have the correct version of the framework installed. Since our tool ships a whole package without external dependencies, therefore it can guarantee that your application runs well regardless of the different versions of the framework available on the client machine.
Another reason is this tool offers a unique way to protect your code. By using the tool, you will be able to inject system function calls (defined in Microsoft .NET Framework class libraries) into your own code. After obfuscation, the embedded system calls can no longer be easily identified, and thus it becomes much more difficult for your competitors to understand the inflated code.
.NET programs are distributed in unit of assemblies, one assembly often refers to a few other assemblies. Our linker first loads the entry assembly, finds its entry point for an EXE file, or some public methods for a DLL file, it then recursively follows the calling graph of the MSIL code to link all required code together. The code might reside in the same assembly as the entry module, or in some referenced assemblies. During the walk, relevant classes and other entities are marked. By the end, a new assembly that contains all required bits of code is created. The entry point methods can be configured using our GUI tool.
The mini-deployment tool uses fusion APIs to find out all of the dependent assemblies and modules, including those in the GAC (Global Assembly Cache) and those in the application directory, then copy them into the deployment folder. The deployment folder maintains a directory hierarchy that emulates the Microsoft .NET installation; it contains its own GAC, its own registry, and its own run time files. The presence of a local GAC supports those applications that require different versions of the same assembly and different versions of the .NET framework in the same way as if the full .NET framework exists. The local GAC also shields the mini-deployed applications from using the external GAC when the full .NET Framework is also installed on the same machine.
(1) You can use the tool to link any
assemblies or modules that do not contain native code into a single assembly.
For instance, if your assembly is a multi-file assembly that contains several
modules, you can use the tool to link those modules into a
single manifest assembly (which might be very useful since the current version
of Visual Studio .NET does not provide intellisense for multi-file assemblies).
The linked assemblies require the full framework.
(2) The mini-deployment can be used to generate a deployment package only for
.NET executables, including the regular EXEs (console and forms) and windows
service EXEs. In general, in order to generate a package that runs w/o the
framework, it requires full control of the process. If you are providing
components (DLLs) and you do not have control of the calling process, then a
mini package can not be generated.
No. The linker intelligently searches only the required methods and codes. Code is not called from the entry points will not exist in the final assembly. Therefore, the final assembly always has a smaller size than the sum of those assemblies merged.
The linker does, however, provide an option for merging assemblies together, which might be useful in certain circumstances. For example, if you have two small assemblies that some of their private methods are needed by other assemblies (possibly through reflections), then you may simply merge them together.
Yes. The linking and mini-deployment are independent, although there are provided from the same tool. You can perform mini-deployment without linking any assemblies if you are not concerned with disk spaces. In some situations where linking introduces runtime problems, mini-deployment might be the only way to go.
Yes. The linking and mini-deployment are independent, although there are provided from the same tool. You can only link assemblies together without generating a mini-deployment package. However, the linked assembly requires the full Microsoft .NET framework.
Yes. The generated package contains its own GAC where different versions of the same assemblies can be stored. The behavior is exactly the same as the GAC provided by the full Microsoft .NET framework.
Yes. What you need to do is to generate two mini packages into the same folder. Deploying multiple applications together save disk space as they share the same runtime and possibly some common assemblies.
They are totally different things. An obfuscator provides limited code protection through modifying symbol names to confuse someone from understanding the decompiled code. Our linker is a tool to link assemblies together. Our linker is not an obfuscator, but it can be used in conjunction with an obfuscator to offer better protection since it can be used to eliminate system calls that are defined in the Microsoft .NET Framework class libraries.
Obfuscators are often used for code protection, but there is one problem none of the current obfuscators address, that is, no matter how good the obfuscation is, there are system library calls and other external references scattered over in your code (see red in below). Since these calls are external references, obfuscators will have to leave them unchanged. However, these references help a lot to understand the decompiled code, because they are well documented and public APIs.
before: (no obfuscators are able to rename following code in red, since they are public APIs) IL_0000: ldarg.0 IL_0001: call instance void [System.Windows.Forms]System.Windows.Forms.Form::.ctor() IL_0006: ldarg.0 IL_0007: newobj instance void [System.Windows.Forms]System.Windows.Forms.TextBox::.ctor() IL_000c: stfld class [System.Windows.Forms]System.Windows.Forms.TextBox A.A::A IL_0011: ldarg.0 IL_0012: ldfld class [System.Windows.Forms]System.Windows.Forms.TextBox A.A::A IL_0017: call valuetype [System.Drawing]System.Drawing.Color [System.Drawing]System.Drawing.Color::get_Cyan() IL_001c: callvirt instance void [System.Windows.Forms]System.Windows.Forms.TextBoxBase::set_BackColor(valuetype [System.Drawing]System.Drawing.Color) IL_0021: ldarg.0
It takes no time to conclude that this is some code about Windows Forms, and it is constructing a textbox, and setting a background color. With this kind of information in mind, a hacker can easily understand your code. There is no viable way to rename or eliminate such calls. Doing so, the code would not run as usual.
Linking is the only solution that can solve the problem. Our linker can actually embed System.Windows.Forms code into your own program, so system calls appear as your own code, and you can obfuscate them at your will. In this way, the linker removes or reduces such public APIs, and thus makes your code much more difficult to decompile after obfuscation. Below shows sample MSIL code after the linker is used and then obfuscated.
after: (absolutely no clue Windows.Forms APIs are used, an obstacle for a hacker to understand this junk) IL_0000: ldarg.0 IL_0001: call instance void a.A::.ctor() IL_0006: ldarg.0 IL_0007: newobj instance void D.c::.ctor() IL_000c: stfld class D.c A.A::A IL_0011: ldarg.0 IL_0012: ldfld class f.a A.A::A IL_0017: call valuetype a.B() IL_001c: callvirt instance void D.c(valuetype g.e) IL_0021: ldarg.0
The linker can be used to link Microsoft .NET Framework assemblies into your own code. You can then disassemble the linked assembly, and recompile it with ildasm with debug option, which can be then brought into a debugger. You can set break points at some internal methods. This provides a way to step through framework calls, and is very useful to learn the framework, or to trouble shoot runtime problems. If you know a bit on MSIL language, you can also add MSIL code into framework methods to intercept certain methods.
$1249 for a license that can be used by 1-5 developers, $2219 for 5-10 develoeprs,
Our linker is designed to be seamlessly integrated into your build process. This cannot be done in a reliable and repeatable fashion if the linker depends only on a graphical user interface for operation.
Yes. You can apply the linker before the obfuscator and protector are performed to your assemblies.
When multiple assemblies are linked together, types
defined in different assemblies are now brought into the same assembly, and
thus objects belong to hard-coded types might behave differently. Object
serialization and declarative security are the two areas that could be
affected. A type is fully identified by the type name, the assembly name, the
assembly version, culture and public key token, e.g.,
When System.Drawing.dll is linked into Scribble.exe, the above type needs to
convert to:
Our linker tries very hard to automatically handle such situations.
System.Drawing.Point, System.Drawing, Version=1.0.3300.0,
Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A
System.Drawing.Point, Scribble, Version=0.0.0.0, Culture=neutral,
PublicKeyToken=null
After linking multiple assemblies into a single one, declarative securities might get affected if the security permission is defined in one of the assemblies that are to be merged. The linker tries its best to rename the security permission to adapt to the resulting assembly. However, when discrepancy occurs, you can start to execute the linked assembly with security turned off. You can turn off code access security by the following command: caspol -s off.
If security permissions are defined for assemblies that are not linked, no special treatments need to be done.
Yes.
This has caused much confusion. Here is more clarification.
Our tool has two independent capabilities, linking and minideployment. For mixed images produced by VC++ .NET, the linking part does not work, but the minideployment part works just fine. These two aspects are independent, you can actually generate a minideployment without doing any linking. Linking is often used with minideployment since it reduces the final package size.
Suppose you have an EXE developed in C#/VB.NET, that refers to 10 other assemblies with 7 in C#/VB.NET and 3 in VC++ .NET, you will be able to link those 7 assemblies into the final EXE, but those 3 assemblies with unmanaged code must be shipped with the EXE as 3 separate files.
In other words, unmanaged code won't prevent you from using our tool, you will be still able to generate a package that can be shipped w/o the full framework. It is just that unmaged DLL and mixed assemblies are shipped as separate files.
We will consider adding support for linking VC++.NET assemblies depending on the demand
Yes, 100%.
Our product works on those platforms with .NET support, namely, the following
platforms,
Microsoft Windows® 98
Microsoft Windows NT® 4.0 (SP 6a required)
Microsoft Windows Millennium Edition (Windows Me)
Microsoft Windows 2000 (SP2 Recommended)
Microsoft Windows XP Professional
Microsoft Windows XP Home Edition
Since .NET does not run on WIN95, therefore, our linker does NOT support WIN95.
Our linker currently does not support UNIX systems.
Our linker deals with strong named assemblies automatically, no extra work is required.
Usually, attaching a strong name signature to your code
involves two steps:
(1) create the strong name key using the SN utility: sn -k sample.snk
(2) compile your assembly with the key by adding a declaration to the assembly
to indicate the location of the key file, as shown below,
C#:
[assembly: AssemblyKeyFile("sample.snk")]
class StrongNameTest
{
...
}
VB.NET:
<assembly: AssemblyKeyFile("sample.snk")>
Public Class StrongNameTest
...
End Class
Just make sure that your key file is in the correct path when the
protector is invoked, and our protector will automatically re-sign the modified
assembly with the same key file. If you do not have access to the key file, you
can choose to delay sign the linked assembly, or choose to remove the
signature, so you can continue to work with the code.