ClamAV学习【4】——cli_magic_scandesc函数浏览
来源:互联网 发布:徐静蕾字体 mac 编辑:程序博客网 时间:2024/05/16 23:45
今晚继续浏览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; }}
- ClamAV学习【4】——cli_magic_scandesc函数浏览
- ClamAV学习【2】——clamscan入口函数浏览
- ClamAV学习【3】——scanmanager函数浏览
- ClamAV学习【5】—— cli_scanpe函数浏览
- ClamAV学习【6】—— cli_load函数浏览
- ClamAV学习【9】——cvd文件解析及cli_untgz函数浏览
- ClamAV学习【1】——ClamAV流程
- ClamAV学习【7】——病毒库文件格式学习
- ClamAV学习【8】——64位Windows7下编译运行实践
- clamav的学习
- clamav
- Tapestry学习笔记——页面浏览的处理流程
- Android学习笔记02——浏览手机中的文件夹
- Eclipse——浏览功能
- ArcMap——浏览地图
- Eclipse —— 浏览(Navigate)
- 练手项目—新闻浏览
- PERL函数浏览表
- POJ1414 Life Line [暴搜]
- 【BFS】Prime Path
- 复旦陈果老师语录
- python在win下怎么读取中文文件
- iphone 开发学习
- ClamAV学习【4】——cli_magic_scandesc函数浏览
- Effective C++读书笔记(27)
- WindowManager.LayoutParams类
- C高级(6)--其他编程经验
- 与SQL相关的动态性能视图
- C++设计模式之一 工厂模式(简单工厂、工厂和抽象工厂)
- 浏览器专属 CSS Hack:区分 Firefox / Opera / Safari / Internet Explorer
- 失眠了
- 三场排名赛小结(2012.4.4)