ClamAV学习【9】——cvd文件解析及cli_untgz函数浏览
来源:互联网 发布:spss数据分析报告范文 编辑:程序博客网 时间:2024/05/16 14:01
这个cli_untgz函数,是用来解压CVD文件的。
那么,就刚先搞清楚CVD文件的功能作用。下了源码,我们会发现,没有前面提到的*.mdb或者*.hbd等病毒签名文件。原因就是,那些文件都是由CVD文件解压生成的,是的,CVD是个病毒签名压缩文件。(下面是daily.cvd解压后的)
CVD文件,前512个bytes是一个特殊的头文件,在前面也提到过了(http://blog.csdn.net/betabin/article/details/7448447)。记录引擎病毒库的简单信息。然后后面的内容,曾经多次用UE打开,发现是乱码。所以,是个压缩文件。压缩类型,根据cli_untgz函数里面使用的gzread读取函数,可以猜到是使用zlib压缩库压缩的。然后根据函数内容,接着可以判断出,原信息是一个接着一个病毒库文件存储的。既是每个新的病毒库开始的前512bytes中,存储着名字及病毒签名数量。接着就是病毒签名信息。通过签名的病毒签名数量,可以判断正在读取的病毒签名是否读取完。
还是贴代码注释比较好理解:
//解压CVD文件到临时目录中int cli_untgz(int fd, const char *destdir){char *path, osize[13], name[101], type;char block[TAR_BLOCKSIZE];int nbytes, nread, nwritten, in_block = 0, fdd;unsigned int size, pathlen = strlen(destdir) + 100 + 5;FILE *outfile = NULL;struct stat foo;gzFile *infile;//提示 cli_dbgmsg("in cli_untgz()\n");//dup复制文件描述符 if((fdd = dup(fd)) == -1) {cli_errmsg("cli_untgz: Can't duplicate descriptor %d\n", fd);return -1; }//打开文件 if((infile = gzdopen(fdd, "rb")) == NULL) {cli_errmsg("cli_untgz: Can't gzdopen() descriptor %d, errno = %d\n", fdd, errno);if(fstat(fdd, &foo) == 0) close(fdd);return -1; }//路径变量分配内存 path = (char *) cli_calloc(sizeof(char), pathlen); if(!path) {cli_errmsg("cli_untgz: Can't allocate memory for path\n");gzclose(infile);return -1; }//开始循环读取cvd文件内容 while(1) {//每次读取512个bytes部分nread = gzread(infile, block, TAR_BLOCKSIZE);//上一种病毒库已经读完//且读不到下一种病毒库头信息时//结束if(!in_block && !nread) break;if(nread != TAR_BLOCKSIZE) { cli_errmsg("cli_untgz: Incomplete block read\n"); free(path); gzclose(infile); return -1;}//上一种病毒库已经读完//进行下一种病毒库文件头信息处理//既是文件名、大小等if(!in_block) {//解压完病毒库 if (block[0] == '\0') /* We're done */break;//前99bytes中是文件名属性 strncpy(name, block, 100); name[100] = '\0';//该斜号分割不允许//在錡indows下应该也需要更改,不过不影响//name只能是文件名 if(strchr(name, '/')) {cli_errmsg("cli_untgz: Slash separators are not allowed in CVD\n");free(path); gzclose(infile);return -1; }//给路径变量赋值//设置为$tempdir$/newvirusfilename snprintf(path, pathlen, "%s/%s", destdir, name); cli_dbgmsg("cli_untgz: Unpacking %s\n", path);//156位置文件标志 type = block[156];//判断类型 switch(type) {case '0':case '\0': break;case '5': cli_errmsg("cli_untgz: Directories are not supported in CVD\n"); free(path); gzclose(infile); return -1;default: cli_errmsg("cli_untgz: Unknown type flag '%c'\n", type); free(path); gzclose(infile); return -1; }//设置in_block参数//表示接下来开始写内容 in_block = 1;//关闭上一个病毒库文件指针 if(outfile) {if(fclose(outfile)) { cli_errmsg("cli_untgz: Cannot close file %s\n", path); free(path); gzclose(infile); return -1;}outfile = NULL; }//输出文件指针指向当前病毒库文件 if(!(outfile = fopen(path, "wb"))) {cli_errmsg("cli_untgz: Cannot create file %s\n", path);free(path); gzclose(infile);return -1; }//124后的为病毒签名数量 strncpy(osize, block + 124, 12); osize[12] = '\0';//读取数量,用于写是否结束判断标志 if((sscanf(osize, "%o", &size)) == 0) {cli_errmsg("cli_untgz: Invalid size in header\n");free(path); gzclose(infile);fclose(outfile);return -1; }} else { /* write or continue writing file contents *///写入path病毒文件nbytes = size > TAR_BLOCKSIZE ? TAR_BLOCKSIZE : size; nwritten = fwrite(block, 1, nbytes, outfile); if(nwritten != nbytes) {cli_errmsg("cli_untgz: Wrote %d instead of %d (%s)\n", nwritten, nbytes, path);free(path); gzclose(infile);return -1; }//减去已经写了的病毒签名数//判断是否结束 size -= nbytes; if(size == 0)in_block = 0;} } if(outfile)fclose(outfile); gzclose(infile); free(path); return 0;}
- ClamAV学习【9】——cvd文件解析及cli_untgz函数浏览
- ClamAV学习【2】——clamscan入口函数浏览
- ClamAV学习【3】——scanmanager函数浏览
- ClamAV学习【4】——cli_magic_scandesc函数浏览
- ClamAV学习【5】—— cli_scanpe函数浏览
- ClamAV学习【6】—— cli_load函数浏览
- ClamAV学习【1】——ClamAV流程
- ClamAV学习【7】——病毒库文件格式学习
- clamav病毒库格式解析
- ClamAV学习【8】——64位Windows7下编译运行实践
- clamav的学习
- clamav
- VIM 文件浏览插件 — NERDTree
- VIM 文件浏览插件 — NERDTree
- 雅阁学习笔记之windows编程——保存文件和打开浏览文件夹窗口
- android学习——使用SAX、DOM 和 PULL 解析xml文件,及使用pull生成xml文件
- android学习——使用SAX、DOM 和 PULL 解析xml文件,及使用pull生成xml文件
- webkit关键代码浏览——HTML解析
- EXTJS上传图片
- 部署Zabbix集中监控系统
- IBM system x3650 ServerGuide 引导安装指南 (不配置阵列)
- How to use softvol to control the master volume
- andengine编程之sprite(四)
- ClamAV学习【9】——cvd文件解析及cli_untgz函数浏览
- NSDateFormatter设定日期格式
- FileOutputStream flush操作时有时无效的解决办法
- SQL Server 触发器
- oracle 有关emp表的练习题
- Oracle Linux 6 下 Oracle RDBMS Server 11gR2 Preinstall RPM 包说明
- 编译c文件出现undefined reference to `__gxx_personality_v0'
- 删除一个字符串中连续的空格
- 常用聊天/传输工具的协议及端口 腾讯QQ/电驴/淘宝旺旺