Un ingeniero húngaro emprendedor, Can Bölük en Verilave, ha hecho algo similar, sondeando el oscuro sistema nervioso de los fabulosamente complejos microprocesadores x86 de Intel. Lo investigan en busca de códigos de operación no utilizados e indocumentados en los conjuntos de instrucciones de los chips. Y está bastante descubierto. Su código está disponible en Github. Si alguna vez ha programado un chip x86 en lenguaje ensamblador, su primer pensamiento podría ser: "No sabía que había códigos de operación sin usar".
|
etiquetas: microprocesadores , x86 , código chip
LD HL, $i_feel_you_bro
CALL print
RET
Probablemente se trate de, como dice el artículo, instrucciones que quedan ahí por compatibilidad hacia atrás (muchas, "deshabilitadas" antes de lanzar el procesador de turno por no ser funcionales o adecuadas) y luego instrucciones para el remapeo de las propias instrucciones y debugueo a ultrabajo nivel.
Recordemos que desde el pentium pro los procesadores x86 son RISC y las instrucciones son "configurables" (cada instrucción es un conjunto de microinstrucciones, que son las que realmente se ejecutan; como pueden haber bugs de distinto tipo, poder actualizar los microcódigos que conforman las instrucciones es una ventaja).
www.intel.com/content/www/us/en/support/articles/000029051/processors.
Que no quiere decir que no haya instrucciones ocultas con fines maléficos (no voy a poner la mano en el fuego), pero si que casi siempre que salen cosas de estas en realidad son pajas mentales de la gente que malinterpreta cosas que tienen otras funciones pero que evidentemente no deberían ser públicas (si fuera fácil poner en modo debug un procesador o acceder a la ejecución de microinstrucciones individuales, la seguridad brillaría por su ausencia; que no soy fan de la seguridad por ofuscación, pero...)
www.zilog.com/docs/z80/um0080.pdf
La gente de los emuladores sabe un rato largo de esto.
Puedes emular un Z80 con una facilidad pasmosa con simplemente los datashets y un triste switch/case en C o cualquier lenguaje de forma similar (literal lo digo), pero luego aunque lo hagas a la perfección muchos juegos pasan de la preicisión como de la mierda y no tiras.
Ejemplo con el primo hermano del Z80 en la Game Boy: Iridium D y un juego de pinball con graficazos ambos y que se dibujaban fatal en cualquier emulador hasta hace dos días.
Aprobar y olvidar en el mismo acto fue
Por cierto, #5, #6, #11, los típicos comentarios que aportaban información en el menáeme de los inicios.
Al igual que Barrapunto, Menéame ya no es lo que era.
Para el que esté interesado en instrucciones no documentadas x86, recomiendo este video youtu.be/KrksBdWcZgQ
Tambien es un sub generalista
Para el que lo desconozca |Dev (software)
No sé, si yo veo una noticia "descubierto un nuevo órgano sin usar en una rana" no lo considero irrelevante aunque no tenga ni puta idea de ranas.
Hasta donde yo sé, en un JavaScript no hay código máquina.
Pero insisto en lo limitado de mis conocimientos.
Z80, sí.
Premio para el meneante
Supongo que sí... aunque en unos cuantos lo más adecuado sería decir que son "RISC-like"... o que son una mezcla de RISC y CISC.
architecnologia.es/x86-risc-o-cisc
LDAA 07
Edit: Entiéndase por castellano "lenguaje para alguien que no tiene pajolera idea de informática", no como la lengua romance que hablamos en esta página.
Sin embargo una CPU sí puede ser "maligna". Como apuntaron ya hace unos años las "nuevas" CPUs son en realidad microordenadores encapsulados que simulan ser una CPU simple. Estas CPUs llevan otra CPU interna no documentada en absoluto, con su RAM, su ROM, su FLASH y su propio sistema operativo que solo conoce el fabicante. Por ejemplo una CPU de movil tipo ARM suele ofrecer, aparte de función CPU un chip gráfico, de red, radio (GSM, Blutú, etc). Todo en un solo chip. Por mucho que le pongas un Linux por encima y parezca un entorno controlado no hay manera de saber qué está haciendo la CPU por dentro y si está enviando tus datos bancarios a China mediante espacios no usados en los paquetes de datos.
También es cierto que te puedes acercar mucho con compiladores optimizantes. El de Ada tiene mucha fama en eso.
Lo que el ingeniero quiere saber es si existen ordenes que Intel no ha puesto en el manual pero existen dentro del procesador así que va a probar todos los códigos numericos uno tras otro y comprobar el resultado automaticamente con un programa. Esto tiene el problema de evitar que se cuelgue por usar codigos al tun tun y saber si un codigo ha hecho algo.
Para que no se cuelgue se aprovecha que los procesadores ejecutan partes del programa por adelantado como borrador y si el programa llega a esa parte se marca como definitivo para ahorrar tiempo. Si el programa se desvia por otro lado se descarta el borrador. Ojo que aunque el borrador se descarte y se resetea el estado del procesador a como si nunca se hubiesen ejecutado, las instrucciones en realidad si pasaron por el procesador. Lo que hace es apañarselas para que las partes con los codigos de prueba siempre esten en borradores que se descartan.
Para saber si el codigo ha hecho algo se aprovecha que desde hace 20 años los codigos de orden no se ejecutan directamente. Dentro del chip no hay un i7, i5 o lo que sea. Lo que hay un emulador y un procesador parecido a los de movil pero mucho mas potente. Cada codigo que le llega al chip pasa por la capa de emulacion para traducirlo a algo que entienda ese procesador de movil interno. Gracias a que descubrio una forma de leer el numero de pasos que ha dado ese procesador interno al recibir un codigo puede adivinar con bastante precision si un codigo hace algo o no.
TL;DR Los procesadores funcionan con codigos numericos para cada tipo de comando a ejecutar. Los fabricantes dan una lista oficial de comandos. El ingeniero por curiosidad prueba con todos los numeros de forma muy ingeniosa para ver que pasa con cada uno automaticamente.
El articulo se basa en que muchas de esas funciones no estan documentadas oficialmente o si le preguntas a Intel/AMD/ARM/Via te diran que "no existen". Como algunos ya han mencionado, no es una gran novedad, pero el hecho de que esten ahi hace que desconfies de lo que tu CPU esta haciendo. Como ejemplo, un par de casos: El modo Dios, que permite ejecutar cualquier cosa saltandote todas las medidas de seguridad de la CPU o los procesadores secundarios que permiten cambiar el microcodigo (otro conjunto de instrucciones) de forma transparente sin que nadie se entere. Y me voy a guardar el sombrerito de aluminio para otro dia
Sin embargo, en el caso de estas instrucciones no documentadas, para que se pudiesen usar tendrían que estar en el ejecutable que tengas corriendo en tu máquina, y ese ejecutable tendría que estar hecho con un compilador que tuviese constancia de la existencia de dichas instrucciones.
Por lo tanto, es imposible que un JavaScript, que no deja de ser algo interpretado en tiempo de ejecución y no de compilación, use esas instrucciones desconocidas si el motor de ejecución (sea el navegador, sea el motor de java, o lo que sea) no fue compilado para utilizarlas.
#5 Y x86 no es para nada un RISC, es un CISC por que solo acepta instrucciones CISC. Y lo de que internamente es RISC, un exingeniero de Intel difiere: www.quora.com/Why-are-RISC-processors-considered-faster-than-CISC-proc
Tambien vi cosas bastante raras en el codigo, como usar RSP ( el registro de puntero de pila ) como registro de proposito general ( !!! ) en un pequeño tramo del codigo. Intuyo por que hicieron esto pero no estoy seguro... podria ser mera optimizacion, pero seria un poco jarto... no se.
Pues bien, no es solo instrucciones, el binomio microsoft<->intel ( y supongo que AMD tambien, aunque en este caso AMD no fue tan vulnerable ) lleva tiempo haciendo cosas de estas.
Muestra de lo que hablo para los que sepan de arquitectura x86(-64):
m.youtube.com/watch?v=TuDXgAx6fS0
m.youtube.com/watch?v=GOSUuZCpmvM
Lo que digo de la dicotomia de direccionamiento ( CR3 ) entre kernel y usuario, es cosa aparte, esto es la solucion que se hizo para meltdown, que... en fin , pero bueno, cosas bastante esotericas se introdujeron en esos parches.
todo si hay multiples unidades de ejecucion y si es una arquitectura Out Of Order Execution.
RiSC, hoy dia, mas que reducido, deberia entenderse como computacion con instrucciines de tamaño fijo + instrucciones con codificacion ortogonal/simetrica, sobre todo.
También te confirmo que inicialmente las soluciones que se tomaron para evitar o paliar las vulnerabilidades provocaban un bajón de rendimiento más que notable, mientras que ahora entre unas cosas y otras el impacto es mucho menor (aunque siguen saliendo formas de aprovechar las vulnerabilidades y se sigue trabajando en formas de evitar el impacto que introducen)
Además, si alguien tiene los medios para colar sw en medio de un ejecutable del SO, ¿para qué iba a necesitar instrucciones especiales? Ya tiene la forma de colarse en tu máquina simplemente por el hecho de que confías en el suministrador del SO. No necesita instrucciones no documentadas para hacer lo que quiera.
Eso supone que tienes acceso al compilador. Además de que el primer compilador de C tenía una puerta trasera, y aún con acceso al compilador la gente tardó en darse cuenta.
De acuerdo con lo del SO, hay varios proyectos que intentan conseguir compilar un sistema operativo partiendo de lo que puedas escribir a mano.
#75 «¿En qué se diferencia a nivel de ejecución de un x86 moderno [...] ¿porque tiene un conjunto de instrucciones complejas desde el punto de vista del programador»
Si. Si solo acepta CISC no importa como sea el interior, es un procesador CISC. Incluso si internamente use un RISC (aunque al exingeniero de Intel no le guste llamarlo así) el procesador es un conjunto de elementos: internamente también tiene ALU y no por eso es una calculadora.
#71 Leyendo un poco por ahí, concuerdo sobre ARM. Tienen bastantes más instrucciones de las que yo diría que necesita.
No, no sólo acepta CISC. Pero para bajar y programar al nivel de microinstrucciones tienes que estar mal de la cabeza por una serie de razones*, supone un nivel de complejidad inaceptable. Todo el hecho de que a nivel de instrucciones siguan siendo CISC y por debajo RISC es por una serie de razones, más allá de la compatibilidad hacia atrás (si sólo fuera eso, hacías un RISC puro y un "copro-compatibilidad" aparte y listos. No, las instrucciones CISC (desde el punto de vista del programador) tienen sus ventajas también, a nivel de compilador poder jugar con instrucciones que te solucionan asuntos complejos (o poder tener dos rutas, una optimizada para según qué cosas y otra para otras distintas) es una ventaja clara en reducción de número de instrucciones (tamaño de código) y por lo tanto facilita también la optimización de las cachés. También es un infierno para otras cosas (la alineación en las cachés, el cálculo de tiempos de ejecución para saber qué ruta de compilado es más conveniente, etc).
Por otro lado, a nivel de programador da un poco igual porque no vas a programar en ensamblador casi nunca. Y si lo haces, tener más instrucciones y más complejas te facilita la vida, no es precisamente un handicap, por eso tiende a usarse lenguajes de más alto nivel para casi todo lo que no sea programar sistemas.
*Las microops no son estándares como las instrucciones. Cada modelo, chip y procesador específicos de cada familia pueden tener sus propias microops, programar con microops es casi hacerlo para un único modelo específico porque no hay garantías de que puedan funcionarte en otro. Y olvídate de ejecutar microcódigo intel en un amd, por ejemplo. Que poderse se puede, ojo, pero sólo para tu ordenador y equivalentes y ya sólo eso restringe muchísimo la utilidad y conveniencia de hacerlo. Es como programar usando las APIs que te da el fabricante o tirar de las propias funciones internas... mañana te cambian las funciones internas y tu programa deja de funcionar o lo hace mal, mientras que usar las APIs te blinda contra esas cosas.
www.usenix.org/system/files/conference/usenixsecurity17/sec17-koppe.pd
"Our analysis focuses on the AMD K8/K10 microarchitecture since these CPUs do not use cryptographic signatures to verify the integrity and authenticity of microcode updates. Note that Intel started to cryptographically sign microcode updates in 1995 [15] and AMD started to de-ploy strong cryptographic protection in 2011 [15]. We assume that the underlying microcode update mechanism is similar, but cannot analyze the microcode updates since we cannot decrypt them.Contributions.In summary, our main contributions in this paper are as follows:•In-depth Analysis of Microcode.
We provide an in-depth overview of the opaque role of microcode in modern CPUs. In particular, we present the fundamental principles of microcode updates as deployed by vendors to patch CPU defects and errors.
•Novel RE Technique.
We introduce the first semi-automatic reverse engineering technique to disclose microcode encoding of general-purpose CPUs. Furthermore, we describe the design and implementation of our framework that allows us to perform this reverse engineering.
•Comprehensive Evaluation.
We demonstrate the efficacy of our technique on several Commercial Off-The-Shelf (COTS) AMD x86CPUarchitectures. We provide the microcode encoding format and report novel insights into AMD x86CPUinternals. Additionally, we present our hardware reverse engineering findings based on delayering actual CPUs.
•Proof-of-Concept Microprograms.
We are the first to present fully-fledged microprograms for x86CPUs. Our carefully chosen microprograms highlight benefits as well as severe consequences of unveiled microcode to real-world systems."
"7 Microprograms
In this section, we demonstrate the effectiveness of our re-verse engineering effort by presenting microprograms that successfully augment existing x86 instructions and add foreign logic. With this paper, we also publish microcode patches [42] that are compiled from scratch and run on unmodified AMD CPUs, namely K8 Sempron 3100+ andK10 Athlon II X2 260/280. We found that the microcode ROM content varies between different processors, but the macroinstruction entry points into the microcode ROM are constant. Thus we assume our microcode patches are compatible with a wider range of K8/K10-based CPUs. We discuss additional applications of microcode in Sec-tion 8"
El problema es que no están documentadas y la ingeniería inversa vale para un modelo o unos pocos, el esfuerzo puede tranquilamente no valer la pena salvo para conseguir conocimiento, aparte de otras trabas (parece que, según el documento, todos los procesadores más modernos encriptan para dificultar aún más la labor).