Archivo de la categoría ‘Programación’

Proyecto. Towner: Destrozando otro juego Flash (Facebook y Tuenti)

Share on Google+Share on FacebookTweet about this on Twitter

No tenía pensado embarcarme en este mini proyecto, cuando la verdad tengo unos cuantos pendientes a los cuales no logro sacarles tiempo. Dejémoslo simplemente en que era algo que tenía que hacer, así mataba un par de pájaros de un tiro. Por el contrario que sucedió con Hammerfest, no tengo absolutamente nada en contra de MetroGames, que si bien creo es la compañía que desarrolló el juego en Flash, por encargo de Facebook y posteriormente de Tuenti. Tampoco es mi intención animar a los Cheaters (tramposos) a hacer trampas en el juego, que aunque existan muchos que su único fin es simplemente ser el mejor de todos (independientemente de como se alcanzó la meta), os recuerdo que esto mata la diversión, y a la larga creo que también lo hace con el espíritu humano.

Es evidente que habrá lectores que no sepa que es “Towner”. Este no es más que un juego realizado en Flash para los usuarios de Tuente y Facebook. El juego trata de construir tu ciudad, para la cual comienzas desde el nivel 1 con muy pocos recursos, y a medida que vas subiendo de nivel con los días/semanas/meses vas pudiendo acceder a más terreno para edificar, nuevos edificios que dan más ventajas y dinero… los nostálgicos recordaremos cierta similitud a Sim City. Con el tiempo puedes realizar también logros que te dan tanto dinero como experiencia. La verdad es que a pesar de que está muy limitado, y sinceramente, y muy mal equilibrado, puede tener cierta adicción, sobre todo quizás por que tiene gran importancia los propios contactos de estas redes sociales que tengas que también juegan, estos te dan dinero, experiencia o logros, y por supuesto poder acceder a la ciudad de tus amigos. El juego implementa también un sistema de pago con dinero real para poder comprar monedas que pueden ser intercambiadas en el juego por dinero de juego, edificios mejores…

Dicho esto podemos ponernos a trabajar. ¿Cual es la intención de este “proyecto”? Al igual que con Hammerfest, poner quizás un poco en evidencia cuestiones que se toman a la ligera en la programación o en la seguridad de los sistemas que se implementan. Así mismo, es una forma perfecta de aprender y tener cada vez una mayor comprensión de las tecnologías de las que disponemos en informática, que no todo es jugar, internet y los videos/fotos XXX. De paso aprovechar para criticar a todos esos Lammers que abundan por Internet que se hacen llamar Hackers o expertos en la materia cuando lo único que saben hacer es ejecutar un programa que hacen otros, sin saber que hay debajo de ello la mayoría de las veces.

Aunque parezca un poco paradójico, aun cuando los chicos de MetroGames han sido relativamente concienzudos para evitar este tipo de  situaciones o chetas, destrozar el juego ha sido quizás más sencillo que con Hammerfest. De todos modos hay que defender el trabajo de los programadores que hay detrás, es su trabajo, y las compañías que están detrás evidentemente lo que intentan es sacar dinero con ellos, con lo que es lógico que quieran proteger sus creaciones. Este tipo de artículos sin duda alguna pone en entredicho su nombre a fin de cuenta. Y aunque sea yo quien lo dice, es una pena que el trabajo de un grupo de programadores, vean como el tiempo en destrozas su criatura es mucho menor al tiempo que se tarda en crearla o hacerla crecer. Pero no divaguemos más y veamos lo que vamos a hacer:

  • Conociendo a tu enemigo: Google, Sniffers y encriptación/desencriptación XOR
  • El enemigo de mi enemigo es mi amigo: Descompiladores, XOR  y RAM. El primer número mágico es 0x66
  • Apretando el gatillo para matar a tu Enemigo: Una de C-al y otra de RAM.


Cuando terminemos podremos controlar entre otras cosas:

  • Los puntos de experiencia
  • El dinero
  • El tiempo de construcción de los edificios
  • El acceso a los edificios de pago
  • La consecución de logros que nos queden



Conociendo a tu Enemigo

Hay muchas formas con las que se puede atacar un sistema, ya sea un equipo físico o un programa informático. El tópico que dice “la imaginación pone el límite” aquí se cumple a la perfección. Siempre que estoy con algún trabajo/proyecto similar, siempre lo planteo del mismo, y lo primero es siempre conocer, cuanto mejor posible, la labor que quieres llevar a cabo. Esto parece una tontería, pero es gracias a esto a que es posible desarrollar lo demás.

Por poco que pensemos, podemos sacar muchas conclusiones:

Es un juego/aplicación Flash incrustada en el navegador, usa nuestros datos de Tuenti/Facebook para acceder y configurar nuestra partida, el juego guarda los datos de la partida a priori cada X tiempo. Esto que parece trivial sirve y para mucho. Por ejemplo, que sea una aplicación Flash ya nos está diciendo que podemos intentar atacar al sistema de 2 formas diferentes!! ya sea modificando el propio contenido Flash o manipulando nuestro propio PC que es quien está ejecutando dicha aplicación. Por otro lado, que use nuestros datos de las redes sociales nos dice casi con toda seguridad que la aplicación Flash deba de tener algún cargador que pase ciertos parámetros de nuestra cuenta de Facebook/Tuenti al juego. Y para terminar, que el juego guarde datos cada X nos abre de nuevo una tercera vía para atacar al sistema, a fin de cuenta son datos que envía nuestro PC al servidor de ellos, y dichos datos pueden modificarse.

En realidad solo es tiempo para que cualquiera de los 3 sistemas posibles para atacar el sistema tenga éxito, pero es evidente que si podemos obtener lo mismo por una vía mucho más rapida, será la que vamos a usar. Antes de comenzar por tanto, vamos a lo más simple del mundo, usar Google para ver si alguien ha hecho el trabajo ya por nosotros, aunque por supuesto, copiar el trabajo de otro no es que sea muy gratificante ni nos ayuda demasiado, pero a veces puede ilustrarnos en nuestro camino. Efectivamente, no son pocos sitios en Internet donde hablan de posibles trampas que pueden hacerse en este juego, que yo haya visto todas usando CheatEngine, y por lo que veo quizás solo fuese efectivo realizarlas hace ya mucho tiempo, antes que actualizasen el juego y le añadiesen ciertas capas de seguridad. CheatEngine es un gran programa en la medida que puede ahorrarnos mucho trabajo, pero una vez más lo divertido no es abrir un programa y seguir un tutorial, sino saber que hace realmente el programa y por qué nos ahorra realmente tiempo. De todos modos, no he visto por la web ningun ataque a “Towner” que sea real… hasta hoy claro.

