Mucho se a hablado de hooks en windows, tan solo basta con buscar tutoriales en google
y obtendremos cientos de resultados.
Pero no sucede lo mismo en linux, por eso se me ocurrió hacer éste tutorial.
Pero recuerda! esta técnica solo funciona en la aplicación en la que se ejecuta aun que
con la suficiente comprensión se puede llevar a algo más "grande", pero en si mismo con ésto
lograran entender cuales son los mecanismos de hooking ya que de nada serviría un código
generico sin entender las bases, espero que quede claro...
Las funciones que tenemos por costrumbre usar(por ej:VirtualProtect)cambian relativamente,
pero POSIX nos ayudara con ésta tarea, entonces antes de continuar tengo que hacer algunas
aclaraciones.


Tanto éste tutorial, como los códigos proporcionados estan hechos 100% por mi NvK, con
el objetivo de demostrar como funcionan los hooks en x86, por lo tanto toma nota :
NO ME HAGO RESPONSABLE POR EL MAL USO QUE PUEDAS DARLE, ESTE TUTORIAL TIENE FINES EDUCATIVOS.

Temario :
[+] Introducción.
[+] POSIX y Syscalls para hooking.
[+] getpagesize y mprotect.
[+] Programando nuestra función a modificar.
[+] Usando gdb para depurar y encontrar nuestro código.
[+] Programando nuestro hook-code.
[+] Viendo nuestro hook en gdb
[+] Unhook - restaurando nuestra función 1° parte
[+] Unhook - restaurando nuestra función 2° parte.
[+] Debugeando el unhook.
[+] Código final.
[+] Conclusiones finales.
[+] Despedida.


Introducción:
Debo aclarar que la poca documentación que se puede encontrar en internet es bastante oscura,
y que hasta ahora no habia visto ningun "how to" o paso a paso, por lo que tratare de explicar
ésta cuestión lo más detalladamente posible, ademas introduciré mis propios conceptos y técnicas
por ésto te pido que no trates de seguir el tutorial "mecanicamente" sino que te esfuerce por
comprender y así poder desarrollar tu propia metodología y estudio.
Una de las tecnicas para la alineación de pagina(tema que tocare más adelante) se me ocurrió
al leer un artículo de self-mutating en linux x64, claro que es solo una idea y que aquí
se trata el mundo de los hooks en x86, no obstante dejare el link(junto con otros) al final
de ésta lectura.

Para ésta prueba de concepto usare un bactrack 5 r3 virtualizado, pero claro que si entiendes
ésta tecnica podrías llevarla a cualquier plataforma linux.

POSIX y Syscalls para hooking:
Antes de empezar a programar quiero aclarar algunos conceptos.
Ya que, el lector podría pensar que las funciones usadas en windows son las mismas que en
linux y que por lo tanto funcionan de la misma manera, ésto ademas de estar lejos de la verdad
implica una lectura acerca de las normas POSIX tanto como lo que son los syscalls y para que
sirven(ademas de su relación con el kernel), no me expandire en éstos conceptos ya que,
la wikipedia nos los explica a la perfección, y aun que no es necesario entenderlos 100% te
serviría para entender el mundo de linux.
Hoy tan solo usaremos 2 funciones y aun que en un futuro me gustaría hablar sobre inyecciones
y sus técnicas, el entender éste artículo te introducirá en las metodologías usadas en linux
por ende, si el tema es de tu interés podrás buscar por tu cuenta técnicas relacionadas y
entenderlas, aunque ésto último lo dejare a criterio personal.

