]>
glassweightruler.freedombox.rocks Git - Ventoy.git/blob - wimboot/wimboot-2.7.3/src/peloader.c
2 * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
35 * Load PE image into memory
38 * @v len Length of PE image
39 * @v pe Loaded PE structure to fill in
40 * @ret rc Return status code
42 int load_pe ( const void *data
, size_t len
, struct loaded_pe
*pe
) {
43 const struct mz_header
*mzhdr
;
45 const struct pe_header
*pehdr
;
47 const struct pe_optional_header
*opthdr
;
48 size_t section_offset
;
49 const struct coff_section
*section
;
50 char name
[ sizeof ( section
->name
) + 1 /* NUL */ ];
58 DBG2 ( "Loading PE executable...\n" );
62 if ( mzhdr
->magic
!= MZ_HEADER_MAGIC
) {
63 DBG ( "Bad MZ magic %04x\n", mzhdr
->magic
);
66 pehdr_offset
= mzhdr
->lfanew
;
67 if ( pehdr_offset
> len
) {
68 DBG ( "PE header outside file\n" );
71 pehdr
= ( data
+ pehdr_offset
);
72 if ( pehdr
->magic
!= PE_HEADER_MAGIC
) {
73 DBG ( "Bad PE magic %08x\n", pehdr
->magic
);
76 opthdr_offset
= ( pehdr_offset
+ sizeof ( *pehdr
) );
77 opthdr
= ( data
+ opthdr_offset
);
78 pe
->base
= ( ( void * ) ( intptr_t ) ( opthdr
->base
) );
79 section_offset
= ( opthdr_offset
+ pehdr
->coff
.opthdr_len
);
80 section
= ( data
+ section_offset
);
82 /* Load header into memory */
83 DBG2 ( "...headers to %p+%#x\n", pe
->base
, opthdr
->header_len
);
84 memcpy ( pe
->base
, data
, opthdr
->header_len
);
85 end
= ( pe
->base
+ opthdr
->header_len
);
87 /* Load each section into memory */
88 for ( i
= 0 ; i
< pehdr
->coff
.num_sections
; i
++, section
++ ) {
89 memset ( name
, 0, sizeof ( name
) );
90 memcpy ( name
, section
->name
, sizeof ( section
->name
) );
91 section_base
= ( pe
->base
+ section
->virtual );
92 filesz
= section
->raw_len
;
93 memsz
= section
->misc
.virtual_len
;
94 DBG2 ( "...from %#05x to %p+%#zx/%#zx (%s)\n",
95 section
->raw
, section_base
, filesz
, memsz
, name
);
96 memset ( section_base
, 0, memsz
);
97 memcpy ( section_base
, ( data
+ section
->raw
), filesz
);
98 if ( end
< ( section_base
+ memsz
) )
99 end
= ( section_base
+ memsz
);
101 pe
->len
= ( ( ( end
- pe
->base
) + opthdr
->section_align
- 1 )
102 & ~( opthdr
->section_align
- 1 ) );
104 /* Load copy of raw image into memory immediately after loaded
105 * sections. This seems to be used for verification of X.509
108 raw_base
= ( pe
->base
+ pe
->len
);
109 memcpy ( raw_base
, data
, len
);
111 DBG2 ( "...raw copy to %p+%#zx\n", raw_base
, len
);
113 /* Extract entry point */
114 pe
->entry
= ( pe
->base
+ opthdr
->entry
);
115 DBG2 ( "...entry point %p\n", pe
->entry
);