Hallo,
ich möchte auch hier zeigen wie man ein HWID System in Visual Basic realisieren kann.
Erst mal eine kleine Info was für Informationen man auslesen kann und wie man das macht.
Um die folgenden Funktionen nutzen zu können muss man System.Management importieren dazu schreibt man folgendes in der erste Reihe das Programms:
Code:
Imports System.Management
Zusätzlich muss man noch einen Verweiß hinzufügen, die mach man indem man die Eigenschaften des Projekts öffnet auf Verweise geht und nach System.Management sucht.
Dies habe ich auch auf den 2 folgenden Bildern dargestellt:
Die ID des Prozessors, sie ist bei den selben CPU Modellen immer gleich könnte also doppelt vorkommen.
Code:
Private Function gethwid() As String 'by EvolutionClips.de
Dim cpuInfo As String = String.Empty
Dim mc As New ManagementClass("win32_processor")
Dim moc As ManagementObjectCollection = mc.GetInstances()
For Each mo As ManagementObject In moc
If cpuInfo = "" Then
cpuInfo = mo.Properties("processorID").Value.ToString()
Return cpuInfo
Exit For
End If
Next
End Function
Die MAC-Adresse ist für jeden PC einzigartig können allerdings verändert werden z.b in einer Virtuelle Maschine.
Code:
Private Function GetMacAddress() As String 'by EvolutionClips.de
Dim mc As ManagementClass = New ManagementClass("Win32_NetworkAdapterConfiguration")
Dim moc As ManagementObjectCollection = mc.GetInstances()
For Each mo As ManagementObject In moc
If mo.Item("IPEnabled") Then
Return mo.Item("MacAddress").ToString()
End If
Next
End Function
Die Festplatten ID, sie ist einzigartig und verändert sich nur wenn man die Festplatte tauscht oder eine andere Primäre Festplatte benutzt.
Der Integer der in die Funktion mit einfließt ist die ID der Festplatte 0 entspricht der ersten Festplatte
Code:
Function GetHDDSerial(ByVal HDD_idx As Integer) As String
Dim searcher As New System.Management.ManagementObjectSearcher( _
"SELECT * FROM Win32_DiskDrive")
For Each wmi_HD As System.Management.ManagementObject In searcher.Get()
If wmi_HD.Item("Index") = HDD_idx Then
Return wmi_HD.Item("Signature").ToString
End If
Next wmi_HD
End Function
Und zum Schluss noch eine Funktion um einen MD5 Hash zu erstellen, damit der User nicht sieht um was in dem Wert enthalten ist den er sieht. Diese Funktion benötigt noch 2 zusätzliche Verweise und zwar System.Security.Cryptography und System.Text:
Code:
Imports System.Security.Cryptography, System.Text
Code:
Public Function MD5StringHash(ByVal strString As String) As String
Dim MD5 As New MD5CryptoServiceProvider
Dim Data As Byte()
Dim Result As Byte()
Dim Res As String = ""
Dim Tmp As String = ""
Data = Encoding.ASCII.GetBytes(strString)
Result = MD5.ComputeHash(Data)
For i As Integer = 0 To Result.Length - 1
Tmp = Hex(Result(i))
If Len(Tmp) = 1 Then Tmp = "0" & Tmp
Res += Tmp
Next
Return Res
End Function
Nun kommen wir zum eigentlichen Programm, alle Funktionen benötigen keine Admin rechte das heißt das Programm kann ohne Probleme gestartet werden.
Ich baue die Funktionen in das Form Load ein, da die IDs ja sowieso bei jedem Start benötigt werden, das Programm benötigt dann zwar länger zum Starten, man könnte es auch in einem BGW / Thread einbauen, aber für das Tutorial mache ich das so:
Code:
'HWID/MAC/HDDID System by EvolutionClips.de
Imports System.Management 'Für HWID, MAC und HDD-ID
Imports System.Security.Cryptography, System.Text 'Für die MD5 Funktion
Imports System.Text
Public Class Form1
'Variablen Festlegen
Dim cpuid As String = ""
Dim mac As String = ""
Dim hddid As String = ""
Dim hwid as String = ""
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
cpuid = gethwid()
mac = GetMacAddress()
hddid = GetHDDSerial(0)
End Sub
'Hier die anderen Funktionen, ich lasse sie aus Platzgründen mal weg.
....
End Class
Jetzt hat man alle Werte in Variablen gespeichert nun müssen wir dadraus noch eine einzigartige ID machen, das machen wir mit der MD5-Funktion:
(Dies ist ebenfalls im Load Event)
Code:
hwid = MD5StringHash(cpuid & mac & hddid & "byEvolutionClips.de")
Hier wurde nun in die Variable hwid der MD5-Hash von der CPU-ID, der Mac-Adresse, der HDD-ID und von dem festgelegten Wert eingetragen, der festgelegten Wert sorgt dafür das zwei Programm nicht die selbe HWID haben können, weil wenn nur ein Zeichen für den Hash anders ist, sich der komplette Hash Wert verändert.
Deshalb sollte man für jedes Programm einen anderen festgelegten Wert benutzen.
Die Werte(CPU-ID, Mac-Adresse, HDD-ID) kann natürlich auch anders anordnen.
Um nun die Abfragen an den Server zustellen benötigt man einen Webclient und dafür die System.Net Klasse, welche man ebenfalls mit
Importiert.
Nun kommen wir zur Abfragen ob diese HWID gültig ist, dafür benötigen wie einen Webserver der PHP und MySQL unterstützt und folgendes PHP-Script
(Man kann es auch ohne PHP und ohne MySQL machen die Methode finde ich aber nicht so gut
Dazu erstellt man ein Textdokument in dem Alle HWID drin sind lädt es z.b. nach http:// meinedomain.tld/hwid.txt hoch, und im Programm nutzt man folgenden Code:
Code:
(Im Form Load unter der Zuweisung der HWID)
Try
Dim client As WebClient = New WebClient()
Dim reply As String = client.DownloadString("http://meindomain.tld/hwid.txt")
If reply.Contains(hwid) Then 'wenn in der hwid.txt auf meinedomain.tld die hwid vorhanden ist, dann
Me.Hide() 'HWID Fenster verstecken
Programm.show() 'Das Programm Fenster anzeigen
Else 'Wenn die HWID nicht vorhanden ist, dann
MsgBox("HWID nicht gelistet!", MsgBoxStyle.Critical)
Application.Exit() 'Programm beenden
End If
Catch ex As Exception
MsgBox(ex.Message) 'wenn eine Fehler auftritt Fehler anzeigen und Programm beenden
Application.Exit()
End Try
Der Nachteil ist das das Programm immer alle HWIDs herunterlädt und wenn es sehr viele sind könnte er theoretisch mehrer GB herunterladen was bei manchen schon länger dauern kann.
)
hwid.php
PHP Code:
<?php
$hwid = mysql_real_escape_string($_GET['hwid']); //mysql escape Zeichen hinzufügen gegen sql injection
//$hwid ist die HWID vom Programm
$connectionid = mysql_connect ("localhost", "user", "passwort"); //zur Datenbank verbinden
if (!mysql_select_db ("datenbankname", $connectionid)) //Datenbank auswählen und testen
{
die ("Keine Verbindung zur Datenbank");
}
$user = mysql_query("SELECT hwid FROM tabellenname WHERE hwid='".$hwid."' LIMIT 1") or die(mysql_error()); //wert auslesen, bei denen die HWID der entspricht die das Programm gesendet hat.
$verify = mysql_num_rows($user); //die Zeilen Zählen entweder 1 oder 0
if($verify > 0){ // Wenn es 1 oder mehr Zeilen sind die HWID wieder ausgeben
echo $hwid;
}else{
echo "NO"; //Wenn es 0 Zeilen sind eine NO zurückgeben.
}
?>
Dieses PHP Dokument muss dann hochgeladen werden z.b. http:// meinedomain.tld/hwid.php
Die SQL-Tabelle benötigt eigentlich nur eine Spalte mit der HWID, man kann allerdings noch Spalten für einen Index und z.B. eine Beschreibung hinzufügen. SQL-File in der Beschreibung(tabellenname.sql.rar)
Nun kommen wir zu dem Code im Programm:
Code:
(Im Form Load unter der Zuweisung der HWID)
Try
Dim client As WebClient = New WebClient()
Dim reply As String = client.DownloadString("http://meinedomain.tld/hwid.php?hwid=" & hwid)
If reply = hwid Then 'wenn HWID richtig ist
Me.Hide() 'HWID Fenster verstecken
Programm.Show() 'Das Programm Fenster anzeigen
Else
MsgBox("HWID nicht gelistet!", MsgBoxStyle.Critical)
Application.Exit() 'Programm beenden
End If
Catch ex As Exception
MsgBox(ex.Message) 'wenn eine Fehler auftritt Fehler anzeigen und Programm beenden
Application.Exit()
End Try
Wenn die HWID nun auf dem Server mit PHP und MySQL gefunden wurde öffnet sich die programm.vb und form1.vb verschwindet, wenn die HWID nicht vorhanden ist wird HWID nicht gelistet! ausgegeben und das Programm beendet.
In der Programm.vb kann dann euer Programm stehen, das von euch geschrieben wurde und durch die HWID geschutzt werden soll.
Hier noch einmal das komplette Programm:
Code:
Imports System.Management
Imports System.Security.Cryptography, System.Text
Imports System.Net
Public Class Form1
Dim cpuid As String = ""
Dim mac As String = ""
Dim hddid As String = ""
Dim hwid As String = ""
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
cpuid = gethwid()
mac = GetMacAddress()
hddid = GetHDDSerial(0)
hwid = MD5StringHash(cpuid & mac & hddid & "byEvolutionClips.de")
Try
Dim client As WebClient = New WebClient()
Dim reply As String = client.DownloadString("http://meinedomain.tld/hwid.php?hwid=" & hwid)
If reply = hwid Then 'wenn HWID richtig ist
Me.Hide() 'HWID Fenster verstecken
Programm.Show() 'Das Programm Fenster anzeigen
Else
MsgBox("HWID nicht gelistet!", MsgBoxStyle.Critical)
Application.Exit() 'Programm beenden
End If
Catch ex As Exception
MsgBox(ex.Message) 'wenn eine Fehler auftritt Fehler anzeigen und Programm beenden
Application.Exit()
End Try
End Sub
Private Function gethwid() As String
Dim cpuInfo As String = String.Empty
Dim mc As New ManagementClass("win32_processor")
Dim moc As ManagementObjectCollection = mc.GetInstances()
For Each mo As ManagementObject In moc
If cpuInfo = "" Then
cpuInfo = mo.Properties("processorID").Value.ToString()
Return cpuInfo
Exit For
End If
Next
End Function
Private Function GetMacAddress() As String
Dim mc As ManagementClass = New ManagementClass("Win32_NetworkAdapterConfiguration")
Dim moc As ManagementObjectCollection = mc.GetInstances()
For Each mo As ManagementObject In moc
If mo.Item("IPEnabled") Then
Return mo.Item("MacAddress").ToString()
End If
Next
End Function
Public Function MD5StringHash(ByVal strString As String) As String
Dim MD5 As New MD5CryptoServiceProvider
Dim Data As Byte()
Dim Result As Byte()
Dim Res As String = ""
Dim Tmp As String = ""
Data = Encoding.ASCII.GetBytes(strString)
Result = MD5.ComputeHash(Data)
For i As Integer = 0 To Result.Length - 1
Tmp = Hex(Result(i))
If Len(Tmp) = 1 Then Tmp = "0" & Tmp
Res += Tmp
Next
Return Res
End Function
Function GetHDDSerial(ByVal HDD_idx As Integer) As String
Dim searcher As New System.Management.ManagementObjectSearcher( _
"SELECT * FROM Win32_DiskDrive")
For Each wmi_HD As System.Management.ManagementObject In searcher.Get()
If wmi_HD.Item("Index") = HDD_idx Then
' wenn Index gefunden, Signature-Property zurückgeben
Return wmi_HD.Item("Signature").ToString
End If
Next wmi_HD
' Falls Index nicht gefunden, Leerstring zurückgeben
Return ""
End Function
End Class
Projekt auch im Anhang
Ich hoffe ich konnte euch weiterhelfen!
Bei Fragen einfach fragen

mfg EvolutionClips