getpagesize y mprotect:
Entonces las 2 funciones usadas seran:
0x1: getpagesize - consigue el tamaño de una pagina de memoria.
0x2: mprotect - Ajusta permisos de memoria.
int getpagesize(void);
Se encuentra en <unistd.h> y es un syscall en algunas arquitecturas para el símbolo
PAGE_SIZE, encontrado en el kernel, pero recuerda que éste valor depende de la arquitectura
de tu ordenador por lo que no siempre debería tener un valor de 4096d(0x1000h).
La usaremos junto a mprotect para "desprotejer" un area de memoria alineada en la cual
escribiremos nuestro hook.
Más información en : [Enlace externo eliminado para invitados]
int mprotect(void *addr, size_t len, int prot);
Se encuentra en <sys/mman.h> y es un system call.
Su uso es cambiar la protección de la memoria, y debe estar alineado hasta un límite de
página, usar los siguientes flags para los accesos a la memoria.
PROT_READ - Las paginas pueden ser de lectura.
PROT_WRITE - Las paginas pueden ser de escritura.
PROT_EXEC - Las paginas pueden ser ejecutadas.
PROT_NONE - Paginas no pueden ser accesadas por la memoria.
Si intentaramos escribir una region de memoria de un programa que esta protegida
o incluso si se encuentra fuera del rango de memoria(por ejemplo la del kernel)
la señal SIGSEGV(segment violation) sera utilizada como terminador del programa.
Obviamente la alineacion de pagina la conseguiremos con un pequeño algoritmo y usando
getpagesize.
Más información en : [Enlace externo eliminado para invitados]

Programando nuestra función a modificar.
Es hora de empezar a programar!, primero agregaremos los includs y definiremos los tipos
de datos que vamosa usar:
#include <sys/mman.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

typedef unsigned long 	_dword;
typedef unsigned short 	_word;
typedef unsigned int 		_uint32;
typedef unsigned char		_byte;
typedef void *          _pvoid;

// funcion a hookear
void xprintf()
{
  printf("[*] xprintf llamada!");
}

// funcion de escritura
void xwrite()
{
  printf("[!] xprintf hookeada.\n");
}

int main()
{
  return 0;
}
Hasta aquí lo hicimos bien, ya definidos los tipos de datos y la función que sera hookeada
ahora es debemos obtener la dirección de memoria de la función a hookear, es decir xprintf.
para compilar debemos movernos a la ruta donde se encuentra nuestro .c en mi caso hook.c
y compilaremos con el siguiente comando:
gcc -g hook.c

código:
int main()
{
  printf ("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n");
  printf ( "Direccion de funcion a hookear: \t0x%lx\n", (_dword)&xprintf );
  printf ("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n\n");
}
Imagen


En mi caso la direccion devuelta fue de 0x8048538(recuerda que éste valor puede cambiar es tu maquina).

Usando gdb para depurar y encontrar nuestro código:
Antes de programar nuestra función, quiero hablarles acerca de gdb el cual es un depurador
(sin GUI como en los viejos tiempos) que nos sera útil para entender que es lo que estamos
haciendo y buscar nuestra función.
NOTA: No explicare todo acerca de la depuración en linux ya que no es el objetivo del tutorial,
pero si quieres documentación al respecto te dejo éste enlaze:

[Enlace externo eliminado para invitados]

Primero cargaremos nuestro .out, para que que funcione es necesario que hayas compilado con el flag -g.
Ok nos vamos a la ruta de nuestro .out y ponemos el siguiente comando:
gdb a.out (aun que también puedes cargar gdb directamente y luego hacer file a.out)

Imagen


una vez compilado(con el flag -g recuerda) introduce el comando disassemble main:
NOTA: Para que no te confundas las direcciones recuerda dejar solo la función xprintf en el main
ejemplo :
int main()
{
  xprintf();
  
  return 0;
}
disassemble main
Este es el resultado:
Dump of assembler code for function main:
   0x08048702 <+0>:	push   %ebp
   0x08048703 <+1>:	mov    %esp,%ebp
   0x08048705 <+3>:	and    $0xfffffff0,%esp
   0x08048708 <+6>:	call   0x8048524 <xprintf>
   0x0804870d <+11>:	mov    $0x0,%eax
   0x08048712 <+16>:	mov    %ebp,%esp
   0x08048714 <+18>:	pop    %ebp
   0x08048715 <+19>:	ret
Como podemos ver en 0x08048708 hay un call(0x8048524) que es el que contiene la direccion
de la función a hookear osea xprintf.
NOTA : Anteriormente el valor de xprintf me daba 0x8048538 y ahora 0x8048524, ésto sucedió por
que en el transcurso del tutorial había cambiado la posición de una de las funciones así que tan solo
ignóralo.

