Structured Exception Handler

Iniciado por Usuario887, 13 Mayo 2020, 18:56 PM

0 Miembros y 1 Visitante están viendo este tema.

Usuario887

Hola,

pongo el tema aqui porque me refiero precisamente a su programacion en ensamblador.

Estoy intentando modificar el SEH para especificar la rutina de manejo de exception. Sin embargo lo hice de esta manera:

Código (asm) [Seleccionar]

MOV ESI, OFFSET handler
MOV DWORD PTR FS:[0], ESI
;...


Y no funciono. Luego busque un poco en internet y encontre esto:

Código (asm) [Seleccionar]

MOV ESI, OFFSET handler
PUSH ESI
PUSH DWORD PTR FS:[0] ;supongo que esto se utiliza como algun tipo de firma
MOV DWORD PTR FS:[0], ESP
;...


Este si funciona. Lo que no entiendo es por que.
¿alguien sabe por que, o en donde podria encontrar una explicacion?

Saludos y gracias de antemano.

Eternal Idol

#1
Es que no se pone un puntero a funcion ahi sino un puntero a una estructura que apunta a la estructura que estaba ahi anteriormente en su primer campo y tiene otro campo mas que es el puntero al manejador. Y asi es como se construye la cadena de manejadores.

Mas informacion en el archivo:
https://web.archive.org/web/20041011152640fw_/http://www.spiff.tripnet.se/~iczelion/Exceptionhandling.html

Y si depuramos con el WinDbg el siguiente ejemplo:
Código (asm) [Seleccionar]
.386
.model flat, stdcall

includelib kernel32.lib
ExitProcess PROTO stdcall :DWORD

.code
main:
int 3
assume fs:nothing

MOV ESI, OFFSET handler
PUSH ESI
PUSH DWORD PTR FS:[0]
MOV DWORD PTR FS:[0], ESP

xor eax, eax
mov eax, dword ptr [eax]
ret


handler:
invoke ExitProcess, 1
ret
end main


Podemos ver que al principio:
dd fs:0 l1
0053:00000000  006ff930

dd 006ff930 l2
006ff930  006ff948 77a788c0

u 77a788c0 l1
ntdll!_except_handler4:
77a788c0 8bff            mov     edi,edi

dd 006ff948 l2
006ff948  ffffffff 77a853d2

u 77a853d2 l1
ntdll!FinalExceptionHandlerPad50:
77a853d2 90              nop

Y no seguimos que ffffffff debe ser el señalador de fin de cadena.

Ahora ejecutamos nuestro programa hasta MOV DWORD PTR FS:[0], ESP

dd fs:0 l1
0053:00000000  006ff8d0

dd 006ff8d0 l2
006ff8d0  006ff930 008d101a ;en rojo la ultima estructura que existia hasta entonces

u 008d101a
seh+0x101a:
008d101a 6a01            push    1
008d101c e801000000      call    seh+0x1022 (008d1022)
008d1021 c3              ret


u 008d1022
seh+0x1022:
008d1022 ff2500208d00    jmp     dword ptr [seh+0x2000 (008d2000)]

dps 008d2000 l1
008d2000  754a4f20 KERNEL32!ExitProcessImplementation
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

Cita de: Eternal Idol en 13 Mayo 2020, 19:51 PM
Podemos ver que al principio:
dd fs:0 l1
0053:00000000  006ff930

dd 006ff930 l2
006ff930  006ff948 77a788c0

u 77a788c0 l1
ntdll!_except_handler4:
77a788c0 8bff            mov     edi,edi

dd 006ff948 l2
006ff948  ffffffff 77a853d2

u 77a853d2 l1
ntdll!FinalExceptionHandlerPad50:
77a853d2 90              nop

Y no seguimos que ffffffff debe ser el señalador de fin de cadena.

Ahora ejecutamos nuestro programa hasta MOV DWORD PTR FS:[0], ESP

dd fs:0 l1
0053:00000000  006ff8d0

dd 006ff8d0 l2
006ff8d0  006ff930 008d101a ;en rojo la ultima estructura que existia hasta entonces

u 008d101a
seh+0x101a:
008d101a 6a01            push    1
008d101c e801000000      call    seh+0x1022 (008d1022)
008d1021 c3              ret