Una vez que San Google no nos da nada de información sobre Towner que pueda ser de interés, hay que empezar a trabajar, empezando por intentar seleccionar el mejor de los 3 ataques, a priori,  a realizar. Es decir, analizar cada uno de los casos:

  • Atacando al juego modificando los datos que son enviados al servidor cuando la partida se guarda

    La ventaja de este sistema es que es muy fácil llevarlo a cabo, tan solo hace falta colocar un Sniffer y ver que datos son los que nuestro PC está enviando a sus servidores. El problema es que no suele ser efectivo casi nunca, dado que los datos enviados suelen estar codificados/encriptados para evitar que un ojo audaz lea de forma fácil el contenido de dichos datos, y pueda modificarlos sin problema alguno. Aun así, no requiere prácticamente nada para comprobarlo, ni tiempo ni complejidad, con lo que nunca está de comprobarlo. Además, nunca está de más ver si podemos sacar algo en claro de ello, aun cuando los datos vayan protegidos. Con un simple sniffer o proxy podemos interceptar la información, dado que es información que envía nuestro PC a su servidor lo más probable es que sea por medio de un método POST, mirando un Sniffer Tendríamos:

    POST http://social.tuenti.metrogames.com/thetowner-tuenti/ HTTP/1.1
    Host: social.tuenti.metrogames.com
    User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b7pre) Gecko/20101002 Firefox/4.0b7pre
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en-us,en;q=0.8,es-es;q=0.5,es;q=0.3
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Keep-Alive: 115
    Proxy-Connection: keep-alive
    Cookie: PHPSESSID=xxxxxxxxxxxxxxxxxxxxxxxxxxxx
    Referer: http://content.ak.metrogames.com/social/thetowner-tuenti/cargadorf788d4aeab3c04950be07c6f4141bd38.swf/[[DYNAMIC]]/1
    Content-type: application/x-www-form-urlencoded
    Content-length: 769

    [bloque de datos]

    Bueno, para empezar podemos sacar algunas cosas en claro. Por la etiqueta Referer podemos inferir que efectivamente todo el juego obedece a una pequeña aplicación cargador que casi con toda seguridad es invocada con anterioridad, el mismo nombre cargadorxxxxxxxxxx.swf deja esto bastante claro. En realidad ese numero largo lo que representa exactamente es el Hash MD5 del propio archivo, un buen sistema para que luego dicho cargador pueda hacer una verificación interna de si dicho archivo ha sido modificado o no: El cargador calcula su propio hash, y si esta coincide con el del nombre del archivo, interpreta que el archivo no ha sido modificado, con lo que es legitimo.

    La intención aquí era ver lo que he simplificado tan solo como [bloque de datos]. Es un chorizo un poco grande y sin mucho interés sinceramente, por eso lo he omitido. Las etiquetas de dicho bloque de datos que son enviados son meta1, amount, meta0, mg_sid y meta2, los datos asignados a cada campo como digo son ilegible, con lo que sería improbable atacar al sistema simplemente modificando sus datos. mg_sid parece ser un ID de usuario, mientras que meta1, meta2 y meta3 probablemente sean campos para verificar que la información es correcta y no se ha modificado y para enviar al servidor nuestros datos. Bueno, dado que tenemos otros métodos de ataque viables, no vamos a buscar más por esta vía, aunque se podría seguir investigando y probando.


  • Atacando al juego modificando la RAM del sistema

    Esta quizás sea la técnica más utilizada en este tipo de aplicaciones. Es simple, al ser una aplicación Flash, esta se ejecuta y procesa en nuestro propio PC, es decir que tanto las instrucciones que se ejecutan de la aplicación como los datos de esta están casi con toda seguridad en la memoria RAM de nuestro equipo, y es algo a lo que podemos acceder sin mucha complicación. Esto es básicamente lo que hace CheatEngine, monitorizar las páginas de RAM que son usadas por una aplicación concreta.

    Este método suele ser muy efectivo, el problema que tiene es que casi todos los programadores del mundo usan diferentes técnicas para evitar que el usuario pueda obtener de la RAM algún dato de utilidad, ya sea escondiéndose lo mejor posible en la RAM para que dichos datos no sean encontrados, ya sea encriptando/codificando dichos datos o ya sea usando algún sistema de checksum para intentar evitar que se puedan introducir datos incorrectos.

    Para ver la viabilidad de este sistema de forma simple, podríamos intentar usar CheatEngine o cualquier edidor/visualizador de RAM para buscar en la memoria reservada al navegador algún valor concreto del juego, por ejemplo el dinero. No obstante, si hiciésemos esto no lograríamos en este caso ningún resultado. El siguiente paso sería usar CheatEngine para intentar averiguar la ubicación de la RAM en la cual se encuentra dicho valor, ya que aunque estuviese encriptado quizás podríamos deducirlo de algún modo. Para esto podríamos ir buscando conjuntos de bytes en la memoria que fuesen cambiando a medida que nuestro dinero (por ejemplo) cambiase, y cada vez reducir más la posible ubicación en memoria. En el mejor de los casos y con mucha mucha paciencia, en este caso concreto, encontraríamos el lugar exacto, aunque por desgracia los datos serían completamente in-interpretables para nosotros:

    Address: 075E11B4 Value: 3254212197
    Address: 075E11B0 Value: -1933194698

    A lo más que llegaríamos sería obtener esas dos direcciones de memoria, cada una conteniendo un dato de 4 Bytes, lo que harían un total de 8 Bytes, teniendo en cuenta que las dos posiciones de memoria son contiguas. Esto podría significar que quizás el valor sea almacenado en 8 Bytes, o por el contrario que cada una de las posiciones almacenase una parte del dinero, o que fuesen dos posiciones independientes siendo una un dato de control de la otra. Las posibilidades son infinitas. De todos modos aun cuando pudiésemos obtener dichas direcciones (que son diferentes en cada ejecución, con lo que esas posiciones mías no le sirven a nadie), sería imposible inferir un valor de ellas. Podemos por tanto suponer que el dinero al menos posee algún tipo de codificación/cifrado que nos impide usar este sistema.


  • Atacando al juego modificando el contenido Flash

    Este sistema suele ser el más complejo, pero el que más información nos puede brindar sobre nuestro objetivo. Dado que es una aplicación Flash, en teoría podríamos ser capaces de descargar dicha aplicación como tal (archivos .swf) y por medio de descompiladores y desensambladores lograr el acceso al código de la aplicación. Modificar lo que deseásemos y volver a montarlo todo sin que el servidor de ellos pueda darse cuenta de que hemos modificado algún contenido de este.

    Hacer esto ya no es tan simple. Principalmente porque las primeras capas de seguridad que se implementan en aplicaciones Flash son precisamente para evitar estos escenarios. No obstante la teoría es correcta, y los resultados suelen ser sorprendentes.

    Como ya hemos dicho, el primer problema al que nos encontramos es que antes de la aplicación tenemos un cargador que controla muchos aspectos de esta, el cargador entre otras cosas vigila que la aplicación en sí sea legítima, lo cual es muy simple de hacer usado algún tipo de CRC. No obstante el cargador mismo es otra aplicación Flash, con lo que aplicando el mismo principio podrámos descargar el cargador, descompilarlo/desensamblarlo, modificarlo para evitar ciertas capas de seguridad y montarlo de nuevo. Tiempo, tiempo y más tiempo. De todos modos hay que intentarlo, así que lo primero que podríamos hacer sería descargar tanto el Cargador como el Juego. ¿Como? A fin de cuenta no deberían de ser más que archivos Flash .swf, con lo que sin complicación alguna un Sniffer podría interceptar las peticiones a ellos y obtener las rutas a dichos archivos de forma manual. Es más, si aun guardamos las peticiones del primer apartado, en teoría deberían de aparecer allí. Mirando los registros anteriores tenemos que en este momento para mí las direcciones serían:

    http://content.ak.metrogames.com/social/thetowner-tuenti/cargadorcargadorf788d4aeab3c04950be07c6f4141bd38.swf
    http://content.ak.metrogames.com/social/thetowner-tuenti/juego648bcec512718feb2868a727888933cb.swf

    Como he supuesto que eran esas? Es cierto que en los registros tengo muchas otras peticiones a archivos swf, pero es evidente que puedo empezar por estas dos, para empezar porque el nombre del archivo comienza por Cargador en el primer caso y Juego en el segundo. Luego con eso ya puedo descargar ambos archivos.

    Los chicos de MetroGames son listos, y si intentamos ondar un pocon en dichos archivos, veremos que efectivamente la estructura del archivo cargador.swf corresponde a un archivo Flash, no es así para el archivo Juego.swf que hemos descargado. Esto podemos verlo si examinamos los primeros 8 Bytes (la cabecera) de sendos archivos:

    Cargador.swf: 43 57 53 0A 82 AF 02 00 | CWS.‚¯..
    Juego.swf:       25 31 35 6C 1A 02 75 66 | %15l..uf

    Los 8 primeros bytes de un archivo flash son siempre los mismos. Los 3 primeros son el ID de los arcivos Flas, serán (en ASCII) CWS para archivos Flash comprimidos y FWS los que no. El byte 4º especifica la versión Flash usada para crearlo y los 4 bytes restantes la longitud de archivo Flash sin comprimir. En el caso del archivo Cargador.swf vemos que coincide perfectamente con lo que sería un archivo Flash, su cabecera CWS (Bytes 46 57 53), Versión 10 (Bye 0A) y un tamaño de 176002 Bytes (Bytes 82 AF 02 00). ¿Pero que sucede con el archivo Juego.swf? Es evidente que algo sucede. Podríamos pensar que no es un archivo swf, pero si examinásemos el resto de arcivo swf que se descargan veríamos que todos tendrían una cabecera igual/similar a este. Lo más seguro por lo tanto que por protección, los archivos Flash del juego sean transmitido al PC de forma encriptada y que sea el mismo Loader (el cargador) quien los desencripta. Esto es un sistema bastante inteligente, ya que el acceso y/o modificación de dichos archivos sería prácticamente imposible, a priori, con lo que todo el código del juego queda protegido.

    No obstante, es evidente que el primer eslabón en la cadena, en este caso el Loader no puede estar encriptado, dado que tiene que poder ser interpretado y procesado directamente por el PC, y es la razón de que este si es enviado de forma “estandar”. Para poder solucionar esto podríamos continuar con el desensamblado/descompilado del cargador, aprender (si es posible) el sistema que usa para desencriptar los archivos y crear un programita o sistema para de este modo poder por fin tener acceso al archivo Flash original del juego. Pero aun cuando esto fuese posible, hay sistemas mucho más rapidos para lograr la misma tarea. No obstante, dado el cifrado tan simple que se ha usado vamos a ver los dos sistemas