Desensamblamos una vez más:
disassemble 0x8048524
Dump of assembler code for function xprintf:
   0x08048524 <+0>:	push   %ebp
   0x08048525 <+1>:	mov    %esp,%ebp
   0x08048527 <+3>:	sub    $0x18,%esp
   0x0804852a <+6>:	movl   $0x80487e0,(%esp)
   0x08048531 <+13>:	call   0x8048450 <puts@plt>
   0x08048536 <+18>:	leave  
   0x08048537 <+19>:	ret
el push ebp, mov esp, ebp es el stack frame que se crea cada vez que creamos una función,
sirve para activar el direccionamientos y "habilitar" el paso de parametros. Ya he hecho
un tutorial referente a éste tema.

Resultador en imagen:
Imagen


Programando nuestro hook-code.
Es hora de programar nuestra función que hookeara a xprintf. Comentare el código para que
pueda ser comprendido.
void hook_memory_addr(void *addr, void *hijack_addr) // addr = xprintf | hijack_addr = xwrite
{
  // obtenemos el tamaño de una pagina de memoria.
  int page_size= getpagesize();
  
  // escribimos nuestro código de salto.
  _byte jmp_opcodes[] =
  {
    0xe9  ,                         // - JMP
    0x00  , 0x00  , 0x00  , 0x00  , // - Futura direccion de la funcion a saltar.
    0xc3                            // - RETN
  };
  // aquí obtendremos una copia de *addr es decir la direccion de nuestra función a hookear
  // ya que addr(de parametro) la usaremos para la alineacion de pagina necesaria para mprotect.
  _dword *p_addr = (_pvoid)addr; // direccion original
  // direccion a hookear
  printf ( "Direccion de funcion a hookear: \t\t\t0x%lx\n", (_dword)p_addr );
  
  // esto alinea la direccion de memoria con respecto al tamaño de una pagina.
  addr -= ((_dword)addr % page_size);
  // colocaremos la direccion de xprintf, el tamaño de la pagina (que estara alineado)
  // y fijamos los permisos de escritura, lectura, escritura y ejecución.
  mprotect(addr, page_size , (PROT_READ | PROT_WRITE | PROT_EXEC) );
  
  // Direccion alineada.
  printf ( "Direccion de funcion alineada a una pagina de memoria: \t0x%lx\n", (_dword)addr );
  
  // esta es la tecnica de obtener la longitud de salto clasica, restamos la direccion
  // de la función de escritura(xwrite) con la que queremos hookear(xprintf)
  _dword jmp_size = (_dword)((_dword)hijack_addr - (_dword)p_addr);
  jmp_size -= 0x5; // alineación
  
  // Tamaño del salto.
  printf ( "Tam. del salto: 0x%lx\n", (_dword)jmp_size );
  
  // se copia desde la posicion 1 del array por que ahí esta el opcode de salto(0xe9)
  // y copiamos 0x4 por que es la longitud de una direccion de memoria(4 bytes).
  memcpy(&jmp_opcodes[1], (_dword *)&jmp_size, 0x4);
  
  // solo para ver el código del salto completo.
  int opcodes= 0;
  for(;opcodes<sizeof(jmp_opcodes);opcodes++)
    printf("-opcodes : 0x%x\n", jmp_opcodes[opcodes]);
  
  // finalmente hookeamos, copiando el contenido de jmp_opcodes el cual tendra nuestro
  // código de salto a xprintf que no es más que la direccion de la función a hookear 
  // usamos memccpy que copiara el contenido de jmp_opcodes a xprintf hasta encontrar 0xc3
  // que es el opcode para RETN (necesario para salir de la función correctamente).
  memccpy((_dword *)p_addr, (_byte*)jmp_opcodes, 0xc3, sizeof(jmp_opcodes));
  
}
Si probamos nuestra función ahora veremos que se ha hookeado correctamente, y ademas obtendremos
un plus de información que nos servira para saber que es lo que hicimos.
Output:
Direccion de funcion a hookear: 			0x8048524
Direccion de funcion alineada a una pagina de memoria: 	0x8048000
Tam. del salto: 0xf
-opcodes : 0xe9
-opcodes : 0xf
-opcodes : 0x0
-opcodes : 0x0
-opcodes : 0x0
-opcodes : 0xc3
[!] xprintf hookeada.
Imagen


