Coverage Report

Created: 2025-07-12 06:52

/src/upx/src/lefile.h
Line
Count
Source (jump to first uncovered line)
1
/* lefile.h --
2
3
   This file is part of the UPX executable compressor.
4
5
   Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
6
   Copyright (C) 1996-2025 Laszlo Molnar
7
   All Rights Reserved.
8
9
   UPX and the UCL library are free software; you can redistribute them
10
   and/or modify them under the terms of the GNU General Public License as
11
   published by the Free Software Foundation; either version 2 of
12
   the License, or (at your option) any later version.
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; see the file COPYING.
21
   If not, write to the Free Software Foundation, Inc.,
22
   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24
   Markus F.X.J. Oberhumer              Laszlo Molnar
25
   <markus@oberhumer.com>               <ezerotven+github@gmail.com>
26
 */
27
28
#pragma once
29
30
#include "util/membuffer.h"
31
32
class InputFile;
33
class OutputFile;
34
35
/*************************************************************************
36
//
37
**************************************************************************/
38
39
class LeFile {
40
protected:
41
    explicit LeFile(InputFile *) noexcept;
42
    virtual ~LeFile() noexcept;
43
44
    virtual bool readFileHeader();
45
    virtual void writeFile(OutputFile *, bool);
46
47
protected:
48
    enum { FIXUP_EXTRA = 3 };
49
50
    struct alignas(1) le_header_t {
51
        // 0x00
52
        byte _[2];             // signature: 'LE' || 'LX'
53
        byte byte_order;       // 0 little endian
54
        byte word_order;       // 0 little endian
55
        LE32 exe_format_level; // 0
56
        LE16 cpu_type;         // 1->286..4->586
57
        LE16 target_os;        // 1->OS2
58
        byte _0[4];            // module_version = 0
59
        // 0x10
60
        LE32 module_type; // 0x200->compatible with PM windowing
61
        LE32 memory_pages;
62
        LE32 init_cs_object;
63
        LE32 init_eip_offset;
64
        // 0x20
65
        LE32 init_ss_object;
66
        LE32 init_esp_offset;
67
        LE32 memory_page_size;
68
        LE32 bytes_on_last_page;
69
        // 0x30
70
        LE32 fixup_size;
71
        byte _1[4]; // fixup_checksum = 0
72
        LE32 loader_size;
73
        byte _2[4]; // loader_checksum = 0
74
        // 0x40
75
        LE32 object_table_offset;
76
        LE32 object_table_entries;
77
        LE32 object_pagemap_offset;
78
        LE32 object_iterate_data_map_offset;
79
        // 0x50
80
        byte _3[4]; //  resource_offset
81
        LE32 resource_entries;
82
        LE32 resident_names_offset;
83
        LE32 entry_table_offset;
84
        // 0x60
85
        byte _4[4]; //  module_directives_table_offset = 0
86
        LE32 module_directives_entries;
87
        LE32 fixup_page_table_offset;
88
        LE32 fixup_record_table_offset;
89
        // 0x70
90
        LE32 imported_modules_name_table_offset;
91
        LE32 imported_modules_count;
92
        LE32 imported_procedures_name_table_offset;
93
        byte _5[4]; // per_page_checksum_table_offset =  0
94
        // 0x80
95
        LE32 data_pages_offset;
96
        byte _6[4]; // preload_page_count = 0
97
        LE32 non_resident_name_table_offset;
98
        LE32 non_resident_name_table_length;
99
        // 0x90
100
        byte _7[4]; // non_resident_names_checksum
101
        LE32 automatic_data_object;
102
#if 1
103
        byte _8[44];
104
#else
105
        LE32 debug_info_offset;
106
        LE32 debug_info_length;
107
        // 0xA0
108
        LE32 preload_instance_pages;
109
        LE32 demand_instance_pages;
110
        LE32 extra_heap_alloc;
111
        byte reserved[12];
112
        LE32 versioninfo;
113
        LE32 unknown;
114
        // 0xC0
115
        LE16 device_id;
116
        LE16 ddk_version;
117
#endif
118
    };
119
120
    struct alignas(1) le_object_table_entry_t {
121
        LE32 virtual_size;
122
        LE32 base_address;
123
        LE32 flags;
124
        LE32 pagemap_index;
125
        LE32 npages;
126
        LE32 reserved;
127
    };
128
129
    struct alignas(1) le_pagemap_entry_t {
130
        byte h;
131
        byte m;
132
        byte l;
133
        byte type; // 0x00-legal;0x40-iterated;0x80-invalid;0xC0-zeroed
134
    };
135
136
    virtual void readObjectTable();
137
    virtual void writeObjectTable();
138
    // virtual void encodeObjectTable(){oobject_table = iobject_table; iobject_table = nullptr;}
139
    // virtual void decodeObjectTable(){encodeObjectTable();}
140
141
    virtual void readFixupPageTable();
142
    virtual void writeFixupPageTable();
143
    // virtual void encodeFixupPageTable(){ofpage_table = ifpage_table; ifpage_table = nullptr;}
144
    // virtual void decodeFixupPageTable(){encodeFixupPageTable();}
145
146
    virtual void readPageMap();
147
    virtual void writePageMap();
148
0
    virtual void encodePageMap() {
149
0
        opm_entries = ipm_entries;
150
0
        ipm_entries = nullptr;
151
0
    }
152
0
    virtual void decodePageMap() { encodePageMap(); }
153
154
    virtual void readResidentNames();
155
    virtual void writeResidentNames();
156
0
    virtual void encodeResidentNames() {
157
0
        ores_names = ires_names;
158
0
        ires_names = nullptr;
159
0
    }
160
0
    virtual void decodeResidentNames() { encodeResidentNames(); }
161
162
    virtual void readNonResidentNames();
163
    virtual void writeNonResidentNames();
164
0
    virtual void encodeNonResidentNames() {
165
0
        ononres_names = inonres_names;
166
0
        inonres_names = nullptr;
167
0
    }
168
0
    virtual void decodeNonResidentNames() { encodeNonResidentNames(); }
169
170
    virtual void readEntryTable();
171
    virtual void writeEntryTable();
172
    // virtual void encodeEntryTable(){oentries = ientries; ientries = nullptr;}
173
    // virtual void decodeEntryTable(){encodeEntryTable();}
174
175
    virtual void readFixups();
176
    virtual void writeFixups();
177
    // virtual void encodeFixups(){ofixups = ifixups; ifixups = nullptr;}
178
    // virtual void decodeFixups(){encodeFixups();}
179
180
    virtual void readImage();
181
    virtual void writeImage();
182
    // virtual void encodeImage(){oimage = iimage; iimage = nullptr;}
183
    // virtual void decodeImage(){encodeImage();}
184
185
    void countFixups(unsigned *) const;
186
    unsigned getImageSize() const;
187
188
    InputFile *fif = nullptr;
189
    OutputFile *fof = nullptr;
190
    unsigned le_offset = 0;
191
    unsigned exe_offset = 0;
192
193
    le_header_t ih = {}, oh = {};
194
195
    le_object_table_entry_t *iobject_table = nullptr;
196
    le_object_table_entry_t *oobject_table = nullptr;
197
    unsigned *ifpage_table = nullptr;
198
    unsigned *ofpage_table = nullptr;
199
    le_pagemap_entry_t *ipm_entries = nullptr;
200
    le_pagemap_entry_t *opm_entries = nullptr;
201
    byte *ires_names = nullptr;
202
    byte *ores_names = nullptr;
203
    byte *ifixups = nullptr;
204
    byte *ofixups = nullptr;
205
    byte *inonres_names = nullptr;
206
    byte *ononres_names = nullptr;
207
    MemBuffer mb_iimage;
208
    SPAN_0(byte) iimage = nullptr;
209
    MemBuffer mb_oimage;
210
    SPAN_0(byte) oimage = nullptr;
211
    byte *ientries = nullptr;
212
    byte *oentries = nullptr;
213
214
    unsigned soobject_table = 0;
215
    unsigned sofpage_table = 0;
216
    unsigned sopm_entries = 0;
217
    unsigned sores_names = 0;
218
    unsigned sofixups = 0;
219
    unsigned sononres_names = 0;
220
    unsigned soimage = 0;
221
    unsigned soentries = 0;
222
223
private:
224
    // disable copy and move
225
    UPX_CXX_DISABLE_COPY_MOVE(LeFile)
226
};
227
228
/* vim:set ts=4 sw=4 et: */