Todo se transforma, nada se pierde.
Es imposible proteger bien un código. Salvo que compiles en binario, pero aun en binario, puede haber una herramienta que te haga ingeniería reversa y te lo convierta en código en algún lenguaje, por ejemplo C.
La ventaja del binario es que es más difícil separar el código específico de las propias librerías.
En mi caso he usado ofuscación con #DEFINE para los nombres de los variables, clases y propiedades.
Para texto, hay que tomarse el trabajo de pasarlo a hexadecimal o algo similar, asignarle un nombre de constante especifico y usar esas constantes mientras codificamos.
Para ocultar las máscaras, el procedimiento es hacer lo mismo que con las strings, y asignarlas al vuelo.
oLbl1.caption = DeCodifico(_TEXTO_LBL_1)
entonces en tu diccionario tendras un define para oLbl1, otra para DeCodifico y otra para _TEXTO_LBL_1 y al decompilar se verá:
_00101001010101.caption = _100010100101("517565206c6120467565727a61206c6f732061636f6d7061f165")
Entonces si el fulano encuentra esto, le va a costar saber de que se está hablando, porque no puede encontrar facilmente lo que tiene que modificar.
Pero como Edgar, con paciencia "oriental", puede llegar a abrirlo.
Saludos: Miguel, La Pampa (RA)
4c61726761205669646120792050726f7370657269646164
517565206c6120467565727a61206c6f732061636f6d7061f165
hecho con python
toHex = lambda x:"".join([hex(ord(c))[2:].zfill(2) for c in x])