Skip to content

Instantly share code, notes, and snippets.

@caiorss

caiorss/build.sh Secret

Created September 19, 2020 18:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save caiorss/751fad7bf7707949e824ed2c19a73752 to your computer and use it in GitHub Desktop.
Save caiorss/751fad7bf7707949e824ed2c19a73752 to your computer and use it in GitHub Desktop.
LD_PRELOAD - Linux test
#!/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
#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);
}
#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);
}
#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