¿Qué pasaría si alguien escribiera un programa que cambiara el valor de los dígitos binarios en una computadora y luego ejecutara el programa?

¿Algo como esto?

#define MEM_SIZE 0xFFFFFFFF // 4 GB, supone un sistema de 32 bits

int main ()
{
sin signo * ptr = 0;
while (ptr <MEM_SIZE)
{
* ptr = ~ (* ptr);
ptr ++;
}
}

Esto negará todos los bits en la memoria. En la mayoría de los sistemas (todos con una MMU) en ejecución, provocará un error de segmentación, a menos que se ejecute como parte del núcleo, lo que tendría consecuencias aún peores. Aún así, el resultado sería un fracaso rápido y difícil.

Supongo que ejecutar esto en DOS sería interesante, no hay segfaults allí, pero me pregunto qué sucederá una vez que el ciclo sobrescriba el código del programa o la pila …

Entonces, para responder la pregunta. ¿Qué pasaría si alguien escribiera un programa que cambiara el valor de los dígitos binarios en una computadora? Ver arriba, ahí está tu programa … no pasó nada. Si ese programa se ejecutó, puede provocar una falla de seguridad (falla segura) o pánico del núcleo, o sobrescribir todo y probablemente dar como resultado una decodificación de instrucciones ilegal u otras cosas aleatorias (no es seguro).

Si su programa se ejecuta en un proceso con memoria virtual (es decir, cualquier proceso de usuario que se ejecute en x86 en la parte superior de un sistema operativo moderno, consulte Memoria virtual), ese proceso seguramente se bloqueará de inmediato. La mayoría de los sistemas operativos harán que la parte más baja del espacio de direcciones virtuales sea ilegible e inescrutable para todos los procesos, por lo que cualquier intento de cargar o almacenar en direcciones numéricas 0–0xFFFF o más probablemente resulte inmediatamente en una falla de segmentación o protección que cause el proceso Ser asesinado. En un sistema operativo correctamente escrito, esto no hará ningún daño a otros procesos.

Si logró ejecutar código como ese como un proceso de kernel privilegiado, o en un sistema sin memoria virtual configurada (o disponible en absoluto, muchas plataformas integradas no lo tienen), es bastante seguro decir que sucederán cosas muy malas el sistema.

Si las estructuras de datos internos del sistema operativo se almacenan en la parte inferior de la memoria, es probable que sobrescriba rápidamente algo importante, como una tabla de controladores de interrupciones instalados, almacenamientos intermedios de E / S o estados relacionados con el planificador de procesos. Eso probablemente hará que el sistema operativo se cuelgue o se bloquee (saltando a una dirección basura) la próxima vez que se active una interrupción del temporizador o realice una llamada a nivel del sistema operativo.

Si la memoria del proceso del usuario se almacena en las direcciones inferiores, comenzará a provocar que los procesos del usuario, incluido, eventualmente, ese proceso en sí mismo, se comporten mal. Si solo escribe datos aleatorios o voltea bits indiscriminadamente, es probable que los procesos se bloqueen o salten a alguna dirección aleatoria y comiencen a interpretar los datos que estén allí como instrucciones. Si la memoria del kernel no está protegida de alguna manera, es probable que algún proceso comience a sobrescribir la memoria en el kernel y luego se bloqueará todo el sistema como se indicó anteriormente. De lo contrario, probablemente bloqueará la mayoría de los procesos en el sistema, a menos que su proceso se suicide relativamente rápido.

Ver también: Core War

ok, así que después de haber pasado algún tiempo programando en una computadora que probablemente te permita salirte con la tuya, voy a intentarlo.

El BBC Micro estaba bastante relajado sobre lo que podía o no podía hacer. Solo como ejemplo de eso, escribí un pequeño programa (de unos 100 bytes si no recuerdo mal) que podría copiar el contenido * completo * de la RAM de una máquina a través de la red en otra máquina, y luego comenzar a ejecutarlo en la ubicación precisa donde el otro había sido detenido.

Entonces, si hicieras esto, ¿qué pasaría?

Supongamos que comenzó en el extremo inferior de la memoria: ejecuta algunos búferes que nunca debe tocar, probablemente rompa partes del sistema operativo como lo hace, pero debido a que está ejecutando su código, nada llegará allí por un tiempo, a menos que es impulsado por interrupción, por ejemplo, presionar una tecla.

Un poco más alto y puede llegar a la pila, pero para un código tan simple no se necesitan llamadas a funciones, por lo que puede que ni siquiera lo note.

Si se movió más arriba y comenzó en el área donde estaba el código, es probable que cambie una operación válida por una no válida, pero podría ser posible producir un código válido. El conjunto de instrucciones 6502 es muy escaso: casi el 50% de los posibles códigos de operación no se utilizaron en el original, por lo que hay muchas posibilidades de golpear uno no válido. Y las posibilidades de que los valores no solo sean válidos sino que también formen un bucle son aún más escasas. En este caso, el código casi seguramente se detendría.

