elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Usando Git para manipular el directorio de trabajo, el índice y commits (segunda parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  ASM (Moderador: Eternal Idol)
| | | |-+  Ejemplo de la necesidad de la instruccion CLI
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Ejemplo de la necesidad de la instruccion CLI  (Leído 2,756 veces)
Usuario887


Desconectado Desconectado

Mensajes: 310


Ver Perfil
Ejemplo de la necesidad de la instruccion CLI
« en: 9 Mayo 2020, 17:58 pm »

Hola,

Entiendo bien lo que hace esta instruccion: desactiva las interupciones enmascarables. Y se que existen variedad de ejemplos acerca de su filosofia, sin embargo no me queda clara su necesidad real; creo que muchas soluciones podrian implementarse mas facilmente sin ello.

Un ejemplo concreto: estaba revisando un codigo en el que se utiliza:

Código
  1. CLI
  2. PUSH DS
  3. PUSH CS
  4. POP DS
  5. JZ _noChar
  6. LEA BX, _buffer
  7. PUSH SI
  8. MOV SI, WORD PTR [_index]
  9. MOV BYTE PTR [BX+SI], AL
  10. INC SI
  11. MOV WORD PTR [_index], SI
  12. POP SI
  13. MOV BX, WORD PTR [_index]
  14. CMP BX, 32H
  15. JB _noOverlapping
  16. MOV AX, 0
  17. MOV WORD PTR [_index], AX
  18. _noOverlapping:
  19. _noChar:
  20. ;en seguida se recupera el registro DS
  21.  
Este es el fragmento de un hook a una rutina de interrupcion que guarda en un buffer indexado el contenido de AL cada vez que es ejecutada.
Sin embargo no entiendo, por ejemplo, en este caso, cual es la necesidad de ello.

Tengo las siguientes suposiciones:
¿es porque el contenido de los registros se pierde? ¿entonces por que no ademas de guardar el regustro EFLAGS en la pila no tambien el contenido de los registros?
¿es por velocidad de ejecucion? Me parece un prejuicio aceptable.

En verdad solo me pregunto si alguien conoce bien la necesidad de tal cosa y tiene la amabilidad de compartirlo conmigo.

Gracias por su tiempo. Saludos.


Por cierto... El buffer tiene un tamano de 32 unidades hexadecimales, por tanto el
Código
  1. MOV BX, WORD PTR [_index]
  2. CMP BX, 32H
  3. JB _noOverlapping
  4.  

No subestimo la intuicion, lo digo solo por si acaso.  :silbar:


« Última modificación: 9 Mayo 2020, 18:10 pm por marax » En línea

Eternal Idol
Kernel coder
Moderador
***
Desconectado Desconectado

Mensajes: 5.937


Israel nunca torturó niños, ni lo volverá a hacer.


Ver Perfil WWW
Re: Ejemplo de la necesidad de la instruccion CLI
« Respuesta #1 en: 10 Mayo 2020, 01:10 am »

Entiendo bien lo que hace esta instruccion: desactiva las interupciones enmascarables. Y se que existen variedad de ejemplos acerca de su filosofia, sin embargo no me queda clara su necesidad real; creo que muchas soluciones podrian implementarse mas facilmente sin ello.

https://en.wikipedia.org/wiki/Interrupt_flag#CLI

"CLI is commonly used as a synchronization mechanism in uniprocessor systems. For example, a CLI is used in operating systems to disable interrupts so kernel code (typically a driver) can avoid race conditions with an interrupt handler."

En principio es para evitar que tu codigo sea interrumpido en medio de su ejecucion, para evitar la reentrada. ¿Que manera mas sencilla que cli/sti propones?

Mas informacion y ejemplo practico: http://www.plantation-productions.com/Webster/www.artofasm.com/DOS/ch17/CH17-4.html#HEADING4-139

¿es porque el contenido de los registros se pierde? ¿entonces por que no ademas de guardar el regustro EFLAGS en la pila no tambien el contenido de los registros?

En el fragmento que dejaste no se guarda EFLAGS, pero bueno entiendo que yo tengo ese libro en papel, en realidad se empuja EFLAGS en la pila para simular el estado de llamada a una interrupcion, sino se joderia la pila cuando el codigo original de la interrupcion (o el de la int 16h) se terminara con IRET.

"In Real-Address Mode, the IRET instruction preforms a far return to the interrupted program or procedure. During this operation, the processor pops the return instruction pointer, return code segment selector, and EFLAGS image from the stack to the EIP, CS, and EFLAGS registers, respectively, and then resumes execution of the interrupted program or procedure."

https://www.felixcloutier.com/x86/iret:iretd


« Última modificación: 10 Mayo 2020, 01:12 am por Eternal Idol » En línea

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón
Usuario887


Desconectado Desconectado

Mensajes: 310


Ver Perfil
Re: Ejemplo de la necesidad de la instruccion CLI
« Respuesta #2 en: 10 Mayo 2020, 12:26 pm »

¿Que manera mas sencilla que cli/sti propones?
Antes del ejemplo que muestras en seguida se me ocurria salvar todos los registros en la rutina del ISR para que asi, al terminar, los registros continuasen con su valor original (en la cadena de "valores originales") tal como el sistema operativo salva un PCB antes de entrar en otro proceso. Sin ambargo entiendo ahora por que se desactivan las interrupciones en ese fragmento:

Código
  1. CLI
  2. PUSH DS
  3. PUSH CS
  4. POP DS
  5. JZ _noChar
  6. LEA BX, _buffer
  7. PUSH SI
  8. MOV SI, WORD PTR [_index]
  9. MOV BYTE PTR [BX+SI], AL
  10. INC SI
  11. MOV WORD PTR [_index], SI
  12. ;////////////////esta es la region critica
  13. POP SI
  14. MOV BX, WORD PTR [_index]
  15. CMP BX, 32H
  16. JB _noOverlapping
  17. MOV AX, 0
  18. MOV WORD PTR [_index], AX
  19. _noOverlapping:
  20. _noChar:
  21. ;en seguida se recupera el registro DS
  22.  
Si ocurre una reentrada en ese punto, la direccion de memoria a la que hace referencia _index podria ser incrementada dos veces si se presiona una tecla en ese preciso momento.
Y viendo el codigo dos veces estoy viendo mas de una sección critica. Ahora si tiene sentido.
Aunque sigo con una pregunta:
¿deben todos los ISR salvar el valor de los registros que utiliza? Porque no se por que siento que en algun momento un ISR no me va a funcionar porque alguna llamada a un servicio de interrupcion va a modificar un registro que estoy a punto de utilizar. Llamame paranoico... lo soy. Solo me pregunto si como norma general los ISR deben hacer eso. De hecho tambien seria curiosidad por el funcionamiento (ademas de paranoia).

Este link lo voy a guardar. Estaba buscando algo asi desde hace rato. Muchas gracias por citarlo.

En el fragmento que dejaste no se guarda EFLAGS, pero bueno entiendo que yo tengo ese libro en papel, en realidad se empuja EFLAGS en la pila para simular el estado de llamada a una interrupcion, sino se joderia la pila cuando el codigo original de la interrupcion (o el de la int 16h) se terminara con IRET.
Esto lo lei varias veces pero no logro entender precisamente a lo que te refieres.
No se guarda EFLAGS pero eso es implicito en una llamada a una interrupcion, ¿no?.

yo tengo ese libro en papel
¿Cual libro?

se empuja EFLAGS en la pila para simular el estado de llamada a una interrupcion, sino se joderia la pila cuando el codigo original de la interrupcion (o el de la int 16h) se terminara con IRET.
Esta bien... te refieres con simular a mantener la integridad de la entrada inmediatamente anterior de la cadena de ejecucion de las interrupciones (en la pila), ¿no?.

Gracias por la ayuda y el enlace.
Saludos.
En línea

Eternal Idol
Kernel coder
Moderador
***
Desconectado Desconectado

Mensajes: 5.937


Israel nunca torturó niños, ni lo volverá a hacer.


Ver Perfil WWW
Re: Ejemplo de la necesidad de la instruccion CLI
« Respuesta #3 en: 10 Mayo 2020, 13:07 pm »

Aunque sigo con una pregunta: ¿deben todos los ISR salvar el valor de los registros que utiliza?

"A typical ISR structure is shown below
<save the registers used in the ISR>
sti     ; enable further interrupts
...
<ISR body>
...
<restore the saved registers>
iret    ; return to the interrupted program"

https://link.springer.com/chapter/10.1007/0-387-27155-4_15

Esto lo lei varias veces pero no logro entender precisamente a lo que te refieres.

Que yo sepa el hook antes de la instruccion cli llama al ISR que estaba originalmente en 09h y al servicio 01h del ISR de la interrupcion 16h:

Código
  1. PUSHF ;empuja EFLAGS en la pila
  2. CALL CS :_oldISR
  3. MOV AH,01H
  4. PUSHF  ;empuja EFLAGS en la pila
  5. CALL CS:_chkISR

¿Cual libro?

The Rootkit Arsenal Escape and Evasion in the Dark Corners of the System de Bill Blunden (2009), HookTSR es un ejemplo que viene en el segundo capitulo (no se quien habra copiado a quien ya que no diste la fuente de tu fragmento).

Esta bien... te refieres con simular a mantener la integridad de la entrada inmediatamente anterior de la cadena de ejecucion de las interrupciones (en la pila), ¿no?.

Para poder llamar al ISR hace falta poner EFLAGS en la pila ya que igual que el hook de ISR debe terminar con IRET y esa instruccion asume que EFLAGS fue empujado en la pila. Por cierto hace falta ejecutar CLI en el hook justamente por haber llamado a los otros ISRs que ejecutaron STI, el hook es llamado con las interrupciones ya deshabilitadas como se explica en el enlace de arriba (15.1    Interrupt Processing in the Real Mode).
En línea

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón
Usuario887


Desconectado Desconectado

Mensajes: 310


Ver Perfil
Re: Ejemplo de la necesidad de la instruccion CLI
« Respuesta #4 en: 10 Mayo 2020, 13:38 pm »

<save the registers used in the ISR>
:rolleyes:

Que yo sepa el hook antes de la instruccion cli llama al ISR que estaba originalmente en 09h y al servicio 01h del ISR de la interrupcion 16h
Si, precisamente, solo me intrigaba como estabas adivinando tantas cosas, ya vi a que te refieres con que tienes el libro en papel. Estaba pensando que hacias un juego de palabras que no estaba entendiendo.

The Rootkit Arsenal Escape and Evasion in the Dark Corners of the System de Bill Blunden (2009), HookTSR es un ejemplo que viene en el segundo capitulo (no se quien habra copiado a quien ya que no diste la fuente de tu fragmento).
Buen chiste.
Bill Blunden y Matt Pietrek desnudaron a Microsoft...
https://books.google.es/books/about/Undocumented_Windows.html?id=HLhbcgAACAAJ&redir_esc=y

Para poder llamar al ISR hace falta poner EFLAGS en la pila ya que igual que el hook de ISR debe terminar con IRET y esa instruccion asume que EFLAGS fue empujado en la pila. Por cierto hace falta ejecutar CLI en el hook justamente por haber llamado a los otros ISRs que ejecutaron STI, el hook es llamado con las interrupciones ya deshabilitadas como se explica en el enlace de arriba (15.1    Interrupt Processing in the Real Mode).
Si si... esto lo sabia, solo no habia aprendido a distinguir un sector critico.

Gracias por tu ayuda.
« Última modificación: 10 Mayo 2020, 13:46 pm por marax » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Equivalencia C a ASM de una instrucción.
Electrónica
Meta 3 6,771 Último mensaje 19 Octubre 2008, 06:24 am
por MARCO_RECARGADO
se atasca en una instruccion
Java
Tyrz 9 5,657 Último mensaje 21 Enero 2011, 20:57 pm
por kasiko
Instrucción % en C++?
Programación General
.:UND3R:. 1 2,346 Último mensaje 17 Enero 2012, 16:49 pm
por pucheto
Instruccion if
Programación C/C++
BJM 3 2,103 Último mensaje 22 Octubre 2012, 17:48 pm
por rir3760
Instruccion sscanf [C]
Programación C/C++
oblivionxor 6 2,770 Último mensaje 26 Febrero 2013, 20:36 pm
por oblivionxor
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines