Remove the strong name from 3rd party assemblies?
Asked Answered
B

3

10

How can I remove a strong name from a 3rd party assembly that I do not have the source code for, maybe using ilasm/ildasm (since it is possible to add a strong name using ilasm/ildasm)?

Generally, it seems to be possible, since this tool seems to be able to do this.

Botanize answered 2/8, 2016 at 9:28 Comment(5)
To answer you original question, yes that's obviously so easy. Deployed code is by definition unsafe and compromised. Signing is just one layer of protection (there must be others) for casual crackers.Jeffjeffcoat
XY question, removing a strong name is never necessary.Juryrig
@HansPassant I asked this to put together a demo on how easy (or hard) it is to replace a referenced assembly in a 3rd party application. Which can't be done as long as it has a strong name and is referenced by its strong name.Botanize
Well, of course. If it is was easy then there wouldn't be any point in having strong names. You have to know the private key, that proves that you are the "owner" of the file and that it hasn't been tampered with. You want to tamper with it.Juryrig
It is easy. It a single click with a tool. It removes the strong name of all assmeblies in a folder and redirect the assembly-references to the ones without the strong name. So a strong name is not a valid way to secure that the code you load was not altered.Botanize
P
5

Just use a tool to do it for you, doing it manually will probably take you too much time and hell, if there are tools out there then why reinvent the wheel?

Personally I have never used SNRemove but here is a list of tools I generally use:


EDIT: simple-assembly-explorer/SimpleAssemblyExplorer.Core/Assembler/Assembler.cs - this class should give you an idea of how strong name keys can be removed from strong named assemblies.

Pallbearer answered 2/8, 2016 at 9:53 Comment(4)
I would like to learn how this is done without an external tool (except the tools that come with .NET itself).Botanize
You will need to use a .NET assembly reader and probably an hex editor. There are no tools shipped with VS/.NET that can be used to remove a strong name.. Removing it by hand is basically fixing up the references, cleaning the assembly and fixing attributes/flags of types that uses signed types.Pallbearer
Are sure that it is not possible using ilasm/ildasm (which comes with .NET)?Botanize
I am pretty sure ildasm has no functionality to modify strong name verification.. You must understand that removing strong names was never a requirement at Microsoft while developing .NET hence you will not find a tool from the official toolset that does this for you. There is a sn.exe (strong name) inside the same folder as ildasm.exe which you can check out but I doubt it will help you get any further.Pallbearer
M
2

This is to remove strong name validation, not remove the strong name signature, however searches for strongname validation errors seem to route to this question so this is not irrelevant.

sn.exe can be used to disable strongname validation (sn.exe can be accessed via visual studio developer command prompt)

To disable strongname validation for all assemblies with a given public key token:

sn.exe -Vr *,<public key hex token>

or to disable validation for all assemblies with any public key:

sn.exe -Vr *,*
Mariellemariellen answered 6/12, 2017 at 19:19 Comment(0)
O
1

You can remove the strong name signature from an assembly programatically, using Mono.Cecil, like this:

public static void removeStrongName(string assemblyPath) {
    using (AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(
        assemblyPath,
        new ReaderParameters() { ReadWrite = true }
    )) {
        // Remove strong name signature from the assembly
        assembly.Name.PublicKey = new byte[0] {};
        assembly.MainModule.Attributes &= ~ModuleAttributes.StrongNameSigned;

        assembly.Write();
    }
}

This only removes the strong name signature from the assembly. If you also need to break the strong name validation between the assembly and its dependencies, you need to:

  1. Remove the public key from the references to the assembly's dependencies, in the assembly. This way, the runtime will not perform strong name validation on the dependency.

    This can be done like this:

    public static void removeStrongNameFromReferences(string assemblyPath) {
        using (AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(
            assemblyPath,
            new ReaderParameters() { ReadWrite = true }
        )) {
            // Remove public key portion from the references
            foreach (ModuleDefinition module in assembly.Modules) {
                foreach (AssemblyNameReference reference in module.AssemblyReferences) {
                    reference.PublicKey = null;
                }
            }
    
            assembly.Write();
        }
    }
    
  2. Remove the public key from the dependencies themselves. Otherwise, the runtime will fail to load the dependencies, as their identity will not match the identity inferred from the assembly reference, i.e. Dependency, Version=1.0.0.0, Culture=neutral, PublicKeyToken=61560d59bd5f3f5c versus the expected Dependency, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.

    Call removeStrongName on the dependencies.

Oliana answered 15/7 at 15:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.