clamav的unrar解压模块加载

网络安全 专栏收录该内容
14 篇文章 0 订阅

clamav使用的unrar功能,是一个单独的模块,使用C++实现,编译完成之后生成两个so文件libunrar.so和libclamunrar_iface.so,由命名可知,前者为unrar功能的主体,而后者为封装的接口。在使用的时候,作为动态库进行加载。

如下的configure变量,可指定unrar编译使用的编译器等参数。

  CXX         C++ compiler command
  CXXFLAGS    C++ compiler flags
  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
              nonstandard directory <lib dir>
  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
              you have headers in a nonstandard directory <include dir>

编译完成之后,由ldd命令可见,libclamunrar_iface.so需要使用到libclamunrar.so。

$:~/clamav-0.103.1$ ldd libclamav/.libs/libclamunrar_iface.so
        linux-vdso.so.1 (0x00007ffe60753000)
        libclamunrar.so.9 => ./libclamav/.libs/libclamunrar.so.9 (0x00007f68c7ba6000)

在clamd守护进程初始化时,调用rarload加载libclamunrar_iface共享库。之后,将测试一下库中是否有以下函数:

  • libclamunrar_iface_LTX_unrar_open
  • libclamunrar_iface_LTX_unrar_peek_file_header
  • libclamunrar_iface_LTX_unrar_extract_file
  • libclamunrar_iface_LTX_unrar_skip_file
  • libclamunrar_iface_LTX_unrar_close

以上测试的同时,将相应函数赋值给全局函数指针,测试通过之后,设置rar加载标志have_rar为真。

static void rarload(void)
{
    void *rhandle = NULL;

    if (is_rar_inited) return;
    is_rar_inited = 1;

    if (have_rar) return;

    rhandle = load_module("libclamunrar_iface", "unrar");
    if (NULL == rhandle)
        return;

    if ((NULL == (cli_unrar_open = (cl_unrar_error_t(*)(const char *, void **, char **, uint32_t *, uint8_t))get_module_functi     on(rhandle, "libclamunrar_iface_LTX_unrar_open"))) ||
        (NULL == (cli_unrar_peek_file_header = (cl_unrar_error_t(*)(void *, unrar_metadata_t *))get_module_function(rhandle, "     libclamunrar_iface_LTX_unrar_peek_file_header"))) ||
        (NULL == (cli_unrar_extract_file = (cl_unrar_error_t(*)(void *, const char *, char *))get_module_function(rhandle, "li     bclamunrar_iface_LTX_unrar_extract_file"))) ||
        (NULL == (cli_unrar_skip_file = (cl_unrar_error_t(*)(void *))get_module_function(rhandle, "libclamunrar_iface_LTX_unra     r_skip_file"))) ||
        (NULL == (cli_unrar_close = (void (*)(void *))get_module_function(rhandle, "libclamunrar_iface_LTX_unrar_close")))) {

        cli_warnmsg("Failed to load function from UnRAR module\n");
        cli_warnmsg("Version mismatch?\n");
        cli_warnmsg("UnRAR support unavailable\n");
        return;
    }
    have_rar = 1;
}

以下load_module函数,首先增加SEARCH_LIBDIR路径到查找路径中,之后遍历库名称name和可能的后缀的组合,尝试加载共享库。

static void *load_module(const char *name, const char *featurename)
{
    static const char *suffixes[] = {
        LT_MODULE_EXT "." LIBCLAMAV_FULLVER,
        PASTE(LT_MODULE_EXT ".", LIBCLAMAV_MAJORVER),
        LT_MODULE_EXT,
        "." LT_LIBEXT};

    const char *searchpath;
    const lt_dlinfo *info;
    lt_dlhandle rhandle;
    
    if (lt_dladdsearchdir(SEARCH_LIBDIR)) {
        cli_dbgmsg("lt_dladdsearchdir failed for %s\n", SEARCH_LIBDIR);
    }

    searchpath = lt_dlgetsearchpath();
    if (!searchpath)
        searchpath = "";
    
    cli_dbgmsg("searching for %s, user-searchpath: %s\n", featurename, searchpath);
    for (i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); i++) {
        snprintf(modulename, sizeof(modulename), "%s%s", name, suffixes[i]);
        rhandle = lt_dlopen(modulename);
        if (rhandle)
            break;
        cli_dbgmsg("searching for %s: %s not found\n", featurename, modulename);
    }   

如下文件libclamav/Makefile中,默认情况下prefix为/usr/local,也可在configure时通过–prefix指定其它目录,所以SEARCH_LIBDIR默认是/usr/local/lib64目录,在make install时,将libunrar.so和libclamunrar_iface.so都安装在了此目录。

exec_prefix = ${prefix}

libdir = ${exec_prefix}/lib64

libclamav_la_CFLAGS = $(IFACE_CFLAGS) $(MSPACK_CFLAGS) $(AM_CFLAGS) $(YARA_CFLAGS) -DSEARCH_LIBDIR=\"$(libdir)\"

clamd启动之后,可测试rar压缩文件,使用clamav项目中test子目录下的两个rar文件clam-v2.rar和clam-v3.rar进行测试。

$ clamdscan --no-summary test/clam-v2.rar 

test/clam-v2.rar: Clamav.Test.File-6 FOUND
$ 
$ clamdscan --no-summary test/clam-v3.rar  

test/clam-v3.rar: Clamav.Test.File-6 FOUND

clamav版本:0.103.1

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值