43
43
// 4: sequence of null-terminated strings
44
44
45
45
use object:: pe:: * ;
46
- use object:: { LittleEndian as LE , U16Bytes , U32Bytes , U16 , U32 } ;
46
+ use object:: { LittleEndian as LE , U16Bytes , U32Bytes } ;
47
47
use std:: ops:: { Deref , DerefMut } ;
48
48
49
49
use super :: data:: DataWriter ;
50
50
use super :: string_table:: StringTable ;
51
51
52
52
pub ( crate ) const NULL_IMPORT_DESCRIPTOR_SYMBOL : & str = "__NULL_IMPORT_DESCRIPTOR" ;
53
53
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)
56
56
}
57
57
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)
60
60
}
61
61
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 > ,
64
83
}
65
84
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 { }
69
91
70
92
pub ( crate ) fn write_short_import (
71
93
data : & mut DataWriter ,
72
94
dll_name : & str ,
73
95
name : & & str ,
74
- ordinal_or_hint : Option < u16 > ,
96
+ ordinal_or_hint : Option < std :: primitive :: u16 > ,
75
97
) {
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 ) ,
88
108
} ) ;
89
109
data. write_c_str ( name) ;
90
110
data. write_c_str ( dll_name) ;
@@ -143,29 +163,29 @@ pub(crate) fn write_import_descriptor(
143
163
let import_descriptor_pointer_to_relocations = file. data . len ( ) - file. offset ;
144
164
145
165
let header = import_directory_header. get_mut ( file. data ) ;
146
- header. number_of_relocations = u16_aligned ( 3 ) ;
166
+ header. number_of_relocations = u16 ( 3 ) ;
147
167
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 ) ;
149
169
150
170
// todo: CoffRelocWriter
151
171
152
172
// relocation 0: [3] import lookup table rva => points to UNDEF symbol .idata$4
153
173
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 ) ,
157
177
} ) ;
158
178
// relocation 1: [2] name rva => points to DLL name section .idata$6
159
179
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 ) ,
163
183
} ) ;
164
184
// relocation 2: [4] import address table rva => points to UNDEF symbol .idata$5
165
185
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 ) ,
169
189
} ) ;
170
190
171
191
// [1] section .idata$6 data
@@ -269,6 +289,47 @@ pub(crate) fn write_null_import_descriptor(data: &mut DataWriter) {
269
289
) ;
270
290
}
271
291
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
+
272
333
struct CoffFileWriter < ' data > {
273
334
data : & ' data mut DataWriter ,
274
335
offset : usize ,
@@ -279,43 +340,43 @@ struct CoffFileWriter<'data> {
279
340
impl < ' data > CoffFileWriter < ' data > {
280
341
fn new ( data : & ' data mut DataWriter , machine : u16 ) -> Self {
281
342
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 ) ,
290
351
} ) ;
291
352
let string_table = CoffStringTable :: new ( ) ;
292
353
Self { data, offset : file_offset, number_of_sections : 0 , string_table }
293
354
}
294
355
295
- fn file_header_mut ( & mut self ) -> & mut ImageFileHeader {
356
+ fn file_header_mut ( & mut self ) -> & mut ImageFileHeaderUnaligned {
296
357
self . data . get_pod_mut ( self . offset )
297
358
}
298
359
299
360
fn write_section_header ( & mut self , name : & str , characteristics : u32 ) -> CoffSectionHeader {
300
361
self . number_of_sections += 1 ;
301
- let offset = self . data . write_pod ( & ImageSectionHeader {
362
+ let offset = self . data . write_pod ( & ImageSectionHeaderUnaligned {
302
363
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) ,
312
373
} ) ;
313
374
CoffSectionHeader { offset }
314
375
}
315
376
316
377
fn start_symbol_table ( & mut self ) -> CoffSymbolTableWriter < ' _ , ' data > {
317
378
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 ) ;
319
380
CoffSymbolTableWriter { file : self , offset, number_of_symbols : 0 }
320
381
}
321
382
}
@@ -338,7 +399,7 @@ impl Drop for CoffFileWriter<'_> {
338
399
fn drop ( & mut self ) {
339
400
let number_of_sections = self . number_of_sections ;
340
401
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) ;
342
403
self . string_table . write ( self . data ) ;
343
404
}
344
405
}
@@ -356,7 +417,7 @@ impl CoffStringTable {
356
417
writer. write ( data) ;
357
418
}
358
419
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 ] {
360
421
let mut result = [ 0u8 ; 8 ] ;
361
422
if value. len ( ) > 8 {
362
423
// add 4 for the string table length
@@ -375,7 +436,7 @@ struct CoffSectionHeader {
375
436
}
376
437
377
438
impl CoffSectionHeader {
378
- fn get_mut ( self , data : & mut DataWriter ) -> & mut ImageSectionHeader {
439
+ fn get_mut ( self , data : & mut DataWriter ) -> & mut ImageSectionHeaderUnaligned {
379
440
data. get_pod_mut ( self . offset )
380
441
}
381
442
}
@@ -416,8 +477,8 @@ impl Drop for CoffSectionRawData<'_, '_> {
416
477
let header = self . header . get_mut ( self . file . data ) ;
417
478
let size_of_raw_data = end_offset - self . offset ;
418
479
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 ) ;
421
482
}
422
483
}
423
484
@@ -444,9 +505,9 @@ impl CoffSymbolTableWriter<'_, '_> {
444
505
let name = self . file . string_table . get_raw_name ( name) ;
445
506
self . file . write_pod ( & ImageSymbol {
446
507
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 ) ,
450
511
storage_class : options. storage_class ,
451
512
number_of_aux_symbols : options. number_of_aux_symbols ,
452
513
} ) ;
@@ -458,7 +519,7 @@ impl Drop for CoffSymbolTableWriter<'_, '_> {
458
519
fn drop ( & mut self ) {
459
520
let pointer_to_symbol_table = self . offset - self . file . offset ;
460
521
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 ) ;
463
524
}
464
525
}
0 commit comments