Skip to content

Minimalistic hook engine for x86_64/Linux

License

Notifications You must be signed in to change notification settings

mejedi/hook-engine

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

hook-engine

Minimalistic hook engine for x86_64/Linux

Example:

Imagine we'd like to hook read function from libc:

ssize_t read(int fd, void *buf, size_t count);

Whenever read is called, we want to transfer control to __wrap__read (our custom function), as if read was defined as follows:

ssize_t read(int fd, void *buf, size_t count) {
  return __wrap__read(fd, buf, count);
}

Hook-engine literally patches read code in memory. Since read was altered, we need another function that performs identically to unmodified read. This is called a trampoline, and hook-engine can create one.

Let's start with a trampoline definition:

ssize_t __real__read(int fd, void *buf, size_t count);
HOOK_DEFINE_TRAMPOLINE(__real__read);

HOOK_DEFINE_TRAMPOLINE reserves space in the program's code segment. Hook-engine renders tramoline's code there at runtime.

Now we can implement fake descriptor #42, yielding a quote from Douglas Adams:

ssize_t __wrap__read(int fd, void *buf, size_t count) {
  if (fd == 42) {
    static const char msg[] = "answer to life the universe and everything";
    if (count >= sizeof msg) count = (sizeof msg) - 1;
    memcpy(buf, msg, count);
    return count;
  }
  return __real__read(fd, buf, count);
}

Finally install the hook and render the trampoline:

if (hook_install(read, __wrap__read, __real__read) != 0) {
  fprintf(stderr, "%s\n", hook_last_error());
  exit(EXIT_FAILURE);
}