Antes de comenzar a despedazar trozo a trozo cada parte, vamos a terminar con este bloque. De los 3 posibles ataques a realizar el primero quedaría descartado. De los otros dos, vamos a usar el primero (modificaciones internas de la RAM) aplicando lo que aprenderemos del segundo (desensamblando el código original. Con lo que a priori nos vamos a encontrar con dos problemas a resolver:

El primero, lograr obtener los archivos desencriptados para poder trabajar con ellos.
El segundo, encontrar en los archivos desencriptados el santo grial, el sistema que están usando los amigos de MetroGames para evitar el Tampering (la modificación en RAM de los aspectos del juego)

 

El Enemigo de mi Enemigo es mi Amigo

 

  • Desencriptación de Juego.swf (y otros archivos)
  • Búsqueda de los sistemas de protección de MetroGames

 

Llegados a este punto debemos de tener en el disco duro una copia de los archivos originales cargador.swf (que como hemos dicho es completamente válido) y un archivo Juego.swf (que como hemos dicho tiene algún tipo de encriptación).

En este aspecto los programadores de MetroGames no han sido muy listos, y aunque la idea era buena no han sabido ponerla en práctica de forma decente. Lo primero que vamos a hacer es realizar la desencriptación del archivo Juego.swf, y lo vamos a hacer de 2 formas diferente: Desencriptándolo nosotros y dejando que dicha labor la haga el cargador

 

  • Desencriptando

    Si queremos poder manejar el archivo Juegos.swf para poder pasarlo por algún descompilador o desensamblador necesitamos tenerlo desencritpado. Vamos a ver como hemos dicho 2 métodos: Dsencriptado manual y desencriptado automático (por asi decirlo). Normalmente ni pensaría en realizar un desencriptado “manual”, sería muy complicado saber cuestiones como el tipo de cifrado, el algoritmo usado, la key… y eso sin contar que el sistema podría ser completamente creado para tal afecto, con lo que la única forma sería desensablar el cargador e intentar encontrar las rutinas de desencriptado, implementarlas en C (u otro lenguaje) y procesar los archivos, y eso en el caso de encontrar en el cargador.swf desensamblado todos los datos que necesitásemos. Pero la verdad es que nos lo han puesto tan fácil que ya sea el desencriptado manual o automático nos va a llevar poco mas o menos el mismo tiempo (y eso que el desencriptado automático es bastante simple).

    Desencriptado Manual

    Lo primero es como siempre suponer. No todas las suposiciones son siempre correctas, y muchas veces hace falta probar varias veces antes de dar con la tecla correcta. Veamos, la encriptación/desencriptación que hayan empleado debería de ser bastante rápida de realizarse, nadie quiere que por un simple juego Flash el procesador comenzase a trabajar sin parar. Por otro lado lo ideal sería emplear un sistema de cifrado que en la medida de lo posible no incrementase el tamaño del archivo, puesto que supondría una mayor carga ya no solo para el usuario final, sino para sus propios servidores. A poder ser, si fuese yo intentaría usar algún sistema de cifrado que fuese simple de implementar, recordemos que Flash (ActionScript) no es el lenguaje C. En cuanto al tipo de cifrado lo normal sería implementar un cifrado de tipo simétrico, en la que la misma key fuese la que encriptase y desencriptase, sobre todo para evitar tamaños de Keys kilométricos. Tambien tenemos una gran ventaja!! Tenemos acceso primero al archivo cifrado, pero también tenemos acceso a parte del contenido no cifrado de este!! Recordemos que conocemos de antemano parte de la cabecera del archivo Flash (Al menos los 4 primeros Bytes sabemos que con casi total seguridad serán 46 57 53 0A)

    Aun con todo esto, suponer el sistema que están usando puede ser algo azaroso. No obstante, para quienes leyeron uno de los capítulos de encriptación, recordará que existe un método de cifrado usado casi universalmente, por no decir que es la base de la gran mayoría de todos los cifrados simétricos que existen a día de hoy: XOR. XOR es una operación lógica entre dos números binarios, cuyo resultado será 1 si ambos dígitos binarios son diferentes (uno es cero y el otro es uno) o cero si ambos dígitos son iguales. Es decir, 0000 XOR 1111 = 1111, 0011 XOR 1010 = 1001. Este sistema tiene la peculiaridad que puedes conocer cualquiera de los 3 miembros sabiendo tan solo dos de ellos y realizando entre ellos la operación XOR. Este tipo de cifrado generalmente toma los datos de Byte en Byte y va realizando XOR a cada uno de ellos con una key. Dicha Key no hace falta que sea dele mismo tamaño que los datos originales, normalmente lo que se hace con ella es o un flujo de Key (en el caso de los cifrados de flujos) o simplemente se repite una y otra vez la key para aplicarla a todos los datos de entrada. Es decir supongamos que tenemos los Bytes: 46 57 53 0A y nuestra key fuese 05. El resultado de dicho cifrado sería tomando cada Byte y aplicando a cada uno la operación XOR con el byte de la clave (05 en este caso).

    Dejando la teoría a un lado, por suerte para nosotros y mala suerte para MetroGames, ellos no hacen otra cosa que realizar precisamente un cifrado XOR, usando como Key únicamente un Byte, el cual se repite para cada Byte del archivo cifrado. Así obtienen un cifrado que no aumenta el tamaño del archivo, que lo hace aparentemente seguro para ojos indiscretos y que es muy rápido y simple de implementar. Es decir:

    Primeros Bytes Cifrados del archivo Juego.swf:
    25 31 35 6C 1A 02 75 66

    Clave XOR (aun desconocida)
    XY XY XY XY XY XY XY XY

    A priori desconzco la clave XOR, aunque ya he adelantado que es una key de un solo Byte que se repite, con lo que a cada Byte del archivo cifrado se le aplicará la misma operación con la mismo valor. Como podemos inferir dicha Key? Bueno, en este caso no hace falta profundizar. Si recordamos la breve teoría que expuse anteriormente, es muy facil obtener el tercer operando de una operación XOR si tenemos 2 de ellos. En este caso no tenemos el segundo operando, la key, (Enc XOR Key = Desenc) pero si dispongo del primero y de parte del resultado!!:

    25 31 35 6C 1A 02 75 66 <- 8 primeros Bytes del archivo encriptado
    43 57 53 0A xx xx xx xx <- 4 primeros Bytes Conocidos que tendrá el archivo desencriptado

    66 66 66 66 xx xx xx xx <- Resultado obtenido al realizar la operación XOR Byte a Byte.

    Curiosamente vemos que los 4 primeros Bytes devuelven el mismo valor hexadecimal: 0x66. Es decir, que la clave Xor para esos 4 primeros Bytes es 0x66. Evidentemente si se repite la misma para los 4 primeros Bytes, podemos suponer que la clave XOR que se ha usado para encriptar TODOS los datos no es otra que 0x66. Si esto es cierto, bastaría con aplicar XOR a todo el archivo encriptado con el valor 0x66 para cada uno de los bytes de este. El resultado debería de ser el archivo Juegos.swf desencriptado. Realizar el proceso a mano evidentemente no es viable. O se hace uso de algún programita o se implementa uno en un momento, lo cual no tendría mayor dificultad. Personalmente dado que tengo ya instalado (y hago buen uso de él) WinHex, voy a realizarlo con él. No tengo más que abrir el archivo Juego.swf encriptado con Winhex, Edición -> Modificar datos. Llegados a este punto solo tengo que seleccionar XOR e introducir 66. Y listo, el archivo desencriptado al instante. No podemos ver ningún dato de interés porque recordemos que los archivos flash con cabecera CWS están comprimidos. Pero puedo garantizar que el resultado es un archivo swf que podemos guardar como Juego_des.swf.

    De todos modos hemos llegado ha este punto suponiendo muchas cosas. Podríamos a ver dado muchos palos de ciego o incluso no lograr absolutamente nada. Tampoco estaría nada perdido. Dado que tenemos acceso al archivo Cargador.swf, podríamos descompilarlo/desensamblarlo y buscar en su código algún indicio del sistema de cifrado usado, así como la key. En este caso tampoco habría sido uan cuestión complicada si se sabe donde mirar. Por motivos legales no puedo copiar evidentemente código desensamblado de otros sin autorización (y dudo mucho que me la den). Si os puedo decir sin duda alguna que encontrar el tipo de cifrado es muy fácil, sobre todo si se han usado nombres descriptivos. En C, el código necesario no sería otra cosa que:

    while (indice < sizeof(Buffer))
    {
    Buffer [indice] = Buffer [indice] ^ clave;
    }

    En C la operación XOR se realiza mediante el operador ^, el reto es más que evidente. Básicamente en el buffer estaría almacenado el archivo encriptado, simplemente a cada byte de este se le iría aplicando XOR con la clave, y almacenando el resultado en la msima posición. Por otro lado, encontrar la key tampoco debería de ser un problema, y cuando lo fuese, sabiendo que el sistema usado es un cifrado XOR byte a Byte, podríamos aplicar lo anteriormente explicado.

    Desencriptado Automático

    Y por supuesto, tenemos el método de siempre. Si es un archivo Flash, esté encriptado o no, en algún momento este se deberá de desencriptar para que pueda ser usado. Si se desencripta, quedará almacenado en algún lugar. ¿Donde? En la RAM por supuesto. Esto quiere decir, que cuando la aplicación esté en ejecución, tendremos la certeza de que en algún lugar de la RAM dicho archivo encriptado Juego.swf se encontrará desencriptado. Solo hay que buscarlo y hacer un volcado de dicha sección de la RAM a un archivo, que nombraríamos Juego_des.swf. ¿Como? Tenemos en la red multitud de programas para tener acceso a la RAM. En mi caso de nuevo uso WinHex (un gran programa sin duda). Solo tengo que abrir la sección de RAM que está usando mi navegador para la aplicación Flash que se está ejecutando. Dado que estoy usando Firefox 4.0 beta, todo el contenido Flash no se ejecuta en el espacio de Firefox, sino de un proceso llamado plugin-container.exe. Tan solo tengo que acceder al espacio reservado para tal efecto con Winhex. Una vez abierto habría que buscar el contenido desencriptado. ¿Como?. Bueno, es fácil. Sabemos como es la cabecera de un archivo Flash. Con ello, si tenemos cerrado todas las demas pestaás de nuestro navegador, no nos costará nada encontrar el inicio del bloque que buscamos. OJO!! Las aplicaciones Flash recordemos que suelen estar comprimidas, pero una vez procesadas, en RAM se encuentran DESCOMPRIMIDAS!! Esto quiere decir que la cabecera a buscar no serían los Bytes 43 57 53 0A (correspondientes a un archivo flash CWS), sino que tendríamos q buscar por los Bytes 46 57 53 0A, correspondiente a la cabecera FWS, es decir sin comprimir. Lo más seguro es que al 5 intento como mucho demos con el inicio de bloque:


    La imagen no ha podido salir peor… lo importante es que en mi caso en la primera iteración ya apareció el bloque buscado. Como se puede saber si es realmente el buscado u otro? Hombre, con un poquito de sentido común. Por ejemplo, si se mira un poquito más abajo se puede leer perfectamente “Juego”, demasiadas casualidades. Teniendo el inicio de bloque tan solo habría  que extraer el bloque comprendido de su inicio a su fin. Esto también es tremendamente sencillo. Recordemos que los Bytes 5-8 indican el tamaño en Byte. En este caso tenemos que el tamaño en Bytes = 7C 64 13 00. WinHex automáticamente nos dice que si interpretamos todo ello como un valor de 32 bits en LittleEndian, el resultado es 1270908 Bytes. Si se quiere calcular tan solo hay que introducir el número al reves en cualquier calculadora (LittleEndian). Es decir 0x13647C = 1270908 (en Bytes). Si marcamos el inicio de bloque, nos desplazamos a un offset relativo al inicio de bloque de 1270908 Bytes, marcamos el fin de bloque y copiamos/extraemos/cortamos dicho bloque a otro archivo, habremos obtenido de otra forma el archivo Juegos_desc.swf

    La única diferencia entre el desencriptado automático y manual es que en RAM se encuentra también descomprimido. El tenerlo descomprimido o no, es indiferente. Si necesitamos tenerlo descomprimido para intentar dilucidar algo de este, bastaría con procesador cno cwstofws o con Flasm para realizar tal tarea. La cuestión es que al finalizar, tendremos un archivo Juegos.swf completamente desencriptado y listo para asaltar.


  • Buscando los sistemas de protección

    Si logramos atacar directamente el archivo Juegos.swf y comprender sus secretos, no nos hará falta tener que lidiar con las protecciones dele cargador ni con volver a compilar los originales una vez modificados. Aquí por tanto entraría la fase pura y dura de Descompilación/Desensamblado del archivo Juegos.swf.

    Esto es sumamente simple con los programas adecuados, pero tenemos aquí el mismo problema, no puedo copiar/pegar código desensamblado/descompilado, puesto que no sería legal. Es legal hacerlo en casa y usarlo como mejor me venga, pero no distribuirlo, lo siento. No obstante si puedo ir diciendo a groso modo cuales fueron los pasos que realicé.

    En mi caso me bastó con usar un desemsablador como el de sothink, que en su versión Trial es más que suficiente, tan solo queremos echar un ojo. Podríamos haber usado otras herramientas como Flasm, pero por desgracia hace tiempo que no se actualiza y no es capaz de procesar los archivos Flash 10. Si descompilamos el archivo original con este programa, podremos tener acceso a todo el código original AS (ActionScript) de la gran mayoría del juego. AS no es muy complicado de entender, y cualquier programador amateurs debería ser más que capaz de interpretar casi todo lo que ve.

    Aun así hay que aplicar un poco la lógica. ¿Que estamos buscando? No se trata de leer el código de inicio a fin, no estamos tan locos, solo necesitamos información que nos pueda resultar útil para llevar a cabo nuestra tarea, como en el pasado pudo serlo en buscar la key o el sistema de cifrado del cargador. Lo primero es buscar la tabla o estructura donde se almacena cada uno de los objetos que hay en el juego: Casas, edificios, elementos de decoración… Dado que cada elemento tiene una serie de propiedades, lo más normal es pensar que en algún lugar del código se especifica dicha estructura. Con prueba error es fácil encontrarlo. Podemos comenzar buscando por ejemplo la palabra “house” (de Red House, o casa roja). Al primero o segundo intento nos toparemos de lleno con lo que parece sin duda alguna una estructura. No hace falta ser un Einstein para ver más o menos la estrcutura que están usando. Parece que usan un objeto estructurado en el que van almacenando uno a uno todos los datos relativos a dicho objeto, como el dinero que cuestan, el tiempo (en segundos) de fabricación, el “tuenti-Crédito” que cuesta en los objetos que son de pago… etc etc. Siguiendo la misma lógica vemos que la aplicación en ese punto del código está preparando lo que será la estructura que se mantendrá en memoria con todos los objetos del juego, lo cual es muy importante. Ya no solo porque de un plumazo tengamos acceso a TODOS los objetos del juego y sus parámetros, sino porque si somos un poco cuidadosos podremos ver el motivo por el cual no podemos usar el método de búsqueda en RAM de los valores del juego (dado que están protegidos). Si nos fijamos bien, muchos de los parámetros son pasados a la estructura por una función especial, llamada protectint o algo así. Es decir, una función que curiosamente se llama Proteger Enteros (números enteros). Es decir, algunos valores antes de copiarse a la estructura que quedará en RAM se pasan por una función extraña, que casi con toda seguridad modificará los datos de algún modo y devolverá unos datos diferentes, que serán los que serán almacenados y usados en toda la aplicación. Esta función es la responsable que nos sea imposible localizar valores en RAM relativos al juego.

    En realidad una vez que veamos esto, el resto es coser y cantar. Con un poco de suerte dicha función se encontrará definida e implementada en el mismo código del archivo Juego.swf. Si es así podemos comprender que está realizando exactamente, y una vez que lo comprendamos replicar dicho comportamiento, ya sea a mano si es simple o en C si es laborioso. Si rastreamos la función, veremos que en realidad la tarea que lleva a cabo es muy simple. Llegado a este punto sí puedo pegar el código que podemos encontrar en AS. Más que nada porque la función que han usado los amigos de MetroGames no la han desarrollado ellos, sino que prácticamente la han calcado a una usada en otro proyecto (que no es de ellos). El código de unos no es exactamente el mismo al código que voy a pegar aquí, pero vamos… lo que nos interesa es exactamente igual. El orignal lo podemos encontrar AQUI, en Google Code. Voy a pegar las funciones que nos interesan:

    private const ENCRYPT_CONST:int=286331153;
    private static const CONSTANT:int=1716716216;
    private static const ROUNDS:int=10;
    private static const POLY:uint=3172090000;

    public function ProtectedInt(arg1:int=0)
    {
    super();
    _value = encode(arg1);
    checksum = getChecksum(_value);
    var loc2:*;
    var loc3:*;
    var loc1:*;
    loc1 = protectIntCount++;
    protectDict[loc1] = this;
    return;
    }

    private function encode(arg1:int):int
    {
    var loc1:*;
    loc1 = undefined;
    loc1 = 0;
    arg1 = arg1 + CONSTANT;
    loc1 = 0;
    while (loc1 < ROUNDS)
    {
    if ((arg1 & 1) != 0)
    {
    arg1 = arg1 >>> 1 ^ POLY;
    }
    else
    {
    arg1 = arg1 >>> 1;
    }
    loc1 = (loc1 + 1);
    }
    return arg1;
    }

    private function getChecksum(arg1:int):int
    {
    var loc1:*;
    loc1 = undefined;
    loc1 = undefined;
    arg1 = arg1 + ENCRYPT_CONST;
    loc1 = 0;
    while (loc1 < 10)
    {
    arg1 = arg1 >> 1 ^ (arg1 & 1) * 2567483615;
    loc1 = loc1 + 1;
    }
    return arg1;
    }

    En realidad lo que realiza la función ProtectedInt() es simple. Según su implementación genera dos valores que serán los que finalmente serán almacenados. El valor real que será convertido por medio de la función encode (), y otro llamado CheckSum que será calculado respecto al valor ya convertido a través de la función getChecksum. Aunque no expongo el resto de las funciones que toman parte en ello, si indicar que cuando se lee o se establece un nuevo valor, la aplicación comprueba si este es válido o no por su CheckSum. Esto es muy facil de comprobar, la aplicación calcula con la misma función el checksum del valor introducido/leido y lo compara con el que tiene almacenado. Si coincide da por bueno el valor, si no coincide nos obliga a refrescar el navegador, e internamente computa un aviso con “Eres un tramposo” o algo similar.

Con esto ya tenemos todo, ya podríamos estar perfilando el final de todo esto. Tenemos lo fundamental, el código de protección usado para enmascarar la RAM y hacer inviable la modificación directa sobre ella. Esto lo realiza como hemos visto de dos formas. Primero codifica el valor por medio de una función, con el fin de que sea imposible su localización en la RAM a priori, además de evitar que el valor crezca o decrezca de forma predecible. Por otro lado, cada vez que se lee o se escribe un valor protegido se le comprueba el checksum para asegurar que el valor introducido/leido es válido. De este modo aun cuando supiésemos el lugar exacto en memoria que ocupa por ejemplo el dinero, tampoco nos serviría de nada poner números aleatorios con la esperanza de que uno de ellos al pasar por la función de codificación diese como resultado un número alto, ya que aun cuando se diese dicha casualidad, al comprobarse dicho valor contra el checksum almacenado, se invalidaría inmediatamente. Es decir, vamos a tener que jugar siempre con dos valores: El valor codificado y el checksum de dicho valor.


Apretando el Gatillo

Ya solo queda poner en práctica todo lo que se ha logrado, y aunque parezca mentira todos y cada uno de los pasos tenían un fin, completamente necesario para el siguiente paso.

Dado que tenemos acceso a las funciones de encriptación y checksum, siempre podríamos coger papel y lapiz, pero es evidente que sería muy poco práctico. Ya que hemos comenzando, no nos cuesta demasiado escribir unas líneas en C para implementar el comportamiento antes visto, es decir, algo así como traducir ese pequeño código de AS a C/C++. Podría terminar todo esto simplemente pegando el código de la mini aplicación que he creado para calcular dichos valores, o mucho mejor, subir la aplicación ya compilada para que cualquiera pudiese darle a ejecutar y entretenerse en hacer trampas. No obstante este no es el objetivo de este artículo. La experiencia nos dice que si le das un caramelo a un niño se lo va a comer, cuando a lo mejor solo querías enseñarle las personas que han trabajado en él. Así que si no publico ni lo uno ni lo otro, al menos estoy obligando a quien realmente quiera hacer trampas a convertir el código en C, compilarlo por él mismo y terminar él solo, no obstante si cualquiera tiene cualquier duda relativa al código en C a escribir o realmente quiere aprender con todo esto y se queda trabado en algún sitio, es libre de preguntar lo que desee. Espero que se comprenda.

Cuando todo se ha terminado, tendremos disponible una pequeña aplicación llamada Towner.exe que al ejecutarla nos pediría por pantalla un número. Al darle a enter nos calcularía tanto el valor codificado como el Checksum asociado a dicho valor. Esos dos valores son los que nos servirán para buscar en la RAM. Por ejemplo, si tengo 10 millones de monedas y quiero saber donde y como está almacenado en RAM dicho valor, tendré que pasar por el programa el número 10 millones. Será el nuevo valor obtenido el que busque en RAM. Es por eso que en realidad no es necesario realizar el proceso de desencriptado del valor, solo el de encriptado. Del mismo modo si quisiese modificar el lugar en el cual se almacena mi dinero, una vez que tengo el lugar localizado, buscando previamente por el valor almacenado en RAM, calcularía un nuevo valor (por ejemplo 500 millones). Ya solo tendría que sustituir en RAM los valores viejos (el valor y el checksum) por los valores nuevos. Veamos todo esto con algunas pantallas, supongamos que deseamos cambiar el tiempo de construcción de TODOS los elementos de 24 horas a 1 segundo:

  • Necesitamos conocer el valor real y el checksum que el juego guarda en su estructura interna, que está RAM

    queremos cambiar de golpe TODOS los tiempos de fabricación de 1 día a 1 segundo. Los tiempos, como vimos en el código, se expresan en segundos, luego 24 horas = 86400 segundos. Lo primero por tanto será calcular el valor codificado y el checksum de 86400:

  • Una vez conocido los valores, encontrar sus posiciones en la RAM

    Podemos utilizar por ejemplo CheatEngine o WinHex para encontrar la posición de dichos valores. Una gran ventaja de que los valores estén codificados, es que es muy poco probable que en la zona de memoria que vamos a buscar se encuentren otros valores iguales que no pertenezcan a la estructura de objetos. De decir, si buscásemos por ejemplo el valor 86400 es posible que apareciese cientos de veces en toda la RAM asignada a plugins-container.exe, incluso aun cuando dicho valor fuese el real guardado por la estructura de datos!! lo que significaría tener que filtrar todos aquellos que no perteneciesen a la misma estructura de datos. Una cosa es modificar una estructura de datos en la que sabemos que estamos haciendo, y otra muy diferente modificar posiciones de memoria que no sabemos a que se están usando!! Aviso, modificar la RAM puede tener resultados fulminantes e inmediatos si modificamos lo que no debemos, es de suma importancia saber siempre que estamos modificando con seguridad. En cambio, el valor 4014934722 es mucho menos probable que sea encontrado sin que pertenezca a dicha estructura. De todos modos una de las medidas de protección es también una ventaja, el Checksum. Dado que existe un CheckSum por cada valor protegido, si encontramos 100 instancias de un valor y solo 50 de su CheckSum pareja, podremos filtrar sin problema alguno los 50 que NO SON nuestro objetivo y que pertenecen simplemente a otro proceso o es memoria sin uso.

    Con esto, debería de ser muy simple encontrar las posiciones. Para el valor = 4014934722, obtenemos 131 instancias, para el CheckSum = 794834924 otras tantas, luego podemos estar más o menos seguros que son todas instancias o valores que usa el juego para un valor de 86400 segundos (24 horas). Ojo!! No estamos filtrando más, eso quiere decir que en esas 131 entradas estarían no solo los tiempos de construcción de todos los objetos de 24 horas, sino también por ejemplo aquellos tiempos de reparación que son también 24 horas. Es decir, cualquier parámetro con un valor de 24 horas que el juego pueda usar, entre ellos por supuesto los tiempos de fabricación:


  • Una vez tenemos las 131 x 2 posiciones, calculamos el nuevo valor para 1 segundo y los introducimos.

    Queremos modificar los tiempos a 1 segundo, eso implica que debemos calcular con nuestra pequeña aplicación los valores para 1 segundo. Por motivos más que obvios no voy a poner los valores tanto de 24 horas como de 1 segundo, o algún listillo tendría todo lo necesario para al menos realizar dicha modificación.

    Una vez tenemos los valores correcto, tan solo tenemos que modificar las 131 primeras entradas por el nuevo valor, y las 131 siguientes con el Checksum correcto.



Conclusión

¿Cual es el resultado a todo esto? Bueno, del ejemplo anterior sería este:


Y por supuesto dichos edificios pasarían a tardar tan solo 1 segundo en construirse. Podría haber optado por mostrar que sucede al modificar la experiencia o el dinero, pero este cambio tan solo tendrá efecto mientras no vuelva a cargar el juego, dado que no son datos que se guardan en el servidor. Repito que esto tiene tan solo fines teóricos y didácticos, no queremos tramposos entre nosotros.

Una vez que tenemos la “formula de oro” el resto es solo la imaginación. Por ejemplo si estableciésemos un cero al precio de las tuentimonedas del cohete, podríamos crear tantos cohetes quisiésemos sin pagar nada, o tener acceso a objetos de otros niveles, o completar aquellos logros que aun nos faltan, como por ejemplo el de la fabricación de 10.000 casas.

 

El objetivo de este tipo de artículos continúa siendo el mismo, el darles un tirón de oreja a los programadores despistados que trabajan con este tipo de tecnologías. Ya no solo a los amigos de MetroGames, sino a cualquier otro que esté embarcado en proyectos similares. De echo hay que decir que los amigos de MetroGames no han hecho un trabajo demasiado malo protegiendo sus intereses. Quizás el usar un cifrado XOR simple sea demasiado cutre, aunque es verdad que simplemente con ello te quitas de un plumazo a todo aquel listillo que intenta descargar manualmente la aplicación Flash Juego.swf, y se lleva la sorpresa de que aparenta ser un archivo corrupto, cuando en realidad está cifrado. Sobre las protecciones que implementan para enmascarar la RAM en realidad es que no pueden hacer mucho más. Se podría intentar complicar, por ejemplo usando funciones propias de AS que fuesen muy difíciles de implementar en otros lenguajes como en C, lo que añadiría mayor complejidad al asunto. Pero bueno, no voy ahora a pensar posibles mejoras del juegecito, primero porque no me pagan para ello y segundo porque creo que ya he invetido suficiente tiempo en ello.

Un saludo a todos, y en especial para mis… “sobrinos”, sin los que sin duda no habría tenido interés alguno en destrozar este juego de Facebook y Tuenti.

Firefox 3.7: Aceleración por Hardware y una de Navegadores

Share on Google+Share on FacebookTweet about this on Twitter

No soy muy dado a este tipo de entradas, pero mientros concluyo con el último capítulo de Encriptación y Autentificación me he animado a decir algunas palabras sobre lo que está por llegar por parte de Firefox.

Firefox abrió la guerra de los navegadores hace unos años. Nadie apostaba por él, pero en cambio demostró no solo ser mucho más seguro que la competencia (IE, Opera y Safari básicamente), sino que también mucho más rapido. Por otro lado, la sustitución de los peligrosos ActiveX por complementos o temas hizo que Firefox ganase adeptos cada día que pasaba.

Tanto Opera como Safari viendo lo que pasaba creyeron que podían seguir los pasos de Firefox e intentar robar cacho a IE, cosa que tan solo Firefox estaba logrando arrancar a base de bocados. Microsoft por su parte no le dió más importancia hasta que Firfox se había convertido realmente en una opción más que viable y con un mercado bastante amplio, lo que hizo a MS sacar su IE 7 y posteriormente IE8, francamente una chapuza cada uno de ellos.

Explotó de nuevo la guerra, Opera y Safari querían tajada y Google quiso unirse a la fiesta con Chrome. Superar a Firefox en cuanto prestaciones y versatilidad resulta imposible a día de hoy, por lo que tanto unos como otros se han centrado los últimos meses simplemente en optimizar código, mejorar el engine JavaScript para mejorar los tiempos de renderizado de webs y cosillas similares. Esto se ha logrado hasta tal punto que a día de hoy sin duda alguna el navegador más rapido renderizando una web es sin duda alguna y con diferencia Chrome, seguido de Safari y Firefox más o menos en igualdad de condiciones, por detrás a corta distancia Opera y en último lugar y muy alejado IE.

Aquí hay que ser realista y tener mucho cuidado con los test que se realizan y quien los haces, así como conocer un poco cada navegador. De no hacerlo, los test no valen absolutamente para nada, y entra el fanatismo y la publicidad gratuita. Esto tampoco significa que cada navegador vaya orientado a un grupo diferente de usuarios, exceptuando quizás IE y Safari, que se quedan descolgados del resto por falta de “utilidad”.

Como hemos dicho, Chrome de Google es con diferencia el navegador más rápido a la hora de renderizar una web, pero en contrapartida también es con mucha diferencia el navegador más simple y menos cargado de todos. Optimizar un código de un millón de líneas es más complejo y difícil que optimizar un código de 100. Esto no hace a Chrome ni mejor ni peor, simplemente es un navegador ligero, actualmente no demasiado versátil si lo comparamos con Firefox, pero es que su planteamiento es muy diferente que el que hizo crear por ejemplo Firefox. Tiene una tasa de mercado entorno al 6%

Tanto Safari como Google usan el mismo motor de renderizado, WebKit, el cual hace que los dos compartan el mismo alma por así decirlo. Esto no quiere decir que sean iguales ni mucho menos, pero por ejemplo comparten prácticamente los mismos estándares y muchas funciones. Safari no es un navegador ya de por sí con muchas funcionalidades y se ha demostrado que es bastante “inseguro” en comparación con la competencia. Esto hace que no tenga un mercado claro, lo mismo que le ocurre a IE, lo que hace que sus usuarios (el 99% usuarios de MAC OS) usen en sus ordenadores (o se planteen) otros navegadores como Chrome o Firefox.Tan solo cuenta con un 4% aproximadamente de mercado, y desde hace ya tiempo va perdiendo cada día mas usuarios, aunque de muy poquito en poco. Resulta curioso que si tenemos en cuenta que tanto Windows como MAC OS usan navegadores predeterminados diferentes, y que tanto Chrome como Safari están disponibles ambos para MAC OS y Windows, es simplemente impresionante que Chrome ya haya superado en índice de mercado a Safari, sin siquiera tener OS propio (quitando Android o el OS Chrome)

Opera es un caso extraño. Opera lleva en el mercado muchos años, y siempre ha tenido un buen rendimiento, seguridad y versatilidad. En cambio por una extraña razón, aun cuando Firefox no era una opción y tan solo existía IE, Opera nunca gozó de “suerte” o siquiera de demasiada aficción. Tengo que reconocer que antes de Firefox era mi navegador por defecto y tenía ciertas cualidades que me parecían bastante interesantes, como en aquella época era el renderizado de webs para móviles por ejemplo. Opera ha mantenido más o menos siempre la misma cuota de mercado, un 2-3%. Aun después de todos los esfuerzos de Opera, tiene en estos tiempos un problema añadido: Firefox y Chrome. El primero por ser con diferencia (desde mi punto de vista) el mejor navegador en términos generales del mercado, y el segundo tiene Google detrás, por no decir que es un navegador actualmente bastante eficiente. Esto me temo que hará que Opera continúe su camino en “solitario”, y sinceramente… tienen todo mi respeto, siempre han estado ahí, y eso se agradece, no hay que olvidar que muchas de las innovaciones que hoy por hoy tenemos en los navegadores se las debemos a ellos.

IE, Internet Explorer… bueno, me temo que microsoft tiene actualmente la guerra perdida. Se mantiene a salvo simplemente por una cuestión llamada Windows, y que actualmente con las nuevas leyes de seleccionar navegador perderá aun otro trozo más de mercado. Día a día IE pierde cuota de mercado, situándose actualmente en torno al 60%. Si tenemos en cuenta que Windows lo tiene preinstalado y que Windows se usa en más de un 90% de los ordenadores, es impresionante que Firefox esté ganando terreno. No es tan impresionante si tenemos en cuenta que IE es una porquería. Quizas ya no en seguridad como siempre se critica (que también), sino por el rendimiento tan pobre que tiene, la falta de estándares que soporta y las pocas funcionalidades que nos ofrece.

En último lugar y lo que me ha hecho escribir estas líneas, Firefox. Firefox no solo comenzó siendo una posible alternativa más rápida y segura q IE, sino que pronto se convirtió en toda una plataforma eficiente para la navegación y desarrollo web. Son innumerables las extensiones ¡ÚTILES! que tenemos, y por supuesto para los amantes de la estética los temas. Firefox es simplemente rápido (aunque no el que más en términos generales), Compatible (aunque no el que más) e increíblemente versátil. Pero tiene otro AS en la manga, y es aun lo que puede dar de sí.

No voy a entrar por tanto si mejor Safari, si mejor IE o mejor Opera. De los tres más cariño a Opera, pero si tengo que ser franco, aunque en su última versión (creo que se ha liberado ya la 10.5) es muy rápida, situándose más cerca de Chrome y por encima de Safari y Firefox, no creo que marque una diferencia significativa, a fin de cuenta la velocidad no lo es todo.

Chrome se diseñó simplemente para dar agilidad a la navegación. Creado de Cero para ello, la preocupación de los desarrolladores no era crear extensiones o añadir funcionalidad, simplemente ser el más rapido. Y lo logró. Y si tu que me lees lo único que quieres o deseas de un navegador es velocidad a la hora de renderizar una web, actualmente Chrome es lo mejor que puedes tener… actualmente. Si deseas algo más, Chrome no te lo va a dar, al menos por ahora y en mucho tiempo.

Firefox… al ser un proyecto de código libre como Chrome tiene muchas ventajas. Primero que es mucho menos vulnerable a ataques externos, con lo que es mucho más seguro. Por otro lado es la propia comunidad quien crea, mejora, aporta… Actualmente el proyecto Firefox tiene una aceptación impresionante, es una plataforma poderosa y eficiente.

En cambio parece que lo que fue una virtud para él, su velocidad a la hora de renderizar páginas, ahora al estar tan de moda en laa competencia parece ser que deja a Firefox en una posición inferior, vulnerable. Ahora parece que todos los navegadores son rápidos y eficientes. Pero como hemos dicho hay mucha trampa en ello. Para comenzar, Firefox es realmente muy rápido, lo que sucede es que casi todo el mundo tiene más de un y dos complementos cargados, muchos de ellos consumen bastante memoria, lo que hace que el navegador sea en su conjunto más lento. Si desechásemos todo aquello que hace de Firefox tan versatil y útil, su rendimiento aumentaría considerablemente. A fin de cuenta no se puede tener todo en este mundo… ¿o si? Pese a ello, es evidente que Chrome está bastante por encima de Firefox y aun arrancando Firefox sin nada, Chrome es más rápido.

En cambio Firefox tiene un par de ases en la manga. El primero, el cual ya ha pasado a versión Alpha, (y que es el motivo de este artículo) se llama DirectWrite, aceleración por hardware para el navegador. El segundo, aun en fases relativamente iniciales se llama Electrolysis.

En las últimas build de Firefox, Firefox 3.7a3pre, se ha incluido ya soporte para DirectWrite, una tecnología que proviene de Directx, soportada por las tarjetas de video (mínimo Directx9, recomendado DirectX10+) y tan solo Windows 7 o Windows Vista. La idea es simple, dotar al navegador la capacidad de usar la tarjeta de video para las siguientes tareas:

  • Disminuir notablemente el renderizado del texto e imágenes
  • Aumentar exponencialmente el rendimiento al procesar archivos SVG o el manejo de rutinas de transformaciones de objetos
  • Aumentar la calidad tanto del texto como de las imágenes visualizadas

básicamente, podemos simplificar todo ello y decir que se logra disminuir de forma notable el tiempo de procesar páginas web de cierto tamaño (este blog es una buena prueba de ello, por la cantidad de texto en cada página), el más que evidente suavizado de las fuentes (lo cual hace que la lectura en el navegador sea más comoda y “bonita”, ya este el texto escrito en horizontal, vertical, diagonal… las fuentes siempre se verán perfectamente), y por supuesto la representación de gráficos 2D, ya sean imágenes, transformaciones de estas o gráficos vectoriales SVG.

Personalmente antes de ponerme con ello pensé que era una mejora relativa, pero la verdad es que el resultado es inmediato. Simplemente la propia estética del navegador mejora con el más que notable suavizado de fuente y otros pequeños detalles. Más tarde, comencé a testearlo con pruebas más concretas, y es cuando en algún que otro ejemplo dije: “Joder…”.

Normalmente estamos acostumbrados a que nos incluyan mejoras de las cuales no solemos percatarnos. Me pueden decir que el navegador es más rápido, pero por muchos test que me enseñen yo quiero ver que esto es verdad cuando navego yo, no cuando ejecuto test especializados. Y por ahora las pruebas que tengo es que efectivamente DirectWrite en Firefox se nota. Es curioso no obstante, ver como muchos de los benchmark que existen actualmente no tienen en cuenta este tipo de factores a la hora de puntuar un navegador. Todo el mundo se está preocupando actualmente en mejorar sin límites los motores JavaScript, pero no es lo único importante. Sí, es evidente que JS es muy importante, pero no lo es todo. Muchos de los test actuales se limitan a comprobar el tiempo de ejecución de los diferentes scripts JS que tienen para comparar resultados… y eso es válido, pero solo para JS. El único benchmark relativamente fiable y completo pueda ser Peaceckeeper, y para el resultado final especifica que no tiene en cuenta el rendimiento 2D, dado que no todos siquiera lo soportan.

Vale, todo esto es mu bonit0, pero ¿donde está la pega? ¿Cuando? ¿Dónde?

Bueno, tiene inconvenientes. Por ejemplo que tan solo es posible usar esta tecnología en Windows Vista o Windows 7, es decir, por ahora entre ambos tienen un 30% quizás de mercado, dado que Windows 7 ya ha superado el 10%. Por otro lado requiere de una tarjeta de video no demasiado antigua y relativamente actualizada, lo cual tampoco debe de ser un problema para todos aquellos que disponen de Vista o 7, dado que lo “normal” es que dispongan de una tarjeta de vídeo que soporta DX9+.

¿Cuando? Actualmente ya ha sido implementada en Firefox 3.7 Alpha. Por experiencia puedo decir que generalmente cuando una función pasa a implementarse a Firefox, normalmente en las fases Alpha, suelen fallar una y otra vez, y poco a poco con las diferentes Builds se van corrigiendo los problemas. En cambio DirectWrite parece ser bastante estable, lo cual agilizará el desarrollo y pulido de este. Cuando pude probar esta nueva tecnología, es cierto que las dos primeras build tenían algunos problemillas, como algún parpadeo que otro del navegador y cosillas por el estilo. Desde ayer no he observado ningún problema ni bug sobre esto, lo cual es más que positivo. Firefox 3.7 está actualmente en fase Alpha 3 desde hace relativamente pocos días. Si todo marcha bien podría ser necesario tan solo una versión Alpha más o incluso liberar ya la Beta 1. Una tres versiones Betas, otras tantas RC (Release Candidate) y dispondremos de Firefox 3.7 final. Las build no obstante las tenemos prácticamente de forma diarias, actualmente como digo, las build corresponden a lo que será dentro de poco la liberación oficial de Firefox 3.7 Alpha 3. Todo ello lo que implica es que todos aquellos que quieran verlo implementado de forma “versión final”, tendrán que esperar hasta el lanzamiento de Firefox 3.7 (o quizás sea llamado Firefox 4).

¿Donde? No obstante, no implica que cualquiera pueda comenzar a utilizar estas funciones, solo tiene que comprender el riesgo y “dificultades” que pueden presentar usar compilaciones diarias. Sí, te garantizan estar usando lo último de lo último, pero evidentemente no siempre todo funciona bien… es más, casi nunca funciona todo bien. Por ejemplo, otra característica añadida, ha estado fallando muchísimo durante al menos una o dos semanas, hasta que se ha ido arreglando poco a poco.

Firefox 3.7 no solo nos dejará este buen sabor de boca. La otra función que ya está añadida a la versión Alpha 2 ha sido el comienzo de lo que será una parte de Electrolysis. En este caso concreto, se ha separado del nucleo del propio navegador los plugins. Con plugins no me refiero a las extensiones, sino a Adobe Flash, Java… anteriormente todos ellos corrían de una forma u otra dentro del propio navegador, lo cual hacía que si por cualquier circunstancia dicho plugins fallaba, el navegador entero sufía las consecuencias. Ahora se ha separado a otro proceso. Si algún plugins falla, el navegador no se verá afectado, simplemente será necesario refrescar la web que ha dado el problema.

¿Como? Todo aquel que quiera comenzar a usar estas características tendrá que una versión Build, lo cual no es recomendable para la gran mayoría:

Firefox 3.7a3pre

Una vez instalada, se debe de habilitar dicha opción. Dado que es una opción aun en desarrollo, no se encuentra activada por defecto. Para ello es necesario acceder a la ventana de configuración avanzada de firefox, que para quien no lo sepa, se accede tecleando en la barra de direcciones lo siguiente:

about:config

Una vez realizado, veremos un listado con cantidad de configuraciones. Buscamos en nuestro caso dos entradas concretas:

a) gfx.font_rendering.directwrite.enabled -> Cambiarlo a True
b) mozilla.widget.render-mode -> Cambiarlo “6” (sin las comillas)