u 008d1022
seh+0x1022:
008d1022 ff2500208d00    jmp     dword ptr [seh+0x2000 (008d2000)]

dps 008d2000 l1
008d2000  754a4f20 KERNEL32!ExitProcessImplementation

De esto puedo intentar deducir un monton de cosas aunque no se utilizar WinDbg.

Citar
Podemos ver que al principio:
dd fs:0 l1
0053:00000000  006ff930

¿Entonces existe un solo manejador de excepcion el cual se encuentra en 053h:0?
(supongo que dd es un comando y tendra que ver con dump)


dd 006ff930 l2
006ff930  006ff948 77a788c0

u 77a788c0 l1
ntdll!_except_handler4:
77a788c0 8bff            mov     edi,edi

dd 006ff948 l2
006ff948  ffffffff 77a853d2


Imagino que esta es la estructura... ¿por que termina en 0ffffffffh? es decir ¿no deberia tener un tamano fijo?  :huh:


u 008d101a
seh+0x101a:
008d101a 6a01            push    1
008d101c e801000000      call    seh+0x1022 (008d1022)
008d1021 c3              ret


Bueno este debe ser el manejador... esto explica por que no podia repetirlo las veces que queria sin utilizar la pila.

Gracias por responder y disculpa mi ignorancia (jaja).

Eternal Idol

Cita de: marax en 13 Mayo 2020, 20:32 PM
De esto puedo intentar deducir un monton de cosas aunque no se utilizar WinDbg.

Si vas a trabajar en Windows es el depurador por excelencia.

Cita de: marax en 13 Mayo 2020, 20:32 PM
¿Entonces existe un solo manejador de excepcion el cual se encuentra en 053h:0?

No, es una cadena, por eso se usa la estructura, lee el enlace que deje antes. Si el primero de la lista retorna que no manejo el error entonces el proceso de la cadena continua llamando al siguiente.

Cita de: marax en 13 Mayo 2020, 20:32 PMImagino que esta es la estructura... ¿por que termina en 0ffffffffh? es decir ¿no deberia tener un tamano fijo?  :huh:

La estructura tiene un tamaño fijo, son dos campos, el primero es un puntero a una estructura de su mismo tipo (para hacer la cadena; es una simple lista) y el segundo es el puntero al manejador, como decia el tamaño es fijo, dos punteros, dos DWORDs, 8 bytes (todo esto en 32 bits).

Cita de: marax en 13 Mayo 2020, 20:32 PMBueno este debe ser el manejador... esto explica por que no podia repetirlo las veces que queria sin utilizar la pila.

Si, ese es el manejador de mi ejemplo (el que llama a ExitProcess), si simplemente lo pusiera en fs:[0] el codigo de Windows lo usaria como un puntero a la estructura y por eso fallaria.
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

Cita de: Eternal Idol en 13 Mayo 2020, 19:51 PM
Mas informacion en el archivo:
https://web.archive.org/web/20041011152640fw_/http://www.spiff.tripnet.se/~iczelio

Voy a leer esto antes de hacer las preguntas que tengo acerca de lo que dijiste en el ultimo mensaje.

Cita de: Eternal Idol en 13 Mayo 2020, 20:37 PM
Si vas a trabajar en Windows es el depurador por excelencia.

Hablando de depuradores... no se si sea mas adecuado hacer un nuevo tema pero ¿existe una manera de que un depurador -o un depurador en si que- tenga permisos de ring 0? (me refiero a acceder a la memoria, escribir en puertos, etc...).

Gracias por responder.

Eternal Idol

Cita de: marax en 15 Mayo 2020, 18:31 PMHablando de depuradores... no se si sea mas adecuado hacer un nuevo tema pero ¿existe una manera de que un depurador -o un depurador en si que- tenga permisos de ring 0? (me refiero a acceder a la memoria, escribir en puertos, etc...).

Si pero se necesitan dos maquinas (con una sola penas podes ver), la depurada puede ser virtual, y configurar el SO de la maquina depurada para que habilite el depurador de modo Kernel:
https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/setting-up-kernel-mode-debugging-in-windbg--cdb--or-ntsd

No hay codigo para depurar pero si simbolos (PDBs en un servidor publico de Microsoft).
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