License Binding Detection
Protection Module: LicenseBinding
Detects changes in hardware fingerprint to prevent license key sharing and unauthorized hardware transfers.
Available for:
- Desktop Applications
- Mobile Applications
- Server Applications
How It Works
License Binding creates a unique hardware fingerprint and validates it on each application start or on-demand.
Fingerprint Components:
- CPU Information - Processor ID, core count, features
- Motherboard - Serial number, manufacturer, model
- MAC Addresses - Primary network adapter
- Hard Drive - Serial numbers, volume IDs
- BIOS/UEFI - Serial number, version
- GPU - Device ID (optional)
- Mobile Device ID - IMEI, Android ID, IDFV (iOS)
Detection Scenarios:
- License key transferred to different machine
- Hardware component replacement (motherboard, CPU)
- Virtual machine cloning
- License sharing between multiple devices
Configuration
JSON Configuration
JSON
{
"protections": {
"LicenseBinding": {
"enabled": true,
"action": "close",
"config": {
"allowedChanges": 2,
"strictMode": false,
"components": ["cpu", "motherboard", "mac", "hdd"]
}
}
}
}{
"protections": {
"LicenseBinding": {
"enabled": true,
"action": "close",
"config": {
"allowedChanges": 2,
"strictMode": false,
"components": ["cpu", "motherboard", "mac", "hdd"]
}
}
}
}Code-Based Configuration
C#
await Payload.ConfigureAsync(config =>
{
config.AddProtection(
ProtectionModuleType.LicenseBinding,
ActionType.Close,
new
{
allowedChanges = 2,
strictMode = false,
components = new[] { "cpu", "motherboard", "mac", "hdd" }
}
);
});await Payload.ConfigureAsync(config =>
{
config.AddProtection(
ProtectionModuleType.LicenseBinding,
ActionType.Close,
new
{
allowedChanges = 2,
strictMode = false,
components = new[] { "cpu", "motherboard", "mac", "hdd" }
}
);
});Available Actions
| Action | Behavior | Recommended For |
|---|---|---|
| Close | Terminate application | Strict licensing |
| Custom | Execute validation logic | Reactivation prompts |
| Log | Record change and continue | Analytics |
Configuration Parameters
| Parameter | Description | Default |
|---|---|---|
allowedChanges | Number of components that can change | 2 |
strictMode | Require exact match (0 changes) | false |
components | Hardware components to track | All |
cloudValidation | Validate with backend server | false |
gracePeriodDays | Days to allow after change | 0 |
Fingerprint Components
JSON
{
"components": [
"cpu", // Processor ID
"motherboard", // Motherboard serial
"mac", // Network adapter MAC
"hdd", // Hard drive serial
"bios", // BIOS serial
"gpu", // Graphics card (optional)
"deviceId" // Mobile device ID
]
}{
"components": [
"cpu", // Processor ID
"motherboard", // Motherboard serial
"mac", // Network adapter MAC
"hdd", // Hard drive serial
"bios", // BIOS serial
"gpu", // Graphics card (optional)
"deviceId" // Mobile device ID
]
}When to Use
Recommended for:
- Commercial desktop software with node-locked licenses
- Enterprise applications with hardware binding
- Development tools (IDEs, compilers)
- Professional creative software
- Server applications with CPU-based licensing
Not recommended for:
- Consumer apps without licensing
- Free/open-source software
- Web applications (use different validation)
Code Examples
Basic License Validation
C#
config.RegisterCustomAction("license-validation", async (threat) =>
{
var changedComponents = threat.Metadata["changedComponents"] as string[];
var changeCount = (int)(threat.Metadata["changeCount"] ?? 0);
await LogSecurityEventAsync("license_binding_violation", new
{
ChangedComponents = changedComponents,
ChangeCount = changeCount,
MachineId = Environment.MachineName
});
var result = await ShowLicenseDialog(
"Hardware Change Detected",
$"Your hardware configuration has changed ({changeCount} components). " +
"Please reactivate your license or contact support."
);
if (result == DialogResult.Reactivate)
{
await ReactivateLicenseAsync();
}
else
{
Environment.Exit(-1);
}
});config.RegisterCustomAction("license-validation", async (threat) =>
{
var changedComponents = threat.Metadata["changedComponents"] as string[];
var changeCount = (int)(threat.Metadata["changeCount"] ?? 0);
await LogSecurityEventAsync("license_binding_violation", new
{
ChangedComponents = changedComponents,
ChangeCount = changeCount,
MachineId = Environment.MachineName
});
var result = await ShowLicenseDialog(
"Hardware Change Detected",
$"Your hardware configuration has changed ({changeCount} components). " +
"Please reactivate your license or contact support."
);
if (result == DialogResult.Reactivate)
{
await ReactivateLicenseAsync();
}
else
{
Environment.Exit(-1);
}
});Cloud-Based Validation
C#
config.RegisterCustomAction("cloud-license-check", async (threat) =>
{
var currentFingerprint = threat.Metadata["currentFingerprint"]?.ToString();
var storedFingerprint = threat.Metadata["storedFingerprint"]?.ToString();
// Validate with backend
var response = await LicenseApiClient.ValidateHardwareAsync(new
{
LicenseKey = CurrentLicense.Key,
CurrentFingerprint = currentFingerprint,
StoredFingerprint = storedFingerprint
});
if (response.IsValid)
{
// Update stored fingerprint
await UpdateStoredFingerprintAsync(currentFingerprint);
return;
}
if (response.CanReactivate)
{
await ShowReactivationDialogAsync();
}
else
{
await ShowLicenseViolationMessageAsync(
"This license key is already in use on another device. " +
"Please purchase an additional license or deactivate the other device."
);
Environment.Exit(-1);
}
});config.RegisterCustomAction("cloud-license-check", async (threat) =>
{
var currentFingerprint = threat.Metadata["currentFingerprint"]?.ToString();
var storedFingerprint = threat.Metadata["storedFingerprint"]?.ToString();
// Validate with backend
var response = await LicenseApiClient.ValidateHardwareAsync(new
{
LicenseKey = CurrentLicense.Key,
CurrentFingerprint = currentFingerprint,
StoredFingerprint = storedFingerprint
});
if (response.IsValid)
{
// Update stored fingerprint
await UpdateStoredFingerprintAsync(currentFingerprint);
return;
}
if (response.CanReactivate)
{
await ShowReactivationDialogAsync();
}
else
{
await ShowLicenseViolationMessageAsync(
"This license key is already in use on another device. " +
"Please purchase an additional license or deactivate the other device."
);
Environment.Exit(-1);
}
});Grace Period Implementation
C#
config.RegisterCustomAction("license-grace-period", async (threat) =>
{
var lastChangeDate = await GetLastHardwareChangeDateAsync();
var gracePeriodDays = 7;
if (lastChangeDate.HasValue)
{
var daysSinceChange = (DateTime.UtcNow - lastChangeDate.Value).TotalDays;
if (daysSinceChange < gracePeriodDays)
{
var remainingDays = (int)(gracePeriodDays - daysSinceChange);
await ShowWarningAsync(
"Hardware Change Detected",
$"Please reactivate your license within {remainingDays} days."
);
return;
}
}
// Grace period expired
await RecordHardwareChangeAsync();
await ShowReactivationRequiredDialogAsync();
});config.RegisterCustomAction("license-grace-period", async (threat) =>
{
var lastChangeDate = await GetLastHardwareChangeDateAsync();
var gracePeriodDays = 7;
if (lastChangeDate.HasValue)
{
var daysSinceChange = (DateTime.UtcNow - lastChangeDate.Value).TotalDays;
if (daysSinceChange < gracePeriodDays)
{
var remainingDays = (int)(gracePeriodDays - daysSinceChange);
await ShowWarningAsync(
"Hardware Change Detected",
$"Please reactivate your license within {remainingDays} days."
);
return;
}
}
// Grace period expired
await RecordHardwareChangeAsync();
await ShowReactivationRequiredDialogAsync();
});Strict vs Flexible Mode
Strict Mode (0 changes allowed)
JSON
{
"config": {
"strictMode": true,
"allowedChanges": 0
}
}{
"config": {
"strictMode": true,
"allowedChanges": 0
}
}Use for:
- High-value software
- Per-device licensing
- Preventing any hardware transfer
Flexible Mode (N changes allowed)
JSON
{
"config": {
"strictMode": false,
"allowedChanges": 2
}
}{
"config": {
"strictMode": false,
"allowedChanges": 2
}
}Use for:
- Consumer software
- Allowing component upgrades (RAM, HDD)
- Normal hardware maintenance
Mobile Device Binding
Android
C#
config.RegisterCustomAction("android-device-binding", async (threat) =>
{
var storedDeviceId = await SecureStorage.GetAsync("device_id");
var currentDeviceId = Android.Provider.Settings.Secure.GetString(
context.ContentResolver,
Android.Provider.Settings.Secure.AndroidId
);
if (storedDeviceId != currentDeviceId)
{
await ShowDialogAsync(
"Device Mismatch",
"This license is bound to a different device."
);
Environment.Exit(-1);
}
});config.RegisterCustomAction("android-device-binding", async (threat) =>
{
var storedDeviceId = await SecureStorage.GetAsync("device_id");
var currentDeviceId = Android.Provider.Settings.Secure.GetString(
context.ContentResolver,
Android.Provider.Settings.Secure.AndroidId
);
if (storedDeviceId != currentDeviceId)
{
await ShowDialogAsync(
"Device Mismatch",
"This license is bound to a different device."
);
Environment.Exit(-1);
}
});iOS
C#
config.RegisterCustomAction("ios-device-binding", async (threat) =>
{
var storedDeviceId = await SecureStorage.GetAsync("device_id");
var currentDeviceId = UIDevice.CurrentDevice.IdentifierForVendor.AsString();
if (storedDeviceId != currentDeviceId)
{
var alert = UIAlertController.Create(
"Device Mismatch",
"This license is bound to a different device.",
UIAlertControllerStyle.Alert
);
alert.AddAction(UIAlertAction.Create("Exit", UIAlertActionStyle.Default,
_ => Thread.CurrentThread.Abort()
));
await PresentViewControllerAsync(alert, true);
}
});config.RegisterCustomAction("ios-device-binding", async (threat) =>
{
var storedDeviceId = await SecureStorage.GetAsync("device_id");
var currentDeviceId = UIDevice.CurrentDevice.IdentifierForVendor.AsString();
if (storedDeviceId != currentDeviceId)
{
var alert = UIAlertController.Create(
"Device Mismatch",
"This license is bound to a different device.",
UIAlertControllerStyle.Alert
);
alert.AddAction(UIAlertAction.Create("Exit", UIAlertActionStyle.Default,
_ => Thread.CurrentThread.Abort()
));
await PresentViewControllerAsync(alert, true);
}
});Platform Compatibility
| Platform | Support | Fingerprint Components |
|---|---|---|
| Windows | ✔ | CPU, Motherboard, MAC, HDD, BIOS |
| Linux | ✔ | CPU, MAC, HDD, DMI |
| macOS | ✔ | CPU, Serial Number, MAC |
| Android | ✔ | Android ID, IMEI (with permission) |
| iOS | ✔ | IDFV, Device Model |
Best Practices
- Allow Component Upgrades
C#
// Don't bind to components users commonly upgrade
components = new[] { "cpu", "motherboard" }; // Exclude HDD, RAM// Don't bind to components users commonly upgrade
components = new[] { "cpu", "motherboard" }; // Exclude HDD, RAM- Provide Reactivation Option
C#
// Always offer a way to reactivate after legitimate hardware changes
await ShowReactivationDialog();// Always offer a way to reactivate after legitimate hardware changes
await ShowReactivationDialog();- Use Cloud Validation for Critical Apps
C#
// Validate with your licensing server
var isValid = await LicenseServer.ValidateAsync(fingerprint, licenseKey);// Validate with your licensing server
var isValid = await LicenseServer.ValidateAsync(fingerprint, licenseKey);- Grace Period for User Convenience
C#
// Allow 7 days for users to reactivate after hardware change
gracePeriodDays = 7;// Allow 7 days for users to reactivate after hardware change
gracePeriodDays = 7;Threat Detection Details
JSON
{
"threatId": "LIC-2025-12-28-7890",
"description": "Hardware fingerprint mismatch detected",
"moduleType": "LicenseBinding",
"detectedAt": "2025-12-28T19:00:00Z",
"confidence": 1.0,
"metadata": {
"storedFingerprint": "ABC123DEF456",
"currentFingerprint": "XYZ789GHI012",
"changedComponents": ["motherboard", "cpu", "bios"],
"changeCount": 3,
"allowedChanges": 2,
"strictMode": false
}
}{
"threatId": "LIC-2025-12-28-7890",
"description": "Hardware fingerprint mismatch detected",
"moduleType": "LicenseBinding",
"detectedAt": "2025-12-28T19:00:00Z",
"confidence": 1.0,
"metadata": {
"storedFingerprint": "ABC123DEF456",
"currentFingerprint": "XYZ789GHI012",
"changedComponents": ["motherboard", "cpu", "bios"],
"changeCount": 3,
"allowedChanges": 2,
"strictMode": false
}
}Related Protections
Custom Actions
License validation logic
Actions
Configure responses