con esos dos cambios, tan solo reiniciar. Si reunimos las condiciones suficientes, nos daremos cuenta inmediatamente, aunque solo sea por el suavizado de la fuente. Ni que decir tiene que Thunderbird ya incorpora estas mismas funcionalidades en sus build más actuales, y se habilita exactamente igual.

¿Algunos ejemplos sorprendentes?

PNG girando a gran velocidad
Globo -> Esta es realmente sorprende, probarla antes y después. De ir a trompicones y no poder a ir completamente fluido
Google Maps

¿Esto es todo?  No, aun no hemos hablado de Electrolysis, aunque aun tardará en ver la luz.

Aunque en ningún sitio lo dicen, tanto IE, Safari, Opera y Chrome usan las prestaciones de los ordenadores multi-nucleos o multiprocesador. Firefox no. Sí, no es broma, Firefox actualmente tan solo usa un núcleo. El proyecto Electrolysis separará en tres la carga del navegador. Por un lado las pestañas, por otro lado los plugins y por otro la interfaz. Con las últimas build, los plugins han logrado ser separados del nucleo con éxito, es tan solo el comienzo de Electrolysis. Cuando el proyecto haya concluído y todo esté integrado en Firefox, se espera que el rendimiento de Firefox se acerque prácticamente a rozar Chrome, esperando en principio una duplicación/triplicación de rendimiento a la hora de renderizar webs.