Viendo nuestro hook en gdb.
Vamos a darle un rapido vistaso a lo que hicimos y como se ve tras un depurador.
disassemble main
Dump of assembler code for function main:
   0x08048702 <+0>:	push   %ebp
   0x08048703 <+1>:	mov    %esp,%ebp
   0x08048705 <+3>:	and    $0xfffffff0,%esp
   0x08048708 <+6>:	sub    $0x10,%esp
   0x0804870b <+9>:	movl   $0x8048538,0x4(%esp)
   0x08048713 <+17>:	movl   $0x8048524,(%esp)
   0x0804871a <+24>:	call   0x804854c <hook_memory_addr> <---- funcion hookeadora.
   0x0804871f <+29>:	call   0x8048524 <xprintf>          <---- xprintf hookeada.
   0x08048724 <+34>:	mov    $0x0,%eax
   0x08048729 <+39>:	leave  
   0x0804872a <+40>:	ret
NOTA: Si ahora mismo desensamblamos 0x8048524(xprintf) no encontraremos el jmp ya que el
programa no se ha iniciado y la función hook_memory_addr no se a llamado


Ahora pondremos un breakpoint en 0x0804871f, para ver como quedo nuestra función modificada
b *0x0804871f
y luego:
run

Una vez iniciado el programa se detiene en nuestro breakpoint y procederemos a mirar los
registros:
info registers
...
eip            0x804871f	0x804871f <main+29>
...
Imagen


El que nos interesa a nosotros es EIP(INSTRUCTION POINTER) ya que es el que contiene el
flujo de nuestro programa y ahora mismo apuntara a nuestra función(xprintf)
eip            0x804871f	0x804871f <main+29>
Con esta información desensamblaremos 0x804871f y veremos nuestra función.
disassemble 0x804871f

...
=> 0x0804871f <+29>:	call   0x8048524 <xprintf>
...
Nosotros vamos a buscar el call a xprintf en este caso se encuentra en 0x8048524 y
lo desensamblaremos para ver que ha pasado.
Como vemos, hemos sobreescrito el stack frame con el código de salto.
disassemble 0x8048524
Dump of assembler code for function xprintf:
   0x08048524 <+0>:	jmp    0x8048538 <xwrite> <--- jump code
   0x08048529 <+5>:	ret                       <--- retorno de la función
   0x0804852a <+6>:	movl   $0x80487f0,(%esp)
   0x08048531 <+13>:	call   0x8048450 <puts@plt>
   0x08048536 <+18>:	leave  
   0x08048537 <+19>:	ret
Imagen

FUNCION HOOKEADA!

