每个使用libclamav库的应用程序都必须包括clamav.h头文件
#include
一、装载库
初始化装载库的函数列出如下:
int cl_loaddb(const char * filename , struct cl_node **root , unsigned int *signo);
//装载选择的数据库
int cl_lodedbdir(const char * dirname , struct cl_node **root , unsigned int *signo );
//从目录dirname装载所有的数据库,函数返回默认(硬编码hardcoded)数据库的目录路径。在初始化后,一个内部数据库代表由参数root传出,root必须被初始化到NULL,装载的签名序号由参数signo传出,如果不关心签名计数,参数signo设置为NULL,
const char *cl_retdbdir(viod);
函数cl_loaddb和cl_lodedbdir装载成功时,返回0,失败时,返回一个负数。
函数cl_loaddb用法如下:
...
struct cl_node *root = NULL;
int ret , signo = 0;
ret = cl_loaddbdir(cl_retdbdir() , &root , &signo );
二、错误处理
使用函数cl_strerror将错误代码转换成可读的消息,函数cl_strerror返回一个字符串,
使用方法如下:
if(ret){ //ret是错误码,为负数
printf("cl_loaddbdir() error : %s\n " , cl_strerror(ret) );
exit(1);
}
三、初始化数据库内部传输
函数cl_build被用来初始化数据库的内部传输路径,函数列出如下:
int cl_build(struct cl_node *root );
函数cl_build使用方法如下:
if((ret=cl_build(root)))
printf("cl_build() error : %s\n " , cl_strerror(ret));
四、数据库重装载
保持内部数据库实例的更新是很重要的,可以使用函数簇cl_stat来检查数据库的变化,函数簇cl_stat列出如下:
int cl_statinidir(const char * dirname , struct cl_stat * dbstat);
int cl_statchkdir(const char * dbstat);
int cl_statfree(struct cl_stat *dbstat);
调用函数cl_statinidir初始化结构cl_stat变量,方法如下:
...
struct cl_stat dbstat;
memset(&dbstat , 0 , sizeof(struct cl_stat));
cl_statinidir(dbdir , &dbstat );
检查数据库的变化仅需要调用函数cl_statchkdir,方法如下:
...
if(cl_statchkdir(&dbstat)==1){//数据库发生变化
reload_database...;//重装载数据库
cl_statfree( &dbstat );
cl_statinidir(cl_retdbdir() , &dbstat );
}
在重装载数据库后,需要重新初始化这个结构。
五、★★★数据扫描函数★★★
使用下面的函数可以扫描一个buffer、描述符或文件:
int cl_scanbuff(const char *buffer , unsigned int length ,const char **virname ,const struct cl_node *root );
int cl_scandesc(int desc , const char ** virname ,unsigned long int *scanned ,const struct cl_node *root , const struct cl_limits *limits , unsigned int options);
int cl_scanfile(const char *filename ,const char **virname ,unsigned long int *scanned ,const struct cl_node *root ,const struct cl_limits *limits ,unsigned int options);
所有这些函数都将病毒名存储在指针virname中,它指向内部数据库结构的一个成员,不能直接释放。
后两个函数还支持文件限制结构cl_limits,结构cl_limits用来限制扫描文件数量、大小等,以防止服务超载攻击,列出如下:
struct cl_limits{
int maxreclevel; //最大递归级
int maxfiles;//扫描的最大文件数
int maxratio;//最大压缩率
short archivememlim;//使用bzip2(0/1)的最大内存限制
long int maxfilesize;//最大的文件尺寸,大于这个尺寸的文件不被扫描
}
参数options配置扫描引擎,并支持下面的标识(可以使用标识组合):
CL_SCAN_STDOPT 推荐的扫描选项集的别名,它用来给将来libclamav的版本新特征使用。
CL_SCAN_RAW 不做任何事情,如果不想扫描任何特殊文件,就单独使用它。
CL_SCAN_ARCHIVE 激活各种文件格式的透明扫描。
CL_SCAN_BLOCKENCRYPTED可使用它的标识加密文件作为病毒(Encrypted.Zip,Encrypted.RAR)。
CL_SCAN_BLOCKMAX 如果达到maxfiles、maxfilesize、或maxreclevel限制,标识文件作为病毒。
CL_SCAN_MAIL激活对邮件文件的支持。
CL_SCAN_MAILURL邮件扫描器将下载并扫描列在邮件中的URL,这个标识不应该装载的服务器上使用,由于潜在的问题,不要在默认情况下设置这个标识。
CL_SCAN_OLE2 激活对Microsoft Office文档文件的支持。
CL_SCAN_PE激活对编写执行文件(Portable Executable file)的扫描,并允许libclamav解开UPX、Petite和FSG格式压缩的可执行文件。
CL_SCAN_BLOCKBROKEN libclamav将尝试检测破碎的可执行文件并标识他们为Broken.Executable。
CL_SCAN_HTML激活HTML格式(包括Jscript解密)文件扫描。
上面的所有函数,如果文件扫描无病毒时,返回0(CL_CLEAN)。当检测到有病毒时,返回CL_VIRUS,函数操作失败返回其他值。
扫描一个文件的方法如下:
...
struct cl_limits limits;
const char *virname;
memset (&limits , 0 , sizeof(struct cl_limits));
limits.maxfiles=1000;//扫描目录中的最大文件数1000个
limits.maxfilesize=10*1048576;//扫描目录中文件的最大尺寸10MB
limits.maxreclevel=5;//最大递归级数
limits.maxratio=200;//最大压缩率
limits.archivememlim=0;//取消对bzip2扫描器的内存限制
if((ret=cl_scanfile(" /home/zolw/test",&virname,NULL,root,&limits,CL_STDOPT)) == CL_VIRUS){
printf("Detected %s virus.\n",virname);
}else{
printf(No virus detected.\n);
if(ret!=CL_CLEAN)
printf("Error : %s\n",cl_strerror(ret));
}
六、释放内存
因为内部数据库的root使用了应用程序分配的内存,因此,如果不再扫描文件时,用下面的函数释放root。
void cl_free(struct cl_node *root);
七、使用clamav-config命令检查libclamav编译信息
使用clamav-config命令检查的方法及显示结果列出如下:
# clamav-config --libs
-L/usr/local/lib -lz -lbz2 -lgmp -lpthread
# clamav-config --cflags
-I/usr/local/include -g -O2
八、ClamAV病毒库格式
ClamAV病毒库是一个数据签名的装有一个或多个数据库的.tar文件。文件头是512字节长字符串,用冒号分开,格式如下:
ClamAV-VDB:build time:version:number of signatures:functionality
level required:MD5 checksum:digital signature:builder name:build time (sec)
使用命令sigtool-info可显示ClamAV Virus Database 文件的详细信息。