/* test file extract API */
int entrypoint(void)
{
  unsigned char buf[4];
  /* fixme:compiler assumes LE here = {1, 2, 3, 4}; */
  uint32_t x, i;
  uint64_t y;
  *(uint32_t*)buf = le32_to_host(0x04030201);
  for (i=0;i<3;i++) {
    extract_new(i);
    if (write(buf, sizeof(buf)) != sizeof(buf))
      return 0xbad1;
    /* switch input to extracted file */
    if (input_switch(1) != 0)
      return 0xbad2;
    if (seek(0, SEEK_END) != 4)
      return 0xbad3;
    if (seek(0, SEEK_SET) != 0)
      return 0xbad4;
    x = 0x5a5a5a5a;
    if (read(&x, sizeof(x)) != sizeof(x))
      return 0xbad5;
    if (cli_readint32(&x) != 0x04030201)
      return 0xbad6;
    /* switch back to normal file */
    if (input_switch(0) != 0)
      return 0xbad7;
    if (seek(0, SEEK_SET) != 0)
      return 0xbad8;
    if (read(&x, sizeof(x)) != sizeof(x))
      return 0xbad9;
    x = le32_to_host(x);
    if (x != 0x44434241)
      return 0xbad10;
    /* write to extracted file again */
    if (write(buf, sizeof(buf)) != sizeof(buf))
      return 0xbad11;
    /* switch input to extracted file */
    if (input_switch(1) != 0)
      return 0xbad12;
    if (seek(0, SEEK_END) != 8)
      return 0xbad13;
    if (seek(0, SEEK_SET) != 0)
      return 0xbad14;
    if (read(&y, sizeof(y)) != sizeof(y))
      return 0xbad15;
    y = le64_to_host(y);
    if (y != 0x0403020104030201UL)
      return 0xbad16;
    if (input_switch(0) != 0)
      return 0xbad17;
  }
  return 0xf00d;
}
Пример #2
0
void mbr_convert_to_host(struct mbr_boot_record *record)
{
    struct mbr_partition_entry *entry;
    unsigned i;
 
    for (i = 0; i < MBR_MAX_PARTITION_ENTRIES; ++i) {
        entry = &record->entries[i];
 
        entry->firstLBA = le32_to_host(entry->firstLBA);
        entry->numLBA = le32_to_host(entry->numLBA);
    }
    record->signature = be16_to_host(record->signature);
}
Пример #3
0
static uint32_t riff_endian_convert_32(uint32_t value, int big_endian)
{
	if (big_endian)
		return be32_to_host(value);
	else
		return le32_to_host(value);
}
Пример #4
0
int32_t cli_bcapi_matchicon(struct cli_bc_ctx *ctx , const uint8_t* grp1, int32_t grp1len,
			    const uint8_t* grp2, int32_t grp2len)
{
    int ret;
    char group1[128], group2[128];
    const char **oldvirname;
    struct cli_exe_info info;

    if (!ctx->hooks.pedata->ep) {
	cli_dbgmsg("bytecode: matchicon only works with PE files\n");
	return -1;
    }
    if ((size_t) grp1len > sizeof(group1)-1 ||
	(size_t) grp2len > sizeof(group2)-1)
	return -1;
    oldvirname = ((cli_ctx*)ctx->ctx)->virname;
    ((cli_ctx*)ctx->ctx)->virname = NULL;
    memcpy(group1, grp1, grp1len);
    memcpy(group2, grp2, grp2len);
    group1[grp1len] = 0;
    group2[grp2len] = 0;
    memset(&info, 0, sizeof(info));
    if (ctx->bc->kind == BC_PE_UNPACKER || ctx->bc->kind == BC_PE_ALL) {
	if(le16_to_host(ctx->hooks.pedata->file_hdr.Characteristics) & 0x2000 ||
	   !ctx->hooks.pedata->dirs[2].Size)
	    info.res_addr = 0;
	else
	    info.res_addr = le32_to_host(ctx->hooks.pedata->dirs[2].VirtualAddress);
    } else
	info.res_addr = ctx->resaddr; /* from target_info */
    info.section = (struct cli_exe_section*)ctx->sections;
    info.nsections = ctx->hooks.pedata->nsections;
    info.hdr_size = ctx->hooks.pedata->hdr_size;
    cli_dbgmsg("bytecode matchicon %s %s\n", group1, group2);
    ret = matchicon(ctx->ctx, &info, group1[0] ? group1 : NULL,
		    group2[0] ? group2 : NULL);
    ((cli_ctx*)ctx->ctx)->virname = oldvirname;
    return ret;
}
Пример #5
0
static int gpt_prtn_intxn(cli_ctx *ctx, struct gpt_header hdr, size_t sectorsize)
{
    prtn_intxn_list_t prtncheck;
    struct gpt_partition_entry gpe;
    unsigned i, pitxn;
    int ret = CL_CLEAN, tmp = CL_CLEAN;
    off_t pos;
    size_t maplen;
    uint32_t max_prtns = 0;
    int virus_found = 0;

    maplen = (*ctx->fmap)->real_len;

    /* convert endian to host to check partition table */
    hdr.tableStartLBA = le64_to_host(hdr.tableStartLBA);
    hdr.tableNumEntries = le32_to_host(hdr.tableNumEntries);

    prtn_intxn_list_init(&prtncheck);    

    /* check engine maxpartitions limit */
    if (hdr.tableNumEntries < ctx->engine->maxpartitions) {
        max_prtns = hdr.tableNumEntries;
    }
    else {
        max_prtns = ctx->engine->maxpartitions;
    }

    pos = hdr.tableStartLBA * sectorsize;
    for (i = 0; i < max_prtns; ++i) {
        /* read in partition entry */
        if (fmap_readn(*ctx->fmap, &gpe, pos, sizeof(gpe)) != sizeof(gpe)) {
            cli_dbgmsg("cli_scangpt: Invalid GPT partition entry\n");
            prtn_intxn_list_free(&prtncheck);
            return CL_EFORMAT;
        }

        /* convert the endian to host */
        gpe.firstLBA = le64_to_host(gpe.firstLBA);
        gpe.lastLBA = le64_to_host(gpe.lastLBA);

        if (gpe.firstLBA == 0) {
            /* empty partition, invalid */
        }
        else if ((gpe.firstLBA > gpe.lastLBA) ||
                 (gpe.firstLBA < hdr.firstUsableLBA) || (gpe.lastLBA > hdr.lastUsableLBA)) {
            /* partition exists outside bounds specified by header or invalid */
        }
        else if (((gpe.lastLBA+1) * sectorsize) > maplen) {
            /* partition exists outside bounds of the file map */
        }
        else {
            tmp = prtn_intxn_list_check(&prtncheck, &pitxn, gpe.firstLBA, gpe.lastLBA - gpe.firstLBA + 1);
            if (tmp != CL_CLEAN) {
                if (tmp == CL_VIRUS) {
                    cli_dbgmsg("cli_scangpt: detected intersection with partitions "
                               "[%u, %u]\n", pitxn, i);
                    ret = cli_append_virus(ctx, PRTN_INTXN_DETECTION);
                    if (ret == CL_VIRUS)
                        virus_found = 1;
                    if (SCAN_ALLMATCHES || ret == CL_CLEAN)
                        tmp = 0;
                    else
                        goto leave;
                } else {
                    ret = tmp;
                    goto leave;
                }
            }
        }

        /* increment the offsets to next partition entry */
        pos += hdr.tableEntrySize;
    }

 leave:
    prtn_intxn_list_free(&prtncheck);
    if (virus_found)
        return CL_VIRUS;
    return ret;
}
Пример #6
0
static int gpt_validate_header(cli_ctx *ctx, struct gpt_header hdr, size_t sectorsize)
{
    uint32_t crc32_calc, crc32_ref;
    uint64_t tableLastLBA, lastLBA;
    size_t maplen, ptable_start, ptable_len;
    unsigned char *ptable;

    maplen = (*ctx->fmap)->real_len;

    /* checking header crc32 checksum */
    crc32_ref = le32_to_host(hdr.headerCRC32);
    hdr.headerCRC32 = 0; /* checksum is calculated with field = 0 */
    crc32_calc = crc32(0, (unsigned char*)&hdr, sizeof(hdr));
    if (crc32_calc != crc32_ref) {
        cli_dbgmsg("cli_scangpt: GPT header checksum mismatch\n");
        gpt_parsemsg("%x != %x\n", crc32_calc, crc32_ref);
        return CL_EFORMAT;
    }

    /* convert endian to host to check partition table */
    hdr.signature = be64_to_host(hdr.signature);
    hdr.revision = be32_to_host(hdr.revision);
    hdr.headerSize = le32_to_host(hdr.headerSize);
    hdr.headerCRC32 = crc32_ref;
    hdr.reserved = le32_to_host(hdr.reserved);
    hdr.currentLBA = le64_to_host(hdr.currentLBA);
    hdr.backupLBA = le64_to_host(hdr.backupLBA);
    hdr.firstUsableLBA = le64_to_host(hdr.firstUsableLBA);
    hdr.lastUsableLBA = le64_to_host(hdr.lastUsableLBA);
    hdr.tableStartLBA = le64_to_host(hdr.tableStartLBA);
    hdr.tableNumEntries = le32_to_host(hdr.tableNumEntries);
    hdr.tableEntrySize = le32_to_host(hdr.tableEntrySize);
    hdr.tableCRC32 = le32_to_host(hdr.tableCRC32);;

    ptable_start = hdr.tableStartLBA * sectorsize;
    ptable_len = hdr.tableNumEntries * hdr.tableEntrySize;
    tableLastLBA = (hdr.tableStartLBA + (ptable_len / sectorsize)) - 1;
    lastLBA = (maplen / sectorsize) - 1;

    /** HEADER CHECKS **/
    gpt_printSectors(ctx, sectorsize);

    /* check signature */
    if (hdr.signature != GPT_SIGNATURE) {
        cli_dbgmsg("cli_scangpt: Invalid GPT header signature %llx\n",
            (long long unsigned)hdr.signature);
        return CL_EFORMAT;
    }

    /* check header size */
    if (hdr.headerSize != sizeof(hdr)) {
        cli_dbgmsg("cli_scangpt: GPT header size does not match stated size\n");
        return CL_EFORMAT;
    }

    /* check reserved value == 0 */
    if (hdr.reserved != GPT_HDR_RESERVED) {
        cli_dbgmsg("cli_scangpt: GPT header reserved is not expected value\n");
        return CL_EFORMAT;
    }

    /* check that sectors are in a valid configuration */
    if (!((hdr.currentLBA == GPT_PRIMARY_HDR_LBA && hdr.backupLBA == lastLBA) ||
          (hdr.currentLBA == lastLBA && hdr.backupLBA == GPT_PRIMARY_HDR_LBA))) {
        cli_dbgmsg("cli_scangpt: GPT secondary header is not last LBA\n");
        return CL_EFORMAT;
    }
    if (hdr.firstUsableLBA > hdr.lastUsableLBA) {
        cli_dbgmsg("cli_scangpt: GPT first usable sectors is after last usable sector\n");
        return CL_EFORMAT;
    }
    if (hdr.firstUsableLBA <= GPT_PRIMARY_HDR_LBA || hdr.lastUsableLBA >= lastLBA) {
        cli_dbgmsg("cli_scangpt: GPT usable sectors intersects header sector\n");
        return CL_EFORMAT;
    }
    if ((hdr.tableStartLBA <= hdr.firstUsableLBA && tableLastLBA >= hdr.firstUsableLBA) ||
        (hdr.tableStartLBA >= hdr.firstUsableLBA && hdr.tableStartLBA <= hdr.lastUsableLBA)) {
        cli_dbgmsg("cli_scangpt: GPT usable sectors intersects partition table\n");
        return CL_EFORMAT;
    }
    if (hdr.tableStartLBA <= GPT_PRIMARY_HDR_LBA || tableLastLBA >= lastLBA) {
        cli_dbgmsg("cli_scangpt: GPT partition table intersects header sector\n");
        return CL_EFORMAT;
    }

    /* check that valid table entry size */
    if (hdr.tableEntrySize != sizeof(struct gpt_partition_entry)) {
        cli_dbgmsg("cli_scangpt: cannot parse gpt with partition entry sized %u\n",
                   hdr.tableEntrySize);
        return CL_EFORMAT;
    }


    /* check valid table */
    if ((ptable_start + ptable_len) > maplen) {
        cli_dbgmsg("cli_scangpt: GPT partition table extends over fmap limit\n");
        return CL_EFORMAT;
    }

    /** END HEADER CHECKS **/

    /* checking partition table crc32 checksum */
    ptable = (unsigned char*)fmap_need_off_once((*ctx->fmap), ptable_start, ptable_len);
    crc32_calc = crc32(0, ptable, ptable_len);
    if (crc32_calc != hdr.tableCRC32) {
        cli_dbgmsg("cli_scangpt: GPT partition table checksum mismatch\n");
        gpt_parsemsg("%x != %x\n", crc32_calc, hdr.tableCRC32);
        return CL_EFORMAT;
    }

    return CL_SUCCESS;
}
Пример #7
0
static int gpt_scan_partitions(cli_ctx *ctx, struct gpt_header hdr, size_t sectorsize)
{
    struct gpt_partition_entry gpe;
    int ret = CL_CLEAN, detection = CL_CLEAN;
    size_t maplen, part_size = 0;
    off_t pos = 0, part_off = 0;
    unsigned i = 0, j = 0;
    uint32_t max_prtns = 0;

    /* convert endian to host */
    hdr.signature = be64_to_host(hdr.signature);
    hdr.revision = be32_to_host(hdr.revision);
    hdr.headerSize = le32_to_host(hdr.headerSize);
    hdr.headerCRC32 = le32_to_host(hdr.headerCRC32);
    hdr.reserved = le32_to_host(hdr.reserved);
    hdr.currentLBA = le64_to_host(hdr.currentLBA);
    hdr.backupLBA = le64_to_host(hdr.backupLBA);
    hdr.firstUsableLBA = le64_to_host(hdr.firstUsableLBA);
    hdr.lastUsableLBA = le64_to_host(hdr.lastUsableLBA);
    hdr.tableStartLBA = le64_to_host(hdr.tableStartLBA);
    hdr.tableNumEntries = le32_to_host(hdr.tableNumEntries);
    hdr.tableEntrySize = le32_to_host(hdr.tableEntrySize);
    hdr.tableCRC32 = le32_to_host(hdr.tableCRC32);

    /* print header info for the debug */
    cli_dbgmsg("GPT Header:\n");
    cli_dbgmsg("Signature: 0x%llx\n", (long long unsigned)hdr.signature);
    cli_dbgmsg("Revision: %x\n", hdr.revision);
    gpt_printGUID(hdr.DiskGUID, "DISK GUID");
    cli_dbgmsg("Partition Entry Count: %u\n", hdr.tableNumEntries);
    cli_dbgmsg("Partition Entry Size: %u\n", hdr.tableEntrySize);

    maplen = (*ctx->fmap)->real_len;

    /* check engine maxpartitions limit */
    if (hdr.tableNumEntries < ctx->engine->maxpartitions) {
        max_prtns = hdr.tableNumEntries;
    }
    else {
        max_prtns = ctx->engine->maxpartitions;
    }

    /* use the partition tables to pass partitions to cli_map_scan */
    pos = hdr.tableStartLBA * sectorsize;
    for (i = 0; i < max_prtns; ++i) {
        /* read in partition entry */
        if (fmap_readn(*ctx->fmap, &gpe, pos, sizeof(gpe)) != sizeof(gpe)) {
            cli_dbgmsg("cli_scangpt: Invalid GPT partition entry\n");
            return CL_EFORMAT;
        }

        /* convert the endian to host */
        gpe.firstLBA = le64_to_host(gpe.firstLBA);
        gpe.lastLBA = le64_to_host(gpe.lastLBA);
        gpe.attributes = le64_to_host(gpe.attributes);
        for (j = 0; j < 36; ++j) {
            gpe.name[i] = le16_to_host(gpe.name[i]);
        }

        /* check that partition is not empty and within a valid location */
        if (gpe.firstLBA == 0) {
            /* empty partition, invalid */
        }
        else if ((gpe.firstLBA > gpe.lastLBA) ||
                 (gpe.firstLBA < hdr.firstUsableLBA) || (gpe.lastLBA > hdr.lastUsableLBA)) {
            cli_dbgmsg("cli_scangpt: GPT partition exists outside specified bounds\n");
            gpt_parsemsg("%llu < %llu, %llu > %llu\n", gpe.firstLBA, hdr.firstUsableLBA,
                         gpe.lastLBA, hdr.lastUsableLBA);
            /* partition exists outside bounds specified by header or invalid */
        }
        else if (((gpe.lastLBA+1) * sectorsize) > maplen) {
            /* partition exists outside bounds of the file map */
        }
        else {
            /* print partition entry data for debug */
            cli_dbgmsg("GPT Partition Entry %u:\n", i);
            gpt_printName(gpe.name, "Name");
            gpt_printGUID(gpe.typeGUID, "Type GUID");
            gpt_printGUID(gpe.uniqueGUID, "Unique GUID");
            cli_dbgmsg("Attributes: %llx\n", (long long unsigned)gpe.attributes);
            cli_dbgmsg("Blocks: [%llu(%llu) -> %llu(%llu)]\n",
                (long long unsigned)gpe.firstLBA, (long long unsigned)(gpe.firstLBA * sectorsize), 
                (long long unsigned)gpe.lastLBA, (long long unsigned)((gpe.lastLBA+1) * sectorsize));

            /* send the partition to cli_map_scan */
            part_off = gpe.firstLBA * sectorsize;
            part_size = (gpe.lastLBA - gpe.firstLBA + 1) * sectorsize;
            ret = cli_map_scan(*ctx->fmap, part_off, part_size, ctx, CL_TYPE_PART_ANY);
            if (ret != CL_CLEAN) {
                if (SCAN_ALLMATCHES && (ret == CL_VIRUS))
                    detection = CL_VIRUS;
                else
                    return ret;
            }
        }

        /* increment the offsets to next partition entry */
        pos += hdr.tableEntrySize;
    }

    if (i >= ctx->engine->maxpartitions) {
        cli_dbgmsg("cli_scangpt: max partitions reached\n");
    }

    return detection;
}
Пример #8
0
int cli_scanswf(cli_ctx *ctx)
{
    struct swf_file_hdr file_hdr;
    fmap_t *map = *ctx->fmap;
    unsigned int bitpos, bitbuf, getbits_n, nbits, getword_1, getword_2, getdword_1, getdword_2;
    const char *pt;
    unsigned char get_c;
    size_t offset = 0;
    unsigned int val, foo, tag_hdr, tag_type, tag_len;
    unsigned long int bits;

    cli_dbgmsg("in cli_scanswf()\n");

    if(fmap_readn(map, &file_hdr, offset, sizeof(file_hdr)) != sizeof(file_hdr)) {
        cli_dbgmsg("SWF: Can't read file header\n");
        return CL_CLEAN;
    }
    offset += sizeof(file_hdr);
    /*
    **  SWF stores the integer bytes with the least significate byte first
    */
    
    file_hdr.filesize = le32_to_host (file_hdr.filesize); 

    cli_dbgmsg("SWF: Version: %u\n", file_hdr.version);
    cli_dbgmsg("SWF: File size: %u\n", file_hdr.filesize);

    if(!strncmp(file_hdr.signature, "CWS", 3)) {
        cli_dbgmsg("SWF: zlib compressed file\n");
        return scancws(ctx, &file_hdr);
    } else if(!strncmp(file_hdr.signature, "ZWS", 3)) {
        cli_dbgmsg("SWF: LZMA compressed file\n");
        return scanzws(ctx, &file_hdr);
    } else if(!strncmp(file_hdr.signature, "FWS", 3)) {
        cli_dbgmsg("SWF: Uncompressed file\n");
    } else {
        cli_dbgmsg("SWF: Not a SWF file\n");
        return CL_CLEAN;
    }

    INITBITS;

    GETBITS(nbits, 5);
    cli_dbgmsg("SWF: FrameSize RECT size bits: %u\n", nbits);
    {
        uint32_t xMin = 0, xMax = 0, yMin = 0, yMax = 0;
        GETBITS(xMin, nbits); /* Should be zero */
        GETBITS(xMax, nbits);
        GETBITS(yMin, nbits); /* Should be zero */
        GETBITS(yMax, nbits);
        cli_dbgmsg("SWF: FrameSize xMin %u xMax %u yMin %u yMax %u\n", xMin, xMax, yMin, yMax);
    }

    GETWORD(foo);
    GETWORD(val);
    cli_dbgmsg("SWF: Frames total: %d\n", val);

    /* Skip Flash tag walk unless debug mode */
    if(!cli_debug_flag) {
        return CL_CLEAN;
    }

    while(offset < map->len) {
        GETWORD(tag_hdr);
        tag_type = tag_hdr >> 6;
        if(tag_type == 0)
            break;
        tag_len = tag_hdr & 0x3f;
        if(tag_len == 0x3f)
            GETDWORD(tag_len);

        pt = tagname(tag_type);
        cli_dbgmsg("SWF: %s\n", pt ? pt : "UNKNOWN TAG");
        cli_dbgmsg("SWF: Tag length: %u\n", tag_len);
        if (tag_len > map->len) {
            cli_dbgmsg("SWF: Invalid tag length.\n");
            return CL_EFORMAT;
        }
        if ((offset + tag_len) < offset) {
            cli_warnmsg("SWF: Tag length too large.\n");
            break;
        }
        if(!pt) {
            offset += tag_len;
            continue;
        }

        switch(tag_type) {
            case TAG_SCRIPTLIMITS: {
                unsigned int recursion, timeout;
                GETWORD(recursion);
                GETWORD(timeout);
                cli_dbgmsg("SWF: scriptLimits recursion %u timeout %u\n", recursion, timeout);
                break;
            }

            case TAG_FILEATTRIBUTES:
                GETDWORD(val);
                cli_dbgmsg("SWF: File attributes:\n");
                if(val & SWF_ATTR_USENETWORK)
                    cli_dbgmsg("    * Use network\n");
                if(val & SWF_ATTR_RELATIVEURLS)
                    cli_dbgmsg("    * Relative URLs\n");
                if(val & SWF_ATTR_SUPPRESSCROSSDOMAINCACHE)
                    cli_dbgmsg("    * Suppress cross domain cache\n");
                if(val & SWF_ATTR_ACTIONSCRIPT3)
                    cli_dbgmsg("    * ActionScript 3.0\n");
                if(val & SWF_ATTR_HASMETADATA)
                    cli_dbgmsg("    * Has metadata\n");
                if(val & SWF_ATTR_USEDIRECTBLIT)
                    cli_dbgmsg("    * Use hardware acceleration\n");
                if(val & SWF_ATTR_USEGPU)
                    cli_dbgmsg("    * Use GPU\n");
                break;

            default:
                offset += tag_len;
                continue;
        }
    }

    return CL_CLEAN;
}