Proyecto ayuda...Ofuscacion de codigo

que tal bueno.. como ando de vacaciones me propuse a programar algo que considero un poco complejo al menos para mi y necesito orientacion si alguien tiene idea o ya lo ha echo antes.

el proyecto como dice el titulo es hacer un programa que ofusque codigo en java. echo en java.. simple tomar un archivo.java y generar otro.java ofuscado..

las herramientas que dispongo y lo que e echo es..

programe una clase que me hace un cifrado con el metodo cesar (http://es.wikipedia.org/wiki/Cifrado_César)
en base a eso pense hacer codigo java ofuscado que tome el codigo fuente lo cifre o lo devuelva en una sola linea.. ejemplo

 
y la salida cifrada sea con 4 desplazamientos
 
en un archivo de texto tendre las palabras reservadas public int class etc.. que se leeran cada vez tengo un metodo que hace que si
lee del codigo fuente una palabra verifica si es reservada dentro del archivo. si lo es pasa directamente tal como es y si no se va al metodo cifrar obtengo el cifrado y la "escribe"

eso ya lo tengo controlado, investigue mas y tendria que hacer programas que analisen
lexico
sintactico
semantico

por esos analisadores creoq dandole puedo programarlos.. mi duda va sobre esto

el caso de por ejemplo el metodo System.out.println("hoola")
eso alguien sabe con que podria analizarlo? obviamente no es una palabra reservada no podria meter todas esas cosas en el archivo de palaras se haria muy grande imaginen todos los posibles de System.* y demas metodos de java

lo que se me ocurre es de alguna forma saber o analizar los archivos de las clases estandar java
tener en otro archivo los nombres de clases analizarlos tambien y saber que si ejemplo
me encuentro con un System que busque dentro del archivo System y vea si existe out si es asi busque y vea si esta println
por podria ser que se escribiera mal y en lugar de System.out.* sea System.outt.* seria error de sintaxis no?

y despues de las comillas decirle que no cifre nada porq serian mensajes lo e pesando de esa forma

digamos que queremos imprimir una variable ejemplo..
 
mi programa sabria ya que este bien echo que int no se cifrara numero si y despues de un = no se cifra tampoco

quedando como
 
y si queremos imprimir
 
entonses el programa haria esto System.out.println() eso no se cifra
y no encontro comilas dentro del parentesis entons se cifra lo que esta dentro el nuevo codigo ofuscado quedaria
 
con lo que la variable ryqivs se imprime y muestra 2

como el codigo original..

bueno hasta aqui con algunas dudas si alguien me quiere ayudar en esto estaria muy bien..
o si ay alguien que me oriente y sepa donde y que buscar

es un proyecto personal que se me ocurrio si se termina pues lo publico aqui para que alguien mas haga uso de ello

la clase que cifra textos la estoy puliendo con algunas cosas luego la subo para que se la bajen..

salu2

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

Te podría servir de ejemplo

Te podría servir de ejemplo usar ver como hace el trabajo un ofuscador. Por ejemplo: es muy bueno.

Al menos para que veas como debería de ser lo que produzcas.

No debes de ofuscar nada que sea publico, ni protegido, por que si lo hicieras romperías con tus clientes.

El problema no es minúsculo, por que tienes que parsear el código Java para poder tenerlo en un AST y después cargarlo dinámicamente para determinar si lo que estás viendo lo puedes ofuscar o no ( como en el caso de System.out.println )

Existen ya gramaticas que parsean todo Java y lo hacen muy correctamente. La onda es si quieres aventarte el rollo aprender a usarlos.

Otra opción ( que es la que yo haría ) es para empezar, tratar de identificar todas las variables de tu código, y los métodos privados, línea por línea.

Esto sería un tanto más fácil, si no eres tan estricto.

Por ejemplo, todas las variables tienen en la misma linea un   y en los atributos como solo deberías de ofuscar los privados, todos tendrían  , algo similar pasa con los métodos:  

Te digo que funciona si no eres tan estricto, por que en Java lo siguiente es válido:

 

Entonces, si tratas el código linea por linea puedes utilizar expresiones regulares.

Este es un ejemplo que solamente reemplaza las variables.

El código se ve apantallador, pero es por que tiene muchos comentarios, es realmente sencillo de entender.

 

Al ejecutar este programa, va a leer su propio código fuente y va a reemplazar las variables.

Este es el resultado de la ejecución:

 

Como ves el resultado compila perfectamente, por que sigue siendo código Java válido.

Ahora el chiste sería encontrar las expresiones regulares para, atributos, metodos, strings, enteros,, etc. etc. etc todo lo que quieras ofuscar. Meterlo en una estructura de datos más compleja ( como maps, listas etc. etc ) y después reemplazarlos.

Obvio esto es mucha talacha, pero es lo que precisamente los parseadores hacen bien, sacar tokens y simplificarte la vida, por ejemplo, mi código no detecto la variable "variablesPattern" por que no terminaba en punto y coma (;) ni tampoco la variable "reemplazos" por que tenía por ahí unos piquitos ( &ltString> ) que le hacían quedar fuera de la expresion.

Este es un ejemplo nada más, en la realidad esta es una tarea bastante compleja.

En fin, espero que esto te de alguna idea.

Saludos.

Imagen de ezamudio

Sobre fuente?

Los ofuscadores reales trabajan sobre el bytecode por varias razones: primero, es un hecho que el código al menos compiló bien. Segundo, es más fácil hacer el análisis de cobertura de código y las dependencias, etc (ver dónde hay llamadas a un método o referencias a una variable), porque vas a tener que cambiar el nombre del método "metodo()" por "aaaa()" no sólo en la declaración sino en todos lados donde se llame. También el nombre de la clase y las variables.

Imagen de genitalico

q ondas gracias OscarRyz por

q ondas gracias OscarRyz por la respuesta en breve me pongo analizar todo ese codigo que es musho xD...y planteo mis dudas por lo primero sobre ser estricto con el codigo en tu ejemplo de

private
String
name
=
"The name"
;

programe que en cuanto se encuentre un espacio salto de linea lo tome como una palabra con eso me libro de ser estricto y ya probe y funciona y tomando como palabra todo eso pues empezaria por ver si es reservada o no y ya.. ahora tengo un problema y es que no puedo detectar las tabulaciones
digamos

private String

pues bueno no me lee el String por que no es espacio si no tabulador, pense que por estar como un espacio o algo asi me detectaria pero tengo problemas con eso ya intente mi programa recorre letra por letra y guarda en un char[] todo hasta que haya un espacio, salto de linea y tabulador o comillas etc
con eso hago despues un string y guardo la palabra

bueno el problema es que en mi char[]
puedo hacer
if(cha[i]==(char)32) es un espacio
pero nu pedo hacer que verifique
if(char[i]=='\t')

me recomendaron poner
if(char[i]=="\\t")

pero no funciona como puedo checar que hay tabulacion porq ahi falla mi programa.

empiezo de esta manera habro el archivo mediante la entrada estandar

y tomo linea por linea
con readLine.
despues ese String lo convierto a un array de caracteres y ahi hago toda esa verficacion de separar las palabras al encontrarse en el arreglo un espacio etc..

esa es mi duda ahorita..

por otro lado tiene razon ezamudio no habia pensado en eso al cifrar los metodos y cambiarlos se deberian llamar del mismo modo. pero creoq no habria problema si todo el proyecto por asi decirlo se ofusca con mi programa ya que asi haria los mismos cifrados sobre las palabras con lo que los metodos se cambiarian con el mismo nombre.

esa es una ahora pensando en lo que se refiere a los println y demas metodos que expuse arriba. pense separar mi programa en dos.
ofuscar solamente la parte algoritmica con lo que no habria problema ya que solo en esos codigos habrian metodo y y variables y nada mas..
el problema seria cmo dijo ezamudio cambiar nombre en la parte de implementacion..
podria solucionarlo haciendo de alguna forma que tome el codigo de algoritmo ofucado lo decifre en un paso previo a la compilacion con lo que estaria como se escribio originalmente y compilar y borrar ese archivo decifrado..

pero ya seria meterme en otros rollos.

ahora lo de ofuscar ya en los bycodes? me entro la duda como se puede hacer eso?

salu2

Pues hace sentido totalmente

Pues hace sentido totalmente trabajar sobre el bytecode en vez de trabajar sobre el código fuente. Claro los retos ahí son diferentes a bajo nivel ( leer en el formato del bytecode en vez de strings planos por ejemplo ) aunque a alto nivel es lo mismo. Tienes que renombrar nombres, procurando no romper a los clientes que tengas , por ejemplo si lo que ofuscaras fuera una biblioteca para ser usada desde otra aplicación, si le cambiarás el nombre a una clase o método, ya no te podrían llamar, aunque internamente sustituyeras todas las llamadas.

También es interesante ofuscar el flujo, y no solo los nombres. Por ejemplo de sitio de Zelix ClassMaster viene este ejemplo:

Original:
 

Y después:

 

Sobre tu problema con el tabulador, esta raro, pero definitivamente no es con '\\t'

Imagen de genitalico

lo siento pero m perdi un

lo siento pero m perdi un poco con mis post empezare a revisar loq pusieron y si tengo dudas las posteoo salu2