~quf/no-cutscene-kiseki

428cb5374ae67d375b7841883103fed0c2f8ed36 — Lukas Himbert 1 year, 8 months ago f8bff65
change rdata memory protect
2 files changed, 22 insertions(+), 5 deletions(-)

M src/lib.rs
M src/win.rs
M src/lib.rs => src/lib.rs +15 -5
@@ 156,22 156,32 @@ pub fn run_and_patch_game(exe_path: &std::path::Path) -> anyhow::Result<()> {
        let mut game = SuspendedGameProcess::new(exe_path).context("couldn't launch suspended game process")?;

        // Obtain information about the text segment pages
        let text_segment_offset = 0x140001000usize;
        let mem_info = win::virtual_query_ex(game.process_handle(), Some(text_segment_offset as *const core::ffi::c_void)).context("couldn't query process memory pages")?;
        if mem_info.BaseAddress as usize + mem_info.RegionSize < 0x1403dfda3 {
        let text_offset = 0x140001000usize;
        let rdata_offset = 0x1407ea000usize;
        let text_mem_info = win::virtual_query_ex(game.process_handle(), Some(text_offset as *const core::ffi::c_void)).context("couldn't query process text pages")?;
        let rdata_mem_info = win::virtual_query_ex(game.process_handle(), Some(rdata_offset as *const core::ffi::c_void)).context("couldn't query process rdata pages")?;

        if text_mem_info.BaseAddress as usize + text_mem_info.RegionSize < 0x1403dfda3 {
            // Are our addresses of interest part of the page region?
            return Err(anyhow::Error::msg("text segment page region is unexpectedly small, bailing out"));
        }
        if rdata_mem_info.BaseAddress as usize + rdata_mem_info.RegionSize < 0x14032a5b1 {
            return Err(anyhow::Error::msg("rdata segment page region is unexpectedly small, bailing out"));
        }

        // Change memory protection flags
        let rw = win::PAGE_READWRITE;
        let oldflags = win::virtual_protect_ex(game.process_handle(), mem_info.BaseAddress, mem_info.RegionSize, rw).context("couldn't change text segment memory protection")?;
        let old_text_flags = win::virtual_protect_ex(game.process_handle(), text_mem_info.BaseAddress, text_mem_info.RegionSize, rw).context("couldn't change text memory protection")?;
        let old_rdata_flags = win::virtual_protect_ex(game.process_handle(), rdata_mem_info.BaseAddress, rdata_mem_info.RegionSize, rw).context("couldn't change rdata memory protection")?;

        // apply patches
        apply_patches(game.process_handle()).context("couldn't apply mod patches")?;

        // Change memory protection flags back
        let _ = win::virtual_protect_ex(game.process_handle(), mem_info.BaseAddress, mem_info.RegionSize, oldflags).context("couldn't change text segment memory protection back to original value")?;
        let _ = win::virtual_protect_ex(game.process_handle(), text_mem_info.BaseAddress, text_mem_info.RegionSize, old_text_flags)
            .context("couldn't change text memory protection back to original value")?;
        let _ = win::virtual_protect_ex(game.process_handle(), rdata_mem_info.BaseAddress, rdata_mem_info.RegionSize, old_rdata_flags)
            .context("couldn't change rdata memory protection back to original value")?;

        // Resume main thread, actually starting the game
        game.resume().context("couldn't resume game process after applying patch")?;

M src/win.rs => src/win.rs +7 -0
@@ 132,6 132,13 @@ pub fn get_drives_with_fallback() -> impl Iterator<Item = char> {
    })
}

// process handle rights
pub use windows::Win32::System::Threading::PROCESS_ALL_ACCESS;
pub use windows::Win32::System::Threading::PROCESS_QUERY_INFORMATION;
pub use windows::Win32::System::Threading::PROCESS_VM_OPERATION;
pub use windows::Win32::System::Threading::PROCESS_VM_READ;
pub use windows::Win32::System::Threading::PROCESS_VM_WRITE;

// process creation flags (we just need one)
pub use windows::Win32::System::Threading::CREATE_SUSPENDED;