1. Основной смысл обфускации - потереть имена методов, переменных, классов, неймспейсов и т.д., заменив их на какую-нибудь ерунду, что уже значительно затрудняет реверс кода. И это единственное возможное необратимое действие - восстановить оригинальне имена в автоматическом режиме уже не получится, только если вручную, по смыслу, во время подробного анализа и реверса исходника.
2. При обфускации можно соершать куда более веселые действия, чем просто переименование - можно запутывать сам байткод (MSIL), красть байты и т.д. Чтобы это обратить, реверсеру придется в подробностях изучить как именно вы запутываете и крадете байткод, то есть просто редактированием MSIL тут не обойтись - придется писать утилиту, которая будет восстанавливать байткод в автоматическом режиме.
Аналогично со строковыми константами - их можно шифровать и оборачивать в вызов своего метода-расшифровщика, тут тоже придется писать утилиту для автоматического патчинга байткода - чтобы она ползала по сборке, искала вызов этого метода-расшифровщика и заменяла его на уже расшифрованную строку (причем для расшифровки можно этот метод и вызывать). То есть опять же, просто правкой MSIL не обойтись - надо тратить время на написание автоматической утилиты.
3. Так же можно упаковывать байткод, распаковывая его в реальном времени, тогда придется его дампить чтобы изучить, и его правка в оригинальной сборке (там, где он ещё упакован) может оказаться весьма нетривиальной.
4. Редакторов MSIL множество, и да , они позволяют вмешиваться в код сборки, но как я уже выше написал, порой просто редактора недостаточно, нужно сперва почистить сборку от обфускации, а потом уже патчить программу с помощью редактора.