domingo, 19 de noviembre de 2023

Generador de códigos de amigo para Torre Miau (Meow Tower)

 
 
Recientemente me descargué un juego de nonogramas para el móvil llamado Meow Tower
En este juego en concreto concreto vas subiendo de nivel, desbloqueando "gatos", aspectos, y temas. Pero existen varios de esos desbloqueables que la única manera de conseguirlos es mediante códigos de amigo. 5 en total.

Pero... ¿Y si no tienes amigos? :( Nah, fuera coñas, tú no vas a molestar a nadie pidiendo que se instale el jueguecito para que te de su p*** código. Ademas para evitar que la gente comparta los códigos de amigo en grupos de Facebook o Reddit estos códigos una vez se generan caducan a los 15 minutos.
Pues bien, hay un dicho popular que se remonta a hace miles de años que dice que quien es hacker, ya lo es para toda la vida, así que ahí tenéis hermosos, un generador de códigos de amigo para que no tengáis que molestar a nadie más :')

viernes, 1 de septiembre de 2023

Frikada del mes: Crackeando un juego J2ME de mi infancia

Hace muchismos años, estamos hablando de cuando los teléfonos móviles aun no tenían pantalla táctil, las marcas de moda eran Nokia y Sony Ericsson, y los juegos que se descargaban en formato .JAR no te pedían microtransacciones, hubo uno en especial que me llamó bastante la atención. Se trataba de un juego de golf que era capaz de generar 3D incluso en los teléfonos más sencillos llamado Par 3 Golf.

No os imagináis la de veces que completé el primer nivel, y digo esto porque el juego te pedía que comprases una clave si querías jugar al resto de niveles. Esta clave es vinculada a un PIN que cambiaba si re-instalabas el juego y no era precisamente baratica la p** clave.
Pues bien, eso fue mucho antes de que me convirtiese en un friki, así que ahora llegó el momento de crackear finalmente el juego después de tantos años. Para ello tan solo necesitamos un decompilador de Java. Empecemos por ver de donde viene el valor del PIN:
Antes de que os asustéis debo deciros que el código decompilado aparte de no incluir nombres de variables/funciones, las pocas que sí tienen están ofuscadas usando términos del lenguaje Java aleatorias como append, insert, equals, parseInt... que sus nombres no tienen ninguna relación con lo que hacen realmente. Esto esta hecho con la única intención de confundir a los hackers de ingeniería inversa como yo. Buena jugada, ResetGame. 
Os hago un resumen, la función D checkea mediante la función AI.I si hay datos guardados del juego (lo cual incluye el PIN) y si no existen porque es la primera vez que se abre el juego, setea el PIN (que está en la dirección de almacenamiento 6) a los últimos 16 bits bits del timestamp en ese momento. Lo cual viene siendo... aleatoriedad total.
Pero... un momento... 16 bits significa que tenemos numeros del 0-65535 pero el PIN tiene 6 digitos. WTF??
Miremos el codigo que imprime el PIN:
El PIN se obtiene con la funcion de "Obtener valor de memoria" this.C para la dirección 6. Pues al resultado que se obtuvo de (timestamp & 0xFFFF) se le va a hacer padding con 0s hasta tener 5 cifras, por ejemplo, si el valor es 999 quedará 00999. Y finalmente el primer dígito será la suma de estos 5 digitos modulo 10. En este caso 0+0+9+9+9=27 por lo que nos quedamos con el 7 y el PIN mostrado sería 700999.
Lo mismo aplica con mi PIN del primer screenshot: 1+7+4+6+6=24, por lo que el primer digito del PIN será... sorpresa.
Pero vayamos a lo importante... ¿Como podemos generar una clave a partir del PIN? Vayamos a la funcion que procesa el valor introducido...
Lo primero que hace es borrar el primer dígito que introducimos... Interesante, el primer dígito de la clave no se tiene en cuenta. Después guarda en la posición 8 del almacenamiento el valor del PIN introducido, sea correcto o no.
Pues bien, resulta que hay una función que se llama en varias partes del juego que comprueba si la última clave introducida coincide con el PIN denominada "length" que a su vez aplica una función matemática que han llamado "parseInt" al PIN y este resultado debe coincidir con la clave introducida.
¡Ya esta! Si no os han sangrados los ojos viendo los nombres ofuscados de las funciones, os daréis cuenta de que la clave a introducir debe ser el resultado de (PIN<<5 & 0xFFFF) | (PIN >> 11 & 0x1F) con un digito cualquiera 0-9 delante de ese resultado. Os dejo Un calculador de claves que podeis usar desde el navegador:
Introduzca PIN:
Más tarde apareció... Par 72 Golf, que si me preguntáis la diferencia con el 3 la verdad no lo se ya que el juego es prácticamente idéntico aunque con más niveles. En este caso se puede decir que directamente no existía PIN, ya que siempre mostraba el mismo (RESETgame). Veamos lo que hace en esta ocasión:


Pues vemos que en esta ocasión el valor que se almacena del timestamp no son los 16 bits menos significativos, sino que es el número de día (1000*60*60*24). Ademas es muy curioso, ya que parece que la clave a introducir sería ese número de día de la instalación con un margen de 15 días a partir de los cuales la clave que te entregan dejaría de ser valida. Aparte de eso, también existe una clave "55205" que siempre funcionaría e imagino que únicamente se entregaría en caso de "emergencia" cuando alguien se quejase de que la clave basada en días que le entregaron no funcionaba. Pero... tenemos un problema. Por alguna razón le dieron fecha de caducidad a las keys basadas en el día actual. Con la operación & 0x3FFF impiden que se puedan introducir fechas posteriores a Noviembre de 2014, así que a día de hoy la unica forma de desbloquear el juego es con la clave "55205".

En fin, si de verdad has llegado hasta aquí, que sepas que eres 1 entre un millón. ¡Enhorabuena!

sábado, 29 de abril de 2023

Instagram: ¿Quien te deja de seguir? ¿Quien no te sigue de vuelta? Vuelve Insta-Script

Una de las tareas que más le interesa a los profesionales de Instagram es la de poder extraer la lista de sus seguidores a un fichero de texto. Esto permite poder comparar su lista de seguidores con valores anteriores (y detectar unfollowers) así como compararlo con la lista de gente a la que siguen, y detectar cuentas que no te siguen de vuelta.

En 2015 cree por primera vez Insta-script como un script para Linux que obtenía estas listas y mostraba las diferencias, pero eventualmente dejó de funcionar cuando la API de Instagram empezó a requerir estar logueado para obtener estas listas.

8 años después (fijaos si me he esperado) he re-implementado Insta-Script como un script JS que se ejecuta en el dev-tools del navegador (esa cosa que aparece cuando pulsas F12 en el navegador) de forma que es tan sencillo como abrir instagram.com en el navegador web del PC, loguearte, ejecutar el siguiente código en la consola del dev-tools, y se descargará automaticamente la lista de seguidores en formato txt:


En el primer parámetro userid debemos escribir el ID numérico de la cuenta de Instagram para obtener los seguidores, o en caso de no saberlo, el nombre de usuario de Instagram.
En el segundo parametro mode usaremos el valor "followers" o "following" dependiendo de si queremos extraer la lista de seguidores o personas a las que se siguen. La lista que obtendremos tendrá el siguiente aspecto:


Como podéis comprobar, obtiene los IDs de Instagram ordenados de menor a mayor seguidos del nombre de usuario. Esto permite detectar cuando un usuario simplemente se ha cambiado el nombre de usuario, y no confundirlo con un follow-unfollow de 2 usuarios distintos, así como evitar que se desordenen las cuentas cuando vayamos a comparar archivos.
Por último comentar que si la cuenta de la que estamos extrayendo seguidores no es la cuenta con la que estamos logueados, es posible que se filtren algunas de las cuentas de la lista, por lo que recomiendo siempre loguearse en la cuenta de la que queremos extraer la lista.

Y para terminar... ¿Como obtener los follows que no te siguen de vuelta? Pues en esta ocasión lo hice mediante un batch para Windows. Más sencillo imposible. Creais un archivo unfollowbacks.bat en un directorio con ambos txt con el siguiente contenido y lo ejecutais:

domingo, 26 de febrero de 2023

Grabando video en un diskette. Evolución de los formatos de video (AV1 y H266)

 ¿Quien no se acuerda de los diskettes? 

Por allá en los 90, era el dispositivo de almacenamiento por excelencia para compartir archivos, en una época donde los grabadores de CD eran caros, e Internet era lento (56kbps a traves del modem) y poco accesible.
Pues lo habitual era usarlo para compartir documentos de Word, Excel, pequeños juegos de PC, imágenes de baja resolución... Esto es debido a su limitado almacenamiento de apenas 1.38 MB.

Los más pros, a finales de los 90, consiguieron hacer algo inimaginable años atrás con el diskette: almacenar canciones enteras de casi 3 minutos gracias al revolucionario formato de audio MP3, eso sí, a 64kbps, lo cual es una calidad de audio pésima. Con una calidad aceptable de 128kbps se podía grabar 1 minuto y medio aproximadamente, que tampoco estaba mal.

Pues bien, ¿y que pasa con el vídeo? Cualquiera que le hubieses pedido grabar un vídeo en un diskette por entonces se habría reído de ti, y con razón. Y es que el formato de vídeo revolucionario por entonces, el MPEG, permitía grabar vídeo a 240p 1374 kbit/s. Esto significaría un vídeo de máximo 8 segundos con una calidad pésima.

A día de hoy, es claramente sabido que en una microSD del tamaño de una uña nos cabe lo equivalente a miles de diskettes, pero no solo han mejorado los dispositivos de almacenamiento en estos años, la codificación de vídeo también, así que... ¿Sería factible grabar vídeo en un diskette en 2023?

Repasemos la evolución de los códec de vídeo más populares:

* MPEG1 (VCD) - 1993
* MPEG2 (DVD) - 1995

* MPEG4 (DIVX) - 1999
* H264 (AVC) - 2004

* VP9 (Google) - 2012
* H265 (HEVC) - 2013

* AV1 (AOMedia) - 2018
* H266 (VVC) - 2020

Los he ordenado cronológicamente por orden de aparición, y los he separado por categorías, ahora os explicaré por qué:

* MPEG1 fue un formato revolucionario mucho mas eficiente que los previamente existentes como Cinepak, que permitió por primera vez grabar películas en un CD. Más tarde, con la aparición del medio físico DVD, apareció una variación llamada MPEG2 cuya única diferencia es que permitía un mayor ancho de banda, alcanzando con él los 480p.

* Mas tarde, y bajo el nombre de MPEG4, empezaron a mejorar el algoritmo. DivX fue el nombre con el que conocimos por primera vez esta compresión más eficiente. Siguieron mejorándolo, creando MPEG4 parte 2, o H263 para los amigos, compresión que permitió grabar vídeo en el móvil de forma eficiente por primera vez (formato .3GP). MPEG4 parte 10, o H264, no necesita presentación y es que desde su aparición ha sido el códec de vídeo por excelencia en el BluRay, televisión digital, streaming, cámaras de video y móvil,... En todo.

* Unos años después, no solo mejoraron aun más el H264 creando H265, sino que Google también se animó a crear un nuevo códec de vídeo VP9 (Sucesor de VP8), que usaría para los vídeos de su plataforma YouTube, ambos con una eficiencia similar, y mejor que H264, aunque no lo reemplazarían del todo debido a la alta popularidad que tuvo H264, y a que H264 se podía decodificar por hardware por esos años. El hecho de que el hardware capaz de decodificar H265 tardó en aparecer, hizo que su implantación en dispositivos fuese lenta y la gente siguiera utilizando H264.

* Finalmente, y recientemente han aparecido dos nuevos códecs de vídeo con una eficiencia aun mejor, AV1 de AOMedia, y H266. A día de hoy, AV1 esta despegando bastante bien, gracias a su enorme eficiencia, y es soportado por FFMPEG, VLC, navegadores web,... Mientras tanto, H266, a febrero de 2023, sigue siendo tan novedoso que aun no es compatible ni con FFMPEG, ni con VLC, ni practicamente con nada. Ambos desde mi punto de vista proporcionan una compresión de eficiencia similar.

A continuación tenéis una pequeña comparativa que he hecho de estos últimos códecs, tras codificar 1s de vídeo 540p a distintos tamaños. (PD: Quien adivine que película es, tiene premio)




Bueno, pues... ¿que resultados obtendríamos codificando AV1 en un diskette?

Para el audio usaré HE-AAC con audio mono, manteniendo los 44100 Hz eso sí.
HE-AAC es actualmente el mejor códec de audio existente para bajos bitrates, mucho mejor incluso que OPUS, que ya es decir. Usaré el mínimo bitrate que permite codificar HE-AAC con esta configuración, que es 16 Kbps y que sorprendentemente suena bastante mejor que los 64 kbps en MP3 de la época.

Mi plan es codificar un vídeo musical entero, a 480p (DVD) en vez de 240p (VCD). En busca de ideas para el vídeo, encontré que por alguna bizarra razón el clásico Crazy Frog - Axel F está disponible en YouTube en 4k, lo cual garantiza el máximo de calidad al re-escalar a 480p, ademas de ser un clásico de los 2000's.

Tras codificar el vídeo en AV1, lamentablemente solo me entró 1 minuto en el diskette, aunque pensándolo bien... ¡¡Es 1 minuto de vídeo a 480p en un p*** diskette!! Totalmente inimaginable en los 2000's.


Ya solo por curiosidad, quise comprobar cual es la máxima duración que podría caber en el diskette bajando la resolución a 144p, y usando la mínima calidad de imagen permitida por el encoder, ademas de bajar el audio a 32000 Hz y 12 Kbps. Tras encontrar un vídeo musical que duraba 5 minutos, lo codifiqué en AV1... ¡Y entró entero! No solo eso, sino que incluso sobraron 60 Kb en el diskette. El resultado es la siguiente aberración.


Sí, la calidad de imagen es horrible, aunque si nos paramos a pensar es parecida a la de algunos vídeos web existentes a finales de los 90's, sí, de esos que se reproducían con el Real Player.


jueves, 2 de febrero de 2023

Creando un computador mecánico programable de un reloj digital (sin electrónica)

 ¡Feliz 2023 frikazos!

Lo primero de todo, quería disculparme por adelantado por este post, ya que es una 💩 pero algo había que escribir en el blog para que no vaya cogiendo polvo.

Como sabéis, los primeros computadores de la historia no usaban electricidad, eran puramente mecanicos. Ej: La maquina "Bombe" para descifrar Enigma creada por Alan Turing, de la cual no hay mucho más que explicar ya que hay una peli y to' 



Pues bien, una tarde de aburrimiento me puse a pensar si habría una forma simple de crear un computador mecánico programable, con la suficiente "potencia" para implementar un reloj digital, de forma que hubiesen salidas mecanicas que se conectasen a cada uno de los segmentos de una pantalla de 7 segmentos. Lo que vendría siendo algo así:


Tras investigar posibles opciones, encontré una bastante interesante. Resulta que en los años 60 apareció un "juguete educativo" que era un computador mecánico totalmente programable (se nota que antes de que apareciese TikTok los niños eran más listos) llamado DigiComp I:



Esta maquina era capaz de implementar programas como un contador binario, o el juego del Nim, entre otros. Aquí podéis verla en funcionamiento con el programa del contador binario:




Como veis, es muy sencilla, y se puede replicar fácilmente con impresión 3D, gomitas, y alambre, como se muestra en esta web. También podéis probar su funcionamiento en este simulador online. Su único inconveniente... es que solo tiene 3 tristes bits :') Con eso sinceramente no se puede hacer una 💩.
Pero si nos fijamos bien, ¿Que limita la maquina a tener únicamente 3 bits, 3 condiciones de set, y 3 condiciones de reset? ¡Simplemente quisieron hacerla así de simple! Nada nos impide construir una versión que tenga 32 bits, por ejemplo, siguiendo exactamente la misma mecánica.
Y ahí es donde entro yo, empezando por crearme otro simulador, que en este caso permita escalar la maquinita. En esta ocasión elegí Excel, para variar un poco. Aquí podéis ver mi simulador con el tamaño del DigiComp I original:


Y ahora, simulando que conectamos las salidas a una pantalla de 7 segmentos, así se vería la implementación de un contador del 0 al 9:


Como podéis apreciar, la maquinita ha crecido un poco...
Originalmente tenia pensado crear un contador binario de toda la vida que al llegar a 9 regrese a 0, y de forma paralela, implementar lógica para convertir ese numero binario a los bits del 7 segmentos. Peeero, como podéis imaginar, aunque en DigiComp sería posible, aumentaría más su tamaño que si simplemente verificamos el valor anterior del 7 segmentos para calcular el próximo.

La implementación final, para un reloj de 24h sería la siguiente monstruosidad:


¡Seguro que funcionaría! Pero ahora a ver quien tiene huevos de fabricarlo.

FAQs:

P: ¿Donde puedo descargar el Excel con tu simulador?
R: Si a alguien le interesa descargar el proyecto, que me deje un comentario abajo y os dejo un enlace.

P: ¿Como se ajustaría la hora?
R: Literalmente se haría moviendo manualmente los segmentos con la mano, de forma que muestren la hora actual. Sí, sorprendentemente funcionaría haciendo eso.

P: ¿Que pasa cuando llega a las 23:59?
R: El siguiente valor será 00:00, ¿O que pensabas? No soy tan mal programador.

P: Yo quiero construir tu maquinita de la hora
R: ¡Buena suerte!

P: Te sobran "x", se podría optimizar.
R: No le he dado importancia a minimizar el numero de "tubitos", que son los que se usan para programar, ya que son piezas muy simples, e igualmente este proyecto es una 💩. Si que he intentado minimizar un poco el numero de bits, y el numero de condiciones de set y reset (columnas), que son los que harían crecer la maquinita.

P: ¿Que más opciones te planteaste para tu reloj digital, aparte de DigiComp?
R: Literalmente empecé a idear un computador mecánico capaz de ejecutar programas en Brainf*ck, y una version simplificada con direccionamiento de 1 bit que reemplazaría las instrucciones + y - (incrementar / decrementar) por 1 y 0 (setear bit a 1/0), pero sería demasiado lento, y una pesadilla de programar.

P: Sí, sí, muy bonito pero... ¿Puede correr Doom?
R: ¡Claro que sí nene! En un mundo paralelo