elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Usando Git para manipular el directorio de trabajo, el índice y commits (segunda parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  ASM (Moderador: Eternal Idol)
| | | |-+  Ayuda con hooks
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: Ayuda con hooks  (Leído 8,354 veces)
Josta

Desconectado Desconectado

Mensajes: 7


Ver Perfil
Ayuda con hooks
« en: 24 Diciembre 2013, 05:48 am »

Hola, realmente no se nada de ASM, en c++ hice unos hooks buscando en internet y apoyandome con detours, en windows mi hook funciona a la perfeccion, pero resulta que quiero hacer uno para linux, y con una funcion que encontre, segun lo que lei, esta ingresa un jmp en la funcion original para hacer la llamada a mi funcion, eso funciona hasta ahi, lo que pasa es que yo quiero que al finalizar mi funcion, esta continue en la original, un esquema sería algo así:

Código
  1. void funcion_original()
  2. {
  3.    hook_funcion(); // Esperar a que termine
  4.    // continuamos
  5. }

El código que tengo es el siguiente, el que incluye mi hook hecho en windows con detours, por si acaso tienen duda, el hook lo hago a una función que está en un ejecutable del cual no tengo el código fuente( samp-server.exe ), ahí viendo el código ustedes se darán cuenta de lo que intento hacer..

Código
  1. #include "main.h"
  2.  
  3.  
  4. DWORD OnQUERYCallBack;
  5.  
  6. typedef pair<string, int> packet;
  7. map<string, int> packetsLog;
  8.  
  9. map<string, int> bannedIPs;
  10.  
  11.  
  12. #ifdef __linux__
  13. void HookFunction ( BYTE *origen, BYTE *destino )
  14. {
  15. mprotect((void*)(((int)origen / 4096) * 4096), 4096, PROT_WRITE | PROT_READ | PROT_EXEC);
  16.        *( DWORD* )( origen ) = 0xE9;
  17.        *( DWORD* )(origen + 0x01 ) = destino - ( origen+ 5 );
  18. return;
  19. }
  20. #endif
  21.  
  22. void BanIP(const char *host)
  23. {
  24. char Regla[255];
  25. #ifdef _WIN32
  26. sprintf(Regla, "netsh advfirewall firewall add rule name=\"SA-MP Ban - %s\" dir=in action=block remoteip=%s enable=yes", host, host);
  27. #else
  28. sprintf(Regla, "iptables -A INPUT -s %s -j DROP", host);
  29. #endif
  30. system(Regla);
  31. }
  32.  
  33.  
  34. int OnSAMPQuery(struct in_addr in, u_short host, char *buffer, int len, SOCKET s)
  35. {
  36. if(bannedIPs.find(inet_ntoa(in)) != bannedIPs.end()) // for prevent add multiple rules
  37. {
  38. return 0;
  39. }
  40.  
  41. map<string, int>::iterator iter = packetsLog.find(inet_ntoa(in));
  42. if(iter == packetsLog.end())
  43. {
  44. packetsLog.insert(packet(inet_ntoa(in), 1));
  45. }
  46. else
  47. {
  48. if(iter->second >= 350)
  49. {
  50. logprintf("[FIREWALL] %s was banned - reason: query flood", iter->first.c_str());
  51. bannedIPs.insert(packet(iter->first.c_str(), iter->second));
  52. BanIP(iter->first.c_str());
  53. }
  54. iter->second++;
  55. }
  56.  
  57. #ifdef _WIN32
  58. return OnSAMPQuery_O(in, host, buffer, len, s);
  59. #else
  60. // Aquí que pongo ??
  61. #endif
  62. }
  63. #ifdef _WIN32
  64. void LimpiarDatos(void *arg)
  65. #else
  66. void *LimpiarDatos(void *arg)
  67. #endif
  68. {
  69. while(1)
  70. {
  71. #ifdef _WIN32
  72. Sleep(6000);
  73. #else
  74. sleep(6);
  75. #endif
  76. packetsLog.clear();
  77. bannedIPs.clear();
  78.  
  79. }
  80. }
  81. PLUGIN_EXPORT unsigned int PLUGIN_CALL Supports()
  82. {
  83.    return SUPPORTS_VERSION | SUPPORTS_AMX_NATIVES;
  84. }
  85.  
  86.  
  87. PLUGIN_EXPORT bool PLUGIN_CALL Load(void **ppData)
  88. {
  89. #ifdef _WIN32
  90. _beginthread(LimpiarDatos, 0, 0);
  91. #else
  92. pthread_t thread1;
  93. pthread_create(&thread1, NULL, LimpiarDatos, NULL);
  94. #endif
  95.  
  96. pAMXFunctions = ppData[PLUGIN_DATA_AMX_EXPORTS];
  97.  
  98. logprintf = (logprintf_t)ppData[PLUGIN_DATA_LOGPRINTF];
  99. DWORD version = (DWORD)ppData[PLUGIN_DATA_LOGPRINTF];
  100.  
  101.  
  102. if(version == SAMP_03x)
  103. {
  104. logprintf("  - Server version: SA-MP 0.3x");
  105. OnQUERYCallBack = ADDR_03x;
  106. }
  107. else if(version == SAMP_03xR12)
  108. {
  109. logprintf("  - Server version: SA-MP 0.3x R1-2");
  110. OnQUERYCallBack = ADDR_03xR12;
  111. }
  112. else if(version == SAMP_03xR2)
  113. {
  114. logprintf("  - Server version: SA-MP 0.3x R2");
  115. OnQUERYCallBack = ADDR_03xR2;
  116. }
  117. else
  118. {
  119. logprintf("  - Your version of SA-MP is not supported.");
  120. return true;
  121. }
  122.  
  123.  
  124.  
  125. #ifdef _WIN32
  126. OnSAMPQuery_O = (onsampquery_t)DetourFunction((PBYTE)OnQUERYCallBack, (PBYTE)OnSAMPQuery);
  127. #else
  128. HookFunction((PBYTE)OnQUERYCallBack,(PBYTE)OnSAMPQuery);
  129. #endif
  130.  
  131. logprintf("  - Anti Query flood by Josstaa 1.1 loaded \n");
  132.    return true;
  133. }
  134.  
  135.  
  136. PLUGIN_EXPORT void PLUGIN_CALL Unload()
  137. {
  138.    logprintf("  - Anti Query flood by Josstaa 1.1 unloaded");
  139. }
  140.  
  141. AMX_NATIVE_INFO PluginNatives[] =
  142. {
  143.    {0, 0}
  144. };
  145.  
  146. PLUGIN_EXPORT int PLUGIN_CALL AmxLoad( AMX *amx )
  147. {
  148.    return amx_Register(amx, PluginNatives, -1);
  149. }
  150.  
  151.  
  152. PLUGIN_EXPORT int PLUGIN_CALL AmxUnload( AMX *amx )
  153. {
  154.    return AMX_ERR_NONE;
  155. }
  156.  
  157.  

Por cierto, las direcciones las saque con IDA Pro, aquí están
Código
  1. #ifdef _WIN32
  2.  
  3. #include <windows.h>
  4. #include <process.h>
  5.  
  6.  
  7. #pragma comment(lib, "detours/detours.lib")
  8. #include "detours/detours.h"
  9. #define SAMP_03x 0x487DD0
  10. #define SAMP_03xR12 0x488060
  11. #define SAMP_03xR2 0x488140
  12.  
  13. #define ADDR_03x 0x490850
  14. #define ADDR_03xR12 0x490B10
  15. #define ADDR_03xR2 0x490C30
  16. #else
  17. #define SAMP_03x 0x80B0410
  18. #define SAMP_03xR12 0x80B07C0
  19. #define SAMP_03xR2 0x80B0840
  20.  
  21. #define ADDR_03x 0x80C6EF0
  22. #define ADDR_03xR12 0x80C72B0
  23. #define ADDR_03xR2 0x80C73A0
  24.  
  25. typedef int SOCKET;
  26. typedef unsigned long DWORD;
  27. typedef unsigned char BYTE;
  28. typedef BYTE * PBYTE;
  29.  
  30. #include <unistd.h>
  31. #include <sys/socket.h>
  32. #include <netinet/in.h>
  33. #include <arpa/inet.h>
  34. #include <sys/mman.h>
  35. #include <string.h>
  36. #include <pthread.h>
  37.  
  38. #endif


« Última modificación: 24 Diciembre 2013, 05:56 am por Josta » En línea

xv0


Desconectado Desconectado

Mensajes: 1.027



Ver Perfil
Re: Ayuda con hooks
« Respuesta #1 en: 24 Diciembre 2013, 11:02 am »

Ese hook lo que hace por lo que veo es bloquear direcciones de entrada, pero como es C++ no dijo nada mas.

segun lo que lei, esta ingresa un jmp en la funcion original para hacer la llamada a mi funcion, eso funciona hasta ahi, lo que pasa es que yo quiero que al finalizar mi funcion, esta continue en la original

Supongo que esa es la pregunta, ya que no veo nigun codigo en ASM. La mejor opcion seria si puedes substituir ese jmp por un call, el call de la funcion original llama a tu funcion y esta instruccion carga en el stack la siguiente direccion de la funcion original, cuando estes en tu funcion simplemente retornas a la original con un ret. Vamos es lo normal, pero si no puedes substituir nada tienes que replantearlo de otra manera.

Un saludo.


En línea

Josta

Desconectado Desconectado

Mensajes: 7


Ver Perfil
Re: Ayuda con hooks
« Respuesta #2 en: 24 Diciembre 2013, 22:49 pm »

Lo hice así, nomás cambie el 0xE9 por 0xE8, que lo que hace es el call, y en la funcion al final puse asm("ret"); pero al momento de ejecutarse da crash y en la ventana aparece Violación de segmento (`core' generado)

Código
  1. void HookFunction ( BYTE *origen, BYTE *destino )
  2. {
  3. mprotect((void*)(((int)origen / 4096) * 4096), 4096, PROT_WRITE | PROT_READ | PROT_EXEC);
  4.        *( DWORD* )( origen ) = 0xE8;
  5.        *( DWORD* )(origen + 0x01 ) = destino - ( origen+ 5 );
  6. return;
  7. }

Código
  1. int OnSAMPQuery(struct in_addr in, u_short host, char *buffer, int len, SOCKET s)
  2. {
  3.  
  4. if(bannedIPs.find(inet_ntoa(in)) != bannedIPs.end()) // for prevent add multiple rules
  5. {
  6. return 0;
  7. }
  8.  
  9. map<string, int>::iterator iter = packetsLog.find(inet_ntoa(in));
  10. if(iter == packetsLog.end())
  11. {
  12. packetsLog.insert(packet(inet_ntoa(in), 1));
  13. }
  14. else
  15. {
  16. if(iter->second >= 350)
  17. {
  18. logprintf("[FIREWALL] %s was banned - reason: query flood", iter->first.c_str());
  19. bannedIPs.insert(packet(iter->first.c_str(), iter->second));
  20. BanIP(iter->first.c_str());
  21. }
  22. iter->second++;
  23. }
  24.  
  25.  
  26.  
  27. #ifdef _WIN32
  28. return OnSAMPQuery_O(in, host, buffer, len, s);
  29. #else
  30. asm("ret");
  31. #endif
  32. }
« Última modificación: 24 Diciembre 2013, 22:51 pm por Josta » En línea

xv0


Desconectado Desconectado

Mensajes: 1.027



Ver Perfil
Re: Ayuda con hooks
« Respuesta #3 en: 25 Diciembre 2013, 06:09 am »

Pero acaso sabes el estado del stack?

Esa funcion utilizara la pila, y la direccion con la que ret salta a lo mejor se modifica, depuralo.

Un saludo.

P.D: Creo que estas en el subforo equivocado.
« Última modificación: 25 Diciembre 2013, 06:10 am por cpu2 » En línea

Josta

Desconectado Desconectado

Mensajes: 7


Ver Perfil
Re: Ayuda con hooks
« Respuesta #4 en: 26 Diciembre 2013, 02:21 am »

No, no lo se. Crees que puedas enseñarme lo básico? Tienes skype? Sería de mucha ayuda
En línea

xv0


Desconectado Desconectado

Mensajes: 1.027



Ver Perfil
Re: Ayuda con hooks
« Respuesta #5 en: 27 Diciembre 2013, 11:35 am »

No utilizo Skype, prueba desensamblando las funciones para saber como esta el estado del stack. Igualmente como no se trata de mi lenguaje no tengo muy claro que se hace, se llama ala funcion OnSAMPQuery y si no es un win32 retorna.

Pero no entiendo, si no es win32 no llama a esa funcion no? Mejor explica paso a paso y si te lias con el dissasembler dimelo.

Un saludo.

En línea

Josta

Desconectado Desconectado

Mensajes: 7


Ver Perfil
Re: Ayuda con hooks
« Respuesta #6 en: 27 Diciembre 2013, 23:17 pm »

Esos if's son ejecutados por el compilador, _WIN32 se define cuando el compilador esta bajo windows, si es así se incluye ese código, si no, significa que es linux y se añade el equivalente para linux

Esta es la función original desensamblada

http://pastebin.com/pQTwxJPt

Y esta es la del .so

http://pastebin.com/Dd5xSdhP

P.D:
Alguna forma por la que podamos conversar? sería mas rápido que aquí en el foro

Por cierto, tengo entendido que en linux los códigos se compilan bajo la sintax AT&T y no la de Intel


EDIT: Encontré la forma de sacar el asm del código generado por el mismo compilador, y puedo compilar el .so con el asm directamente, te lo dejo aquí, creo que así sería más fácil para ti comprender el código, si tu modificas el asm yo veo como implementarlo en C++

http://pastebin.com/PED4a3QG
« Última modificación: 28 Diciembre 2013, 00:05 am por Josta » En línea

xv0


Desconectado Desconectado

Mensajes: 1.027



Ver Perfil
Re: Ayuda con hooks
« Respuesta #7 en: 28 Diciembre 2013, 01:32 am »

No, no hace falta que sean de la sintaxis AT&T, depende del ensamblador pero yo estoy acostumbrado ala de AT&T.

Bien ese dissasembler generado por gcc no me gusta, no pretendo ser quisquilloso pero te importaria poner el dissasembler del binario con objdump?

Código:
objdump -d <binario>

Es la costumbre  ;D.

Leyendo un poco, bueno supongo que tu tambien llegaste a eso, la funcion OnSAMPQuery comienza en .LC7, en .L267 se pasan los parametros de la funcion logprintf como puedes observar se mueve el offset .LC7 que es donde esta la direccion del mensaje, mas abajo en .LEHB8 esta la funcion BanIP.

Pero si me das el dissasembler con el objdump ya lo entiendo todo, es que asi no me gusta leerlo.

Un saludo.



Bueno como no me pasas el dissasembler con la sintaxis que me gusta no podre ayudarte mejor, pero porque no dejas el codigo como antes, sin el call, y donde pusiste el ret pon un simple salto hacia tu funcion origional.

Código
  1. asm ("jmp funcionoriginal");

Un saludo.
« Última modificación: 30 Diciembre 2013, 13:06 pm por Eternal Idol » En línea

Josta

Desconectado Desconectado

Mensajes: 7


Ver Perfil
Re: Ayuda con hooks
« Respuesta #8 en: 31 Diciembre 2013, 01:59 am »

Andaba un poco ocupado, y eso que dices creo ya haberlo hecho y lo único que causa es un loop infinito creo
En línea

xv0


Desconectado Desconectado

Mensajes: 1.027



Ver Perfil
Re: Ayuda con hooks
« Respuesta #9 en: 2 Enero 2014, 10:47 am »

Cierto, no se porque dije eso, la funcion original llamaria a OnSAMPQuery y al comprobar el if volveria a saltar al principio de la funcion original y esta volveria a llamar a OnSAMPQuery se volveria a comprobar el if y volveria a saltar creando un bucle infinito.

Ya que o me subes el codigo dessemsamblado con objdump y no se donde poner el retn, seme ocurre que pongas una "etiqueta" en la funcion original despues de la llamada a la funcion OnSAMPQuery y diciendo que al if que salte a esa "etiqueta" o offset llamalo como quieras.

No se como se hace eso en C++, pero aqui tienes un ejemplo en ASM mezclado.

Código
  1. _Funcionoriginal:
  2.  
  3. call OnSAMPQuery
  4.  
  5. _Linux:
  6.  
  7. ;Continua el codigo.
  8.  
  9. _OnSAMPQuery:
  10.  
  11. #ifdef _WIN32
  12. return OnSAMPQuery_O(in, host, buffer, len, s);
  13. #else
  14. asm("jmp _Linux");
  15. #endif

Creo que asi funcionaria, no tiene porque hacer un ciclo infinito.

Un saludo.
En línea

Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Hooks en VB
Programación Visual Basic
Hendrix 0 1,160 Último mensaje 12 Septiembre 2006, 18:13 pm
por Hendrix
Hooks « 1 2 »
Programación Visual Basic
baZZ 11 3,920 Último mensaje 15 Junio 2007, 21:09 pm
por Hendrix
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines