Hola, estoy recien empezando en esto del assembly (manejo c, pero assembly 0,1%) y quiero hacer un codecave simple, porque quiero parchar algo, quiero hacerlo a mano con un editor hexadecimal.
tengo varias preguntas:
¿en que parte del ejecutable es mejor ubicar el código del codecave? ¿una sección que tenga harto espacio en blanco?
¿como calculo la cantidad de desplazamiento desde el offset del archivo hasta el offset dónde está el codecave? creo que no es la misma al momento de cargarse el programa en memoria.
Tengo un programa que es el cual quiero parchar que hace esto:
offset 10 push parametro3
offset 14 push parametro2
offset 18 push parametro1
offset 22 call function
quiero llamar al code cave antes de "call function", y dentro del codecave duplico el codigo anterior de los push parametro
hacer algo asi:
mov eax, direccion donde volver del codecave
jmp codecave
call function
y el codigo del codecave seria:
push parametro3
push parametro2
push parametro1
push eax ; guardamos la direccion donde volver
;hacer otra cosa
ret ;
¿Porque lo estoy haciendo así? Porque tengo al menos 5 funciones que deben llamar al mismo codecave y usan la misma carga de parametros, entonces la dirección de retorno no siempre será igual. Por eso la idea es guardar la direccion de retorno dentro de eax.
Esta es más o menos la idea en un código de fasm:
si no se ejecutara jmp cave el programa imprimiría hello.
format PE console
entry start
include 'win32a.inc'
;======================================
section '.data' data readable
;======================================
hello_newline db "Hello!",10,0
bye_newline db "Bye!",10,0
;=======================================
section '.code' code readable executable
;=======================================
start:
mov eax, cave_end
jmp cave
print:
push hello_newline
cave_end:
call [printf]
call [getch]
stdcall [exit],0
cave:
push bye_newline
push eax
ret
;====================================
section '.idata' import data readable
;====================================
library msvcrt,'msvcrt.dll'
import msvcrt,\
printf,'printf',\
getch,'_getch',\
exit,'exit'
Mi principal duda, es en que lugar del ejecutable puedo escribir el codecave, y ¿cómo calculo el valor que debe tener eax y el valor del jump? esto es como si fuera viendo el archivo con un editor hexadecimal.
Por favor, si pudieran ayudarme, estoy muy entusiasmado con esto.
Hola. He modificado un poco la idea de lo que sería el codecave:
format PE console
entry start
include 'win32a.inc'
;======================================
section '.data' data readable
;======================================
hello_newline db "Hello!",10,0
bye_newline db "Bye!",10,0
;=======================================
section '.code' code readable executable
;=======================================
start:
call cave
print:
push hello_newline
cave_end:
call [printf]
call [getch]
stdcall [exit],0
cave:
pop eax ; guardamos en eax la direccion de eip previo
add eax,5 ; los 5 bytes de push hello_newline
push bye_newline
jmp eax
;====================================
section '.idata' import data readable
;====================================
library msvcrt,'msvcrt.dll'
import msvcrt,\
printf,'printf',\
getch,'_getch',\
exit,'exit'
de esta forma solo será necesario saber la dirección del codecave.
Hola!
Para hacer un inline, personalmente uso Olly.
Una vez que encuentras el lugar/es que quieres inlinear, buscas una zona en la sección ejecutable (sección .text, .code o como se llame) que tenga el espacio que necesitas (y que tengas 0s, NOPs o el relleno que el compilador ponga).
Normalmente, al final de la sección hay espacio, pero debes tener en cuenta si dicho espacio se encuentra en el ejecutable (un exe mapeado en memoria es diferente a uno en disco: las secciones se alinean, por lo que puede pasar que la sección de la memoria sea mas grande que la sección raw en el disco).
En este caso, si usas Olly, no tendrias problemas pues cuando quieras guradar los cambios hechos, te advertira sobre dicho problema, con lo que tendras que buscar otro lugar con el espacio necesario.
Saludos!