ClamAV学习【9】——cvd文件解析及cli_untgz函数浏览
这个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函数浏览的更多相关文章
- Android学习----AndroidManifest.xml文件解析
一个Android应用程序的结构: 一.关于AndroidManifest.xml AndroidManifest.xml 是每个android程序中必须的文件.它位于整个项目的根目录,描述了pack ...
- mybatis 学习三 关键文件解析
1: mybatis-config.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYP ...
- 简单学习一下ibd数据文件解析
来源:原创投稿 作者:花家舍 简介:数据库技术爱好者. GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 简单学习一下数据文件解析 这是尝试使用Golang语言简单解析My ...
- 八、Android学习第七天——XML文件解析方法(转)
(转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 八.Android学习第七天——XML文件解析方法 XML文件:exten ...
- CocosBuilder 学习笔记(3) AnimationManager 与 ccbi 文件解析
[CocosBuilder]学习笔记目录 1. 相关的类 先介绍和AnimationManager相关的几个类: CCBSequence 时间线.有成员duration(时间线时间,默认10秒).na ...
- 学习 WebService 第二步:知识准备——WSDL文件解析
原文地址:https://www.cnblogs.com/yzw23333/p/7245104.html Web service中一个 WSDL 对应一个 web service地址. 可以想象成一个 ...
- android基础知识13:AndroidManifest.xml文件解析
注:本文转载于:http://blog.csdn.net/xianming01/article/details/7526987 AndroidManifest.xml文件解析. 1.重要性 Andro ...
- Android之AndroidManifest.xml文件解析
转自:Android学习笔记之AndroidManifest.xml文件解析 一.关于AndroidManifest.xml AndroidManifest.xml 是每个android程序中必须的文 ...
- [置顶] Android学习系列-Android中解析xml(7)
Android学习系列-Android中解析xml(7) 一,概述 1,一个是DOM,它是生成一个树,有了树以后你搜索.查找都可以做. 2,另一种是基于流的,就是解析器从头到尾解析一遍xml文件. ...
随机推荐
- 1 数据库开发--MySQL介绍
1.数据库管理软件 C/S 并发.锁 :SQL语句.语法 基本管理和语法学习 一.介绍: mysql数据库管理软件: 套接字:服务端,客户端:客户端可访问服务端得数据 1.支持并发:操作得是共享得数据 ...
- 用API处理位图
procedure TForm1.Button1Click(Sender: TObject); var dc : hdc; MemDc : hdc; MemBitmap : hBitmap; OldM ...
- 向ArcGIS的ToolBarControl中添加任意的windows组建的方法[转]
向ArcGIS的ToolBarControl中添加任意的windows组建的方法[转] Link: http://www.cnblogs.com/mymhj/archive/2012/10/12/27 ...
- ajax传参里含有特殊字符的坑
问题场景:今天在测试自己手上的页面功能时,发现一个小bug,在用ajax向后台发数据时,只要参数中出现一些特殊字符,控制台会报错http 400的问题,其实就是特殊字符服务器不能解析.好了,问题是找到 ...
- Varint 数值压缩
[Varint 数值压缩] Varint 是一种紧凑的表示数字的方法.它用一个或多个字节来表示一个数字,值越小的数字使用越少的字节数.这能减少用来表示数字的字节数.比如对于 int32 类型的数字,一 ...
- s 销售视图数据
INSERT,需将公司ID匹对到以下EXCEL表 INSERT,需将公司ID匹对到以下EXCEL表 [Public] ConnectString=host="siebel://10.10.0 ...
- memcache can't run as root without the -u switch
memcached是一款高速.分布式的内存缓存系统.其官方主页在http://www.danga.com/memcached/1.安装前的准备要安装memcached,需要有libevent的支持.c ...
- asp.net 自定义节配置 (configSections下的section)
<configuration> <configSections> <!--.自定义一个节 CustomSection --> <section name=&q ...
- Text Relatives
[Text Relatives] With TextKit the resources at your disposal range from framework objects—such as te ...
- Atom 编辑器侧边栏忽略隐藏文件
设置中配置需要忽略的文件后缀 package中找到treeview,勾选上这个配置就行