Parchear ejecutable y direcciones de memoria

Iniciado por jmpesp, 25 Junio 2019, 15:47 PM

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

jmpesp

Estoy teniendo el siguiente problema:

Digamos que abro un ejecutable con un debugger y agrego el siguiente codigo:


push rbp
mov rbp, rsp
push r9
push r8
push rdx
push rcx
sub rsp, 20
mov r9, 0
mov r8, 0x0000F7855219251      ; en esta direccion hay una cadena
mov rdx, 0x0000F7855219251    ; ^
mov rcx, 0
call user32.MessageBoxA
add rsp, 20
pop rcx
pop rdx
pop r8
pop r9
pop rbp


Funciona perfecto y sin problemas, pero a la hora de parchear el ejecutable y ejecutarlo de nuevo, las direcciones quedan obsoletas.

Es decir, la cadena ya no esta en 0x0000F7855219251 si no que se cargo en otra direccion diferente, lo mismo pasa con la direccion de user32.MessageBoxA.
Esto por supuesto produce que el programa crashee.

Para destacar: La cadena se carga en una direccion diferente, pero es la misma direccion relativa al codigo. Es decir, esta siempre a 55 bytes desde el inicio del codigo.
Lo mismo con la funcion MessageBoxA, pero la libreria user32 se carga en una direccion diferente.

Como puedo resolver este problema?

Gracias

MCKSys Argentina

Hola!

Todas las direcciones de los binsarios cambian cada vez que se ejecutan. Mas aun con ASLR. Para saber mas sobre el tema, busca info sobre la tabla de relocaciones de los binarios.

Ahora, para solucionar el problema, como bien has dicho, la direccion es relativa al inicio del ejecutable. Si miras en memoria, veras que aunque cambie la direccion, la "distancia" entre el encabezado MZ del binario y la cadena es la misma.

Para obtener la la direccion en que esta corriendo el binario, llama a GetModuleHandle con NULL (cero) y te devolvera la base del binario. Despues solo debes sumarle el offset (distancia) de la cadena y listo.

Si la API no esta en la IAT, vas a tener que usar un resolver.

Saludos!
MCKSys Argentina

"Si piensas que algo está bien sólo porque todo el mundo lo cree, no estás pensando."


jmpesp

Cita de: MCKSys Argentina en 25 Junio 2019, 20:14 PM
Hola!

Todas las direcciones de los binsarios cambian cada vez que se ejecutan. Mas aun con ASLR. Para saber mas sobre el tema, busca info sobre la tabla de relocaciones de los binarios.

Ahora, para solucionar el problema, como bien has dicho, la direccion es relativa al inicio del ejecutable. Si miras en memoria, veras que aunque cambie la direccion, la "distancia" entre el encabezado MZ del binario y la cadena es la misma.

Para obtener la la direccion en que esta corriendo el binario, llama a GetModuleHandle con NULL (cero) y te devolvera la base del binario. Despues solo debes sumarle el offset (distancia) de la cadena y listo.

Si la API no esta en la IAT, vas a tener que usar un resolver.

Saludos!

El problema es que para llamar a GetModuleHandle (o a cualquier funcion de la API) necesito de igual manera conocer la direccion de esta funcion (kernel32 + offset).

Si en el desensamblador "hardcodeo" esta direccion (call kernel32.GetModuleHandle) va a suceder lo mismo.

Gracias por tu respuesta



LUX-FERO

HI.

Puede utilizar el ejemplo:

EIP - 350

o EDI - ..........

En lugar de un valor fijo.
Saludos.

jmpesp

Cita de: LUX-FERO en 27 Junio 2019, 16:42 PM
HI.

Puede utilizar el ejemplo:

EIP - 350

o EDI - ..........

En lugar de un valor fijo.
Saludos.

Podria funcionar para localizar la cadena, no lo habia pensado.

Pero para localizar la funcion parece que voy a tener que parsear la cabecera PE.

Gracias