Interrupción de software
Una interrupción de software es una llamada explícita a una subfunción (generalmente una función del sistema operativo). No tiene nada que ver con una interrupción ( interrupción asíncrona), aunque a menudo se usa el mismo distribuidor de salto (tabla de interrupciones). Los mnemónicos comunes son:
- INT xxh ( interrupción con Intel 8086 )
- SC xxh ( llamada del sistema para Zilog Z8000 )
- TRAP xh ( Trampa con Motorola 68000 )
- LLAME 0005h ( CP / M-80 , Intel 8080 / Zilog Z80 no tenía un comando especial para ello)
Tales llamadas de función son llamadas por programas con la ayuda de comandos especiales dependientes de la arquitectura. Para hacer esto, se debe conocer el número de la subfunción requerida. Este número se utiliza como índice en una tabla de salto (principalmente tabla de vectores de interrupción) que contiene la dirección de inicio de la subrutina.
antecedentes
Originalmente solo se usaba como un distribuidor de salto conveniente y portátil ( MS-DOS ); esto evita entradas dependientes de la versión directamente en el código del sistema operativo (por ejemplo JSR $EDB9); estas llamadas de función tienen funciones adicionales en los sistemas operativos modernos. Con estos comandos, es posible realizar cambios de contexto y tareas que no se pueden implementar (intencionalmente) con los comandos clásicos. Esto INT 21htambién se puede simular en MS-DOS utilizando comandos clásicos (aprox. 20), pero ya no INT 80hse utiliza para llamar a las funciones del sistema operativo en los binarios de Unix .
Esta tecnología solo habilita sistemas operativos protegidos, ya que el cambio en el contexto del sistema operativo solo puede tener lugar en puntos definidos con precisión.
Ejemplo de llamada (Unix, Intel i386)
La función POSIX read (leer datos de un identificador de archivo en la memoria) debe implementarse:
read ( int FileHandle, void* Buffer, unsigned int BufferLength ) ;
La implementación (mínima) (en libc) se ve así:
read proc
push ebx
push ecx
push edx
mov ebx, [esp+16] ; FileHandle
mov ecx, [esp+20] ; Buffer
mov edx, [esp+24] ; BufferLength
mov eax, 0003h ; Funktionnummer für read
int 80h
pop edx
pop ecx
pop ebx
cmp eax, -124 ; Werte von 0...0FFFFFF84h sind Rückgabewerte, -123...-1 sind (negierte) Fehlernummern
jbe .noError
neg eax ; Aus Rückgabewerten -1...-123 werden die Fehlernummern 1...123
mov __errno, eax ; Fehler in errno abspeichern
mov eax, -1
.noError:
ret
end proc
Tratamiento del procesador y sistema operativo
El comando INT 80hhace lo siguiente:
- Dado que el salto pasa por una puerta de llamada, el nivel de prioridad cambia de 3 (usuario) a 0 ( kernel ),
- luego el procesador cambia de la pila de espacio de usuario a la pila de espacio del kernel,
- luego guardó el registro de la bandera y
- Finalmente, hay un salto a una dirección almacenada por el sistema operativo.
La primera acción en el kernel es guardar y probar los argumentos:
- ¿Puede el proceso escribir en el área de memoria entre Buffer y Buffer + BufferLength-1?
- si no ⇒ EFAULT
- ¿Es el FileHandle válido para este proceso?
- si no ⇒ EBADF
- ¿Está el área de memoria entre Buffer y Buffer + BufferLength-1 en la memoria principal?
- ...
Una prueba inadecuada de los argumentos todavía era común a principios y mediados de la década de 1990. Llamando a las funciones del sistema con valores puramente al azar fue suficiente para choque sistemas operativos, el crashme programa de pruebas fue capaz de demostrar esta manera impresionante. Hoy en día, todos los sistemas operativos son órdenes de magnitud más resistentes a tales ataques. Los ataques ya no son posibles con valores aleatorios, para ello son necesarios escenarios sofisticados.
Al final, el kernel ha procesado la llamada a la función y devuelve el IRETcontrol al programa. La devolución se realiza nuevamente a través de una puerta de llamada.
- Obtener la dirección de retorno de la pila
- Reconstruir registro de bandera
- Volver a la pila del espacio de usuario
- Vuelva a establecer el nivel de prioridad en 3