Самые жёсткие способы:
1. Разрешить запуск ПО только по логину/паролю (регистрация на сайте, работать без инета не будет)
2. Привязка к железу
3. Упаковать и обфусцировать весь код
Далее 2 варианта:
1. Вынести весь важный функционал на сервер, само приложение по такой схеме будет просто клиентом, ничего не умеющим, кроме как выполнять запросы на сервер и отображать данные.
2. После авторизации выгружать из интернета dll прямо в память (упакованную и обфусцированую), обнаруживать любую попытку перехвата и банить без разбора. (таким образом защищены приватные читы для игр, но это менее надёжный способ, чем первый. Т.к. перехватить все равно возможно)
Можно сочетать 1 и 2 вариант.
В таком случае (если не вынести все на сервер), взлом тоже возможен, но он достаточно дорогой, и не целесообразен в большинстве случаев.