今晚继续浏览ClamAV代码,挖掘到了cli_magic_scandesc函数,发现前面包装了很多次扫描函数,这里就是最后一层的感觉。一些扫描限制判断加上文件类型判断,采用不同扫描函数处理。

(PS:发现这些函数个头都很大,虽然按着功能分段好理解,但是书本不是说一个函数一个功能模块么?难道是不实际,还是理解错误?)

代码分析如下:

//magic,说明这很神奇
int cli_magic_scandesc(int desc, cli_ctx *ctx)
{
int ret = CL_CLEAN;
cli_file_t type, dettype = 0;
struct stat sb;
uint8_t typercg = 1; //获取文件属性stat结构
if(fstat(desc, &sb) == -1) {
cli_errmsg("magic_scandesc: Can't fstat descriptor %d\n", desc);
return CL_EIO;
} //文件太小无需扫描
if(sb.st_size <= 5) {
cli_dbgmsg("Small data (%u bytes)\n", (unsigned int) sb.st_size);
return CL_CLEAN;
} //引擎已经构建
if(!ctx->engine) {
cli_errmsg("CRITICAL: engine == NULL\n");
return CL_EMALFDB;
} //默认模式扫描
if(!ctx->options) { /* raw mode (stdin, etc.) */
cli_dbgmsg("Raw mode: No support for special files\n");
if((ret = cli_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR)) == CL_VIRUS)
cli_dbgmsg("%s found in descriptor %d\n", *ctx->virname, desc);
return ret;
} //是否超过设置的扫描限制
if(cli_updatelimits(ctx, sb.st_size)!=CL_CLEAN)
return CL_CLEAN; //邮件或者压缩文件扫描
if((SCAN_MAIL || SCAN_ARCHIVE) && ctx->limits && ctx->limits->maxreclevel && ctx->recursion > ctx->limits->maxreclevel) {
cli_dbgmsg("Archive recursion limit exceeded (level = %u).\n", ctx->recursion);
return CL_CLEAN;
} //定位文件,找到文件类型
lseek(desc, 0, SEEK_SET);
type = cli_filetype2(desc, ctx->engine);
if(type == CL_TYPE_ERROR) {
cli_dbgmsg("cli_magic_scandesc: cli_filetype2 returned CL_TYPE_ERROR\n");
return CL_EIO;
}
lseek(desc, 0, SEEK_SET); //非忽略类型还有个什么。需要研究
if(type != CL_TYPE_IGNORED && ctx->engine->sdb) {
if((ret = cli_scanraw(desc, ctx, type, 0, &dettype)) == CL_VIRUS)
return CL_VIRUS;
lseek(desc, 0, SEEK_SET);
} ctx->recursion++; //根据不同的类型,让文件见鬼去吧
switch(type) {
case CL_TYPE_IGNORED:
break; case CL_TYPE_RAR:
#ifdef ENABLE_UNRAR
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_RAR))
ret = cli_scanrar(desc, ctx, 0, NULL);
#else
cli_warnmsg("RAR code not compiled-in\n");
#endif
break; case CL_TYPE_ZIP:
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ZIP))
ret = cli_unzip(desc, ctx);
break; case CL_TYPE_GZ:
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_GZ))
ret = cli_scangzip(desc, ctx);
break; case CL_TYPE_BZ:
#ifdef HAVE_BZLIB_H
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_BZ))
ret = cli_scanbzip(desc, ctx);
#endif
break;
case CL_TYPE_ARJ:
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ARJ))
ret = cli_scanarj(desc, ctx, 0, NULL);
break; case CL_TYPE_NULSFT:
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_NSIS))
ret = cli_scannulsft(desc, ctx, 0);
break; case CL_TYPE_AUTOIT:
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_AUTOIT))
ret = cli_scanautoit(desc, ctx, 23);
break; case CL_TYPE_MSSZDD:
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_SZDD))
ret = cli_scanszdd(desc, ctx);
break; case CL_TYPE_MSCAB:
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CAB))
ret = cli_scanmscab(desc, ctx, 0);
break; case CL_TYPE_HTML:
if(SCAN_HTML && (DCONF_DOC & DOC_CONF_HTML))
ret = cli_scanhtml(desc, ctx);
break; case CL_TYPE_HTML_UTF16:
if(SCAN_HTML && (DCONF_DOC & DOC_CONF_HTML))
ret = cli_scanhtml_utf16(desc, ctx);
break; case CL_TYPE_SCRIPT:
if((DCONF_DOC & DOC_CONF_SCRIPT) && dettype != CL_TYPE_HTML)
ret = cli_scanscript(desc, ctx);
break; case CL_TYPE_RTF:
if(SCAN_ARCHIVE && (DCONF_DOC & DOC_CONF_RTF))
ret = cli_scanrtf(desc, ctx);
break; case CL_TYPE_MAIL:
if(SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_MBOX))
ret = cli_scanmail(desc, ctx);
break; case CL_TYPE_TNEF:
if(SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_TNEF))
ret = cli_scantnef(desc, ctx);
break; case CL_TYPE_UUENCODED:
if(DCONF_OTHER & OTHER_CONF_UUENC)
ret = cli_scanuuencoded(desc, ctx);
break; case CL_TYPE_MSCHM:
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CHM))
ret = cli_scanmschm(desc, ctx);
break; case CL_TYPE_MSOLE2:
if(SCAN_OLE2 && (DCONF_ARCH & ARCH_CONF_OLE2))
ret = cli_scanole2(desc, ctx);
break; case CL_TYPE_POSIX_TAR:
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_TAR))
ret = cli_scantar(desc, ctx, 1);
break; case CL_TYPE_OLD_TAR:
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_TAR))
ret = cli_scantar(desc, ctx, 0);
break; case CL_TYPE_BINHEX:
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_BINHEX))
ret = cli_scanbinhex(desc, ctx);
break; case CL_TYPE_SCRENC:
if(DCONF_OTHER & OTHER_CONF_SCRENC)
ret = cli_scanscrenc(desc, ctx);
break; case CL_TYPE_RIFF:
if(SCAN_ALGO && (DCONF_OTHER & OTHER_CONF_RIFF))
ret = cli_scanriff(desc, ctx->virname);
break; case CL_TYPE_GRAPHICS:
if(SCAN_ALGO && (DCONF_OTHER & OTHER_CONF_JPEG))
ret = cli_scanjpeg(desc, ctx->virname);
break; case CL_TYPE_PDF: /* FIXMELIMITS: pdf should be an archive! */
if(SCAN_PDF && (DCONF_DOC & DOC_CONF_PDF))
ret = cli_scanpdf(desc, ctx, 0);
break; case CL_TYPE_CRYPTFF:
if(DCONF_OTHER & OTHER_CONF_CRYPTFF)
ret = cli_scancryptff(desc, ctx);
break; case CL_TYPE_ELF:
if(SCAN_ELF && ctx->dconf->elf)
ret = cli_scanelf(desc, ctx);
break; case CL_TYPE_SIS:
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_SIS))
ret = cli_scansis(desc, ctx);
break; case CL_TYPE_BINARY_DATA:
ret = cli_check_mydoom_log(desc, ctx->virname);
break; default:
break;
} ctx->recursion--; //没有检查植入性pe文件
if(type == CL_TYPE_ZIP && SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ZIP)) {
if(sb.st_size > 1048576) {
cli_dbgmsg("cli_magic_scandesc: Not checking for embedded PEs (zip file > 1 MB)\n");
typercg = 0;
}
} /* CL_TYPE_HTML: raw HTML files are not scanned, unless safety measure activated via DCONF */
if(type != CL_TYPE_IGNORED && (type != CL_TYPE_HTML || !(DCONF_DOC & DOC_CONF_HTML_SKIPRAW)) && ret != CL_VIRUS && !ctx->engine->sdb) {
if(cli_scanraw(desc, ctx, type, typercg, &dettype) == CL_VIRUS)
return CL_VIRUS;
} ctx->recursion++;
lseek(desc, 0, SEEK_SET);
switch(type) {
case CL_TYPE_TEXT_ASCII:
if((DCONF_DOC & DOC_CONF_SCRIPT) && dettype != CL_TYPE_HTML)
ret = cli_scanscript(desc, ctx);
break;
/* Due to performance reasons all executables were first scanned
* in raw mode. Now we will try to unpack them
*/
case CL_TYPE_MSEXE:
if(SCAN_PE && ctx->dconf->pe)
ret = cli_scanpe(desc, ctx);
break; default:
break;
}
ctx->recursion--; switch(ret) {
case CL_EFORMAT:
case CL_EMAXREC:
case CL_EMAXSIZE:
case CL_EMAXFILES:
cli_dbgmsg("Descriptor[%d]: %s\n", desc, cl_strerror(ret));
return CL_CLEAN;
default:
return ret;
}
}

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