Es decir, tiene una carta que ya todos los navegadores han usado. Esto no quiere decir que no se pueda optimizar aun más el motor JS de Firefox o mejorar todo en su conjunto. Esto quiere decir que gracias a Electolysis Firefox será considerablemente más veloz y seguro. Cuando se separe el contenido web del núcleo de Firefox, cualquier pestaña que deje de funcionar no afectará al comportamiento del resto del navegador, será aun más complicado que u exploit afecte al sistema, el sistema responderá mucho mejor en cualquier tarea. Es decir, pensar en lo que se tiene actualmente, y multiplicarlo por 3.

Actualmente se encuentra en la segunda fase de desarrollo. Quitando la separación de los plugions, el resto no ha sido implementado (y no lo será) en Firefox 3.7. Depende de a la velocidad que avance el proyecto podremos verlo antes o después, esperemos que podamos disfrutarlo en este año. Tener en cuenta que no hablamos de una pequeña modificación al navegador, sino tocar en lo más profundo de este y de como está cimentado.

En un par de meses aproximadamente la versión 3.6.2 de Firefox debería de estar terminada. Con ella, la separación de los plugins, ¿soporte DirectWrite,? Actualizaciones no intrusivas, velocidad al arrancar, una GUI un tanto mejorada… no será sino hasta Firefox 4.0 cuando Electrolysis esté integrado completamente en Firefox, junto con una interfaz bastante cambiada (más similar a la de Chrome), JetPack (que será uan nueva forma de crear extensiones) y Weave (Que permitirá poder sincronizar “navegadores”, pudiendo tener en dos disposivitos diferente los mismos favoritos, contraseñas, historiales… todo de ello de forma completamente segura).

