Qualsiasi software è decompilabile, quindi non c'è protezione che tenga. Tuttavia si tratta di rendere le cose un po' difficili per gli utenti che non hanno competenze da hacker, cioè la maggior parte.

Leggendo la tua richiesta ho subito pensato che si potrebbe leggere il numero seriale della chiavetta e confrontarlo con il numero seriale annegato nel tuo software.

Il codice che ti riporto qui sotto fa uso di WMI ed estrae il numero seriale dell'unità sulla quale è in esecuzione il software. Per un harddisk si usa normalmente la proprietà "Win32_DiskDrive\SerialNumber", mentre per le chiavette USB tale proprietà risulta vuota ed è necessario leggere "Win32_DiskDrive\PNPDeviceID".

codice:
Imports System.Management
Imports System.Text.RegularExpressions

Public Class Form1

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Dim scope As ManagementScope
        Dim query As ObjectQuery
        Dim searcher As ManagementObjectSearcher
        Dim queryCollection As ManagementObjectCollection

        'imposta lo scope sulla macchina locale
        scope = New ManagementScope("\\" & Environment.MachineName & "\root\cimv2")

        'determina il volume che contiene l'eseguibile
        Dim logical As String = IO.Path.GetPathRoot(Application.ExecutablePath).First
        'logical = "F"

        'determina l'unità fisica che contiene il volume
        Dim phisical As String = ""
        query = New ObjectQuery("SELECT * FROM Win32_LogicalDiskToPartition")
        searcher = New ManagementObjectSearcher(scope, query)
        queryCollection = searcher.Get()
        For Each manObj In queryCollection
            Dim matchlogical As Match = Regex.Match(manObj.GetPropertyValue("Dependent").ToString,
                                              "^\\\\" & Environment.MachineName & "\\root\\cimv2:Win32_LogicalDisk.DeviceID=""(?<logical>[A-Z]):""")
            If matchlogical.Groups("logical").Value = logical Then
                Dim matchphisical As Match = Regex.Match(manObj.GetPropertyValue("Antecedent").ToString,
                                                  "^\\\\" & Environment.MachineName & "\\root\\cimv2:Win32_DiskPartition.DeviceID=""Disk #(?<phisical>\d)")
                phisical = matchphisical.Groups("phisical").Value
                Exit For
            End If
        Next

        'determina il numero seriale dell'unità fisica
        Dim hdserial As String = ""
        query = New ObjectQuery("SELECT * FROM Win32_DiskDrive")
        searcher = New ManagementObjectSearcher(scope, query)
        queryCollection = searcher.Get()
        For Each manObj In queryCollection
            Dim matchtag As Match = Regex.Match(manObj.GetPropertyValue("DeviceID").ToString,
                                              "^\\\\.\\PHYSICALDRIVE(?<phisical>\d)")
            If matchtag.Groups("phisical").Value = phisical Then
                hdserial = manObj.GetPropertyValue("PNPDeviceID").ToString
                Exit For
            End If
        Next

        'output
        Dim output As String = String.Format("logical = {0}" & vbCrLf &
                                             "phisical = {1}" & vbCrLf &
                                             "hdserial = {2}", logical, phisical, hdserial)
        MsgBox(output)
    End Sub
End Class
Offuscando opportunamente il codice dovresti ottenere un buon risultato.