La asignación de direcciones lógicas a físicas se realiza mediante las unidades de segmentación y paginación de la CPU. Un proceso (que significa que tanto su programa como cualquier código malicioso que se ejecuta en su espacio de direcciones) no conoce este mapeo; ven un espacio de direcciones continuo, incluso si la unidad de localización no puede asignar ese espacio de direcciones a regiones continuas de la memoria física.
Su ejemplo no funciona, porque el tamaño de la página, al menos en el x86, es de al menos 4k. Así que no podemos tener un límite de página entre 0x100 y 0x104. Estas direcciones se asignarían a la misma memoria física, porque estarían en la misma página.
Sin embargo, eso no importa, porque incluso si su código malicioso escribió datos sobre un límite de página, eso no apagaría mágicamente la unidad de paginación; en su lugar, la unidad de paginación traduciría la dirección virtual a la dirección física de la otra página.
Es realmente bastante simple. Suponiendo que estamos tratando con 4k páginas, las páginas comienzan en direcciones físicas con los últimos 12 bits puestos a cero.
Los últimos 12 bits de cualquier dirección virtual son un desplazamiento en una página. Los otros bits de una dirección se utilizan para identificar la página en una tabla de múltiples capas, que a su vez almacena la dirección física de la página.
Un programa en ejecución (y eso incluye cualquier código malicioso que se ejecute en el mismo espacio de direcciones) no puede escribir directamente en direcciones físicas; cualquier dirección proporcionada por las instrucciones de la máquina se considera una dirección virtual y siempre termina siendo traducida por la segmentación y la unidad de paginación de la CPU, por lo que el "espacio" entre 0x1000 y 0x2000 que percibe no existe para el programa.