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í:
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..
Por cierto, las direcciones las saque con IDA Pro, aquí están
Código (cpp) [Seleccionar]
void funcion_original()
{
hook_funcion(); // Esperar a que termine
// continuamos
}
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 (cpp) [Seleccionar]
#include "main.h"
DWORD OnQUERYCallBack;
typedef pair<string, int> packet;
map<string, int> packetsLog;
map<string, int> bannedIPs;
#ifdef __linux__
void HookFunction ( BYTE *origen, BYTE *destino )
{
mprotect((void*)(((int)origen / 4096) * 4096), 4096, PROT_WRITE | PROT_READ | PROT_EXEC);
*( DWORD* )( origen ) = 0xE9;
*( DWORD* )(origen + 0x01 ) = destino - ( origen+ 5 );
return;
}
#endif
void BanIP(const char *host)
{
char Regla[255];
#ifdef _WIN32
sprintf(Regla, "netsh advfirewall firewall add rule name=\"SA-MP Ban - %s\" dir=in action=block remoteip=%s enable=yes", host, host);
#else
sprintf(Regla, "iptables -A INPUT -s %s -j DROP", host);
#endif
system(Regla);
}
int OnSAMPQuery(struct in_addr in, u_short host, char *buffer, int len, SOCKET s)
{
if(bannedIPs.find(inet_ntoa(in)) != bannedIPs.end()) // for prevent add multiple rules
{
return 0;
}
map<string, int>::iterator iter = packetsLog.find(inet_ntoa(in));
if(iter == packetsLog.end())
{
packetsLog.insert(packet(inet_ntoa(in), 1));
}
else
{
if(iter->second >= 350)
{
logprintf("[FIREWALL] %s was banned - reason: query flood", iter->first.c_str());
bannedIPs.insert(packet(iter->first.c_str(), iter->second));
BanIP(iter->first.c_str());
}
iter->second++;
}
#ifdef _WIN32
return OnSAMPQuery_O(in, host, buffer, len, s);
#else
// Aquí que pongo ??
#endif
}
#ifdef _WIN32
void LimpiarDatos(void *arg)
#else
void *LimpiarDatos(void *arg)
#endif
{
while(1)
{
#ifdef _WIN32
Sleep(6000);
#else
sleep(6);
#endif
packetsLog.clear();
bannedIPs.clear();
}
}
PLUGIN_EXPORT unsigned int PLUGIN_CALL Supports()
{
return SUPPORTS_VERSION | SUPPORTS_AMX_NATIVES;
}
PLUGIN_EXPORT bool PLUGIN_CALL Load(void **ppData)
{
#ifdef _WIN32
_beginthread(LimpiarDatos, 0, 0);
#else
pthread_t thread1;
pthread_create(&thread1, NULL, LimpiarDatos, NULL);
#endif
pAMXFunctions = ppData[PLUGIN_DATA_AMX_EXPORTS];
logprintf = (logprintf_t)ppData[PLUGIN_DATA_LOGPRINTF];
DWORD version = (DWORD)ppData[PLUGIN_DATA_LOGPRINTF];
if(version == SAMP_03x)
{
logprintf(" - Server version: SA-MP 0.3x");
OnQUERYCallBack = ADDR_03x;
}
else if(version == SAMP_03xR12)
{
logprintf(" - Server version: SA-MP 0.3x R1-2");
OnQUERYCallBack = ADDR_03xR12;
}
else if(version == SAMP_03xR2)
{
logprintf(" - Server version: SA-MP 0.3x R2");
OnQUERYCallBack = ADDR_03xR2;
}
else
{
logprintf(" - Your version of SA-MP is not supported.");
return true;
}
#ifdef _WIN32
OnSAMPQuery_O = (onsampquery_t)DetourFunction((PBYTE)OnQUERYCallBack, (PBYTE)OnSAMPQuery);
#else
HookFunction((PBYTE)OnQUERYCallBack,(PBYTE)OnSAMPQuery);
#endif
logprintf(" - Anti Query flood by Josstaa 1.1 loaded \n");
return true;
}
PLUGIN_EXPORT void PLUGIN_CALL Unload()
{
logprintf(" - Anti Query flood by Josstaa 1.1 unloaded");
}
AMX_NATIVE_INFO PluginNatives[] =
{
{0, 0}
};
PLUGIN_EXPORT int PLUGIN_CALL AmxLoad( AMX *amx )
{
return amx_Register(amx, PluginNatives, -1);
}
PLUGIN_EXPORT int PLUGIN_CALL AmxUnload( AMX *amx )
{
return AMX_ERR_NONE;
}
Por cierto, las direcciones las saque con IDA Pro, aquí están
Código (cpp) [Seleccionar]
#ifdef _WIN32
#include <windows.h>
#include <process.h>
#pragma comment(lib, "detours/detours.lib")
#include "detours/detours.h"
#define SAMP_03x 0x487DD0
#define SAMP_03xR12 0x488060
#define SAMP_03xR2 0x488140
#define ADDR_03x 0x490850
#define ADDR_03xR12 0x490B10
#define ADDR_03xR2 0x490C30
#else
#define SAMP_03x 0x80B0410
#define SAMP_03xR12 0x80B07C0
#define SAMP_03xR2 0x80B0840
#define ADDR_03x 0x80C6EF0
#define ADDR_03xR12 0x80C72B0
#define ADDR_03xR2 0x80C73A0
typedef int SOCKET;
typedef unsigned long DWORD;
typedef unsigned char BYTE;
typedef BYTE * PBYTE;
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/mman.h>
#include <string.h>
#include <pthread.h>
#endif