Click here to Skip to main content
15,113,531 members
Articles / Programming Languages / Visual Basic
Tip/Trick
Posted 17 Dec 2012

Tagged as

Stats

18.4K views
457 downloads
10 bookmarked

Resigning a signed assembly

Rate me:
Please Sign up or sign in to vote.
5.00/5 (5 votes)
18 Dec 2012CPOL
In this project we learn how to resign a signed assembly with another one of your choice

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. 

Image 1

Using the code

Construtors

VB
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

VB.NET
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:

VB.NET
<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:

VB.NET
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)

Share

About the Author

Ahmad Dekmak
Technical Lead
Lebanon Lebanon
No Biography provided

Comments and Discussions

 
Questionexcuse me, how to build the source code to .exe? Pin
Member 1140165325-Jan-15 21:32
MemberMember 1140165325-Jan-15 21:32 
QuestionNice Tool !!! Pin
Ashutosh Phoujdar12-Nov-13 18:36
MemberAshutosh Phoujdar12-Nov-13 18:36 
A very handy and nice tool.

Thanks for sharing Smile | :)

SuggestionBroken Link Pin
PaulCedar18-Dec-12 5:37
MemberPaulCedar18-Dec-12 5:37 
GeneralRe: Broken Link Pin
Ahmad Dekmak18-Dec-12 11:33
MemberAhmad Dekmak18-Dec-12 11:33 
QuestionGreat tool Pin
masterJalchr17-Dec-12 23:38
MembermasterJalchr17-Dec-12 23:38 

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

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