Firefox no está muerto, le queda mucho rodaje. Es una de las aplicaciones que tengo que decir más sigo porque sinceramente lo merece. El trabajo realizado sobre él es increible, y mejora cada día. Estoy deseando que la versión 3.6.2/3.7 sea liberada para comenzar a probar Firefox 4.0. Aunque Chrome es una muy buena alternativa, actualmente prefiero Firefox. El tiempo que me ahorra gracias a sus extensiones y a la gran personalización que me da, hace que sea perfecto a mis necesidades. Por supuesto el rendimiento es importante, y es bueno ver que están en ello. No pasará mucho tiempo en que podamos ver a Firefox compitiendo con Chrome por el navegador más veloz también. Y sin olvidar por supuesto que Chrome no es ni la mitad de la mitad de lo que es hoy en día Firefox.

Un saludo a los lectores y a toda la comunidad de Mozilla por su increible trabajo. Da gusto comprobar una vez más que el software libre es la mejor opción. Prometo volver a escribir sobre esto cuando lo dicte el momento.Y con ello, ya puedo volver a terminar el capítulo sobre seguridad.

Apple comienza a banear IDs de usuarios que tienen su dispositivo JailBreak

Share on Google+Share on FacebookTweet about this on Twitter

La noticia llega de forma inesperada para muchos… y es que parece ser que Apple en un intento muy agresivo por su parte estaría comenzando o pensando en suprimir aquellos IDs de dispositivos que están JailBreak. Es decir, que si Apple detecta de modo alguno que tu iPhone o iPod Touch ha sido JB podría añadir este a una lista negra e impedir todo acceso al AppStore, siendo claro el resultado de esto, imposibilidad de poder comprar por iTunes canciones o aplicaciones para tu dispositivo.


 

