mirror of
				https://github.com/Cisco-Talos/clamav.git
				synced 2025-11-03 17:40:56 +00:00 
			
		
		
		
	libclamav: added APM parsing for raw DMGs
This commit is contained in:
		
							parent
							
								
									97fbb02b58
								
							
						
					
					
						commit
						87b71f20d7
					
				
					 2 changed files with 433 additions and 0 deletions
				
			
		
							
								
								
									
										316
									
								
								libclamav/apm.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										316
									
								
								libclamav/apm.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,316 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *  Copyright (C) 2014 Cisco Systems, Inc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Authors: Kevin Lin <kevlin2@cisco.com>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 *  it under the terms of the GNU General Public License version 2 as
 | 
				
			||||||
 | 
					 *  published by the Free Software Foundation.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 *  GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 *  along with this program; if not, write to the Free Software
 | 
				
			||||||
 | 
					 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 | 
				
			||||||
 | 
					 *  MA 02110-1301, USA.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if HAVE_CONFIG_H
 | 
				
			||||||
 | 
					#include "clamav-config.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					#if HAVE_STRING_H
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#include <ctype.h>
 | 
				
			||||||
 | 
					#include <fcntl.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "cltypes.h"
 | 
				
			||||||
 | 
					#include "others.h"
 | 
				
			||||||
 | 
					#include "apm.h"
 | 
				
			||||||
 | 
					#include "prtn_intxn.h"
 | 
				
			||||||
 | 
					#include "scanners.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DEBUG_APM_PARSE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DEBUG_APM_PARSE
 | 
				
			||||||
 | 
					#  define apm_parsemsg(...) cli_dbgmsg( __VA_ARGS__)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#  define apm_parsemsg(...) ;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int apm_prtn_intxn(cli_ctx *ctx, struct apm_partition_info aptable, size_t sectorsize, int old_school);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int cli_scanapm(cli_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    struct apm_driver_desc_map ddm;
 | 
				
			||||||
 | 
					    struct apm_partition_info aptable, apentry;
 | 
				
			||||||
 | 
					    int ret = 0, old_school = 0;
 | 
				
			||||||
 | 
					    size_t sectorsize, maplen, partsize, sectorcheck;;
 | 
				
			||||||
 | 
					    off_t pos = 0, partoff = 0;
 | 
				
			||||||
 | 
					    unsigned i;
 | 
				
			||||||
 | 
					    uint32_t max_prtns = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!ctx || !ctx->fmap) {
 | 
				
			||||||
 | 
					        cli_errmsg("cli_scanapm: Invalid context\n");
 | 
				
			||||||
 | 
					        return CL_ENULLARG;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* read driver description map at sector 0  */
 | 
				
			||||||
 | 
					    if (fmap_readn(*ctx->fmap, &ddm, pos, sizeof(ddm)) != sizeof(ddm)) {
 | 
				
			||||||
 | 
					        cli_dbgmsg("cli_scanapm: Invalid Apple driver description map\n");
 | 
				
			||||||
 | 
					        return CL_EFORMAT;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* convert driver description map big-endian to host */
 | 
				
			||||||
 | 
					    ddm.signature = be16_to_host(ddm.signature);
 | 
				
			||||||
 | 
					    ddm.blockSize = be16_to_host(ddm.blockSize);
 | 
				
			||||||
 | 
					    ddm.blockCount = be32_to_host(ddm.blockCount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* check DDM signature */
 | 
				
			||||||
 | 
					    if (ddm.signature != DDM_SIGNATURE) {
 | 
				
			||||||
 | 
					        cli_dbgmsg("cli_scanapm: Apple driver description map signature mismatch\n");
 | 
				
			||||||
 | 
					        return CL_EFORMAT;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* sector size is determined by the ddm */
 | 
				
			||||||
 | 
					    sectorsize = ddm.blockSize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* size of total file must be described by the ddm */
 | 
				
			||||||
 | 
					    maplen = (*ctx->fmap)->real_len;
 | 
				
			||||||
 | 
					    if ((ddm.blockSize * ddm.blockCount) != maplen) {
 | 
				
			||||||
 | 
					        cli_dbgmsg("cli_scanapm: File described %u size does not match %u actual size\n",
 | 
				
			||||||
 | 
					                   (ddm.blockSize * ddm.blockCount), maplen);
 | 
				
			||||||
 | 
					        return CL_EFORMAT;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* check for old-school partition map */
 | 
				
			||||||
 | 
					    if (sectorsize == 2048) {
 | 
				
			||||||
 | 
					        if (fmap_readn(*ctx->fmap, &aptable, APM_FALLBACK_SECTOR_SIZE, sizeof(aptable)) != sizeof(aptable)) {
 | 
				
			||||||
 | 
					            cli_dbgmsg("cli_scanapm: Invalid Apple partition entry\n");
 | 
				
			||||||
 | 
					            return CL_EFORMAT;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        aptable.signature = be16_to_host(aptable.signature);
 | 
				
			||||||
 | 
					        if (aptable.signature == APM_SIGNATURE) {
 | 
				
			||||||
 | 
					            sectorsize = APM_FALLBACK_SECTOR_SIZE;
 | 
				
			||||||
 | 
					            old_school = 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* read partition table at sector 1 (or after the ddm if old-school) */
 | 
				
			||||||
 | 
					    pos = APM_PTABLE_BLOCK * sectorsize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (fmap_readn(*ctx->fmap, &aptable, pos, sizeof(aptable)) != sizeof(aptable)) {
 | 
				
			||||||
 | 
					        cli_dbgmsg("cli_scanapm: Invalid Apple partition table\n");
 | 
				
			||||||
 | 
					        return CL_EFORMAT;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* convert partition table big endian to host */
 | 
				
			||||||
 | 
					    aptable.signature = be16_to_host(aptable.signature);
 | 
				
			||||||
 | 
					    aptable.numPartitions = be32_to_host(aptable.numPartitions);
 | 
				
			||||||
 | 
					    aptable.pBlockStart = be32_to_host(aptable.pBlockStart);
 | 
				
			||||||
 | 
					    aptable.pBlockCount = be32_to_host(aptable.pBlockCount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* check the partition entry signature */
 | 
				
			||||||
 | 
					    if (aptable.signature != APM_SIGNATURE) {
 | 
				
			||||||
 | 
					        cli_dbgmsg("cli_scanapm: Apple partition table signature mismatch\n");
 | 
				
			||||||
 | 
					        return CL_EFORMAT;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* check if partition table partition */
 | 
				
			||||||
 | 
					    if (strncmp((char*)aptable.type, "Apple_Partition_Map", 32) &&
 | 
				
			||||||
 | 
					        strncmp((char*)aptable.type, "Apple_partition_map", 32) &&
 | 
				
			||||||
 | 
					        strncmp((char*)aptable.type, "Apple_patition_map", 32)){
 | 
				
			||||||
 | 
					        cli_dbgmsg("cli_scanapm: Initial Apple Partition Map partition is not detected\n");
 | 
				
			||||||
 | 
					        return CL_EFORMAT;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* check that the partition table fits in the space specified - HEURISTICS */
 | 
				
			||||||
 | 
					    if (ctx->options & CL_SCAN_PARTITION_INTXN) {
 | 
				
			||||||
 | 
					        ret = apm_prtn_intxn(ctx, aptable, sectorsize, old_school);
 | 
				
			||||||
 | 
					        if ((ret != CL_CLEAN) &&
 | 
				
			||||||
 | 
					            !((ctx->options & CL_SCAN_ALLMATCHES) && (ret == CL_VIRUS))) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return ret;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* print debugging info on partition tables */
 | 
				
			||||||
 | 
					    cli_dbgmsg("APM Partition Table:\n");
 | 
				
			||||||
 | 
					    cli_dbgmsg("Name: %s\n", (char*)aptable.name);
 | 
				
			||||||
 | 
					    cli_dbgmsg("Type: %s\n", (char*)aptable.type);
 | 
				
			||||||
 | 
					    cli_dbgmsg("Signature: %x\n", aptable.signature);
 | 
				
			||||||
 | 
					    cli_dbgmsg("Partition Count: %u\n", aptable.numPartitions);
 | 
				
			||||||
 | 
					    cli_dbgmsg("Blocks: [%u, +%u), ([%u, +%u))\n",
 | 
				
			||||||
 | 
					               aptable.pBlockStart, aptable.pBlockCount,
 | 
				
			||||||
 | 
					               (aptable.pBlockStart * sectorsize),
 | 
				
			||||||
 | 
					               (aptable.pBlockCount * sectorsize));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* check engine maxpartitions limit */
 | 
				
			||||||
 | 
					    if (aptable.numPartitions < ctx->engine->maxpartitions) {
 | 
				
			||||||
 | 
					        max_prtns = aptable.numPartitions;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        max_prtns = ctx->engine->maxpartitions;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* partition table is a partition [at index 1], so skip it */
 | 
				
			||||||
 | 
					    for (i = 2; i <= max_prtns; ++i) {
 | 
				
			||||||
 | 
					        /* read partition table entry */
 | 
				
			||||||
 | 
					        pos = i * sectorsize;
 | 
				
			||||||
 | 
					        if (fmap_readn(*ctx->fmap, &apentry, pos, sizeof(apentry)) != sizeof(apentry)) {
 | 
				
			||||||
 | 
					            cli_dbgmsg("cli_scanapm: Invalid Apple partition entry\n");
 | 
				
			||||||
 | 
					            return CL_EFORMAT;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* convert partition entry big endian to host */
 | 
				
			||||||
 | 
					        apentry.signature = be16_to_host(apentry.signature);
 | 
				
			||||||
 | 
					        apentry.reserved = be16_to_host(apentry.reserved);
 | 
				
			||||||
 | 
					        apentry.numPartitions = be32_to_host(apentry.numPartitions);
 | 
				
			||||||
 | 
					        apentry.pBlockStart = be32_to_host(apentry.pBlockStart);
 | 
				
			||||||
 | 
					        apentry.pBlockCount = be32_to_host(apentry.pBlockCount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* check the partition entry signature */
 | 
				
			||||||
 | 
					        if (aptable.signature != APM_SIGNATURE) {
 | 
				
			||||||
 | 
					            cli_dbgmsg("cli_scanapm: Apple partition entry signature mismatch\n");
 | 
				
			||||||
 | 
					            return CL_EFORMAT;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* check if a out-of-order partition map */
 | 
				
			||||||
 | 
					        if (!strncmp((char*)apentry.type, "Apple_Partition_Map", 32) ||
 | 
				
			||||||
 | 
					            !strncmp((char*)apentry.type, "Apple_partition_map", 32) ||
 | 
				
			||||||
 | 
					            !strncmp((char*)apentry.type, "Apple_patition_map", 32)) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            cli_dbgmsg("cli_scanapm: Out of order Apple Partition Map partition\n");
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        partoff = apentry.pBlockStart * sectorsize;
 | 
				
			||||||
 | 
					        partsize = apentry.pBlockCount * sectorsize;
 | 
				
			||||||
 | 
					        /* re-calculate if old_school and aligned [512 * 4 => 2048] */
 | 
				
			||||||
 | 
					        if (old_school && ((i % 4) == 0)) {
 | 
				
			||||||
 | 
					            if (!strncmp((char*)apentry.type, "Apple_Driver",       32) ||
 | 
				
			||||||
 | 
					                !strncmp((char*)apentry.type, "Apple_Driver43",     32) ||
 | 
				
			||||||
 | 
					                !strncmp((char*)apentry.type, "Apple_Driver43_CD",  32) ||
 | 
				
			||||||
 | 
					                !strncmp((char*)apentry.type, "Apple_Driver_ATA",   32) ||
 | 
				
			||||||
 | 
					                !strncmp((char*)apentry.type, "Apple_Driver_ATAPI", 32) ||
 | 
				
			||||||
 | 
					                !strncmp((char*)apentry.type, "Apple_Patches",      32)) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                partsize = apentry.pBlockCount * 2048;;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* check if invalid partition */
 | 
				
			||||||
 | 
					        if ((partoff == 0) || (partoff+partsize > maplen)) {
 | 
				
			||||||
 | 
					            cli_dbgmsg("cli_scanapm: Detected invalid Apple partition entry\n");
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* print debugging info on partition */
 | 
				
			||||||
 | 
					        cli_dbgmsg("APM Partition Entry %u:\n", i);
 | 
				
			||||||
 | 
					        cli_dbgmsg("Name: %s\n", (char*)apentry.name);
 | 
				
			||||||
 | 
					        cli_dbgmsg("Type: %s\n", (char*)apentry.type);
 | 
				
			||||||
 | 
					        cli_dbgmsg("Signature: %x\n", apentry.signature);
 | 
				
			||||||
 | 
					        cli_dbgmsg("Partition Count: %u\n", apentry.numPartitions);
 | 
				
			||||||
 | 
					        cli_dbgmsg("Blocks: [%u, +%u), ([%u, +%u))\n",
 | 
				
			||||||
 | 
					                   apentry.pBlockStart, apentry.pBlockCount, partoff, partsize);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* send the partition to cli_map_scan */
 | 
				
			||||||
 | 
					        ret = cli_map_scan(*ctx->fmap, partoff, partsize, ctx, CL_TYPE_PART_ANY);
 | 
				
			||||||
 | 
					        if ((ret != CL_CLEAN) &&
 | 
				
			||||||
 | 
					            !((ctx->options & CL_SCAN_ALLMATCHES) && (ret == CL_VIRUS))) {
 | 
				
			||||||
 | 
					                return ret;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (i < aptable.numPartitions) {
 | 
				
			||||||
 | 
					        cli_dbgmsg("cli_scanapm: max partitions exceeded\n");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int apm_prtn_intxn(cli_ctx *ctx, struct apm_partition_info aptable, size_t sectorsize, int old_school)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    prtn_intxn_list_t prtncheck;
 | 
				
			||||||
 | 
					    struct apm_partition_info apentry;
 | 
				
			||||||
 | 
					    unsigned i, pitxn;
 | 
				
			||||||
 | 
					    int ret = 0, tmp = 0;
 | 
				
			||||||
 | 
					    off_t pos;
 | 
				
			||||||
 | 
					    uint32_t max_prtns = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    prtn_intxn_list_init(&prtncheck);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* check engine maxpartitions limit */
 | 
				
			||||||
 | 
					    if (aptable.numPartitions < ctx->engine->maxpartitions) {
 | 
				
			||||||
 | 
					        max_prtns = aptable.numPartitions;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        max_prtns = ctx->engine->maxpartitions;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 1; i <= max_prtns; ++i) {
 | 
				
			||||||
 | 
					        /* read partition table entry */
 | 
				
			||||||
 | 
					        pos = i * sectorsize;
 | 
				
			||||||
 | 
					        if (fmap_readn(*ctx->fmap, &apentry, pos, sizeof(apentry)) != sizeof(apentry)) {
 | 
				
			||||||
 | 
					            cli_dbgmsg("cli_scanapm: Invalid Apple partition entry\n");
 | 
				
			||||||
 | 
					            prtn_intxn_list_free(&prtncheck);
 | 
				
			||||||
 | 
					            return CL_EFORMAT;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* convert necessary info big endian to host */
 | 
				
			||||||
 | 
					        apentry.pBlockStart = be32_to_host(apentry.pBlockStart);
 | 
				
			||||||
 | 
					        apentry.pBlockCount = be32_to_host(apentry.pBlockCount);
 | 
				
			||||||
 | 
					        /* re-calculate if old_school and aligned [512 * 4 => 2048] */
 | 
				
			||||||
 | 
					        if (old_school && ((i % 4) == 0)) {
 | 
				
			||||||
 | 
					            if (!strncmp((char*)apentry.type, "Apple_Driver",       32) ||
 | 
				
			||||||
 | 
					                !strncmp((char*)apentry.type, "Apple_Driver43",     32) ||
 | 
				
			||||||
 | 
					                !strncmp((char*)apentry.type, "Apple_Driver43_CD",  32) ||
 | 
				
			||||||
 | 
					                !strncmp((char*)apentry.type, "Apple_Driver_ATA",   32) ||
 | 
				
			||||||
 | 
					                !strncmp((char*)apentry.type, "Apple_Driver_ATAPI", 32) ||
 | 
				
			||||||
 | 
					                !strncmp((char*)apentry.type, "Apple_Patches",      32)) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                apentry.pBlockCount = apentry.pBlockCount * 4;;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        tmp = prtn_intxn_list_check(&prtncheck, &pitxn, apentry.pBlockStart, apentry.pBlockCount);
 | 
				
			||||||
 | 
					        if (tmp != CL_CLEAN) {
 | 
				
			||||||
 | 
					            if ((ctx->options & CL_SCAN_ALLMATCHES) && (tmp == CL_VIRUS)) {
 | 
				
			||||||
 | 
					                apm_parsemsg("Name: %s\n", (char*)aptable.name);
 | 
				
			||||||
 | 
					                apm_parsemsg("Type: %s\n", (char*)aptable.type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                cli_dbgmsg("cli_scanapm: detected intersection with partitions "
 | 
				
			||||||
 | 
					                           "[%u, %u]\n", pitxn, i);
 | 
				
			||||||
 | 
					                cli_append_virus(ctx, "Heuristic.PartitionIntersection");
 | 
				
			||||||
 | 
					                ret = tmp;
 | 
				
			||||||
 | 
					                tmp = 0;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else if (tmp == CL_VIRUS) {
 | 
				
			||||||
 | 
					                apm_parsemsg("Name: %s\n", (char*)aptable.name);
 | 
				
			||||||
 | 
					                apm_parsemsg("Type: %s\n", (char*)aptable.type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                cli_dbgmsg("cli_scanapm: detected intersection with partitions "
 | 
				
			||||||
 | 
					                           "[%u, %u]\n", pitxn, i);
 | 
				
			||||||
 | 
					                cli_append_virus(ctx, "Heuristic.PartitionIntersection");
 | 
				
			||||||
 | 
					                prtn_intxn_list_free(&prtncheck);
 | 
				
			||||||
 | 
					                return CL_VIRUS;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
 | 
					                prtn_intxn_list_free(&prtncheck);
 | 
				
			||||||
 | 
					                return tmp;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        pos += sectorsize;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    prtn_intxn_list_free(&prtncheck);
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										117
									
								
								libclamav/apm.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								libclamav/apm.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,117 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *  Copyright (C) 2014 Sourcefire, Inc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Authors: Kevin Lin <klin@sourcefire.com>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 *  it under the terms of the GNU General Public License version 2 as
 | 
				
			||||||
 | 
					 *  published by the Free Software Foundation.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 *  GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 *  along with this program; if not, write to the Free Software
 | 
				
			||||||
 | 
					 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 | 
				
			||||||
 | 
					 *  MA 02110-1301, USA.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __APM_H
 | 
				
			||||||
 | 
					#define __APM_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if HAVE_CONFIG_H
 | 
				
			||||||
 | 
					#include "clamav-config.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "cltypes.h"
 | 
				
			||||||
 | 
					#include "others.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define APM_FALLBACK_SECTOR_SIZE 512
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define APM_PTABLE_BLOCK 1
 | 
				
			||||||
 | 
					#define APM_STRUCT_SIZE 512
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DDM_SIGNATURE 0x4552 /* driver description signature ('ER') */
 | 
				
			||||||
 | 
					#define APM_SIGNATURE 0x504D /* partition map signature ('PM') */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* partition flags */
 | 
				
			||||||
 | 
					#define VALID          0x00000001
 | 
				
			||||||
 | 
					#define ALLOCATED      0x00000002
 | 
				
			||||||
 | 
					#define IN_USE         0x00000004
 | 
				
			||||||
 | 
					#define BOOTABLE       0x00000008
 | 
				
			||||||
 | 
					#define READABLE       0x00000010
 | 
				
			||||||
 | 
					#define WRITEABLE      0x00000020
 | 
				
			||||||
 | 
					#define POSINDEPENDENT 0x00000040
 | 
				
			||||||
 | 
					/* end of partition flags */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef HAVE_ATTRIB_PACKED
 | 
				
			||||||
 | 
					#define __attribute__(x)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_PRAGMA_PACK
 | 
				
			||||||
 | 
					#pragma pack(1)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_PRAGMA_PACK_HPPA
 | 
				
			||||||
 | 
					#pragma pack 1
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 8-byte driver description entry for ddmap, big endian */
 | 
				
			||||||
 | 
					struct apm_driver_desc_entry {
 | 
				
			||||||
 | 
					    uint32_t block  __attribute__ ((packed));
 | 
				
			||||||
 | 
					    uint16_t size  __attribute__ ((packed));
 | 
				
			||||||
 | 
					    uint16_t type  __attribute__ ((packed));
 | 
				
			||||||
 | 
					}; //NOTE may need to be renamed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 512(82)-byte driver descriptor map (Block0), big endian */
 | 
				
			||||||
 | 
					struct apm_driver_desc_map {
 | 
				
			||||||
 | 
					    uint16_t signature  __attribute__ ((packed));
 | 
				
			||||||
 | 
					    uint16_t blockSize  __attribute__ ((packed));
 | 
				
			||||||
 | 
					    uint32_t blockCount  __attribute__ ((packed));
 | 
				
			||||||
 | 
					    uint16_t deviceType  __attribute__ ((packed));
 | 
				
			||||||
 | 
					    uint16_t deviceID  __attribute__ ((packed));
 | 
				
			||||||
 | 
					    uint32_t driverData  __attribute__ ((packed));
 | 
				
			||||||
 | 
					    uint16_t driverCount  __attribute__ ((packed));
 | 
				
			||||||
 | 
					    struct apm_driver_desc_entry driverTable[8];
 | 
				
			||||||
 | 
					    /* zeroes fill remainder of sector (430 bytes in 512 sector size) */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 512(136)-byte partition info, big endian;
 | 
				
			||||||
 | 
					 * both the partition table and the individual partitions use this 
 | 
				
			||||||
 | 
					 * struct to describe their details
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct apm_partition_info {
 | 
				
			||||||
 | 
					    uint16_t signature  __attribute__ ((packed));
 | 
				
			||||||
 | 
					    uint16_t reserved  __attribute__ ((packed));
 | 
				
			||||||
 | 
					    uint32_t numPartitions  __attribute__ ((packed));
 | 
				
			||||||
 | 
					    uint32_t pBlockStart  __attribute__ ((packed));
 | 
				
			||||||
 | 
					    uint32_t pBlockCount  __attribute__ ((packed));
 | 
				
			||||||
 | 
					    uint8_t name[32];
 | 
				
			||||||
 | 
					    uint8_t type[32];
 | 
				
			||||||
 | 
					    uint32_t lBlockStart  __attribute__ ((packed));
 | 
				
			||||||
 | 
					    uint32_t lBlockCount  __attribute__ ((packed));
 | 
				
			||||||
 | 
					    uint32_t flags  __attribute__ ((packed));
 | 
				
			||||||
 | 
					    uint32_t bootBlockStart  __attribute__ ((packed));
 | 
				
			||||||
 | 
					    uint32_t bootSize  __attribute__ ((packed));
 | 
				
			||||||
 | 
					    uint32_t bootAddr  __attribute__ ((packed));
 | 
				
			||||||
 | 
					    uint32_t bootAddr2  __attribute__ ((packed));
 | 
				
			||||||
 | 
					    uint32_t bootEntry  __attribute__ ((packed));
 | 
				
			||||||
 | 
					    uint32_t bootEntry2  __attribute__ ((packed));
 | 
				
			||||||
 | 
					    uint32_t bootChecksum  __attribute__ ((packed));
 | 
				
			||||||
 | 
					    uint8_t processor[16];
 | 
				
			||||||
 | 
					    /* zeroes fill remainder of sector (376 bytes in 512 sector size) */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_PRAGMA_PACK
 | 
				
			||||||
 | 
					#pragma pack()
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_PRAGMA_PACK_HPPA
 | 
				
			||||||
 | 
					#pragma pack
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int cli_scanapm(cli_ctx *ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue