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: */ |