Click here to Skip to main content
Click here to Skip to main content

Resigning a signed assembly

By , 18 Dec 2012
Rate this:
Please Sign up or sign in to vote.

Introduction 

Signing a .net assembly is the best way to secure your assemblies from being modified (cracked), and there is a project that describes how to remove the signature of the assembly: 

Remove signing from assembly 

But i didn't found any code that can resign a signed assembly, so if i modified an assembly (using a hex editor), i will be able to resign it (with another key surely) in order to use it signed. 

Using the code

Construtors

Public Sub New(ByVal assembly As String, ByVal snk As Byte())
    _strAssemblyPath = assembly
    _bytSNKFile = snk
End Sub

Public Sub New(ByVal assembly As String, ByVal snk As String)
    _strAssemblyPath = assembly
    _bytSNKFile = IO.File.ReadAllBytes(snk)
End Sub 

Global declarations

Private _bytAssembly As Byte()
Private _bytAssemblyPublicKey As Byte()

Private _bytSNKFile As Byte()
Private _strAssemblyPath As String

Private _strNewStrongKeyName As String
Private csRandom As Random = New Random(Environment.TickCount) 

We need to use some API functions:

<DllImport("MsCorEE.dll", EntryPoint:="StrongNameFreeBuffer", CharSet:=CharSet.Auto)> _
Private Shared Sub StrongNameFreeBuffer(ByVal pbMemory As IntPtr)
End Sub

<DllImport("MsCorEE.dll", EntryPoint:="StrongNameKeyDelete", CharSet:=CharSet.Auto)> _
Private Shared Function StrongNameKeyDelete(ByVal wszKeyContainer As String) As Boolean
End Function

<DllImport("MsCorEE.dll", EntryPoint:="StrongNameKeyInstall", CharSet:=CharSet.Auto)> _
Private Shared Function StrongNameKeyInstall( _
        <MarshalAs(UnmanagedType.LPWStr)> ByVal wszKeyContainer As String, _
        <MarshalAs(UnmanagedType.LPArray, SizeParamIndex:=2, SizeConst:=0)> ByVal pbKeyBlob As Byte(), _
        ByVal cbKeyBlob As Integer) As Boolean
End Function

<DllImport("MsCorEE.dll", EntryPoint:="StrongNameErrorInfo", CharSet:=CharSet.Auto)> _
Private Shared Function StrongNameErrorInfo() As UInt32
End Function

<DllImport("MsCorEE.dll", EntryPoint:="StrongNameSignatureGeneration", CharSet:=CharSet.Auto)> _
Private Shared Function StrongNameSignatureGeneration( _
        ByVal wszFilePath As String, _
        ByVal wszKeyContainer As String, _
        ByVal pbKeyBlob As Integer, _
        ByVal cbKeyBlob As Integer, _
        ByVal ppbSignatureBlob As Integer, _
        ByVal pcbSignatureBlob As Integer) As Boolean
End Function

<DllImport("MsCorEE.dll", EntryPoint:="StrongNameTokenFromAssemblyEx", CharSet:=CharSet.Auto)> _
Private Shared Function StrongNameTokenFromAssemblyEx( _
        ByVal wszFilePath As String, _
        <Out()> ByRef ppbStrongNameToken As IntPtr, _
        <Out()> ByRef pcbStrongNameToken As ULong, _
        ByRef ppbPublicKeyBlob As IntPtr, _
        ByRef pcbPublicKeyBlob As ULong) As Boolean
End Function 

And the main code will consist of the following two functions:

Private Function CheckForPubliKeyIndex(ByVal intIndex1 As Integer) As Boolean
    Dim intIndex2 As Integer
    Do
        If _bytAssemblyPublicKey(intIndex2) <> _bytAssembly(intIndex2 + intIndex1) Then Return False
        intIndex2 += 1
    Loop While (intIndex2 < _bytAssemblyPublicKey.Length)
    Return True
End Function

Public Function Resign() As Boolean
 
    Dim bytSNK As Byte()
    Dim blnReturn As Boolean
    Dim strSNKFile As String = ""

    Try
        strSNKFile = My.Computer.FileSystem.GetTempFileName
        IO.File.WriteAllBytes(strSNKFile, _bytSNKFile)

        Using keyPairFile As FileStream = File.OpenRead(strSNKFile)
            bytSNK = New StrongNameKeyPair(keyPairFile).PublicKey
            keyPairFile.Close()
        End Using

        _bytAssemblyPublicKey = AssemblyName.GetAssemblyName(_strAssemblyPath).GetPublicKey

        If _bytAssemblyPublicKey Is Nothing Then Exit Try

        Using csFileStream As FileStream = File.OpenRead(_strAssemblyPath)
            _bytAssembly = New Byte(csFileStream.Length - 1) {}
            csFileStream.Read(_bytAssembly, 0, csFileStream.Length)
            csFileStream.Close()
        End Using
 
        Dim intAssemblyPublicKeyIndex As Byte = _bytAssemblyPublicKey(0)
        Dim intCounter As Integer
        Dim intPublicKeyIndex As Integer

        Do
            If ((_bytAssembly(intCounter) = intAssemblyPublicKeyIndex) _
                    AndAlso Me.CheckForPubliKeyIndex(intCounter)) Then
                intPublicKeyIndex = intCounter
                Exit Do
            End If
            intCounter += 1
        Loop While (intCounter < Me._bytAssembly.Length)

        Dim num4 As Integer

        Do
            _bytAssembly((intPublicKeyIndex + num4)) = bytSNK(num4)
            num4 += 1
        Loop While (num4 < bytSNK.Length)

        Using csFileStream As FileStream = File.Create(Me._strAssemblyPath)
            csFileStream.Write(_bytAssembly, 0, Me._bytAssembly.Length)
            csFileStream.Close()
        End Using
 
        Me._strNewStrongKeyName = String.Format("{0}-{1}", _
            Me.csRandom.Next(&H989680, &H5F5E0FF).ToString, _
            Me.csRandom.Next(&H989680, &H5F5E0FF).ToString)

        StrongNameKeyDelete(Me._strNewStrongKeyName)

        Using input As New FileStream(strSNKFile, FileMode.Open, FileAccess.Read)
            Using reader As New BinaryReader(input)

                Dim buffer2 As Byte() = New Byte(CInt(reader.BaseStream.Length) - 1) {}
                reader.BaseStream.Seek(0, SeekOrigin.Begin)
                reader.Read(buffer2, 0, CInt(reader.BaseStream.Length))

                Dim length As Integer = CInt(reader.BaseStream.Length)
                reader.Close()
                input.Close()

                If Not StrongNameKeyInstall(Me._strNewStrongKeyName, buffer2, length) Then
                    ' Failed to sign the assembly
                ElseIf StrongNameSignatureGeneration(Me._strAssemblyPath, Me._strNewStrongKeyName, 0, 0, 0, 0) Then
                    blnReturn = True
                Else
                    ' Failed to sign the assembly
                End If

            End Using
        End Using

    Catch exc As Exception
        ' blnReturn = False ' MsgBox(exc.Message)
    Finally
        IO.File.Delete(strSNKFile)
    End Try

    Return blnReturn

End Function 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Ahmad Dekmak
Software Developer (Senior) Mentis
Lebanon Lebanon
No Biography provided

Comments and Discussions

 
QuestionNice Tool !!! PinmemberAshutosh Phoujdar12-Nov-13 17:36 
SuggestionBroken Link PinmemberPaulCedar18-Dec-12 4:37 
GeneralRe: Broken Link PinmemberAhmad Dekmak18-Dec-12 10:33 
QuestionGreat tool PinmembermasterJalchr17-Dec-12 22:38 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140415.2 | Last Updated 18 Dec 2012
Article Copyright 2012 by Ahmad Dekmak
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid