#memory #emulator #reading #emulated #dolphin

dolphin-memory

一个Rust库,使得读取和写入Dolphin模拟器内存更加容易

3个版本

0.2.3 2021年11月28日
0.2.2 2021年11月26日
0.2.1 2021年11月22日

#89 in #emulator


用于 windwaker

MIT 许可证

25KB
417 代码行(不包括注释)

dolphin-memory-rs

一个Rust库,用于从Dolphin模拟器的仿真内存中读取和写入。

目前仅支持Windows平台,尽管理论上可以移植到其他平台。

示例

从内存中读取

使用GCM格式读取游戏ID的简化示例。

use dolphin_memory::Dolphin;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Searches for the dolphin process on loop. Dolphin::new will error
    // when the process isn't found, so you could choose to handle that however.
    let dolphin = loop {
        if let Ok(dolphin) = Dolphin::new() {
            break dolphin;
        }
    };

    // Reads the value at 0x80000000, which is the gcm header address.
    let header_address = 0x80000000;
    // The first 6 bytes of the header include the Game ID, which is a string.
    let game_id = dolphin.read_string(6, header_address, None)?;

    println!("Game ID: {}", game_id);

    Ok(())
}

字节

有时您想读取特定数量的字节。所有便利函数实际上只是调用read的封装,并设置一定数量的字节。

use dolphin_memory::Dolphin;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let dolphin = loop {
        if let Ok(dolphin) = Dolphin::new() {
            break dolphin;
        }
    };

    // The crate provides convenience functions for most common types, but you can also
    // use it to read raw bytes yourself. Note that when reading raw bytes it's up
    // to you to determine how to parse them (eg. if you're dealing with BigEndian data).
    let header_address = 0x80000000;
    let game_id_bytes = dolphin.read(6, header_address, None)?;

    println!(
        "Game ID: {}",
        String::from_utf8(game_id_bytes)
            .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?
    );

    Ok(())
}

指针

处理内存中的指针并不罕见。幸运的是,这个库使得这个过程变得简单。

use dolphin_memory::Dolphin;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let dolphin = loop {
        if let Ok(dolphin) = Dolphin::new() {
            break dolphin;
        }
    };

    // Every call can also optionally follow a chain of pointer addresses.
    // To specify a list of pointers, supply a list of addresses in the
    // order that they need to be chained. The last address will read the actual
    // value at the end of the pointer chain.
    let some_ptr_addr = 0x81234567;
    let some_value_offset = 0xA4;
    let game_id_bytes = dolphin.read(6, some_ptr_addr, Some(&[some_value_offset]))?;

    Ok(())
}

依赖项

~0.4–1.2MB
~24K SLoC