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:
MOV ESI, OFFSET handler
MOV DWORD PTR FS:[0], ESI
;...
Y no funciono. Luego busque un poco en internet y encontre esto:
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.
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:
.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
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).
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.
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.
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).