/*利用这段代码可以看看前面的newhide.c和newjmp.c之间的区别.
你会发现newjmp.c的方法没有办法通过这段代码检查出来*/
#include
#include
#include
#include
#include
#include
#include
#include
struct call{
char *name;
unsigned int num;
};
struct call all_call[]={/*可以自己加想要check的调用*/
{"fork",2},
{"read",3},
{"write",4},
{"open",5},
{"close",6},
{"kill", 37},
{"getdirentries",196},
{"__sysctl",202},
{NULL},
};
int main(int argc,char ** argv)
{
/*看不懂那些kvm函数时请man kvm*/
int i=0;
kvm_t *kd;
char errbuf[_POSIX2_LINE_MAX];
struct nlist nl[]={{NULL},{NULL},{NULL},};
struct sysent sysent_call;
unsigned int callnum;
unsigned int addr;
nl[0].n_name="sysent";
if(argc>=3)
{
/*check单个系统调用
usage: ./checkcall name id (fix)*/
nl[1].n_name=argv[1];
callnum=atoi(argv[2]);
kd=kvm_openfiles(NULL,NULL,NULL,O_RDWR,errbuf);
if(kd<0)
{
printf("error is:%s\n",errbuf);
exit(-1);
}
if(kvm_nlist(kd,nl)<0)
{
printf("error is %s\n",kvm_geterr(kd));
exit(-1);
}
if(!nl[1].n_value)
{
printf("%s is not found\n",nl[1].n_name);
exit(-1);
}
addr =nl[0].n_value+callnum*sizeof(struct sysent);
kvm_read(kd,addr,&sysent_call,sizeof(struct sysent));
printf("sysent[%3d] is begin at 0x%x and the function addr is at 0x%x\n",callnum,addr,sysent_call.sy_call );
if((u_int32_t)sysent_call.sy_call!=nl[1].n_value)
printf("ALERT!! the function %s should be 0x%x\n",nl[1].n_name,nl[1].n_value);
if(argv[3]&&!strcmp(argv[3],"fix"))
{
(u_int32_t)sysent_call.sy_call=nl[1].n_value;
printf("begin to fix it\n");
kvm_write(kd,addr,&sysent_call,sizeof(struct sysent));
}
}
else
{
/*不加参数check all_call数组里面的系统调用*/
printf("will check all call\n");
while(all_call[i].name)
{
i++;
nl[1].n_name=all_call[i-1].name;
callnum=all_call[i-1].num;
kd=kvm_openfiles(NULL,NULL,NULL,O_RDONLY,errbuf);
if (kd<0)
{
printf("the %d error is:%s\n",i,errbuf);
continue;
}
if(kvm_nlist(kd,nl)<0)
{
printf("error is %s\n",kvm_geterr(kd));
continue;
}
if(!nl[1].n_value)
{
printf("%s is not found\n",nl[1].n_name);
continue;
}
addr =nl[0].n_value+callnum*sizeof(struct sysent);
kvm_read(kd,addr,&sysent_call,sizeof(struct sysent));
printf("sysent[%3d] is begin at 0x%x the function addr is at 0x%x\n",callnum,addr,sysent_call.sy_call );
if((u_int32_t)sysent_call.sy_call!=nl[1].n_value)
printf("ALERT!! the function %s should be 0x%x\n",nl[1].n_name,nl[1].n_value);
nl[1].n_name=NULL;
nl[1].n_value=NULL;
}
}
return 0;
}