Unhook - restaurando nuestra función 1° parte.
Anteriormente pudimos apreciar como se ha hookeado la función correctamente, lo que haremos
ahora es restaurar la función a su estado anterior, de éste modo si alguien decide depurar
nuestra aplicación en run-time no se encontrara con nada.
void __save_memory_addr(void *addr, _byte save_buffer[])
{
  _byte unhook_bytes[6] = 
  {
    // Configuración del stack frame.
    0x55,             // - PUSH EBP
    0x89, 0xe5,       // - MOV EBP, ESP
    0x00, 0x00, 0x00, // - 3 bytes de la función sobreescrita.
  };
  _byte save_original_addr[6];
  
  // mover la dirección de xprintf(addr) al buffer copiando los 6 primeros bytes
  // 3 del push ebp, mov ebp, esp.
  // los otros 3 bytes seran los de la instrucción de la función
  // (recuerda que antes aquí escribimos el ret del jmp)
  memcpy((_byte *)save_original_addr, (_dword *)addr, 6);
  
  // ahora copiamos desde la posición 3, guardado de la función en el buffer(save_original_addr)
  // a unhook_bytes sobreescribiendo los 0x00, 0x00, 0x00 sin tocar el push ebp, mov ebp, esp.
  memmove((_byte *)&unhook_bytes[3], (_byte *)&save_original_addr[3], 3);
  
  // y por último copiamos el código de unhook_bytes a save_buffer (que es nuestro parametro).
  memcpy((_byte *)save_buffer, (_byte *)unhook_bytes, sizeof(unhook_bytes));
  
  // solo para ver lo que hicimos
  int b=0;
  for(;b<6;b++)
  {
    printf("opcodes guardados 0x%x\n", unhook_bytes[x]);
  }
  
}
Ahora es tan facil como llamarlo desde el main(recuerda antes de hook_memory_addr).
int main()
{
  // contiene los 6 primeros bytes que seran guardados.
  _byte buf[6];
  // a éste punto ya guardamos los 6 primeros bytes de la función a hookear.
  __save_memory_addr(xprintf, buf);
  
  // hookeamos.
  hook_memory_addr(xprintf, xwrite);
  
  // función sobreescrita.
  xprintf();
  
  return 0;
}
Opcode guardados.
...
// stack frame
opcodes guardados 0x55
opcodes guardados 0x89
opcodes guardados 0xe5
// Estas son las instrucciones de la función xprintf
opcodes guardados 0x83 
opcodes guardados 0xec
opcodes guardados 0x18
...
De otra forma para que quede más legible(desensamblado)
804853b: 83 ec 18 sub $0x18,%esp

Imagen


Unhook - restaurando nuestra función 2° parte.
Bien ya hemos salvado los bytes de la función que seran sobreescrito(usando __save_memory_addr),
pero ésto no es todo, ahora nos queda mover esos bytes de vuelta a la función xprintf.
Para ésto vamos a terminar con un simple memmove para ello haremos ésta pequeña función:
void unhook_memory_addr(void* addr, _byte unhook_bytes[])
{
  // Muy facil de entender, movemos los 6 bytes salvados(del buffer unhook_bytes)pasado como
  // parametro a addr que es xprintf, y así restauramos la función original.
  memmove((_dword*)addr, (_byte*)&unhook_bytes[0], 6);
}
Ahora procedemos a la fase final, unhookear la función.
int main()
{
  _byte buf[6]; // contiene los 6 primeros bytes que seran guardados.
  // salvamos los 6 primeros bytes en buf.
  __save_memory_addr(xprintf, buf);
  
  // llamamos a la función original.
  xprintf();
  
  // hookeamos
  hook_memory_addr(xprintf, xwrite);
  
  // llamamos a la función hookeada
  xprintf();
  
  // restauramos la función a la orignal
  unhook_memory_addr(xprintf, buf);
  
  // llamamos a la función restaurada.
  xprintf();
  
	return 0;
}
Debugeando el unhook.
Antes de terminar vamos a ver como quedo nuestra función restaurada en gdb.
...
0x08048780 <+79>:	call   0x8048524 <xprintf>
...
(gdb) b *0x08048780
Breakpoint 1 at 0x8048780: file hook.c, line 100.
(gdb) r
...
Starting program: /root/Desktop/a.out 
...
...
Breakpoint 1, main () at hook.c:100
100	  xprintf();
(gdb) disassemble 0x8048524
Dump of assembler code for function xprintf:
   0x08048524 <+0>:	push   %ebp
   0x08048525 <+1>:	mov    %esp,%ebp
   0x08048527 <+3>:	sub    $0x18,%esp
   0x0804852a <+6>:	movl   $0x8048850,(%esp)
   0x08048531 <+13>:	call   0x8048450 <puts@plt>
   0x08048536 <+18>:	leave  
   0x08048537 <+19>:	ret    
End of assembler dump.
Imagen


Como ven la función se ha restaurado correctamente.

Código final.
#include <sys/mman.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

typedef unsigned long 	_dword;
typedef unsigned short 	_word;
typedef unsigned int 		_uint32;
typedef unsigned char		_byte;
typedef void *          _pvoid;

