Существует много разных подходов к защите кода. Все они подпадают под категорию DRM (Управление цифровыми правами).
Вот что мне приходит в голову:
Шифрование, фактически изменяющее байтовые коды таким образом, что они могут быть выполнены только при наличии ключа или пароля.
Обфускация, перестановка кода в способ, который все еще полностью выполняется как есть, но реверсирование вручную утомительно, потому что код преднамеренно упорядочен в нестандартном / запутанном порядке.
Щит, защищающий активный код, который был загружен в оперативную память. Это можно сделать с помощью другого процесса, который выполняет проверку памяти в реальном времени с помощью контрольных сумм. Или это можно сделать с помощью шифрования кода в памяти с помощью ключа, хранящегося где-то в памяти, где только приложение знает, где его найти.
Есть так много вариантов для DRM, что у меня возникнут проблемы с выбором любых реализаций, которые стоит перечислить здесь. Простой поиск в Google должен помочь вам указать фактические реализации.