ClamAV学习【4】——cli_magic_scandesc函数浏览的更多相关文章

  1. 学习js回调函数

    <!DOCTYPE HTML> <html> <head> <meta charset="GBK" /> <title> ...

  2. JavaScript学习03 JS函数

    JavaScript学习03 JS函数 函数就是包裹在花括号中的代码块,前面使用了关键词function: function functionName() { 这里是要执行的代码 } 函数参数 函数的 ...

  3. Matlab学习笔记 figure函数

    Matlab学习笔记 figure函数 matlab中的 figure 命令,能够创建一个用来显示图形输出的一个窗口对象.每一个这样的窗口都有一些属性,例如窗口的尺寸.位置,等等.下面一一介绍它们. ...

  4. iOS学习09C语言函数指针

    本次主要学习和理解函数指针 1.函数指针 void printValue(int number) { printf("number = %d\n", number); } int ...

  5. iOS学习05C语言函数

    本次主要是学习和理解函数,函数树状图如下: 1.函数的声明和定义 函数定义的四要素分别为: 返回值类型 :函数的结果值类型,函数不能返回数组. 指定返回类型是void类型说明函数没有返回值. 函数名 ...

  6. matlab学习笔记 bsxfun函数

    matlab学习笔记 bsxfun函数 最近总是遇到 bsxfun这个函数,前几次因为无关紧要只是大概看了一下函数体去对比结果,今天再一次遇见了这个函数,想想还是有必要掌握的,遂查了些资料总结如下. ...

  7. haskell学习笔记_函数

    一开始学习函数式编程语言就被告知函数式编程语言是一种“定义式”的语言,而不是一种命令式的语言,在学习haskell的函数语法时,此感觉更加强烈,haskell的函数定义倾向于一种类似C++里面的swi ...

  8. Haskell学习-高阶函数

    原文地址:Haskell学习-高阶函数 高阶函数(higher-order function)就是指可以操作函数的函数,即函数可以作为参数,也可以作为返回结果.有了这两个特性,haskell可以实现许 ...

  9. python入门学习:7.函数

    python入门学习:7.函数 关键点:函数 7.1 定义函数7.2 传递实参7.3 返回值7.4 传递列表7.5 传递任意数量的实参7.6 将函数存储在模块中 7.1 定义函数   使用关键字def ...

