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