// funcion a hookear
void xprintf()
{
  printf("[*] xprintf llamada!");
}

// funcion de escritura
void xwrite()
{
  printf("[!] xprintf hookeada.\n");
}

void hook_memory_addr(void *addr, void *hijack_addr) // addr = xprintf | hijack_addr = xwrite
{
  // obtenemos el tamaño de una pagina de memoria.
  int page_size= getpagesize();
  
  // escribimos nuestro código de salto.
  _byte jmp_opcodes[] =
  {
    0xe9  ,                         // - JMP
    0x00  , 0x00  , 0x00  , 0x00  , // - Futura direccion de la funcion a saltar.
    0xc3                            // - RETN
  };
  // aquí obtendremos una copia de *addr es decir la direccion de nuestra función a hookear
  // ya que addr(de parametro) la usaremos para la alineacion de pagina necesaria para mprotect.
  _dword *p_addr = (_pvoid)addr; // direccion original
  // direccion a hookear
  printf ( "Direccion de funcion a hookear: \t\t\t0x%lx\n", (_dword)p_addr );
  
  // esto alinea la direccion de memoria con respecto al tamaño de una pagina.
  addr -= ((_dword)addr % page_size);
  // colocaremos la direccion de xprintf, el tamaño de la pagina (que estara alineado)
  // y fijamos los permisos de escritura, lectura, escritura y ejecución.
  mprotect(addr, page_size , (PROT_READ | PROT_WRITE | PROT_EXEC) );
  
  // Direccion alineada.
  printf ( "Direccion de funcion alineada a una pagina de memoria: \t0x%lx\n", (_dword)addr );
  
  // esta es la tecnica de obtener la longitud de salto clasica, restamos la direccion
  // de la función de escritura(xwrite) con la que queremos hookear(xprintf)
  _dword jmp_size = (_dword)((_dword)hijack_addr - (_dword)p_addr);
  jmp_size -= 0x5; // alineación
  
  // Tamaño del salto.
  printf ( "Tam. del salto: 0x%lx\n", (_dword)jmp_size );
  
  // se copia desde la posicion 1 del array por que ahí esta el opcode de salto(0xe9)
  // y copiamos 0x4 por que es la longitud de una direccion de memoria(4 bytes).
  memcpy(&jmp_opcodes[1], (_dword *)&jmp_size, 0x4);
  
  // solo para ver el código del salto completo.
  int opcodes= 0;
  for(;opcodes<sizeof(jmp_opcodes);opcodes++)
    printf("-opcodes : 0x%x\n", jmp_opcodes[opcodes]);
  
  // finalmente hookeamos, copiando el contenido de jmp_opcodes el cual tendra nuestro
  // código de salto a xprintf que no es más que la direccion de la función a hookear 
  // usamos memccpy que copiara el contenido de jmp_opcodes a xprintf hasta encontrar 0xc3
  // que es el opcode para RETN (necesario para salir de la función correctamente).
  memccpy((_dword *)p_addr, (_byte*)jmp_opcodes, 0xc3, sizeof(jmp_opcodes));
  
}

void __save_memory_addr(void *addr, _byte save_buffer[])
{
  _byte unhook_bytes[6] = 
  {
    // Configuración del stack frame.
    0x55,             // - PUSH EBP
    0x89, 0xe5,       // - MOV EBP, ESP
    0x00, 0x00, 0x00, // - 3 bytes de la función sobreescrita.
  };
  _byte save_original_addr[6];
  
  // mover la dirección de xprintf(addr) al buffer copiando los 6 primeros bytes
  // 3 del push ebp, mov ebp, esp.
  // los otros 3 bytes seran los de la instrucción de la función
  // (recuerda que antes aquí escribimos el ret del jmp)
  memcpy((_byte *)save_original_addr, (_dword *)addr, 6);
  
  // ahora copiamos desde la posición 3, guardado de la función en el buffer(save_original_addr)
  // a unhook_bytes sobreescribiendo los 0x00, 0x00, 0x00 sin tocar el push ebp, mov ebp, esp.
  memmove((_byte *)&unhook_bytes[3], (_byte *)&save_original_addr[3], 3);
  
  // y por último copiamos el código de unhook_bytes a save_buffer (que es nuestro parametro).
  memcpy((_byte *)save_buffer, (_byte *)unhook_bytes, sizeof(unhook_bytes));
  
  // solo para ver lo que hicimos
  int b=0;
  for(;b<6;b++)
  {
    printf("opcodes guardados 0x%x\n", unhook_bytes[x]);
  }
  
}

