[FADB] 3. El paso de parámetros por pila

FUNDAMENTOS DE LOS ATAQUES POR DESBORDAMIENTO DE BUFFER

Generalmente, al llamar a funciones también queremos pasarles unos ciertos valores para que trabajen con ellos, lo que llamamos parámetros. El convenio más utilizado es el paso de parámetros por pila. Los parámetros en la pila se pasan en orden inverso a como los recoge la función (¡recordemos el funcionamiento de la pila!).

Supongamos por ejemplo que tenemos una función que realiza alguna operación con dos números enteros, cuya entrada se encuentra en la dirección 0x07000000. Para pasarle por pila los números 10 (A en hexadecimal) y 20 (14 en hexadecimal) como primer y segundo parámetro respectivamente, necesitaríamos el siguiente código:

0x08000000 -> PUSH 20 (Segundo parámetro)
0x08000005 -> PUSH 10 (Primer parámetro)
0x0800000A -> CALL 0x07000000
0x0800000F -> MOV EAX,EBX

Después de la llamada CALL, la pila quedaría como sigue (si consideramos inicialmente ESP = 0x09000000):

0x09000000 -> ??
0x08FFFFFF -> 00
0x08FFFFFE -> 00
0x08FFFFFD -> 00
0x08FFFFFC -> 14 <-- Segundo parámetro (PUSH 20)

0x08FFFFFB -> 00
0x08FFFFFA -> 00
0x08FFFFF9 -> 00
0x08FFFFF8 -> 0A <-- Primer parámetro (PUSH 10)

0x08FFFFF7 -> 08
0x08FFFFF6 -> 00
0x08FFFFF5 -> 00
0x08FFFFF4 -> 0F <-- Dirección de retorno de CALL

con ESP = 0x08FFFFF4 y EIP = 0x07000000. La función entrante en 0x07000000 se encuentra pues que tiene el primer parámetro en ESP+4 y el segundo en ESP+8 (y sucesivamente de 4 en 4 si son varios parámetros). Así pues el código

0x07000000 -> ADD 0x4,ESP
0x07000003 -> POP EAX
0x07000004 -> POP EBX

pone el primer parámetro (0x0000000A) en EAX y el segundo (0x00000014) en EBX, quedando ESP = 0x09000000. Por lo tanto, antes de poder ejecutar la instrucción RET para retornar de la función, tendremos que devolver ESP a su valor original para que pueda extraer la dirección de retorno adecuada:

SUB 0xC,ESP
RET

Restamos 12 (C en hexadecimal), 2 x 4 bytes por cada parámetro + 4 bytes de la dirección de retorno, 12 bytes en total, a ESP = 0x09000000 para convertirlo en 0x08FFFFF4, donde se encuentra la dirección de retorno correcta (0x0800000F). Acto seguido RET saca de la pila 0x0800000F y pone este valor en EIP, con lo que la ejecución continúa en dicha dirección con la instrucción MOV EAX,EBX, con ESP = 0x08FFFFF8.

Comments

Popular Posts