/// Represents the TLS directory `IMAGE_TLS_DIRECTORY64`. #[repr(C)] #[derive(Debug, PartialEq, Copy, Clone, Default, Pread, Pwrite, SizeWith)] pubstruct ImageTlsDirectory { /// The starting address of the TLS raw data. // NOTE: `u32` for 32-bit binaries, `u64` for 64-bit binaries. pub start_address_of_raw_data: u64, /// The ending address of the TLS raw data. // NOTE: `u32` for 32-bit binaries, `u64` for 64-bit binaries. pub end_address_of_raw_data: u64, /// The address of the TLS index. // NOTE: `u32` for 32-bit binaries, `u64` for 64-bit binaries. pub address_of_index: u64, /// The address of the TLS callback functions. /// /// Terminated by a null pointer. // NOTE: `u32` for 32-bit binaries, `u64` for 64-bit binaries. pub address_of_callbacks: u64, /// The size of the zero fill. pub size_of_zero_fill: u32, /// The characteristics of the TLS. pub characteristics: u32,
}
/// TLS information. #[derive(Debug, Clone, PartialEq, Default)] pubstruct TlsData<'a> { /// TLS directory. pub image_tls_directory: ImageTlsDirectory, /// Raw data of the TLS. pub raw_data: Option<&'a [u8]>, /// TLS index. pub slot: Option<u32>, /// TLS callbacks. pub callbacks: Vec<u64>,
}
let itd =
ImageTlsDirectory::parse_with_opts::<T>(bytes, *dd, sections, file_alignment, opts)?;
// Parse the raw data if any if itd.end_address_of_raw_data != 0 && itd.start_address_of_raw_data != 0 { if itd.start_address_of_raw_data > itd.end_address_of_raw_data { return Err(error::Error::Malformed(format!( "tls start_address_of_raw_data ({:#x}) is greater than end_address_of_raw_data ({:#x})",
itd.start_address_of_raw_data,
itd.end_address_of_raw_data
)));
}
if (itd.start_address_of_raw_data as usize) < image_base { return Err(error::Error::Malformed(format!( "tls start_address_of_raw_data ({:#x}) is less than image base ({:#x})",
itd.start_address_of_raw_data, image_base
)));
}
// VA to RVA let rva = itd.start_address_of_raw_data as usize - image_base; let size = itd.end_address_of_raw_data - itd.start_address_of_raw_data; let offset =
utils::find_offset(rva, sections, file_alignment, opts).ok_or_else(|| {
error::Error::Malformed(format!( "cannot map tls start_address_of_raw_data rva ({:#x}) into offset",
rva
))
})?;
raw_data = Some(&bytes[offset..offset + size as usize]);
}
// Parse the index if any if itd.address_of_index != 0 { if (itd.address_of_index as usize) < image_base { return Err(error::Error::Malformed(format!( "tls address_of_index ({:#x}) is less than image base ({:#x})",
itd.address_of_index, image_base
)));
}
// VA to RVA let rva = itd.address_of_index as usize - image_base; let offset = utils::find_offset(rva, sections, file_alignment, opts);
slot = offset.and_then(|x| bytes.pread_with::<u32>(x, scroll::LE).ok());
}
// Parse the callbacks if any if itd.address_of_callbacks != 0 { if (itd.address_of_callbacks as usize) < image_base { return Err(error::Error::Malformed(format!( "tls address_of_callbacks ({:#x}) is less than image base ({:#x})",
itd.address_of_callbacks, image_base
)));
}
// VA to RVA let rva = itd.address_of_callbacks as usize - image_base; let offset =
utils::find_offset(rva, sections, file_alignment, opts).ok_or_else(|| {
error::Error::Malformed(format!( "cannot map tls address_of_callbacks rva ({:#x}) into offset",
rva
))
})?; letmut i = 0; // Read the callbacks until we find a null terminator loop { let callback: u64 = if is_64 {
bytes.pread_with::<u64>(offset + i * 8, scroll::LE)?
} else {
bytes.pread_with::<u32>(offset + i * 4, scroll::LE)? as u64
}; if callback == 0 { break;
} // Each callback is an VA so convert it to RVA let callback_rva = callback as usize - image_base; // Check if the callback is in the image if utils::find_offset(callback_rva, sections, file_alignment, opts).is_none() { return Err(error::Error::Malformed(format!( "cannot map tls callback ({:#x})",
callback
)));
}
callbacks.push(callback);
i += 1;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.