Kurzfassung: Das geht nicht, eine Software vor Raubkopien zu schützen ist unmöglich.
Langfassung: Man kann die Hürden recht hoch legen, aber man kann es nicht verhindern. z.B. bzgl. Seriennummer-Überprüfung kann man man Signaturen nach dem Public/Private Key Verfahren werden. Die Seriennummer wird als Signatur aus den Angaben, die der Benutzer zur Registrierung machen muss erzeugt mittels des private Keys. Dieser Key ist nicht in der Software sondern nur bei dir als Hersteller der Software. Die Software prüft dann beim Start mittels des in der Software abgelegten öffentlichen Schlüssels ob die Signatur gültig ist. So kannst du verhindern, dass jemand neue, gültige Seriennummern erzeugt. Du kannst aber nicht verhindern, dass jemand Seriennummern weitergibt.
Das weitergeben kann man erschweren, in dem die Software die Seriennummern online verifiziert und du so z.B. eine Blacklist pflegen kannst und Seriennummern sperren kannst, die auf extrem vielen verschiedenen Systemen auftauchen. Oder man nimmt in die Infos zur Seriennummer Eigenschaften der Hardware mit auf.
Allerdings muss man da natürlich sehen - das wird immer unkomfortabler für den Benutzer. Früher hab ich mir mehr Spiele oder Filme von "omniösen" Seiten runtergeladen aus zwei Gründen - Kosten & Aufwand
Mittlerweile bevorzuge ich es mir ein Spiel oder Film bei Steam/Amazon einfach zu klicken und fertig. Denn früher musstest du wenn du ein Spiel gekauft hast am die CD nicht verlegen (und aufpassen, dass sie nicht zerkratzte) und am besten auch noch das Handbuch mit der Seriennummer parat haben. War das nicht mehr da- Pech gehabt, Spiel nicht mehr nutzbar. Hat man eine Raubkopie gehabt musste man die nur entpacken, starten und läuft.
Sprich macht man die Hürden zur legalen Nutzung zu hoch steigt der Anreiz sich Alternative Wege zu suchen. Daher kann ein zu hoher Schutz kontraproduktiv sein - den er schreckt potentielle Nutzer ab.
Die obigen Maßnahmen schützen auch nicht davor, das jemand das Programm dekompiliert und den Check zur Prüfung ausbaut. Das kann man auch nicht verhindern, man kann es auch nur erschweren mittels:
* Code Obfuscatoren - die machen den Code unleserlicher, so dass er schwieriger zu verstehen ist
* Die Prüfung an möglichst vielen Stellen verstecken. So gab es Spiele die, die mehrere Layer vom Kopierschützen hatten und einer der war, dass das Spiel zwar lief aber erst später abbrach oder den Spieler immer mit Pech beglückte, so dass man nie 100% sicher war, alle Stellen gefunden zu haben.
Aber hier gilt das ähnlich wie oben - auch das macht es im Zweifelsfall unkomfortabler für den User. So erschweren es Code Obfuscatoren im Fehlerfall sinnvolle Log-Einträge zu erzeugen. Wenn da steht in der Klasse aaa in der methode aab ist eine Exception aufgetreten, weil die Variable aba null war, kann man damit nicht mehr viel anfangen. Außerdem erhöht z.B. die Überprüfung der Registrierung (ggf. mit Online-Zwang) die Chance das da auch Fehler sind und ein Kunde auf einmal seine gekaufte Software nicht mehr nutzen kann.
Von daher muss man gut abwägen, wie viel Schutz will man wirklich.