-
-
Save caiorss/751fad7bf7707949e824ed2c19a73752 to your computer and use it in GitHub Desktop.
LD_PRELOAD - Linux test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env sh | |
# Build unix/Linux executable | |
gcc unix-executable.c -o unix-executable.bin | |
# Build Linux shared library: hook-files-a.so | |
gcc hook-files-a.c -o hook-files-a.so -fpic -shared -ldl -Wall | |
# Build Linux shared library: hook-files-b.so | |
g++ hook-files-b.cpp -o hook-files-b.so -fpic -Wall -shared -ldl | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define _GNU_SOURCE // Enables RTLD_NEXT constant. | |
#include <stdio.h> | |
#include <assert.h> | |
#include <stdint.h> | |
// ----- Unix-specific headers ------- // | |
#include <dlfcn.h> | |
// Annotation for internal symbols not visible outside | |
// this compilation unit (static storage class). | |
#define HIDDEN static | |
// Anotation for calling function whenever the shared library | |
// is loaded by some process. Note: this is a specific GNU | |
// language extension. | |
#define ON_LIBRARY_LOADED __attribute__((constructor)) | |
typedef uint32_t pid_t; | |
typedef uint32_t mode_t; | |
extern pid_t getpid(void); | |
__attribute__((constructor)) static | |
void init_library1() | |
{ | |
fprintf(stderr, " [INFO] init_library1() / Library loaded Ok. \n"); | |
} | |
HIDDEN ON_LIBRARY_LOADED | |
void init_library2() | |
{ | |
fprintf(stderr, " [INFO] init_library2() / Library loaded Ok. \n"); | |
} | |
/** Intercepts (aka hooks) and overrides open() function | |
* from libC (GLIBC) that encapsulates open() system-call | |
* (aka syscall). | |
*---------------------------------------------------------*/ | |
int open(const char* pathname, int flags, mode_t mode) | |
{ | |
// Type alias for function pointer with same | |
// signature as the open() function. | |
typedef int (* open_t) ( const char* pathname | |
, int flags | |
, mode_t mode); | |
// Load old symbol of original C function that was overriden | |
open_t open_real = (open_t) dlsym(RTLD_NEXT, "open"); | |
// Sanity checking => calls abort() if symbol is not found. | |
assert( open_real ); | |
// Log intercepted functional call | |
// pid =>> Process ID of process that loaded this | |
// shared library. | |
fprintf( stderr | |
, " [TRACE] pid = %d / open() ->> File = %s \n" | |
, getpid(), pathname); | |
// Pass control back to intercepted (hooked) function. | |
return open_real(pathname, flags, mode); | |
} | |
FILE* fopen64(const char* filename, const char* type) | |
{ | |
typedef FILE* (* fopen64_t) ( const char* filename | |
, const char* type); | |
fopen64_t old_fun = (fopen64_t) dlsym(RTLD_NEXT, "fopen64"); | |
assert( old_fun != NULL); | |
fprintf( stderr | |
, " [TRACE] pid = %d / fopen64() ->> File = %s \n" | |
, getpid(), filename); | |
return old_fun(filename, type); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <cassert> | |
// Equivalent to C-header <stdint.h> std::uint32_t ... and so on. | |
#include <cstdint> | |
// ----- Unix-specific headers ------- // | |
#include <dlfcn.h> | |
// Annotqtion for defining functions with C-linkage | |
// that must conform to C ABI and calling conventions. | |
#define EXTERN_C extern "C" | |
// Annotation for internal symbols not visible outside | |
// this compilation unit (static storage class). | |
#define HIDDEN static | |
// Anotation for calling function whenever the shared library | |
// is loaded by some process. Note: this is a specific GNU | |
// language extension. | |
#define ON_LIBRARY_LOADED __attribute__((constructor)) | |
// This symbol will be resolved at linking-time by the Linker | |
extern "C" pid_t getpid(void); | |
__attribute__((constructor)) static | |
void init_library1() | |
{ | |
fprintf( stderr | |
," [INFO] init_library1() / Library loaded Ok. \n"); | |
} | |
HIDDEN ON_LIBRARY_LOADED | |
void init_library2() | |
{ | |
fprintf( stderr | |
, " [INFO] init_library2() / Library loaded Ok. \n"); | |
} | |
/** Intercepts (aka hooks) and overrides open() function | |
* from libC (GLIBC) that encapsulates open() system-call | |
* (aka syscall). | |
*---------------------------------------------------------*/ | |
EXTERN_C | |
int open(const char* pathname, int flags, mode_t mode) | |
{ | |
// Type alias for function pointer with same | |
// signature as the open() function. | |
using open_t = int (*) ( const char* pathname | |
, int flags | |
, mode_t mode); | |
// Load old symbol of original C function that was overriden | |
open_t open_real = (open_t) dlsym(RTLD_NEXT, "open"); | |
// Sanity checking => calls abort() if symbol is not found. | |
assert( open_real != nullptr); | |
// Log intercepted functional call | |
// pid =>> Process ID of process that loaded this | |
// shared library. | |
std::fprintf( stderr | |
, " [TRACE] pid = %d / open() ->> File = %s \n" | |
, getpid(), pathname); | |
// Pass control back to intercepted (hooked) function. | |
return open_real(pathname, flags, mode); | |
} | |
EXTERN_C | |
FILE* fopen64(const char* filename, const char* type) | |
{ | |
using fopen64_real = FILE* (*) ( const char* filename | |
, const char* type); | |
auto old_fun = (fopen64_real) dlsym(RTLD_NEXT, "fopen64"); | |
assert( old_fun != nullptr); | |
std::fprintf( stderr | |
, " [TRACE] pid = %d / fopen64() ->> File = %s \n" | |
, getpid(), filename); | |
return old_fun(filename, type); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <assert.h> | |
int main(int argc, char** argv) | |
{ | |
assert(argc == 2 && "Missing file argument"); | |
FILE* fd = fopen64(argv[1], "r"); | |
assert(fd != NULL); | |
char* line = NULL; | |
int n, nread; | |
long len = 0; | |
n = nread = 0; | |
while ((nread = getline(&line, &len, fd)) != -1) | |
{ | |
fprintf( stdout, " [LINE] %d = %s ", ++n, line); | |
} | |
free(line); | |
fclose(fd); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment