Пример #1
0
static unsigned int lhdr(fmap_t *map, uint32_t loff,uint32_t zsize, unsigned int *fu, unsigned int fc, const uint8_t *ch, int *ret, cli_ctx *ctx, char *tmpd, int detect_encrypted, zip_cb zcb) {
    const uint8_t *lh, *zip;
    char name[256];
    uint32_t csize, usize;

    if(!(lh = fmap_need_off(map, loff, SIZEOF_LH))) {
        cli_dbgmsg("cli_unzip: lh - out of file\n");
        return 0;
    }
    if(LH_magic != 0x04034b50) {
        if (!ch) cli_dbgmsg("cli_unzip: lh - wrkcomplete\n");
        else cli_dbgmsg("cli_unzip: lh - bad magic\n");
        fmap_unneed_off(map, loff, SIZEOF_LH);
        return 0;
    }

    zip = lh + SIZEOF_LH;
    zsize-=SIZEOF_LH;

    if(zsize<=LH_flen) {
        cli_dbgmsg("cli_unzip: lh - fname out of file\n");
        fmap_unneed_off(map, loff, SIZEOF_LH);
        return 0;
    }
    if(ctx->engine->cdb || cli_debug_flag) {
        uint32_t nsize = (LH_flen>=sizeof(name))?sizeof(name)-1:LH_flen;
        const char *src;
        if(nsize && (src = fmap_need_ptr_once(map, zip, nsize))) {
            memcpy(name, zip, nsize);
            name[nsize]='\0';
        } else
            name[0] = '\0';
    }
    zip+=LH_flen;
    zsize-=LH_flen;

    cli_dbgmsg("cli_unzip: lh - ZMDNAME:%d:%s:%u:%u:%x:%u:%u:%u\n", ((LH_flags & F_ENCR)!=0), name, LH_usize, LH_csize, LH_crc32, LH_method, fc, ctx->recursion);
    /* ZMDfmt virname:encrypted(0-1):filename(exact|*):usize(exact|*):csize(exact|*):crc32(exact|*):method(exact|*):fileno(exact|*):maxdepth(exact|*) */

    if(cli_matchmeta(ctx, name, LH_csize, LH_usize, (LH_flags & F_ENCR)!=0, fc, LH_crc32, NULL) == CL_VIRUS) {
        *ret = CL_VIRUS;
        return 0;
    }

    if(LH_flags & F_MSKED) {
        cli_dbgmsg("cli_unzip: lh - header has got unusable masked data\n");
        /* FIXME: need to find/craft a sample */
        fmap_unneed_off(map, loff, SIZEOF_LH);
        return 0;
    }

    if(detect_encrypted && (LH_flags & F_ENCR) && DETECT_ENCRYPTED) {
        cli_dbgmsg("cli_unzip: Encrypted files found in archive.\n");
        cli_append_virus(ctx, "Heuristics.Encrypted.Zip");
        *ret = CL_VIRUS;
        fmap_unneed_off(map, loff, SIZEOF_LH);
        return 0;
    }

    if(LH_flags & F_USEDD) {
        cli_dbgmsg("cli_unzip: lh - has data desc\n");
        if(!ch) {
            fmap_unneed_off(map, loff, SIZEOF_LH);
            return 0;
        }
        else {
            usize = CH_usize;
            csize = CH_csize;
        }
    } else {
        usize = LH_usize;
        csize = LH_csize;
    }

    if(zsize<=LH_elen) {
        cli_dbgmsg("cli_unzip: lh - extra out of file\n");
        fmap_unneed_off(map, loff, SIZEOF_LH);
        return 0;
    }
    zip+=LH_elen;
    zsize-=LH_elen;

    if (!csize) { /* FIXME: what's used for method0 files? csize or usize? Nothing in the specs, needs testing */
        cli_dbgmsg("cli_unzip: lh - skipping empty file\n");
    } else {
        if(zsize<csize) {
            cli_dbgmsg("cli_unzip: lh - stream out of file\n");
            fmap_unneed_off(map, loff, SIZEOF_LH);
            return 0;
        }
        if(LH_flags & F_ENCR) {
            cli_dbgmsg("cli_unzip: lh - skipping encrypted file\n");
        } else {
            if(fmap_need_ptr_once(map, zip, csize))
                *ret = unz(zip, csize, usize, LH_method, LH_flags, fu, ctx, tmpd, zcb);
        }
        zip+=csize;
        zsize-=csize;
    }

    fmap_unneed_off(map, loff, SIZEOF_LH); /* unneed now. block is guaranteed to exists till the next need */
    if(LH_flags & F_USEDD) {
        if(zsize<12) {
            cli_dbgmsg("cli_unzip: lh - data desc out of file\n");
            return 0;
        }
        zsize-=12;
        if(fmap_need_ptr_once(map, zip, 4)) {
            if(cli_readint32(zip)==0x08074b50) {
                if(zsize<4) {
                    cli_dbgmsg("cli_unzip: lh - data desc out of file\n");
                    return 0;
                }
                zip+=4;
            }
        }
        zip+=12;
    }
    return zip-lh;
}
Пример #2
0
void fmap_unneed_ptr(fmap_t *m, void *ptr, size_t len) {
    fmap_unneed_off(m, (char *)ptr - (char *)m - m->hdrsz, len);
}