Cortesía de Neowin.net

 



Apple se ha visto presionado por las compañías móviles y por sus propias ganancias. Su objetivo es evitar por todos los medios que el iphone o el ipod touch pueda ser un sistema abierto que ellos, Apple, no pueda controlar. Al margen de si es legal o no sus actuaciones, recordemos que el JB no es un procedimiento ilegal a día de hoy, y posiblemente no lo sea nunca. Luego si no es un proceso ilegal, es posible que Apple legalmente no tenga ninguna autoridad para denegar un servicio a un cliente por un acto legítimo, que en todo caso tan solo rompe las condiciones de la garantía.

Al margen de ello, lo que está claro es que Apple está intentando por todos los medios proteger su gallina de los huevos de oro que cada día que pasa pone menos y menos huevos. El índice de adiciones de aplicaciones en el Store de Apple disminuye considerablemente, el iPad (aun cuando hay que esperar) presagia un varapalo para Apple, El Nexus One comienza a asentarse y demostrar que no solo es un hardware muy superior sino que por un lado o otro otro el iphone irá cayendo poco a poco en el recuerdo. Ante todo esto Apple lo tiene claro, moverse rápido e intentar exprimir lo que queda.

De nuevo vemos una política de empresa completamente restrictiva y que cercena la libertad de los clientes. A fin de cuenta lo único que pretende Apple es el control de sus clientes. Cuando compras un iPhone 3GS no tienes BT, el video es malo, los mms son malos, no tienes acceso al sistema, ni siquiera puedes copiar un archivo. En contraste cualquier dispositivo similar actual permite no solo hacer todo ello, sino que algunos como el Nexus One te permite si lo deseas modificar a voluntad el sistema, sin pérdida de garantía, sin crispaciones, sin tonterías.

A fin de cuenta, todo se ve reflejado en números, y los números dicen que Google aumentó sus beneficios en más de un 50% en el año 2009 frente al 2010.  Es una pena que muchas empresas no comprendan que el cliente es al final quien paga tus facturas, y que por mucho que intentes engañarlos, al final responden.


Es por noticias como estas por las que uno se para a preguntar por qué cometio el error de comprarse un iPod Touch (en mi caso particular) o un iPhone, o cualquier producto de Apple. Ya no es una cuestión siquiera de dinero (Que son los productos más caros), ya no es una cuestión siquera de que sea lo mejor o peor (que no es lo mejor)… se convierte simplemente ya en una cuestión de principios.

Hace unos años cuando adquirí mi iPod Touch estaba contento con la compra, tan solo hay que remitirse a mis post más antiguos. Foros, blogs, investigaciones propias, aprendizaje… comprendía en parte las tonterías de Apple o eso creía. Excusas que se da a uno mismo para no tener que aceptar la inversión de un buen capital en algo que no lo vale. Después de un año, de dos… la perspectiva es muy diferente. Te cansas de las noticias inverosímiles, de los fallos de software y de hardware, de las carencias… pero ya no de las que puedas encontrar tu mismo!! sino en las preguntas de siempre de otros usuarios: no hay modo disco? no puedo enviar un archivo por bt? no puedo….? Y por otro lado veo el mercado que ha expandido para ofrecer productos no solo más baratos sino muy superiores!! y aun así tienes que oír a representantes de Apple escuchar frases como: “Muchas de las veces que se queda colgado un MAC es por culpa de Flash” . “La salida de Windows 7 implicará para nosotros un gran incremento en ventas”, “La garantía queda anulada porque su MAC ha estado expuesto a un ambiente tóxico, ambiente de fumadores”… y tantos otros.

Personalmente me pregunto sinceramente en que momento Apple vendió su alma en post de engañar a algunos cuantos. ¿Hoy? Simplemente otro granito más, A bloquear IDs que tengan dispositivos JB. Que por cierto, personalmente no creo que sea una idea mu positiva, lo que lograrían sería que la comunidad usase más Cydia o la búsqueda de aplicaciones piratas, aumentando aun más la piratería.

Pero esto es así. Apple es así. De cada 100 ideas de Apple, 1 revoluciona el mercado y es una idea grandiosa. Las otras 99 ideas hacen que la opinión publica (al menos la mía y la de muchos otros) piense que se cometió el error una vez en comprar algo con una manzana.

Este blog se creó en sus orígenes precisamente por el iPhone y el iPod Touch, creo que no se puede pedir que sea más imparcial, cuando todo fue para ayudar, alentar y aconsejar positivamente. Pero hace ya tiempo que esos tiempos acabaron, y no hizo falta mucho para darme cuenta de ello.

Por mi parte? Nunca Máis Apple, Nunca Máis.

Proyecto: Adrianne I

Share on Google+Share on FacebookTweet about this on Twitter

Antes de comenzar, citar posiblemente a quien me inspiró a ello, y en cierto modo me ayudó a comprender algunos conceptos y me enseñó por donde buscar, por así decirlo: Bilalt, aunque desgraciadamente no conozco su nombre real y hace ya años que “desapareció”.