随机推荐

  1. SQL中like的用法

    操作符LIKE利用通配符把一个值与类似的值进行比较,通配符有两个: 1.百分号(%): 代表零个.一个或多个字符 2.下划线(_):代表一个数字或字符 下面的条件匹配任何以200开头的值 WHERE ...

  2. spring data jpa 2.0

    参考: https://www.cnblogs.com/zeng1994/p/7575606.html

  3. js解决弹窗问题实现班级跳转DIV示例

    js解决弹窗问题实现班级跳转DIV 1.js代码如下: <%--实现班级跳转DIV--%>  <div id="displayClassDiv" style=&q ...

  4. RAD C++Builder xe7 std::map xtree BUG

    c++Builder 6 下的std::map还能用,有代码提示. 换到xe7,代码提示出来就一个tt.operator [](),代码没法往下写了. 最后把Target Platforms切换到64 ...

  5. div高度自适应的问题

    对象height:100%并不能直接产生效果,是因为跟其父对象有关. #center{height:100%;} 上面的css样式是无效的,不会产生任何效果. 需要改写:   html,body{ m ...

  6. notepad++正则表达式例子

    1.匹配create table USR.APP (  这样的字符串: create.*USR.APP\s+\(

  7. [Android开源项目] GitHub开源项目总结 (转)

    [Android开源项目] GitHub开源项目总结 GitHub开源项目android-styled-dialogs http://neast.cn/forum.php?mod=viewthread ...

  8. Ubuntu-Tensorflow 程序结束掉GPU显存没有释放的问题

    笔者在ubuntu上跑Tensorflow的程序的时候,中途使用了Win+C键结束了程序的进行,但是GPU的显存却显示没有释放,一直处于被占用状态. 使用命令 nvidia-smi 显示如下 两个GP ...

  9. SQLServer性能优化之---水平分库扩展

      汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 第一次引入文件组的概念:http://www.cnblogs.com/dunitia ...

  10. libevent 简单学习

    //NetworkManager.h #ifndef _NET_WORK_MANAGER_ #define _NET_WORK_MANAGER_ #include "event2/util. ...