这个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;
}

原文:http://blog.csdn.net/betabin/article/details/7456873

ClamAV学习【9】——cvd文件解析及cli_untgz函数浏览的更多相关文章

  1. Android学习----AndroidManifest.xml文件解析

    一个Android应用程序的结构: 一.关于AndroidManifest.xml AndroidManifest.xml 是每个android程序中必须的文件.它位于整个项目的根目录,描述了pack ...

  2. mybatis 学习三 关键文件解析

    1:  mybatis-config.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYP ...

  3. 简单学习一下ibd数据文件解析

    来源:原创投稿 作者:花家舍 简介:数据库技术爱好者. GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 简单学习一下数据文件解析 这是尝试使用Golang语言简单解析My ...

  4. 八、Android学习第七天——XML文件解析方法(转)

    (转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 八.Android学习第七天——XML文件解析方法 XML文件:exten ...

  5. CocosBuilder 学习笔记(3) AnimationManager 与 ccbi 文件解析

    [CocosBuilder]学习笔记目录 1. 相关的类 先介绍和AnimationManager相关的几个类: CCBSequence 时间线.有成员duration(时间线时间,默认10秒).na ...

  6. 学习 WebService 第二步:知识准备——WSDL文件解析

    原文地址:https://www.cnblogs.com/yzw23333/p/7245104.html Web service中一个 WSDL 对应一个 web service地址. 可以想象成一个 ...

  7. android基础知识13:AndroidManifest.xml文件解析

    注:本文转载于:http://blog.csdn.net/xianming01/article/details/7526987 AndroidManifest.xml文件解析. 1.重要性 Andro ...

  8. Android之AndroidManifest.xml文件解析

    转自:Android学习笔记之AndroidManifest.xml文件解析 一.关于AndroidManifest.xml AndroidManifest.xml 是每个android程序中必须的文 ...

  9. [置顶] Android学习系列-Android中解析xml(7)

    Android学习系列-Android中解析xml(7) 一,概述 1,一个是DOM,它是生成一个树,有了树以后你搜索.查找都可以做. 2,另一种是基于流的,就是解析器从头到尾解析一遍xml文件.   ...

随机推荐

  1. socket与http的区别

    ---------------------------------------------------------------------------------------------------- ...

  2. 生产者消费者模式做一个golang的定时器

    在主程序启动的时候开一个goroutine作为消费者,用管道连接生产者和消费者,消费者处于无限循环,从管道中获取channel传过来定时event 注意:channel在消费者创建的时候就连通生产者和 ...

  3. VS2015解决方案资源管理器空白,不显示内容

    解决方法: 1.先关闭vs: 2.把C:/Users/<users name>/AppData/Local/Microsoft/VisualStudio/14.0/ComponentMod ...

  4. Golang之Struct(二叉树定义)

    接招吧,看代码: package main import "fmt" //二叉树结构体 //如果每个节点有两个指针,分别用来指向左子树和右子树,我们把这样的结构叫做二叉树 type ...

  5. juniper交换机配置

    1.链接串口配置: minicom -s ```bash Serial port setup  A -    Serial Device      : /dev/ttyS1               ...

  6. jvm编译环境搭建 win Vc篇

    /************************************************************** 技术博客 http://www.cnblogs.com/itdef/   ...

  7. http://4526621.blog.51cto.com/4516621/1343369

    http://4526621.blog.51cto.com/4516621/1343369

  8. 使用windows server2012时FileZilla客户端连接时报150 Opening data channel for directory listing of "/" 响应:425 Can't open data connection

    425 Can't open data connection 和 读取目录列表失败 问题解决 这个问题主要是由于使用Passive Mode模式造成的,解决这个问题很简单: 1.在ftp服务软件中设置 ...

  9. C#使用Log4Net记录日志(转)

    出处:http://www.cnblogs.com/wangsaiming/archive/2013/01/11/2856253.html 第一步:下载Log4Net 下载地址:http://logg ...

  10. mysql 更新替换字符串

    update zxg set newlevel = REPLACE(newlevel,'b','') 把表zxg中的newlevel字段中的b删除