Tipp-Upload: VB.NET 0171: Dynamische Entschlüsselung des eigenen Quellcodes
von Dario
Hinweis zum Tippvorschlag
Dieser Vorschlag wurde noch nicht auf Sinn und Inhalt überprüft und die Zip-Datei wurde noch nicht auf schädlichen Inhalt hin untersucht.
Bitte haben Sie ein wenig Geduld, bis die Freigabe erfolgt.
Über den Tipp
Dieser Tippvorschlag ist noch unbewertet.
Der Vorschlag ist in den folgenden Kategorien zu finden:
- Sonstiges
Dem Tippvorschlag wurden folgende Schlüsselwörter zugeordnet:
Compiler, Crypto, Entschlüsseln, Schutz, Attribute, Reflection
Der Vorschlag wurde erstellt am: 03.01.2008 14:23.
Die letzte Aktualisierung erfolgte am 03.01.2008 14:32.
Beschreibung
.NET-Programme kann man leicht wieder disassemblen und sich den Quellcode ansehen oder verändern.
Ist das aus guten Gründen nicht erwünscht, kann man Mechanismen wie den vorgestellten verwenden, um den eigenen Quellcode z.B. von einem Passwort abhängig zu verschlüsseln, zur Laufzeit zu kompilieren und laufen zu lassen.
Vorteil auch: Die Passwortabfrage kann nicht umgangen werden.
Das Passwort für diesen Upload lautet: ProgrammAccess
Schwierigkeitsgrad |
Verwendete API-Aufrufe: |
Download: |
' Dieser Source stammt von http://www.activevb.de ' und kann frei verwendet werden. Für eventuelle Schäden ' wird nicht gehaftet. ' Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum. ' Ansonsten viel Spaß und Erfolg mit diesem Source! ' ' Beachten Sie, das vom Designer generierter Code hier ausgeblendet wird. ' In den Zip-Dateien ist er jedoch zu finden. ' -------- Anfang Projektgruppe DynamicDecryption.sln -------- ' ------- Anfang Projektdatei DynamicDecryption.vbproj ------- ' ---------------- Anfang Datei Attribute.vb ---------------- Imports System ''' <summary> ''' Eine verschlüsselte Methode - Ach nein, ein Property, dass sie enthält ''' </summary> ''' <remarks></remarks> <AttributeUsage(AttributeTargets.Property)> Class UDEncryptedAttribute Inherits Attribute Private mHashSequence As String Private mImports As New Generic.List(Of String) ''' <summary> ''' Initialisieren ''' </summary> ''' <param name="SHAHashSequence">Hashsequenz des Orginalcodes (SHA256)</param> ''' <param name="Imports">Additional imports</param> ''' <remarks></remarks> Public Sub New(ByVal SHAHashSequence As String, ByVal ParamArray [Imports]() As String) mHashSequence = SHAHashSequence mImports.AddRange([Imports]) End Sub #Region "Properties" ''' <summary> ''' Die hash sequence ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks> Public ReadOnly Property HashSequence() As String Get Return mHashSequence End Get End Property ''' <summary> ''' Imports, die die Funktion braucht ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks> Public ReadOnly Property [Imports]() As IEnumerable(Of String) Get Return mImports End Get End Property #End Region End Class ' ----------------- Ende Datei Attribute.vb ----------------- ' ----------------- Anfang Datei Compiler.vb ----------------- Imports System.Reflection Imports System.ComponentModel Imports System.CodeDom.Compiler Imports System.Environment ''' <summary> ''' Unser Compiler ''' </summary> ''' <remarks></remarks> Public Class Compiler Implements IDisposable Private mProv As New Microsoft.VisualBasic.VBCodeProvider Private mAssembly As [Assembly] ''' <summary> ''' Kompilieren ''' </summary> ''' <param name="Source">Quellcode</param> ''' <returns></returns> ''' <remarks></remarks> Public Function Compile(ByVal Source As String) As Boolean With mProv.CompileAssemblyFromSource(New CompilerParameters With {.GenerateInMemory = _ True}, Source) If .Errors.Count > 0 Then Return False mAssembly = .CompiledAssembly() Return True End With End Function ''' <summary> ''' Die Assembly abfragen ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks> Public ReadOnly Property [Assembly]() As [Assembly] Get Return mAssembly End Get End Property ''' <summary> ''' Und ab in den Mülleimer ''' </summary> ''' <remarks></remarks> Public Sub Dispose() Implements IDisposable.Dispose If mProv Is Nothing Then Return mProv.Dispose() mProv = Nothing GC.SuppressFinalize(Me) End Sub End Class ' ------------------ Ende Datei Compiler.vb ------------------ ' --------------- Anfang Datei CreateSource.vb --------------- Imports System Imports System.Reflection ''' <summary> ''' Quellcode zusammenstellen ''' </summary> ''' <remarks></remarks> Public Class SourceCreator Private mSource As New Text.StringBuilder Private mImports As New List(Of String) ''' <summary> ''' Methoden eines Typen auslesen ''' </summary> ''' <param name="Password">Passwort</param> ''' <param name="tType">Typ</param> ''' <remarks></remarks> Public Sub Reflect(ByVal Password As String, ByVal tType As Type) Dim Container As Type = tType For Each [Property] In Container.GetProperties Dim Attribute As UDEncryptedAttribute = System.Attribute.GetCustomAttributes( _ [Property]).OfType(Of UDEncryptedAttribute).FirstOrDefault If Attribute Is Nothing Then Continue For Dim TempSource As String = CryptoService.Decrypt(Password, [Property].GetValue( _ Nothing, Nothing)) ' Autsch If CryptoService.GetHash(TempSource) <> Attribute.HashSequence Then Throw New Exception("Hashes do not equal. You are stronly adviced to stop " & _ "code execution") Continue For End If mImports.AddRange(Attribute.Imports) mSource.AppendLine(TempSource) Next End Sub ''' <summary> ''' Quellcode zusammenstellen ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks> Public ReadOnly Property Source() As String Get Dim ImportSequence As String = "Imports " & String.Join(Environment.NewLine & _ "Imports ", mImports.Distinct.OrderBy(Function(a As String) _ a.Length).ToArray) Return String.Join(Environment.NewLine, New String() { ImportSequence, "", "", _ "' Programme sequence", "", "", "Public Class DecryptionSource", "", "", _ mSource.ToString, "End Class"}) End Get End Property End Class ' ---------------- Ende Datei CreateSource.vb ---------------- ' -------------- Anfang Datei CryptoService.vb -------------- Imports System.Security.Cryptography ''' <summary> ''' Kryptographiedienste zur Verfügung stellen ''' </summary> ''' <remarks></remarks> Public Class CryptoService ''' <summary> ''' Wir verwenden AES ''' </summary> ''' <remarks></remarks> Private Shared mAlgo As New AesCryptoServiceProvider ''' <summary> ''' Stringdaten verschlüsseln ''' </summary> ''' <param name="Password">Key</param> ''' <param name="Data">Daten</param> ''' <returns>Ergebnis</returns> ''' <remarks></remarks> Public Shared Function Encrypt(ByVal Password As String, ByVal Data As String) As String Return Process(Password, Data, AddressOf mAlgo.CreateEncryptor, AddressOf _ System.Text.Encoding.UTF8.GetBytes, AddressOf Convert.ToBase64String) End Function ''' <summary> ''' Stringdaten entschlüsseln ''' </summary> ''' <param name="Password">Key</param> ''' <param name="Data">Daten</param> ''' <returns>Ergebnis</returns> ''' <remarks></remarks> Public Shared Function Decrypt(ByVal Password As String, ByVal Data As String) As String Return Process(Password, Data, AddressOf mAlgo.CreateDecryptor, AddressOf _ Convert.FromBase64String, AddressOf System.Text.Encoding.UTF8.GetString) End Function ''' <summary> ''' Abstrakte Verschlüsselungsprozedur ''' </summary> ''' <param name="Password">Passwort</param> ''' <param name="Data">Daten</param> ''' <param name="Operation">ICryptoTransform-Operation</param> ''' <returns>Ergebnis</returns> ''' <remarks></remarks> Private Shared Function Process(ByVal Password As String, ByVal Data As String, ByVal _ Operation As Func(Of ICryptoTransform), ByVal Transformer1 As Converter(Of String, _ Byte()), ByVal Transformer2 As Converter(Of Byte(), String)) As String Dim btClear() As Byte InitAlgo(Password) Dim ms As New IO.MemoryStream Dim cs As New CryptoStream(ms, Operation(), CryptoStreamMode.Write) Try btClear = Transformer1(Data) cs.Write(btClear, 0, btClear.Length) cs.Close() Catch ex As Exception Return Nothing End Try Return Transformer2(ms.ToArray) End Function ''' <summary> ''' Algorithmus initialisieren ''' </summary> ''' <param name="Password">Password</param> ''' <remarks></remarks> Private Shared Sub InitAlgo(ByVal Password As String) Dim btSalt(7) As Byte Dim KeyGenerator As New Rfc2898DeriveBytes(Password, btSalt) mAlgo.Key = KeyGenerator.GetBytes(mAlgo.Key.Length) mAlgo.IV = KeyGenerator.GetBytes(mAlgo.IV.Length) End Sub ''' <summary> ''' SHA256-Hash berechnen ''' </summary> ''' <param name="Source">Source data</param> ''' <returns></returns> ''' <remarks></remarks> Public Shared Function GetHash(ByVal Source As String) Return GetHash(Source, AddressOf SHA256.Create) End Function ''' <summary> ''' Hash berechnen ''' </summary> ''' <param name="Source">Daten</param> ''' <param name="CreateAlgo">Algorithmus</param> ''' <returns></returns> ''' <remarks></remarks> Public Shared Function GetHash(ByVal Source As String, ByVal CreateAlgo As Func(Of _ HashAlgorithm)) Dim HashAlgo As HashAlgorithm = CreateAlgo() Dim Dest As Byte() = HashAlgo.ComputeHash(System.Text.Encoding.UTF8.GetBytes(Source)) Dim str As String = "0x" For i As Integer = 0 To Dest.Length - 1 str = str & Hex(Dest(i)) Next Return str End Function End Class ' --------------- Ende Datei CryptoService.vb --------------- ' ----------------- Anfang Datei Encoder.vb ----------------- ''' <summary> ''' Methoden verschlüsseln ''' </summary> ''' <remarks></remarks> Public Class Encoder ''' <summary> ''' Quellcode verschlüsseln ''' </summary> ''' <param name="Source">Sourcecode</param> ''' <param name="Password">Passwort</param> ''' <param name="FuncName">Funktionsname</param> ''' <returns></returns> ''' <remarks></remarks> Public Shared Function EncodeSource(ByVal Source As String, ByVal Password As String, _ ByVal FuncName As String) As String Dim Result As String = "" Result &= String.Format("<UDEncrypted(""{0}"")> _", CryptoService.GetHash(Source)) & _ Environment.NewLine Result &= String.Concat("Public Shared ReadOnly Property ", FuncName, "() As " & _ "String", Environment.NewLine, "Get", Environment.NewLine, "Return """, _ CryptoService.Encrypt(Password, Source), """", Environment.NewLine, "End Get", _ Environment.NewLine, "End Property") Return Result End Function End Class ' ------------------ Ende Datei Encoder.vb ------------------ ' ---------------- Anfang Datei Functions.vb ---------------- ''' <summary> ''' Unsere Funktionen gesammelt ''' </summary> ''' <remarks>Alles, was hier mit [UDEncrypted()] drin steh, wird vom Provider entschlüsselt und kompiliert</remarks> Public Class Functions ''' <summary> ''' Ich bin *die* Methode, aber keiner kann mich lesen xD ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks> <UDEncrypted("0x834CD2AE80AA64D2AA3475A5E4E63AAC10EA9AD262A8F9FE3D59EADB46ECDF2E", _ "System", "System.Diagnostics", "System.Text")> Public Shared ReadOnly Property _ SecretMethod() As String Get Return "Lbz2qLORZ4SI6RC37+FiFipXwn/FphKzR6ET1LW//te5MFKk/M2752saqKsAdKOWuAp2f" & _ "XuvSxOhvJERYv7etEiKeHt3C4zNIKjCGPGbP8u0Nm9bUm/aVf9Vntw6bDVjrv3UCz6xbxDsKpW/oR5CTGhDQI" & _ "kmrMwNWu6pYh+ik2sqNIbbP9ZvTqUU5XcPtc8+5DWU8lXfXVp/zG76Zf66vA21CamkRKzRQ8J/jWRFOWxCPa6" & _ "+VXOL3EkYzsDR53Fuh6oTNCGbqFfeWxwRzKF0NXsHMvVTauRr/ddUUAJHoXAH2PO8FRWOSgViAVr4RPzU9dvJ" & _ "g0wwcNeZH/3BsWxkiLxwEw7xkPnIsTImwymgwsHABfhSXbpPIJGIQAMA0jeYkbJ/J8CYNrPEjbxJCe7YjW/Q/" & _ "KtCqd93caefYArrpCUUIY9uQhm03rF94PKWlsJx" End Get End Property ' Für all die, die keinen Code ausführen, den sie nicht sehen ... ' Public Shared Function SecretMethod(ByVal Path As String, ByVal Text As String) As String ' My.Computer.FileSystem.WriteAllText(Path, String.Format("Der Benutzer hat den Text ' ""{0}"" eingegeben.", Text), False) ' Process.Start(Path) ' Return "Juhu, ich habe in eine Datei geschrieben ;-)" ' End Function End Class ' ----------------- Ende Datei Functions.vb ----------------- ' -------------- Anfang Datei MethodProvider.vb -------------- ''' <summary> ''' Unsere Methoden zur Verfügung stellen ''' </summary> ''' <remarks></remarks> Public Class MethodProvider Implements IDisposable Private mSource As New SourceCreator Private mTypes As New List(Of Type) Private mComp As New Compiler Public Sub Add(Of Container)() mTypes.Add(GetType(Container)) End Sub Public Sub Add(ByVal Type As Type) mTypes.Add(Type) End Sub ''' <summary> ''' Kompilieren und Entschlüsseln ''' </summary> ''' <param name="Password"></param> ''' <returns></returns> ''' <remarks></remarks> Public Function Compile(ByVal Password As String) As Boolean For Each tType In mTypes mSource.Reflect(Password, tType) Next Return mComp.Compile(mSource.Source) End Function ''' <summary> ''' Methodendelegaten abrufen ''' </summary> ''' <param name="Name">Name der Methode</param> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks> Default Public ReadOnly Property Method(ByVal Name As String) As Func(Of Object(), Object) Get Static ExecType As Type = mComp.Assembly.GetType("DecryptionSource") Return Function(Params As Object()) ExecType.GetMethod(Name).Invoke(Nothing, Params) End Get End Property Public Sub Dispose() Implements IDisposable.Dispose mComp.Dispose() GC.SuppressFinalize(Me) End Sub End Class ' --------------- Ende Datei MethodProvider.vb --------------- ' ------------------ Anfang Datei Form1.vb ------------------ Public Class frmPassword Private Sub txtPassword_TextChanged(ByVal sender As System.Object, ByVal e As _ System.EventArgs) Handles txtPassword.TextChanged cmdOK.Enabled = Not (txtPassword.Text = "") End Sub Private Sub cmdQuit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles cmdQuit.Click Application.Exit() End Sub Private Sub cmdOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles cmdOK.Click ' Hashsequenzenvergleich - kann man austricksen ;-) If CryptoService.GetHash(txtPassword.Text) <> _ "0x27C1E848CF348C3E6552D16E213ECBCAB6474A426EA52BF8A5C3A3698C94" Then MessageBox.Show("Das Passwort ist nicht korrekt", "Falsches Passwort", _ MessageBoxButtons.OK, MessageBoxIcon.Error) Exit Sub End If Call (New frmMain With {.Password = txtPassword.Text}).Show() End Sub End Class ' ------------------- Ende Datei Form1.vb ------------------- ' ------------------- Anfang Datei Main.vb ------------------- Imports System.Windows.Forms Public Class frmMain Public Password As String Private mProvider As New MethodProvider Private Sub frmMain_FormClosing(ByVal sender As Object, ByVal e As _ System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing Me.Dispose() Application.Exit() End Sub Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles MyBase.Load frmPassword.Dispose() End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles Button1.Click txtRes.Text = Encoder.EncodeSource(txtMethod.Text, txtPassword.Text, txtMethodName.Text) End Sub Private Sub TextChange(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles txtPassword.TextChanged, txtMethodName.TextChanged, txtMethod.TextChanged Button1.Enabled = txtMethodName.Text <> "" And txtPassword.Text <> "" And _ txtMethod.Text <> "" End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles Button2.Click txtMethodName.Text = "" : txtPassword.Text = "" : txtMethod.Text = "" : txtRes.Text = "" End Sub Private Sub cmdDecodeMethod_Click(ByVal sender As System.Object, ByVal e As _ System.EventArgs) Handles cmdDecodeMethod.Click mProvider.Add(GetType(Functions)) If Not mProvider.Compile(Password) Then MessageBox.Show("Was für ein Mist", "Autsch", MessageBoxButtons.OK, _ MessageBoxIcon.Error) Application.Exit() Else MessageBox.Show("Juhu", "Juhu", MessageBoxButtons.OK, MessageBoxIcon.Information) End If cmdDecodeMethod.Enabled = False cmdExecuteMethod.Enabled = True End Sub Private Sub cmdDecodeMethod_Disposed(ByVal sender As Object, ByVal e As System.EventArgs) _ Handles cmdDecodeMethod.Disposed Me.Dispose() mProvider.Dispose() End Sub Private Sub cmdExecuteMethod_Click(ByVal sender As System.Object, ByVal e As _ System.EventArgs) Handles cmdExecuteMethod.Click ' Methode abfragen - Das ist alles Dim Method As Func(Of Object(), Object) = mProvider("SecretMethod") Dim Path As String = Application.StartupPath & "\Foo.txt" Dim Text As String = InputBox("Geben sie einen Text, z.B. einen Satz, ein", _ "Texteingabe", "Hallo, Welt") If Method IsNot Nothing Then Dim Res As String = CStr(Method.Invoke(New Object() {Path, Text})) MessageBox.Show("Die Methode gibt folgendes zurück: """ & Res & """", _ "Ergebnis", MessageBoxButtons.OK, MessageBoxIcon.Information) End If End Sub End Class ' -------------------- Ende Datei Main.vb -------------------- ' -------- Ende Projektdatei DynamicDecryption.vbproj -------- ' --------- Ende Projektgruppe DynamicDecryption.sln ---------
Diskussion
Diese Funktion ermöglicht es, Fragen, die die Veröffentlichung des Tipps betreffen, zu klären, oder Anregungen und Verbesserungsvorschläge einzubringen. Nach der Veröffentlichung des Tipps werden diese Beiträge nicht weiter verlinkt. Allgemeine Fragen zum Inhalt sollten daher hier nicht geklärt werden.
Folgende Diskussionen existieren bereits
Um eine Diskussion eröffnen zu können, müssen sie angemeldet sein.