hook and loader
已有 538 次阅读2011-9-27 21:09
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <sys/mman.h>
#define __USE_GNU
#include <sys/ucontext.h>
#define INIT_MODULE 0x08053a49
#define CREATE_MODULE 0x8053a48
int page_size;
unsigned char hook_char;
unsigned char *hook_at;
void insert_hook(unsigned int where)
{
if(mprotect((void *)((where) & ~(page_size-1)), page_size, PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
fprintf(stderr, "--> Unable to change memory protection on required page: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
hook_at = (unsigned char *)(where);
hook_char = hook_at[0];
hook_at[0] = 0xcc;
}
void remove_hook()
{
hook_at[0] = hook_char;
}
void dump_module(unsigned char *text)
{
unsigned int *texti;
FILE *f;
int struct_size, module_size;
texti = (unsigned int *)(text);
struct_size = texti[0];
module_size = texti[3];
f = fopen("/tmp/module_header", "w+");
fwrite(text, struct_size, 1, f);
fclose(f);
f = fopen("/tmp/module_text", "w+");
fwrite(text + struct_size, module_size, 1, f);
fclose(f);
}
void setup_sighandler(unsigned int *fp)
{
struct sigaction sa;
memset(&sa, 0, sizeof(struct sigaction));
sa.sa_sigaction = (void *)fp;
sa.sa_flags = SA_SIGINFO|SA_ONESHOT;
sigaction(SIGTRAP, &sa, NULL);
}
void int3_common(ucontext_t *uc)
{
fprintf(stderr, "--> In an int3 handler\n");
remove_hook();
uc->uc_mcontext.gregs[REG_EIP]--; // Restore EIP to point
// the appropriate place
}
void int3_init_module(int signo, siginfo_t *si, ucontext_t *uc)
{
unsigned char **params;
int i;
int3_common(uc);
// ESP 0 = return address
params = (unsigned long) (uc->uc_mcontext.gregs[REG_ESP] + 4);
fprintf(stderr, "--> working our magic for %s\n", params[0]);
dump_module(params[1]);
}
void int3_create_module(int signo, siginfo_t *si, ucontext_t *uc)
{
int3_common(uc);
fprintf(stderr, "--> Create module return address is 0x%08x\n",
uc->uc_mcontext.gregs[REG_EAX]);
insert_hook(INIT_MODULE);
setup_sighandler(int3_init_module);
}
void _init()
{
page_size = getpagesize();
insert_hook(CREATE_MODULE);
setup_sighandler(int3_create_module);
}