/* * Copyright (C) 2013-2019 Cisco Systems, Inc. and/or its affiliates. All rights reserved. * Copyright (C) 2007-2013 Sourcefire, Inc. * * Authors: Tomasz Kojm * * 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 __EXECS_H #define __EXECS_H #include "clamav-types.h" #include "hashtab.h" #include "bcfeatures.h" #include "pe_structs.h" /** @file */ /** Section of executable file. * \group_pe * NOTE: This is used to store PE, MachO, and ELF section information. Not * all members are populated by the respective parsing functions. * * NOTE: This header file originates in the clamav-devel source and gets * copied into the clamav-bytecode-compiler source through a script * (sync-clamav.sh). This is done because an array of this structure is * allocated by libclamav and passed to the bytecode sig runtime. * * If you need to make changes to this structure, you will need to update * it in both repos. Also, I'm not sure whether changing this structure * would require a recompile of all previous bytecode sigs. This should * be investigated before changes are made. * * TODO Modify this structure to also include the section name (in both * repos). Then, populate this field in the libclamav PE/MachO/ELF header * parsing functions. Choose a length that's reasonable for all platforms */ struct cli_exe_section { uint32_t rva; /**< Relative VirtualAddress */ uint32_t vsz; /**< VirtualSize */ uint32_t raw; /**< Raw offset (in file) */ uint32_t rsz; /**< Raw size (in file) */ uint32_t chr; /**< Section characteristics */ uint32_t urva; /**< PE - unaligned VirtualAddress */ uint32_t uvsz; /**< PE - unaligned VirtualSize */ uint32_t uraw; /**< PE - unaligned PointerToRawData */ uint32_t ursz; /**< PE - unaligned SizeOfRawData */ }; /** Executable file information * NOTE: This is used to store PE, MachO, and ELF executable information, * but it predominantly has fields for PE info. Not all members are * populated by the respective parsing functions. * * NOTE: This header file originates in the clamav-devel source and gets * copied into the clamav-bytecode-compiler source through a script * (sync-clamav.sh). This is done because an array of cli_exe_section * structs is allocated by libclamav and passed to the bytecode sig * runtime. * * This structure is not used by the bytecode sig runtime, so it can be * modified in the clamav-devel repo without requiring the changes to * be propagated to the clamav-bytecode-compile repo and that code rebuilt. * It'd be nice to keep them in sync if possible, though. */ struct cli_exe_info { /** Information about all the sections of this file. * This array has \p nsection elements */ struct cli_exe_section *sections; /** Offset where this executable starts in file (nonzero if embedded) */ uint32_t offset; /** File offset to the entrypoint of the executable. */ uint32_t ep; /** Number of sections. * NOTE: If a section is determined to be invalid (exists outside of the * file) then it will not be included in this count (at least for PE). */ uint16_t nsections; /***************** Begin PE-specific Section *****************/ /** Resources RVA */ uint32_t res_addr; /** Size of the header (aligned). This corresponds to * SizeOfHeaders in the optional header */ uint32_t hdr_size; /** Hashset for versioninfo matching */ struct cli_hashset vinfo; /** Entry point RVA */ uint32_t vep; /** Number of data directory entries at the end of the optional header. * This also corresponds to the number of entries in dirs that has * been populated with information. */ uint32_t ndatadirs; /** Whether this file is a DLL */ uint32_t is_dll; /** Whether this file is a PE32+ exe (64-bit) */ uint32_t is_pe32plus; /**< address of new exe header */ uint32_t e_lfanew; /** The lowest section RVA */ uint32_t min; /** The RVA of the highest byte contained within a section */ uint32_t max; /** Offset of any file overlays, as determined by parsing the PE header */ uint32_t overlay_start; /**< size of overlay */ uint32_t overlay_size; /* Raw data copied in from the EXE directly. * * NOTE: The data in the members below haven't been converted to host * endianness, so all field accesses must account for this to ensure * proper functionality on big endian systems (the PE header is always * little-endian) */ /** Image File Header for this PE file */ struct pe_image_file_hdr file_hdr; /** PE optional header. Use is_pe32plus to determine whether the 32-bit * or 64-bit union member should be used. */ union { struct pe_image_optional_hdr64 opt64; struct pe_image_optional_hdr32 opt32; } pe_opt; /**< PE data directory header. If ndatadirs is less than 16, * the unpopulated entries will be memset'd to zero. */ struct pe_image_data_dir dirs[16]; /***************** End PE-specific Section *****************/ }; void cli_exe_info_init(struct cli_exe_info *exeinfo, uint32_t offset); void cli_exe_info_destroy(struct cli_exe_info *exeinfo); #endif