LCOV - code coverage report
Current view: top level - src/pe - section.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 43.8 % 146 64
Test Date: 2026-04-12:00:00:00 Functions: 50.0 % 32 16

            Line data    Source code
       1              : //! PE section module
       2              : 
       3              : use std::marker::PhantomData;
       4              : 
       5              : use crate::coff;
       6              : use crate::common::{into_optional, AsFFI, FromFFI};
       7              : use crate::declare_iterator;
       8              : use crate::generic;
       9              : use crate::to_slice;
      10              : use bitflags::bitflags;
      11              : use lief_ffi as ffi;
      12              : use std::pin::Pin;
      13              : 
      14              : /// This structure defines a regular PE section.
      15              : ///
      16              : /// Note that it implements the trait [`generic::Section`] which provides additional
      17              : /// functions.
      18              : pub struct Section<'a> {
      19              :     ptr: cxx::UniquePtr<ffi::PE_Section>,
      20              :     _owner: PhantomData<&'a ffi::PE_Binary>,
      21              : }
      22              : 
      23            0 : bitflags! {
      24        21684 :     #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
      25            0 :     pub struct Characteristics: u32 {
      26            0 :         const TYPE_NO_PAD = 0x8;
      27            0 :         const CNT_CODE = 0x20;
      28            0 :         const CNT_INITIALIZED_DATA = 0x40;
      29            0 :         const CNT_UNINITIALIZED_DATA = 0x80;
      30            0 :         const LNK_OTHER = 0x100;
      31            0 :         const LNK_INFO = 0x200;
      32            0 :         const LNK_REMOVE = 0x800;
      33            0 :         const LNK_COMDAT = 0x1000;
      34            0 :         const GPREL = 0x8000;
      35            0 :         const MEM_PURGEABLE = 0x10000;
      36            0 :         const MEM_16BIT = 0x20000;
      37            0 :         const MEM_LOCKED = 0x40000;
      38            0 :         const MEM_PRELOAD = 0x80000;
      39            0 :         const ALIGN_1BYTES = 0x100000;
      40            0 :         const ALIGN_2BYTES = 0x200000;
      41            0 :         const ALIGN_4BYTES = 0x300000;
      42            0 :         const ALIGN_8BYTES = 0x400000;
      43            0 :         const ALIGN_16BYTES = 0x500000;
      44            0 :         const ALIGN_32BYTES = 0x600000;
      45            0 :         const ALIGN_64BYTES = 0x700000;
      46            0 :         const ALIGN_128BYTES = 0x800000;
      47            0 :         const ALIGN_256BYTES = 0x900000;
      48            0 :         const ALIGN_512BYTES = 0xa00000;
      49            0 :         const ALIGN_1024BYTES = 0xb00000;
      50            0 :         const ALIGN_2048BYTES = 0xc00000;
      51            0 :         const ALIGN_4096BYTES = 0xd00000;
      52            0 :         const ALIGN_8192BYTES = 0xe00000;
      53            0 :         const LNK_NRELOC_OVFL = 0x1000000;
      54            0 :         const MEM_DISCARDABLE = 0x2000000;
      55            0 :         const MEM_NOT_CACHED = 0x4000000;
      56            0 :         const MEM_NOT_PAGED = 0x8000000;
      57            0 :         const MEM_SHARED = 0x10000000;
      58            0 :         const MEM_EXECUTE = 0x20000000;
      59            0 :         const MEM_READ = 0x40000000;
      60            0 :         const MEM_WRITE = 0x80000000;
      61            0 :     }
      62            0 : }
      63              : 
      64              : impl From<u32> for Characteristics {
      65        21684 :     fn from(value: u32) -> Self {
      66        21684 :         Characteristics::from_bits_truncate(value)
      67        21684 :     }
      68              : }
      69              : impl From<Characteristics> for u32 {
      70            0 :     fn from(value: Characteristics) -> Self {
      71            0 :         value.bits()
      72            0 :     }
      73              : }
      74              : impl std::fmt::Display for Characteristics {
      75            0 :     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
      76            0 :         bitflags::parser::to_writer(self, f)
      77            0 :     }
      78              : }
      79              : 
      80              : impl Section<'_> {
      81              :     /// Create a new Section
      82            0 :     pub fn new() -> Section<'static> {
      83            0 :         Section::from_ffi(lief_ffi::PE_Section::create())
      84            0 :     }
      85              : 
      86              :     /// Create a new Section with the given name
      87            0 :     pub fn new_with_name(name: &str) -> Section<'static> {
      88            0 :         Section::from_ffi(lief_ffi::PE_Section::create_with_name(name.to_string()))
      89            0 :     }
      90              : 
      91              :     /// Create a new Section with the given name and content
      92            0 :     pub fn new_with_content(name: &str, content: &[u8]) -> Section<'static> {
      93            0 :         unsafe {
      94            0 :             Section::from_ffi(lief_ffi::PE_Section::create_with_content(
      95            0 :                 name.to_string(),
      96            0 :                 content.as_ptr(),
      97            0 :                 content.len(),
      98            0 :             ))
      99            0 :         }
     100            0 :     }
     101              : 
     102              :     /// Return the size of the data in the section.
     103         8229 :     pub fn sizeof_raw_data(&self) -> u32 {
     104         8229 :         self.ptr.sizeof_raw_data()
     105         8229 :     }
     106              : 
     107              :     /// Return the size of the data when mapped in memory
     108              :     ///
     109              :     /// If this value is greater than [`Section::sizeof_raw_data`], the section is zero-padded.
     110         8229 :     pub fn virtual_size(&self) -> u32 {
     111         8229 :         self.ptr.virtual_size()
     112         8229 :     }
     113              : 
     114              :     /// The offset of the section data in the PE file
     115         8229 :     pub fn pointerto_raw_data(&self) -> u32 {
     116         8229 :         self.ptr.pointerto_raw_data()
     117         8229 :     }
     118              : 
     119              :     /// The file pointer to the beginning of the COFF relocation entries for the section.
     120              :     /// This is set to zero for executable images or if there are no relocations.
     121              :     ///
     122              :     /// For modern PE binaries, this value is usually set to 0 as the relocations are managed by
     123              :     /// [`crate::pe::Relocation`].
     124         8229 :     pub fn pointerto_relocation(&self) -> u32 {
     125         8229 :         self.ptr.pointerto_relocation()
     126         8229 :     }
     127              : 
     128              :     /// The file pointer to the beginning of line-number entries for the section.
     129              :     /// This is set to zero if there are no COFF line numbers. This value should be zero for an
     130              :     /// image because COFF debugging information is deprecated and modern debug information relies
     131              :     /// on the PDB files.
     132         8229 :     pub fn pointerto_line_numbers(&self) -> u32 {
     133         8229 :         self.ptr.pointerto_line_numbers()
     134         8229 :     }
     135              : 
     136              :     /// No longer used in recent PE binaries produced by Visual Studio
     137         8229 :     pub fn numberof_relocations(&self) -> u16 {
     138         8229 :         self.ptr.numberof_relocations()
     139         8229 :     }
     140              : 
     141              :     /// No longer used in recent PE binaries produced by Visual Studio
     142         8229 :     pub fn numberof_line_numbers(&self) -> u16 {
     143         8229 :         self.ptr.numberof_line_numbers()
     144         8229 :     }
     145              : 
     146              :     /// Characteristics of the section: it provides information about
     147              :     /// the permissions of the section when mapped. It can also provide
     148              :     /// information about the *purpose* of the section (contain code, BSS-like, ...)
     149         8229 :     pub fn characteristics(&self) -> Characteristics {
     150         8229 :         Characteristics::from(self.ptr.characteristics())
     151         8229 :     }
     152              : 
     153              :     /// Content of the section's padding area
     154         1976 :     pub fn padding(&self) -> &[u8] {
     155         1976 :         to_slice!(self.ptr.padding());
     156         1976 :     }
     157              : 
     158              :     /// True if the section can be discarded as needed.
     159              :     ///
     160              :     /// This is typically the case for debug-related sections
     161            0 :     pub fn is_discardable(&self) -> bool {
     162            0 :         self.ptr.is_discardable()
     163            0 :     }
     164              : 
     165              :     /// Return the COFF string associated with the section's name (or a None)
     166              :     ///
     167              :     /// This coff string is usually present for long section names whose length
     168              :     /// does not fit in the 8 bytes allocated by the PE format.
     169         1976 :     pub fn coff_string(&self) -> Option<coff::String<'_>> {
     170         1976 :         into_optional(self.ptr.coff_string())
     171         1976 :     }
     172              : 
     173              :     /// Set the virtual size of the section
     174            0 :     pub fn set_virtual_size(&mut self, virtual_size: u32) {
     175            0 :         self.ptr.pin_mut().set_virtual_size(virtual_size);
     176            0 :     }
     177              : }
     178              : 
     179              : impl std::fmt::Debug for Section<'_> {
     180         8229 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     181         8229 :         let base = self as &dyn generic::Section;
     182         8229 :         f.debug_struct("Section")
     183         8229 :             .field("base", &base)
     184         8229 :             .field("sizeof_raw_data", &self.sizeof_raw_data())
     185         8229 :             .field("virtual_size", &self.virtual_size())
     186         8229 :             .field("pointerto_raw_data", &self.pointerto_raw_data())
     187         8229 :             .field("pointerto_relocation", &self.pointerto_relocation())
     188         8229 :             .field("pointerto_line_numbers", &self.pointerto_line_numbers())
     189         8229 :             .field("numberof_relocations", &self.numberof_relocations())
     190         8229 :             .field("numberof_line_numbers", &self.numberof_line_numbers())
     191         8229 :             .field("characteristics", &self.characteristics())
     192         8229 :             .finish()
     193         8229 :     }
     194              : }
     195              : 
     196              : impl<'a> FromFFI<ffi::PE_Section> for Section<'a> {
     197         8294 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_Section>) -> Self {
     198         8294 :         Section {
     199         8294 :             ptr,
     200         8294 :             _owner: PhantomData,
     201         8294 :         }
     202         8294 :     }
     203              : }
     204              : 
     205              : impl<'a> AsFFI<ffi::PE_Section> for Section<'a> {
     206            0 :     fn as_ffi(&self) -> &ffi::PE_Section {
     207            0 :         self.ptr.as_ref().unwrap()
     208            0 :     }
     209              : 
     210            0 :     fn as_mut_ffi(&mut self) -> std::pin::Pin<&mut ffi::PE_Section> {
     211            0 :         self.ptr.pin_mut()
     212            0 :     }
     213              : }
     214              : 
     215              : impl generic::Section for Section<'_> {
     216        32981 :     fn as_generic(&self) -> &ffi::AbstractSection {
     217        32981 :         self.ptr.as_ref().unwrap().as_ref()
     218        32981 :     }
     219              : 
     220            0 :     fn as_generic_mut(&mut self) -> Pin<&mut ffi::AbstractSection> {
     221            0 :         unsafe {
     222            0 :             Pin::new_unchecked({
     223            0 :                 (self.ptr.as_ref().unwrap().as_ref() as *const ffi::AbstractSection
     224            0 :                     as *mut ffi::AbstractSection)
     225            0 :                     .as_mut()
     226            0 :                     .unwrap()
     227            0 :             })
     228            0 :         }
     229            0 :     }
     230              : }
     231              : 
     232         1976 : declare_iterator!(
     233         1976 :     Sections,
     234         1976 :     Section<'a>,
     235         1976 :     ffi::PE_Section,
     236         1976 :     ffi::PE_Binary,
     237         1976 :     ffi::PE_Binary_it_sections
     238         1976 : );
        

Generated by: LCOV version 2.1-1