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
ElseIf StrongNameSignatureGeneration(Me._strAssemblyPath, Me._strNewStrongKeyName, 0, 0, 0, 0) Then
blnReturn = True
Else
End If
End Using
End Using
Catch exc As Exception
Finally
IO.File.Delete(strSNKFile)
End Try
Return blnReturn
End Function