void unhook_memory_addr(void* addr, _byte unhook_bytes[])
{
  // Muy facil de entender, movemos los 6 bytes salvados(del buffer unhook_bytes)pasado como
  // parametro a addr que es xprintf, y así restauramos la función original.
  memmove((_dword*)addr, (_byte*)&unhook_bytes[0], 6);
}

int main()
{
  // contiene los 6 primeros bytes que seran guardados.
  _byte buf[6];
  // salvamos los 6 primeros bytes en buf.
  __save_memory_addr(xprintf, buf);
  
  // llamamos a la función original.
  xprintf();
  
  // hookeamos
  hook_memory_addr(xprintf, xwrite);
  
  // llamamos a la función hookeada
  xprintf();
  
  // restauramos la función a la orignal
  unhook_memory_addr(xprintf, buf);
  
  // llamamos a la función restaurada.
  xprintf();
  
	return 0;
}
Conclusiones finales.
Como hemos visto a la largo del tutorial, pudimos comprender como funcionan los hooks
paso por paso y depurando lo que hicimos, espero para la próxima explicar como funcionan
las inyecciones remotas incluso para poder poner nuestra shellcode y ejecutar algún tipo de malware.
Como había prometido aquí dejo algunos artículos.
Writing a Self-Mutating x86_64 C Program [Enlace externo eliminado para invitados] (en 64 bits)
[Tutorial - C/C++ + NASM] Paso de funciónes y stack frames http://indetectables.net/viewtopic.php?f=101&t=49072 (que son los stack frames)
Intel 80x86 Assembly Language OpCodes [Enlace externo eliminado para invitados] (para comprender los opcodes).

Despedida.
Y bueno se despide NvK espero que les haya servido. Recuerda que si quieres poner éste material
en otro sitio tienes la liberta de hacerlo, pero por favor respeta al autor por el trabajo realizado.
Saludos y hasta la próxima!
Excelente!!!. la verdad esta muy claro (como el agua. casi creo que es sobre Windows) muy buen tutorial bro.

Saludos
Imagen
Pink escribió:Excelente!!!. la verdad esta muy claro (como el agua. casi creo que es sobre Windows) muy buen tutorial bro.

Saludos
Gracias colega, aun que siempre me pasa que cuando escribo tutos muy largos me equivoco en algunas cosas, por ejemplo
puse dbg y es gdb
Ya está cambiado dbg por gdb XD. Esto es una info para tenerla bien guardada, haré copias de seguridad de las imagenes por si algun dia las borran del servidor. Gracias NvK por compartir esta info no solo al foro, si no a toda la red!.

Saludos!
Soy un camaleón, en tu cama, leona ♪
$DoC escribió:Ya está cambiado dbg por gdb XD. Esto es una info para tenerla bien guardada, haré copias de seguridad de las imagenes por si algun dia las borran del servidor. Gracias NvK por compartir esta info no solo al foro, si no a toda la red!.

Saludos!
Te doy las gracias por el tiempo y la ayuda realizada, ojala le haya podido servir a mucha gente, espero en un futuro(cuando tenga más tiempo) expandirme en estos temas, y hablar sobre inyecciones en linux junto con más temas que ademas implican hardware, electronica, etc.
Un saludo y de nuevo gracias por el respaldo
no se te resiste ningun sistema operativo, haces hooks como el que va a encender el ordenador, te Felicito tio eres un grande de grandes, saludos
Abolición para el torneo del toro de la vega. Death to the murderers of bulls.
Responder

Volver a “Linux”