1 /* 2 * Copyright (C) 2013-2022 Cisco Systems, Inc. and/or its affiliates. All rights reserved. 3 * Copyright (C) 2007-2013 Sourcefire, Inc. 4 * 5 * Authors: Alberto Wu, Tomasz Kojm, Andrew Williams 6 * 7 * Acknowledgements: The header structures were based upon a PE format 8 * analysis by B. Luevelsmeyer. 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 22 * MA 02110-1301, USA. 23 */ 24 25 #ifndef __PE_H 26 #define __PE_H 27 28 #include "clamav.h" 29 #include "others.h" 30 #include "fmap.h" 31 #include "bcfeatures.h" 32 #include "pe_structs.h" 33 #include "execs.h" 34 35 /** Data for the bytecode PE hook 36 * \group_pe 37 * 38 * NOTE: This structure must stay in-sync with the ones defined within the 39 * clamav-bytecode-compiler source at: 40 * - clang/lib/Headers/bytecode_pe.h 41 * - llvm/tools/clang/lib/Headers/bytecode_pe.h 42 * We allocate space for this, populate the values via cli_peheader, and pass 43 * it to the bytecode sig runtime for use. 44 * 45 * TODO Next time we are making changes to the clamav-bytecode-compiler 46 * source, update pe_image_optional_hdr32 and pe_image_optional_hdr64 to 47 * remove DataDirectory from both (like with the definitions here). Then, 48 * remove opt32_dirs and opt64_dirs below. There's no need to have these 49 * bytes in 3 places! Also, consider using a union to hold opt32 and opt64, 50 * since you never need more than one at a time. 51 */ 52 struct cli_pe_hook_data { 53 uint32_t offset; 54 uint32_t ep; /**< EntryPoint as file offset */ 55 uint16_t nsections; /**< Number of sections */ 56 uint16_t dummy; /* align */ 57 struct pe_image_file_hdr file_hdr; /**< Header for this PE file */ 58 struct pe_image_optional_hdr32 opt32; /**< 32-bit PE optional header */ 59 /** Our opt32 no longer includes DataDirectory[16], but the one in the 60 * bytecode compiler source still does. Add this here as a placeholder (and 61 * it gets used, so we need to populate it also */ 62 struct pe_image_data_dir opt32_dirs[16]; 63 uint32_t dummy2; /* align */ 64 struct pe_image_optional_hdr64 opt64; /**< 64-bit PE optional header */ 65 struct pe_image_data_dir opt64_dirs[16]; /** See note about opt32_dirs */ 66 struct pe_image_data_dir dirs[16]; /**< PE data directory header */ 67 uint32_t e_lfanew; /**< address of new exe header */ 68 uint32_t overlays; /**< number of overlays */ 69 int32_t overlays_sz; /**< size of overlays */ 70 uint32_t hdr_size; /**< internally needed by rawaddr */ 71 }; 72 73 int cli_scanpe(cli_ctx *ctx); 74 75 enum { 76 CL_GENHASH_PE_CLASS_SECTION, 77 CL_GENHASH_PE_CLASS_IMPTBL, 78 /* place new class types above this line */ 79 CL_GENHASH_PE_CLASS_LAST 80 }; 81 82 // For info about these, see the cli_peheader definition in pe.c 83 #define CLI_PEHEADER_OPT_NONE 0x0 84 #define CLI_PEHEADER_OPT_COLLECT_JSON 0x1 85 #define CLI_PEHEADER_OPT_DBG_PRINT_INFO 0x2 86 #define CLI_PEHEADER_OPT_EXTRACT_VINFO 0x4 87 #define CLI_PEHEADER_OPT_STRICT_ON_PE_ERRORS 0x8 88 #define CLI_PEHEADER_OPT_REMOVE_MISSING_SECTIONS 0x10 89 90 #define CLI_PEHEADER_RET_SUCCESS 0 91 #define CLI_PEHEADER_RET_GENERIC_ERROR -1 92 #define CLI_PEHEADER_RET_BROKEN_PE -2 93 #define CLI_PEHEADER_RET_JSON_TIMEOUT -3 94 95 int cli_pe_targetinfo(cli_ctx *ctx, struct cli_exe_info *peinfo); 96 int cli_peheader(fmap_t *map, struct cli_exe_info *peinfo, uint32_t opts, cli_ctx *ctx); 97 98 cl_error_t cli_check_auth_header(cli_ctx *ctx, struct cli_exe_info *peinfo); 99 cl_error_t cli_genhash_pe(cli_ctx *ctx, unsigned int class, int type, stats_section_t *hashes); 100 101 uint32_t cli_rawaddr(uint32_t, const struct cli_exe_section *, uint16_t, unsigned int *, size_t, uint32_t); 102 void findres(uint32_t, uint32_t, fmap_t *map, struct cli_exe_info *, int (*)(void *, uint32_t, uint32_t, uint32_t, uint32_t), void *); 103 104 #endif 105