All Projects → kubo → Plthook

kubo / Plthook

Hook function calls by replacing PLT(Procedure Linkage Table) entries.

Programming Languages

c
50402 projects - #5 most used programming language

Projects that are alternatives of or similar to Plthook

Dexcalibur
[Official] Android reverse engineering tool focused on dynamic instrumentation automation. Powered by Frida. It disassembles dex, analyzes it statically, generates hooks, discovers reflected methods, stores intercepted data and does new things from it. Its aim is to be an all-in-one Android reverse engineering platform.
Stars: ✭ 512 (+45.87%)
Mutual labels:  hook, hooking
subhook.nim
subhook wrapper for Nim https://github.com/Zeex/subhook
Stars: ✭ 15 (-95.73%)
Mutual labels:  hook, hooking
Pine
Dynamic java method hook framework on ART.
Stars: ✭ 171 (-51.28%)
Mutual labels:  hook, hooking
RedditVanced
Reddit Android app mod inspired by Aliucord
Stars: ✭ 41 (-88.32%)
Mutual labels:  hook, hooking
Funchook
Hook function calls by inserting jump instructions at runtime
Stars: ✭ 253 (-27.92%)
Mutual labels:  hook, hooking
hookey
Enables all the DLCs. Like Creamapi but just for linux and a subset of Paradox games.
Stars: ✭ 87 (-75.21%)
Mutual labels:  hook, hooking
use-dencrypt-effect
⚛ A custom React hook generating crypting text effect.
Stars: ✭ 39 (-88.89%)
Mutual labels:  hook
Epic
Dynamic java method AOP hook for Android(continution of Dexposed on ART), Supporting 5.0~11
Stars: ✭ 3,434 (+878.35%)
Mutual labels:  hook
hookr
PHP action and filter hook system
Stars: ✭ 39 (-88.89%)
Mutual labels:  hook
goverlay
DirectX hook and game overlay solution for Electron, Qt and CEF, just like discord/steam game overlay,inject any app to overlay in your game
Stars: ✭ 426 (+21.37%)
Mutual labels:  hook
Gelectron
gameoverlay solution for Electron, Qt and CEF, just like discord game overlay and steam game overlay, inject any app to overlay in your game
Stars: ✭ 317 (-9.69%)
Mutual labels:  hook
React Cool Onclickoutside
😎 🖱 React hook to listen for clicks outside of the component(s).
Stars: ✭ 295 (-15.95%)
Mutual labels:  hook
Radioactive State
☢ Make Your React App Truly Reactive!
Stars: ✭ 273 (-22.22%)
Mutual labels:  hook
blog
My Frontend Blog
Stars: ✭ 77 (-78.06%)
Mutual labels:  hook
Swr
React Hooks for data fetching
Stars: ✭ 20,348 (+5697.15%)
Mutual labels:  hook
next-use-contextual-routing
Generate contextual routing / modal routes paths for Next.js
Stars: ✭ 76 (-78.35%)
Mutual labels:  hook
Detoursnt
Detours with just single dependency - NTDLL
Stars: ✭ 314 (-10.54%)
Mutual labels:  hooking
detours
Detours lib that I use
Stars: ✭ 56 (-84.05%)
Mutual labels:  hooking
React Loads
React Loads is a backend agnostic library to help with external data fetching & caching in your UI components.
Stars: ✭ 268 (-23.65%)
Mutual labels:  hook
Teamviewer permissions hook v1
A proof of concept injectable C++ dll, that uses naked inline hooking and direct memory modification to change your TeamViewer permissions.
Stars: ✭ 297 (-15.38%)
Mutual labels:  hooking

PLTHook

Build Status

What is plthook.

A utility library to hook library function calls issued by specified object files (executable and libraries). This modifies PLT (Procedure Linkage Table) entries in ELF format used on most Unixes or IAT (Import Address Table) entries in PE format used on Windows.

What is PLT (or IAT)

Note: This isn't precise explanation. Some details are omitted.

When a function calls another function in another file, it is called via PLT (on Unix using ELF) or IAT (on Windows).

figure1

In order to call foo_func() in libfoo.so, the address of the callee must be known. When callers are in the same file, the relative address to the callee is known at compile time regardless of the absolute address at run time. So some_func() calls foo_func() using relative addressing.

When callers are in other files, the address of the callee cannot be known at compile time. To resolve it, each file has a mapping from external function names to addresses. The callers directly look at the address in the PLT entry for foo_func() and jump to the address.

The addresses in PLT entries are resolved (1) at process startup or (2) at first function call (lazy binding). It depends on OSes or on settings.

What plthook does.

figure2

Plthook changes the address in PLT entries as above. When foo_func() is called from program, hook_foo_func() is called instead. It doesn't change function calls from libfoo.so and libbar.so.

How to call original functions from hook functions.

When hook functions are outside of modified files

figure3

When the hook function hook_foo_func() is in libbar.so, just call the original function foo_func(). It looks the PLT entry in libbar.so and jumps to the original.

When hook functions are inside of modified files

figure4

