From db8823e0add616ad051af29a5b8e88ccf9fbba64 Mon Sep 17 00:00:00 2001 From: Noratrieb <48135649+Noratrieb@users.noreply.github.com> Date: Sun, 2 Feb 2025 12:54:45 +0100 Subject: [PATCH] no --- README.md | 1 + src/lib.rs | 31 +++++++++++++++++++++++++++++++ test2/Makefile | 8 ++++---- test2/tls_exe.rs | 30 ++++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 test2/tls_exe.rs diff --git a/README.md b/README.md index 955fd07..fc84f95 100644 --- a/README.md +++ b/README.md @@ -9,3 +9,4 @@ a PE loader for educational purposes. - https://learn.microsoft.com/en-us/archive/msdn-magazine/2002/march/inside-windows-an-in-depth-look-into-the-win32-portable-executable-file-format-part-2 - https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order - https://www.geoffchappell.com/studies/windows/win32/apisetschema/index.htm?tx=1 +- http://www.nynaeve.net/?p=180 diff --git a/src/lib.rs b/src/lib.rs index 198066e..2b654e1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -245,6 +245,19 @@ impl Debug for BaseRelocationType { } } +#[derive(Clone, Copy, Debug, bytemuck::Zeroable, bytemuck::Pod)] +#[repr(C)] +struct TlsDirectory { + /// Note that this is a VA that should have been relocated earlier. + raw_data_start_va: u64, + /// The last byte of the TLS. + raw_data_env_va: u64, + address_of_index: u64, + address_of_callbacks: u64, + size_of_zero_fill: u32, + characteristics: u32, +} + const IMAGE_FILE_MACHINE_AMD64: u16 = 0x8664; const IMAGE_FILE_MACHINE_ARM64: u16 = 0xaa64; @@ -342,6 +355,15 @@ static GLOBAL_STATE: GlobalStateWrapper = GlobalStateWrapper { }), }; +#[repr(C)] +struct ThreadEnvironmentBlock { + host_thread_ptr: *const (), + _pad: [u8; 80], + thing: *const (), + +} +const _: () = assert!(std::mem::offset_of!(ThreadEnvironmentBlock, thing) == 88); + #[tracing::instrument(skip(pe, is_dll))] fn load<'pe>(pe: &'pe [u8], executable_path: &Path, is_dll: bool) -> Image<'pe> { load_inner(pe, executable_path, is_dll) @@ -560,6 +582,15 @@ fn load_inner<'pe>(pe: &'pe [u8], executable_path: &Path, is_dll: bool) -> Image } } + /* + not what's happening? + tracing::debug!("load TLS"); + let tls_directory = bytemuck::cast_slice::( + &image[opt_header.tls_table.rva as usize..][..opt_header.tls_table.size as usize], + ); + tracing::debug!(?tls_directory, "TLS directory"); + */ + tracing::debug!("applying section protections"); for section in section_table { let mode = if section diff --git a/test2/Makefile b/test2/Makefile index ac1194c..c89081f 100644 --- a/test2/Makefile +++ b/test2/Makefile @@ -1,14 +1,14 @@ SHELL = bash RUSTC = rustc --target x86_64-pc-windows-msvc -Copt-level=3 -Cpanic=abort -Clinker=lld-link -Clink-arg=/NODEFAULTLIB -Clink-arg=/debug:none -Cdebuginfo=0 -build: empty_exe.exe one_dll.exe two_dll.exe constant_data.exe +build: empty_exe.exe one_dll.exe two_dll.exe tls_exe.exe + +tls_exe.exe: tls_exe.rs + $(RUSTC) tls_exe.rs empty_exe.exe: empty_exe.rs $(RUSTC) empty_exe.rs -constant_data.exe: constant_data.rs - $(RUSTC) constant_data.rs - one_dll.exe: one_dll.rs small_dll.dll $(RUSTC) one_dll.rs diff --git a/test2/tls_exe.rs b/test2/tls_exe.rs new file mode 100644 index 0000000..39b9bce --- /dev/null +++ b/test2/tls_exe.rs @@ -0,0 +1,30 @@ +#![feature(thread_local)] +#![no_std] +#![no_main] +#![windows_subsystem = "console"] + +#[panic_handler] +fn handle_panic(_: &core::panic::PanicInfo<'_>) -> ! { + loop {} +} + +#[thread_local] +static mut A_THREAD_LOCAL: u32 = 50; +#[thread_local] +static mut ANOTHER_THREAD_LOCAL: u32 = 55; + +#[inline(never)] +fn set_tls(value: u32) { + unsafe { A_THREAD_LOCAL = value; } + unsafe { ANOTHER_THREAD_LOCAL = value; } +} + +#[no_mangle] +pub extern "stdcall" fn mainCRTStartup() -> u32 { + // Use some indirection to actually force TLS to happen + set_tls(14); + unsafe { A_THREAD_LOCAL + ANOTHER_THREAD_LOCAL } +} + +#[no_mangle] +pub extern "stdcall" fn _tls_index() {}