4343// 4: sequence of null-terminated strings
4444
4545use object:: pe:: * ;
46- use object:: { LittleEndian as LE , U16Bytes , U32Bytes , U16 , U32 } ;
46+ use object:: { LittleEndian as LE , U16Bytes , U32Bytes } ;
4747use std:: ops:: { Deref , DerefMut } ;
4848
4949use super :: data:: DataWriter ;
5050use super :: string_table:: StringTable ;
5151
5252pub ( crate ) const NULL_IMPORT_DESCRIPTOR_SYMBOL : & str = "__NULL_IMPORT_DESCRIPTOR" ;
5353
54- fn u16_aligned ( value : u16 ) -> U16 < LE > {
55- U16 :: new ( LE , value)
54+ fn u16 ( value : u16 ) -> U16Bytes < LE > {
55+ U16Bytes :: new ( LE , value)
5656}
5757
58- fn u32_aligned ( value : u32 ) -> U32 < LE > {
59- U32 :: new ( LE , value)
58+ fn u32 ( value : u32 ) -> U32Bytes < LE > {
59+ U32Bytes :: new ( LE , value)
6060}
6161
62- fn u16_unaligned ( value : u16 ) -> U16Bytes < LE > {
63- U16Bytes :: new ( LE , value)
62+ #[ derive( Debug , Clone , Copy ) ]
63+ #[ repr( C ) ]
64+ pub ( crate ) struct ImportObjectHeaderUnaligned {
65+ /// Must be IMAGE_FILE_MACHINE_UNKNOWN
66+ pub ( crate ) sig1 : U16Bytes < LE > ,
67+ /// Must be IMPORT_OBJECT_HDR_SIG2.
68+ pub ( crate ) sig2 : U16Bytes < LE > ,
69+ pub ( crate ) version : U16Bytes < LE > ,
70+ pub ( crate ) machine : U16Bytes < LE > ,
71+ /// Time/date stamp
72+ pub ( crate ) time_date_stamp : U32Bytes < LE > ,
73+ /// particularly useful for incremental links
74+ pub ( crate ) size_of_data : U32Bytes < LE > ,
75+
76+ /// if grf & IMPORT_OBJECT_ORDINAL
77+ pub ( crate ) ordinal_or_hint : U16Bytes < LE > ,
78+
79+ // WORD Type : 2;
80+ // WORD NameType : 3;
81+ // WORD Reserved : 11;
82+ pub ( crate ) name_type : U16Bytes < LE > ,
6483}
6584
66- fn u32_unaligned ( value : u32 ) -> U32Bytes < LE > {
67- U32Bytes :: new ( LE , value)
68- }
85+ /// # Safety
86+ /// A type that is `Pod` must:
87+ /// - be `#[repr(C)]` or `#[repr(transparent)]`
88+ /// - have no invalid byte values
89+ /// - have no padding
90+ unsafe impl object:: pod:: Pod for ImportObjectHeaderUnaligned { }
6991
7092pub ( crate ) fn write_short_import (
7193 data : & mut DataWriter ,
7294 dll_name : & str ,
7395 name : & & str ,
74- ordinal_or_hint : Option < u16 > ,
96+ ordinal_or_hint : Option < std :: primitive :: u16 > ,
7597) {
76- data. write_pod ( & ImportObjectHeader {
77- sig1 : u16_aligned ( IMAGE_FILE_MACHINE_UNKNOWN ) ,
78- sig2 : u16_aligned ( IMPORT_OBJECT_HDR_SIG2 ) ,
79- version : u16_aligned ( 0 ) ,
80- machine : u16_aligned ( IMAGE_FILE_MACHINE_AMD64 ) ,
81- time_date_stamp : u32_aligned ( 0 ) ,
82- size_of_data : u32_aligned ( ( name. len ( ) + 1 + dll_name. len ( ) + 1 ) as u32 ) ,
83- ordinal_or_hint : u16_aligned ( ordinal_or_hint. unwrap_or_default ( ) ) ,
84- name_type : u16_aligned (
85- IMPORT_OBJECT_CODE << IMPORT_OBJECT_TYPE_SHIFT
86- | IMPORT_OBJECT_NAME << IMPORT_OBJECT_NAME_SHIFT ,
87- ) ,
98+ data. write_pod ( & ImportObjectHeaderUnaligned {
99+ sig1 : u16 ( IMAGE_FILE_MACHINE_UNKNOWN ) ,
100+ sig2 : u16 ( IMPORT_OBJECT_HDR_SIG2 ) ,
101+ version : u16 ( 0 ) ,
102+ machine : u16 ( IMAGE_FILE_MACHINE_AMD64 ) ,
103+ time_date_stamp : u32 ( 0 ) ,
104+ size_of_data : u32 ( ( name. len ( ) + 1 + dll_name. len ( ) + 1 ) as u32 ) ,
105+ ordinal_or_hint : u16 ( ordinal_or_hint. unwrap_or_default ( ) ) ,
106+ name_type : u16 ( IMPORT_OBJECT_CODE << IMPORT_OBJECT_TYPE_SHIFT
107+ | IMPORT_OBJECT_NAME << IMPORT_OBJECT_NAME_SHIFT ) ,
88108 } ) ;
89109 data. write_c_str ( name) ;
90110 data. write_c_str ( dll_name) ;
@@ -143,29 +163,29 @@ pub(crate) fn write_import_descriptor(
143163 let import_descriptor_pointer_to_relocations = file. data . len ( ) - file. offset ;
144164
145165 let header = import_directory_header. get_mut ( file. data ) ;
146- header. number_of_relocations = u16_aligned ( 3 ) ;
166+ header. number_of_relocations = u16 ( 3 ) ;
147167
148- header. pointer_to_relocations = u32_aligned ( import_descriptor_pointer_to_relocations as u32 ) ;
168+ header. pointer_to_relocations = u32 ( import_descriptor_pointer_to_relocations as u32 ) ;
149169
150170 // todo: CoffRelocWriter
151171
152172 // relocation 0: [3] import lookup table rva => points to UNDEF symbol .idata$4
153173 file. data . write_pod ( & ImageRelocation {
154- virtual_address : u32_unaligned ( 0 ) ,
155- symbol_table_index : u32_unaligned ( 3 ) ,
156- typ : u16_unaligned ( IMAGE_REL_AMD64_ADDR32NB ) ,
174+ virtual_address : u32 ( 0 ) ,
175+ symbol_table_index : u32 ( 3 ) ,
176+ typ : u16 ( IMAGE_REL_AMD64_ADDR32NB ) ,
157177 } ) ;
158178 // relocation 1: [2] name rva => points to DLL name section .idata$6
159179 file. data . write_pod ( & ImageRelocation {
160- virtual_address : u32_unaligned ( 12 ) ,
161- symbol_table_index : u32_unaligned ( 2 ) ,
162- typ : u16_unaligned ( IMAGE_REL_AMD64_ADDR32NB ) ,
180+ virtual_address : u32 ( 12 ) ,
181+ symbol_table_index : u32 ( 2 ) ,
182+ typ : u16 ( IMAGE_REL_AMD64_ADDR32NB ) ,
163183 } ) ;
164184 // relocation 2: [4] import address table rva => points to UNDEF symbol .idata$5
165185 file. data . write_pod ( & ImageRelocation {
166- virtual_address : u32_unaligned ( 16 ) ,
167- symbol_table_index : u32_unaligned ( 4 ) ,
168- typ : u16_unaligned ( IMAGE_REL_AMD64_ADDR32NB ) ,
186+ virtual_address : u32 ( 16 ) ,
187+ symbol_table_index : u32 ( 4 ) ,
188+ typ : u16 ( IMAGE_REL_AMD64_ADDR32NB ) ,
169189 } ) ;
170190
171191 // [1] section .idata$6 data
@@ -269,6 +289,47 @@ pub(crate) fn write_null_import_descriptor(data: &mut DataWriter) {
269289 ) ;
270290}
271291
292+ #[ derive( Debug , Clone , Copy ) ]
293+ #[ repr( C ) ]
294+ pub ( crate ) struct ImageFileHeaderUnaligned {
295+ pub ( crate ) machine : U16Bytes < LE > ,
296+ pub ( crate ) number_of_sections : U16Bytes < LE > ,
297+ pub ( crate ) time_date_stamp : U32Bytes < LE > ,
298+ pub ( crate ) pointer_to_symbol_table : U32Bytes < LE > ,
299+ pub ( crate ) number_of_symbols : U32Bytes < LE > ,
300+ pub ( crate ) size_of_optional_header : U16Bytes < LE > ,
301+ pub ( crate ) characteristics : U16Bytes < LE > ,
302+ }
303+
304+ /// # Safety
305+ /// A type that is `Pod` must:
306+ /// - be `#[repr(C)]` or `#[repr(transparent)]`
307+ /// - have no invalid byte values
308+ /// - have no padding
309+ unsafe impl object:: pod:: Pod for ImageFileHeaderUnaligned { }
310+
311+ #[ derive( Debug , Default , Clone , Copy ) ]
312+ #[ repr( C ) ]
313+ pub ( crate ) struct ImageSectionHeaderUnaligned {
314+ pub ( crate ) name : [ u8 ; IMAGE_SIZEOF_SHORT_NAME ] ,
315+ pub ( crate ) virtual_size : U32Bytes < LE > ,
316+ pub ( crate ) virtual_address : U32Bytes < LE > ,
317+ pub ( crate ) size_of_raw_data : U32Bytes < LE > ,
318+ pub ( crate ) pointer_to_raw_data : U32Bytes < LE > ,
319+ pub ( crate ) pointer_to_relocations : U32Bytes < LE > ,
320+ pub ( crate ) pointer_to_linenumbers : U32Bytes < LE > ,
321+ pub ( crate ) number_of_relocations : U16Bytes < LE > ,
322+ pub ( crate ) number_of_linenumbers : U16Bytes < LE > ,
323+ pub ( crate ) characteristics : U32Bytes < LE > ,
324+ }
325+
326+ /// # Safety
327+ /// A type that is `Pod` must:
328+ /// - be `#[repr(C)]` or `#[repr(transparent)]`
329+ /// - have no invalid byte values
330+ /// - have no padding
331+ unsafe impl object:: pod:: Pod for ImageSectionHeaderUnaligned { }
332+
272333struct CoffFileWriter < ' data > {
273334 data : & ' data mut DataWriter ,
274335 offset : usize ,
@@ -279,43 +340,43 @@ struct CoffFileWriter<'data> {
279340impl < ' data > CoffFileWriter < ' data > {
280341 fn new ( data : & ' data mut DataWriter , machine : u16 ) -> Self {
281342 let file_offset = data. len ( ) ;
282- data. write_pod ( & ImageFileHeader {
283- machine : u16_aligned ( machine) ,
284- number_of_sections : u16_aligned ( 0 ) ,
285- time_date_stamp : u32_aligned ( 0 ) ,
286- pointer_to_symbol_table : u32_aligned ( 0 ) ,
287- number_of_symbols : u32_aligned ( 0 ) ,
288- size_of_optional_header : u16_aligned ( 0 ) ,
289- characteristics : u16_aligned ( 0 ) ,
343+ data. write_pod ( & ImageFileHeaderUnaligned {
344+ machine : u16 ( machine) ,
345+ number_of_sections : u16 ( 0 ) ,
346+ time_date_stamp : u32 ( 0 ) ,
347+ pointer_to_symbol_table : u32 ( 0 ) ,
348+ number_of_symbols : u32 ( 0 ) ,
349+ size_of_optional_header : u16 ( 0 ) ,
350+ characteristics : u16 ( 0 ) ,
290351 } ) ;
291352 let string_table = CoffStringTable :: new ( ) ;
292353 Self { data, offset : file_offset, number_of_sections : 0 , string_table }
293354 }
294355
295- fn file_header_mut ( & mut self ) -> & mut ImageFileHeader {
356+ fn file_header_mut ( & mut self ) -> & mut ImageFileHeaderUnaligned {
296357 self . data . get_pod_mut ( self . offset )
297358 }
298359
299360 fn write_section_header ( & mut self , name : & str , characteristics : u32 ) -> CoffSectionHeader {
300361 self . number_of_sections += 1 ;
301- let offset = self . data . write_pod ( & ImageSectionHeader {
362+ let offset = self . data . write_pod ( & ImageSectionHeaderUnaligned {
302363 name : self . string_table . get_raw_name ( name) ,
303- virtual_size : u32_aligned ( 0 ) ,
304- virtual_address : u32_aligned ( 0 ) ,
305- size_of_raw_data : u32_aligned ( 0 ) , // filled out later
306- pointer_to_raw_data : u32_aligned ( 0 ) , // ditto.
307- pointer_to_relocations : u32_aligned ( 0 ) , // (possibly) ditto.
308- pointer_to_linenumbers : u32_aligned ( 0 ) ,
309- number_of_relocations : u16_aligned ( 0 ) ,
310- number_of_linenumbers : u16_aligned ( 0 ) ,
311- characteristics : u32_aligned ( characteristics) ,
364+ virtual_size : u32 ( 0 ) ,
365+ virtual_address : u32 ( 0 ) ,
366+ size_of_raw_data : u32 ( 0 ) , // filled out later
367+ pointer_to_raw_data : u32 ( 0 ) , // ditto.
368+ pointer_to_relocations : u32 ( 0 ) , // (possibly) ditto.
369+ pointer_to_linenumbers : u32 ( 0 ) ,
370+ number_of_relocations : u16 ( 0 ) ,
371+ number_of_linenumbers : u16 ( 0 ) ,
372+ characteristics : u32 ( characteristics) ,
312373 } ) ;
313374 CoffSectionHeader { offset }
314375 }
315376
316377 fn start_symbol_table ( & mut self ) -> CoffSymbolTableWriter < ' _ , ' data > {
317378 let offset = self . len ( ) ;
318- self . file_header_mut ( ) . pointer_to_symbol_table = u32_aligned ( ( offset - self . offset ) as u32 ) ;
379+ self . file_header_mut ( ) . pointer_to_symbol_table = u32 ( ( offset - self . offset ) as u32 ) ;
319380 CoffSymbolTableWriter { file : self , offset, number_of_symbols : 0 }
320381 }
321382}
@@ -338,7 +399,7 @@ impl Drop for CoffFileWriter<'_> {
338399 fn drop ( & mut self ) {
339400 let number_of_sections = self . number_of_sections ;
340401 let header = self . file_header_mut ( ) ;
341- header. number_of_sections = u16_aligned ( number_of_sections) ;
402+ header. number_of_sections = u16 ( number_of_sections) ;
342403 self . string_table . write ( self . data ) ;
343404 }
344405}
@@ -356,7 +417,7 @@ impl CoffStringTable {
356417 writer. write ( data) ;
357418 }
358419
359- pub fn get_raw_name ( & mut self , value : & str ) -> [ u8 ; 8 ] {
420+ pub ( crate ) fn get_raw_name ( & mut self , value : & str ) -> [ u8 ; 8 ] {
360421 let mut result = [ 0u8 ; 8 ] ;
361422 if value. len ( ) > 8 {
362423 // add 4 for the string table length
@@ -375,7 +436,7 @@ struct CoffSectionHeader {
375436}
376437
377438impl CoffSectionHeader {
378- fn get_mut ( self , data : & mut DataWriter ) -> & mut ImageSectionHeader {
439+ fn get_mut ( self , data : & mut DataWriter ) -> & mut ImageSectionHeaderUnaligned {
379440 data. get_pod_mut ( self . offset )
380441 }
381442}
@@ -416,8 +477,8 @@ impl Drop for CoffSectionRawData<'_, '_> {
416477 let header = self . header . get_mut ( self . file . data ) ;
417478 let size_of_raw_data = end_offset - self . offset ;
418479 let pointer_to_raw_data = self . offset - self . file . offset ;
419- header. size_of_raw_data = u32_aligned ( size_of_raw_data as u32 ) ;
420- header. pointer_to_raw_data = u32_aligned ( pointer_to_raw_data as u32 ) ;
480+ header. size_of_raw_data = u32 ( size_of_raw_data as u32 ) ;
481+ header. pointer_to_raw_data = u32 ( pointer_to_raw_data as u32 ) ;
421482 }
422483}
423484
@@ -444,9 +505,9 @@ impl CoffSymbolTableWriter<'_, '_> {
444505 let name = self . file . string_table . get_raw_name ( name) ;
445506 self . file . write_pod ( & ImageSymbol {
446507 name,
447- value : u32_unaligned ( options. value ) ,
448- section_number : u16_unaligned ( options. section_number as u16 ) ,
449- typ : u16_unaligned ( options. base_type | options. complex_type << 8 ) ,
508+ value : u32 ( options. value ) ,
509+ section_number : u16 ( options. section_number as u16 ) ,
510+ typ : u16 ( options. base_type | options. complex_type << 8 ) ,
450511 storage_class : options. storage_class ,
451512 number_of_aux_symbols : options. number_of_aux_symbols ,
452513 } ) ;
@@ -458,7 +519,7 @@ impl Drop for CoffSymbolTableWriter<'_, '_> {
458519 fn drop ( & mut self ) {
459520 let pointer_to_symbol_table = self . offset - self . file . offset ;
460521 let header = self . file . file_header_mut ( ) ;
461- header. pointer_to_symbol_table = u32_aligned ( pointer_to_symbol_table as u32 ) ;
462- header. number_of_symbols = u32_aligned ( self . number_of_symbols ) ;
522+ header. pointer_to_symbol_table = u32 ( pointer_to_symbol_table as u32 ) ;
523+ header. number_of_symbols = u32 ( self . number_of_symbols ) ;
463524 }
464525}
0 commit comments