When the hook function hook_foo_func() is in program, do not call the original function foo_func() because it jumps to hook_foo_func() repeatedly and crashes the process after memory for stack is exhausted. You need to get the address of the original function and set it to the function pointer variable foo_func_addr. Use the fourth argument of plthook_replace() to get the address on Windows. Use the return value of dlsym(RTLD_DEFAULT, "foo_func") on Unixes. The fourth argument of plthook_replace() isn't available on Unixes because it doesn't set the address of the original before the address in the PLT entry is resolved.

Changes

2019-02-17: Support plthook_open_by_address() and change internal logic of plthook_open() on Android.

2019-02-17: Stop checking RELRO and check memory protection at runtime instead.

2019-02-03: Fix crash when programs are compiled with compiler options -Wl,-z,relro and -fno-plt with the help of JC Liang. (#10)

2018-02-06: Android support was contributed by Daniel Deptford.

2017-10-01: plthook_elf.c was rewritten. Plthook had needed to read files on filesystem to get various information about target object files. It now do it only for full RELRO object files. Note that plthook before 2017-10-01 gets segmentation fault while hooking a prelinked file on Linux.

2017-09-18: Fixed for processes on valgrind on Linux.

Usage

If you have a library libfoo.so.1 and want to intercept a function call recv() without modifying the library, put plthook.h and plthook_elf.c, plthook_win32.c or plthook_osx.c in your source tree and add the following code.

#include "plthook.h"

/* This function is called instead of recv() called by libfoo.so.1  */
static ssize_t my_recv(int sockfd, void *buf, size_t len, int flags)
{
    ssize_t rv;
    
    ... do your task: logging, etc. ...
    rv = recv(sockfd, buf, len, flags); /* call real recv(). */
    ... do your task: logging, check received data, etc. ...
    return rv;
}
    
int install_hook_function()
{
    plthook_t *plthook;
    
    if (plthook_open(&plthook, "libfoo.so.1") != 0) {
        printf("plthook_open error: %s\n", plthook_error());
        return -1;
    }
    if (plthook_replace(plthook, "recv", (void*)my_recv, NULL) != 0) {
        printf("plthook_replace error: %s\n", plthook_error());
        plthook_close(plthook);
        return -1;
    }
    plthook_close(plthook);
    return 0;
}

The above code doesn't work when my_recv() is in the file opened by plthook_open() as described here. Use the following code instead in the case.

static ssize_t (*recv_func)(int sockfd, void *buf, size_t len, int flags);

/* This function is called instead of recv() called by libfoo.so.1  */
static ssize_t my_recv(int sockfd, void *buf, size_t len, int flags)
{
    ssize_t rv;
    
    ... do your task: logging, etc. ...
    rv = (*recv_func)(sockfd, buf, len, flags); /* call real recv(). */
    ... do your task: logging, check received data, etc. ...
    return rv;
}
    
int install_hook_function()
{
    plthook_t *plthook;
    
    if (plthook_open_by_address(&plthook, &recv_func) != 0) {
        printf("plthook_open error: %s\n", plthook_error());
        return -1;
    }
    if (plthook_replace(plthook, "recv", (void*)my_recv, (void**)&recv_func) != 0) {
        printf("plthook_replace error: %s\n", plthook_error());
        plthook_close(plthook);
        return -1;
    }
#ifndef WIN32
    // The address passed to the fourth argument of plthook_replace() is
    // availabe on Windows. But not on Unixes. Get the real address by dlsym().
    recv_func = (ssize_t (*)(int, void *, size_t, int))dlsym(RTLD_DEFAULT, "recv");
#endif
    plthook_close(plthook);
    return 0;
}

Note that built-in functions cannot be hooked. For example the C compiler in macOS Sierra compiles ceil() as inline assembly code, not as function call of ceil in the system library.

When a functions is imported by ordinal on Windows, the function name is specified by export_dll_name:@ordinal. For example api-ms-win-shcore-path-l1-1-0.dll:@170.

Another Usage

PLTHook provides a function enumerating PLT/IAT entries.

void print_plt_entries(const char *filename)
{
    plthook_t *plthook;
    unsigned int pos = 0; /* This must be initialized with zero. */
    const char *name;
    void **addr;

    if (plthook_open(&plthook, filename) != 0) {
        printf("plthook_open error: %s\n", plthook_error());
        return -1;
    }
    while (plthook_enum(plthook, &pos, &name, &addr) == 0) {
        printf("%p(%p) %s\n", addr, *addr, name);
    }
    plthook_close(plthook);
    return 0;
}

Supported Platforms

Platform source file status
Linux i386 and x86_64 plthook_elf.c tested on travis-ci
Linux arm, aarch64, powerpc and powerpc64le plthook_elf.c tested on [QENU][] on travis-ci
Windows 32-bit and x64 (MSVC, Mingw32 and Cygwin) plthook_win32.c tested on travis-ci
macOS plthook_osx.c tested on travis-ci
Solaris x86_64 plthook_elf.c perhaps(*1)
FreeBSD i386 and x86_64 except i386 program on x86_64 OS plthook_elf.c perhaps(*1)
Android(*2) plthook_elf.c perhaps(*3)

*1 Tested on a local VM before.
*2 Contributed by Daniel Deptford.
*3 Tested on travis-ci before.

License

2-clause BSD-style license.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].