Voy a ir intentando completar este “reto personal”. Entre otras cosas, siempre me sentí atriado por los gráficos 3D, aunque no quiero decir con esto los juegos, sino el diseño 3D, como crear esos mundos increibles que tanto estamos acostumbrados a ver.

Por otro lado debo de decir que no me puedo consuderar ni mucho menos un gurú en la programación. Lo suficiente quizás para ser capaz de crear el programa que sea con algo de tiempo, pero dudo mucho que este pudiese estar a la altura de un verdadero programador como los que hay, auténticos genios en su campo. Pero por el lado positivo, la informática me ha enseñado que todos los campos dentro de ella de alguna u otra forma están relacionados, lo que quiere decir es que para mi es más facil que para la gran mayoría enfrentarme a un problema concreto (claro está, informáticamente hablando), sea de programación, de diseño… hasta el punto que aunque un genio de la programación sea capaz de hacer lo mismo mucho más eficientemente y más rapido que yo (sin duda alguna), yo tengo ideas o caigo en una serie de cosas que para otro normalmente serían muy complejas o siquiera las tendría en cuenta.

Todo esto me ha ayudado a la hora de poner en marcha Adrianne. A todo esto… quien es Adrianne? Esta es Adrianne:

Con cada serie de nuevas tarjetas gráficas, nVidia ordena crear una Demo especialmente diseñada para ella, intentando poner al máximo sus prestaciones. Hace unos años, con el lanzamiento de la serie 8 de nVidia, nos deleitaba con esta Demo. Se trata de Adrianne Curry si no recuerdo mal, creo que era una PlayMate que se prestó para tal exhibición.

Evidentemente no pretendo obtener un resultado similar. Mi idea es ser capaz al menos de renderizar el cuerpo entero de ella poligonalmente con un mínimo de iluminación, y como un “imposible” dejaría abierta la posibilidad de texturizar el modelo.

En realidad el reto que me propuse pasaba simplemente por ser capaz de realizar un parser para los arcihvos nmb, que son archivos propietarios de nVidia en los que se encuentra toda la geometría de los diseños 3D de estos. Es decir, en el caso de Adrianne, el archivo “geo_model.nmb”contiene toda la información sobre el modelo 3D Adrianne. Al ser un archivo propietario, a menos que llame a la puerta de nVidia y les pida por favor la estructura interna de este, el trabajo a mano a realizar es increiblemente grande. Hay que tener en cuenta que para mis ojos, tan solo es un archivo binario de 64MB, sin aparente información usable en su interior. Luego antes de ser capaz de renderizar nada, lo que tengo q hacer es ir interpretando poco a poco cada bloque hexadecimal de tan ingente archivo. Mi proyecto principal no fue con Adrianne, sino con Dawn, una Demo más antigua. Pero a fin de cuenta la estructura de ambos es muy similar, la diferencia es que ADrianne está en 64MB, y Dawn en tan solo 13MB. Es mas, tan solo la cabeza de Adrianne es más compleja que todo el modelo de Dawn.

Antes de poder hacer nada, la primera etapa es por tanto crear un pequeño Engine gráfico, la creación de un pequeño espacio tridimensional en el que poder representar puntos, polígonos… esto no es algo complicado, sobre todo con la cantidad de información que tenemos en internet. El problema claro está es comprender los ejemplos, el código, cada instrucción… y adaptarlo todo de la mejor forma a nuestro proyecto.

En mi caso he usado OpenGL como render, y GLUT para facilitarme el jugar con las coordenadas espaciales y la perspectiva.

Una vez la plantilla principal del engine está creada, el paso siguiente es verificar si dicho archivo, “geo_model.nmb” realmente contiene la información geométrica de Adrianne, y por supuesto verificar si el engine gráfico funciona. Aquí es donde tenemos que poner a funcionar el cerebro.

Lo más simple de todo, como no tenemos idea de la estructura interna del archivo de nVidia, es intentar renderizar todo el archivo como si fuese todo él un array de puntos. Pensar en un polígono. Su esencia última es el triángulo. Un triangulo se representa por 3 vértices. En cualquier archivo de geometría, lo que más debe de abundar con diferencia son vértices. Los vertices posicionarán los polígonos (triángulos) en el espacio tridimensional, los vértices de las normales serán los que indiquen el vector normal, usado para conocer la cara poligonal que recive la luz o por ejemplo también los vertices de los vectores tangenciales. Con esto quiero decir que de dicho archivo, de ser cierto, el 90% deberían de ser coordenadas espaciales.

Un vértice en un espacio de tres dimensiones se representa por 3 coordenadas x, y z. Si es un espacio bidimensional, usado por ejemplo en el mapeo de las texturas hacen falta tan solo 2 coordenadas u, v. Pero volviendo al tema principal, mi primer parser podría consistir simplemente en leer todo el archivo e interpretarlo como he dicho como un array de vértices. Un vertice normalmente se considera un numero de tipo float (numeros en coma flotante), un tipo de representación numérica, que es usada muy comúnmente cuando se necesita una resolución muy grande o muy pequeña. Un float se representa por medio de 32bits, es decir 4 bytes. Dicho esto, la primera aproximación a realizar es interpretar todo el archivo como una hilera de bloques de 32bytes, en el que se repetirá constantemente el patrón: X, Y, Z. Es decir, los primeros 4*3bytes del archivo serían el vértice 1: la componente X la componente Y y la componente Z. Los 3 floats siguientes se interpretarían como el vértice 2 con sus tres componentes… así sucesivamente.

Renderizar esto es facil, tan solo tenemos que cargar el archivo en memoria y desde nuestro engine hacer q se se representen en pantalla los vértices contenidos en nuestro buffer o la estructura creada. En mi caso he usado una estructura de este tipo:

Typedef Struct {

float x, y,z;
}vertices;

vertices *buffer;

Es decir, creo un array buffer de tipo vértices.Una vez todo está preparado, en el mismo engine tan solo tengo que llamar a este buffer y representar todos los puntos con un bucle simple for, que recorra todo el array. Previamente se ha calculado el número de vértices que tendría el archivo. Esto es facil, si he interpretado que todo el archivo en sí es un conjunto de vértitces, tan solo tengo que conocer por medio de ifstream el tamaño del archivo. Una vez conocido el tamaño del archivo en bytes, dividirlo entre 4 bytes (1 float = 4bytes) y después dividirlo por 3 (cada vértice tiene 3 componentes). El número resultante son los vértices. Por medio de new creo un array dinámicamente.

Cuando todo ello está terminado, con un for recorro todo el array, representando en cada momento el supuesto vértice:

glVertex3f (buffer.x, buffer.y, buffer.z);

Pero para poder lograr tener más información de todo ello, hago que dependiendo del puntero de nuestro buffer (la posición de este) me represente cada punto de un color u otro. Para ello divido el numero de vértices en 4, y el resultado será la umbral de cada trozo. De esta forma si el punto representado se encuentra en el primer cuarto del archivo, se representará de color rojo, si corresponde al segundo verde. Blanco si es al tercero y azul si es al cuarto. Esto es simple con una instrucción if y glColor3f.

Por último queda pensar en algo… de funciona, hemos presupuesto que el primer vértice comienza en la posición del archivo 0, y todos los consiguientes en saltos de 4 bytes. Imaginemos por un momento que tenemos realmente un archivo tan solo con vértices, pero que el primer byte del archivo es un identificador. Quiere decir que de representarlo como digo, no tendría nada!! puesto que mi matrón se extiende por todo el archivo, y jamás tendría un solo vértice representado correctamente. Pero esto mismo sucedería no solo si los vertices comenzasen en el primer byte, sino tb con el segundo y con el tercero. Las posibilidades por tanto sería un desplazamiento de 0, 1, 2 y 3 bytes. 4 no haría falta, dado que son bloques de 4 Bytes cada float, si desplazase 4 sería igual que no desplazar. Hablo de localidad dentro del mismo archivo. Con lo que si quiero representar el archivo a pelo, tengo que hacer en realidad 4 representaciones, cada una variando el desplazamiento 1 byte.

Como si de magia se tratase, con un desplazamiento de 0, y con todo lo comentado, esto es lo que obtengo:

Si no me falla la vista, eso parece ser el bañador de Adrianne? Evidentemente no quiere decir que todo lo que vemos sea parte de la geometría, ni mucho menos. Tan solo hemos pasado a nuestro engine un buffer de 64MB interpretado todo ello como vértices y obtenemos eso. Cláramente el bañador en azul, si está en azul quire decir que el bañador se encontraría en el último cuarto del archivo.

Para un desplazamiento de 1 Byte:

Vaya… en este caso hemos acertado en la cabeza de lleno, una pierna, medio cuerpo, un brazo, el ojo izquierdo, un pendiente… La cabeza en Verde nos dice que está en el segundo cuarto.

Para un desplazamiento de 2:

Otra pierna, en azul a la derecha y girado parece que podría ser el collar y un posible ojo? Tener en cuenta que las posiciones no tiene porqué corresponderse, al menos por ahora.

Y por último para un offset de 3:

Por último tenemos otro brazo, collar, cuerpo…

Creo que la mayoría de toda la geometría queda al descubierto.

Como segundo paso se podría acotar aun más la búsqueda de cada malla (parte del cuerpo) por separado, para conocer la ubicación concreta de cada una de las partes. Una vez realizado podríamos comenzar visualizando el archivo en un editor hexadecimal y ver si podemos extraer información directamente de él, teniendo en cuenta lo qye ya tenemos.

Pero ei… de momento el engine funciona, y se ve claramente un voceto muy primitivo de Adrianne diseccionada, en forma de puntos de colores.

Volver a arriba

Sobre Mí

Cambiar a la versión para móviles

Creative Commons License
Alma Oscura por Theliel is licensed under a Creative Commons Reconocimiento-No comercial-Sin obras derivadas 3.0 Unported License.
Basado en el trabajo de blog.theliel.es.
Para otros permisos que puedan exceder el ámbito de esta licencia, contactar en blog.theliel.es/about/contactar.