rdbo / libmem

Advanced Game Hacking Library for C, Modern C++, Rust and Python (Windows/Linux/FreeBSD) (Process/Memory Hacking) (Hooking/Detouring) (Cross Platform) (x86/x64/ARM/ARM64) (DLL/SO Injection) (Internal/External) (Assembler/Disassembler)
GNU Affero General Public License v3.0
797 stars 96 forks source link

Bug: `write_memory_ex` was not work as expected in Rust. #234

Closed asss-whom closed 3 months ago

asss-whom commented 3 months ago

The rust code of write_memory_ex is

pub fn write_memory_ex<T>(process: &Process, dest: Address, value: &T) -> Option<()> {
    let raw_process: lm_process_t = process.to_owned().into();
    let size = mem::size_of::<T>();
    let result = unsafe {
        libmem_sys::LM_WriteMemoryEx(
            &raw_process as *const lm_process_t,
            dest,
            value as *const T as *const u8,
            size,
        )
    };

    (result == size).then_some(())
}

However, when the value is &[T] (e.g. Vec<u8>.as_slice()), rustc panicked:

error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
  --> src/main.rs:92:47
   |
92 |     write_memory_ex(process, fn_change_value, shellcode.as_slice())?;
   |     ---------------                           ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
   |     |
   |     required by a bound introduced by this call
   |
   = help: the trait `Sized` is not implemented for `[u8]`
note: required by an implicit `Sized` bound in `libmem::write_memory_ex`
  --> C:\...\.cargo\registry\src\rsproxy.cn-0dccff568467c15b\libmem-5.0.0\src\memory.rs:65:24
   |
65 | pub fn write_memory_ex<T>(process: &Process, dest: Address, value: &T) -> Option<()> {
   |                        ^ required by the implicit `Sized` requirement on this type parameter in `write_memory_ex`
help: consider removing this method call, as the receiver has type `Vec<u8>` and `Vec<u8>: Sized` trivially holds
   |
92 -     write_memory_ex(process, fn_change_value, shellcode.as_slice())?;
92 +     write_memory_ex(process, fn_change_value, shellcode))?;
   |

For more information about this error, try `rustc --explain E0277`.
error: could not compile `cetutorial` (bin "cetutorial") due to 1 previous error

Apparently, rustc gave us the wrong fix tip. Maybe the right way is change the wrapper function like this:

Delete    pub fn write_memory_ex<T>(process: &Process, dest: Address, value: &T) -> Option<()>
Add       pub fn write_memory_ex<T: ?Sized>(process: &Process, dest: Address, value: &T) -> Option<()>
Delete    let size = mem::size_of::<T>();
Add       let size = mem::size_of_val(value);
rdbo commented 3 months ago

Well spotted, thank you Fixed: 3a53387