Ломают все. Вопрос только в цене. Не обфускация, не привязка к железу, не ключи не спасают абсолютно. В .Net не имеет вообще значения на каком языке писать поскольку работают они на одном framework-е и разница только в синтаксисе языка. С СОМ и API еще проще, это вообще "стандарт". В основном ломают просто и не затейливо. Дизассемблируют, пошагово проходят до точки выхода из программы или другого действия, деактивирующего программу. Возвращаются назад и ищут обычный if....then или что-то похожее и ... ваша прога взломана. Я использую другой подход. Для отвода глаз ставлю стандартную защиту, типа привязки к ключу или серверу и прочее. А в программе делаю свою проверку или несколько (это уж сами придумайте какую) и программу не вырубаю, а просто заставляю неверно считать. В результате пользователь пока сообразит, что что-то не так, пока разберется, что и где программа неправильно считает. Потом долго матерится, делает вывод, что программа "дерьмо" и на том все заканчивается. Искать и править бесполезно, расчеты и "сбои" разбросаны по всей программе.
Ну вот сдал все свои секреты