Skip to content

Fork of Linux_hook using libcapstone instead of udis86 disassembler

License

Notifications You must be signed in to change notification settings

wiliamhuang/linux_hook_libcapstone

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

linux_hook

linux_hook is a mini framework to hook / intercept the functions in shared libraries under Linux. It only works on x86_64 and ARM64(AArch64) at this time. We might extend it to support PowerPC in future.

libcapstone was adopted to disasseble binary code.

Trampoline technique is adopted in the implementation of linux_hook, so the smallest size functions we can hook needs 5 bytes. A jmp (+/-2GB) instruction with 5 bytes will be placed at the entry of the function we intend to hook. Memory blocks close to the shared libraries are allocated dynamically to provide the space for setting up trampoline ( the code to jump to new function and the code to call old function).

Get started,
git clone https://github.com/wiliamhuang/linux_hook_libcapstone
cd linux_hook
make

Test
LD_PRELOAD=./hook_open.so touch aaa bbb ccc

You should see,
DBG> new_open(aaa)
DBG> new_open(bbb)
DBG> new_open(ccc)

One more test to monitor open() in run a simple hello world in python.
LD_PRELOAD=./hook_open.so python3 ./test/hello.py > 1 ; wc -l 1
LD_PRELOAD=./mini_open.so python3 ./test/hello.py > 2 ; wc -l 2

mini_open.so implements the simplest LD_PRELOAD trick to intercept functions. You should observe file 1 and 2 have different number of lines. We can see the hook based on trampoline is more reliable.


Example of a mini code to use hook_linux to intercept the open() in libc.so.
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdarg.h>
#include <unistd.h>

#include "include/hook.h"

typedef int (*org_open_libc)(const char *pathname, int oflags, ...);
org_open_libc real_open_libc=NULL;

// When the open() in libc.so is called, new_open_libc() will be executed.
int new_open_libc(const char *pathname, int oflags, ...)
{
        int mode = 0, two_args=1, ret;
        char msg[512];

        if (oflags & O_CREAT)   {
                va_list arg;
                va_start (arg, oflags);
                mode = va_arg (arg, int);
                va_end (arg);
                two_args=0;
        }

        snprintf(msg, sizeof(msg), "DBG> new_open_libc(%s)\n", pathname);
        write(STDOUT_FILENO, msg, strlen(msg));

        if(two_args)    {
                ret = real_open_libc(pathname, oflags);
        }
        else    {
                ret = real_open_libc(pathname, oflags, mode);
        }
        return ret;
}

static __attribute__((constructor)) void init_myhook()
{
        register_a_hook("libc", "open64", (void*)new_open_libc, (long int *)(&real_open_libc));

        install_hook();
}

static __attribute__((destructor)) void finalize_myhook()
{
        uninstall_hook();
}

Save the code as 1.c.
gcc -fPIC -c 1.c
gcc -fPIC -shared -o 1.so 1.o obj/hook.o -lcapstone

Now test it.
LD_PRELOAD=./1.so touch aaa bbb ccc

You should see,
DBG> new_open(aaa)
DBG> new_open(bbb)
DBG> new_open(ccc)

About

Fork of Linux_hook using libcapstone instead of udis86 disassembler

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published