Si, en cambio, comenzaste después del programa, verías que la pantalla cambia lentamente, reemplazando, por ejemplo, negro con blanco y viceversa. (o si está en el modo de visualización Modo 7, cambiar cualquier texto para que parezca absurdo.

Hay procesadores que no tienen instrucciones ilegales y si tuviera uno de estos no lo bloquearía. pero aún así se detendría cuando se sobrescribiera el código, a menos que, por casualidad, el galimatías resultante siguiera funcionando.

Entonces, en general, la respuesta es “depende”

Si cada uno se convierte en cero y viceversa, la computadora probablemente ya no funcionará correctamente.

Esto se debe a que cada computadora tiene un “conjunto de instrucciones”. Entonces, supongamos que tiene un programa que suma los números 2 y 3 juntos. Al escribir esto en un pseudocódigo similar al ensamblado, obtienes algo como esto:

mover 2 al registro A
mover 3 al registro B
agregue el registro A y el registro B
almacenar el resultado en algún lugar de la memoria

Ahora inventemos algunos códigos operativos para estas instrucciones:

movimiento: (valor de 4 bits) 0001 o (valor de 4 bits) 1110 (tenemos 2 códigos de operación de movimiento por alguna razón, ¡no lo cuestione!)

agregar: 0000 0010

restar: 1111 1101

tienda: 0000 0100

carga: 1111 1011

Entonces, en una computadora que funciona, el pseudocódigo traducido al código de la máquina sería algo así como:

0010 0001 # mover 0b0010 (2) al registro
0011 0001 # mover 0b0011 (3) al registro
0000 0010 # sumarlos
0000 0100 # almacena el resultado en alguna parte

Ahora, suponiendo que volteamos todos los bits, y por algún milagro que la computadora aún arranque, obtenemos algo como:

1101 1110
1100 1110
1111 1101
1111 1011

Lo que esto hace, suponiendo números sin signo, es mover 0b1101 (13) al registro A y mover 0b1100 (12) al registro B, restarlos y luego cargar algo de la memoria. ¡Esto es completamente diferente de lo que queríamos!

Ahora, obviamente, una computadora puede no funcionar en absoluto si se invierten todos los bits. Acabo de poner el ejemplo para que esto funcione. En el mundo real, los números negativos se volverán positivos, los números positivos se volverán negativos, tendrás instrucciones que ni siquiera existen, etc.

Nada, la forma en que está formulada la pregunta.

¿Por qué?

Nada sucede hasta que se ejecuta el programa. El programa simplemente se sienta allí.

** Actualizado después de la aclaración **

Suponiendo que el programa se ejecute, hay un par de suposiciones: la cuenta que ejecuta el programa tiene privilegios completos de administrador / superusuario, y que el programa tiene acceso a firmware, memoria, CPU, disco, flash y otros componentes. Depende de cómo esté diseñado y diseñado el programa. Por ejemplo, si el programa comienza a ejecutarse en la memoria y la memoria se ve afectada, la computadora debe salir por error inmediatamente y luego, una vez que se reinicia, se comportará normalmente. Si el programa comienza a ejecutarse en las áreas protegidas del sistema, es probable que la computadora se detenga tan pronto como un programa que está intentando cargar en la memoria ya no se cargue, dejando el resto de la computadora intacta. Una operación de reparación o restauración probablemente solucionará el problema.

Si la intención de la pregunta es que de alguna manera todos los bits se voltearían de una vez, habría convertido con éxito una computadora en funcionamiento en un ladrillo.

Los procesadores de la computadora se detendrían en microsegundos por una variedad de razones. Nuestros cerebros son lo suficientemente potentes como para leer la escritura inversa con cierta dificultad, pero para una computadora, voltear los valores de bits en su memoria los convierte efectivamente en una colección desordenada de bits aleatorios sin significado.

Como ya han señalado otros, el programa u otros programas se bloquearán inmediatamente.

Una pregunta más interesante sería: ¿Qué pasaría si se voltea un bit aleatorio en una memoria ejecutable? Este tipo de cambio es lo que se llama mutación en la programación genética. Es un análogo a una mutación en el código genético de dejar organismos que, según Darwin, es la causa de la variación en los organismos.

La mayor parte de la mutación no dará como resultado un organismo que pueda reproducirse porque no puede hacer frente a su entorno. En el caso de la programación, no podrá ejecutarse y la mayoría se bloqueará. En algunos casos raros, se ejecutará con una salida que es diferente del original. En casos aún más raros generaría un mejor resultado.

Se bloqueará, porque cualquier sistema operativo moderno detectará que intentas acceder a la memoria a la que tu proceso no tiene acceso, especialmente no tiene acceso de escritura.

Voltear bits tampoco es nada extraño. Hay un operador para él en muchos lenguajes de programación, como el operador ~ en C. Hay usos para esto en todo tipo de algoritmos, pero generalmente solo cambia los bits de variables que asigna su programa.

Si no comprende el complemento a dos, simplemente inicie la calculadora en Windows, entre en el modo de programación, establezca el número de bits para su número entero, ingrese un número entero y luego invierta bits presionando “No”.

En un sistema operativo bien escrito, ¡este programa en sí mismo atrapa!
Esta suposición es solo una “vue de l’esprit”.