Created
December 28, 2023 08:27
-
-
Save djanatyn/684ebeb618cb58aa96d3ab7487a6cfd5 to your computer and use it in GitHub Desktop.
disassembling melee with radare2 from rust
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use r2pipe::{R2Pipe, R2PipeSpawnOptions}; | |
/// Filename of GALE01 v1.02 GCM disk image. | |
const SSBM_ISO: &str = "ssbm.iso"; | |
/// Filename of converted main.dol -> main.elf, converted with doltool. | |
const MAIN_DOL: &str = "main.elf"; | |
/// Offset of get_rand_int in main.elf and in memory. | |
/// | |
/// Taken from SSBM datasheet. | |
const MEMORY_GET_RAND_INT_OFFSET: u64 = 0x80380580; | |
/// Taken from melee community symbol map. | |
const MEMORY_PEACH_DOWNB_GEN_TURNIP: u64 = 0x8011d018; | |
struct MeleeAnalyzer { | |
r2p: R2Pipe, | |
} | |
impl MeleeAnalyzer { | |
fn new<S: AsRef<str>>(filename: S) -> Result<Self, String> { | |
let mut r2p = R2Pipe::spawn( | |
MAIN_DOL, | |
Some(R2PipeSpawnOptions { | |
exepath: "r2".to_string(), | |
args: vec!["-a", "ppc"], | |
}), | |
) | |
.expect("failed to spawn r2"); | |
eprintln!("spawned r2, running analysis..."); | |
r2p.cmd("aaa").or(Err("failed analysis"))?; | |
Ok(MeleeAnalyzer { r2p }) | |
} | |
fn disasm_function(&mut self, offset: u64) -> Result<String, String> { | |
self.r2p | |
.cmd(format!("s {}", offset).as_str()) | |
.or(Err("failed to seek to subroutine"))?; | |
let disasm = self | |
.r2p | |
.cmd("pdf") | |
.or(Err("failed to disassemble subroutine"))?; | |
Ok(disasm) | |
} | |
fn disasm_instructions(&mut self, offset: u64, instructions: u64) -> Result<String, String> { | |
self.r2p | |
.cmd(format!("s {}", offset).as_str()) | |
.or(Err("failed to seek to subroutine"))?; | |
let disasm = self | |
.r2p | |
.cmd(format!("pd {}", instructions).as_str()) | |
.or(Err("failed to disassemble subroutine"))?; | |
Ok(disasm) | |
} | |
} | |
fn main() -> Result<(), String> { | |
let mut analyzer = MeleeAnalyzer::new(MAIN_DOL)?; | |
{ | |
let disasm = analyzer.disasm_function(MEMORY_GET_RAND_INT_OFFSET)?; | |
println!("get_rand_int:\n{disasm}"); | |
} | |
{ | |
let disasm = analyzer.disasm_instructions(0x8011d088, 3)?; | |
println!("peach_turnip_rng:\n{disasm}"); | |
} | |
Ok(()) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
get_rand_int: | |
; XREFS(736) | |
┌ 60: fcn.80380580 (); | |
│ 0x80380580 80ada8f4 lwz r5, -0x570c(r13) | |
│ 0x80380584 3c800003 lis r4, 3 | |
│ 0x80380588 380443fd addi r0, r4, 0x43fd | |
│ 0x8038058c 80850000 lwz r4, 0(r5) | |
│ 0x80380590 7c8401d6 mullw r4, r4, r0 | |
│ 0x80380594 3c840027 addis r4, r4, 0x27 | |
│ 0x80380598 38049ec3 addi r0, r4, 0x9ec3 | |
│ 0x8038059c 90050000 stw r0, 0(r5) | |
│ 0x803805a0 808da8f4 lwz r4, -0x570c(r13) | |
│ 0x803805a4 80040000 lwz r0, 0(r4) | |
│ 0x803805a8 5400843e srwi r0, r0, 0x10 | |
│ 0x803805ac 7c0301d6 mullw r0, r3, r0 | |
│ 0x803805b0 7c038670 srawi r3, r0, 0x10 | |
│ 0x803805b4 7c630194 addze r3, r3 | |
└ 0x803805b8 4e800020 blr | |
peach_turnip_rng: | |
0x8011d088 482634f9 bl fcn.80380580 | |
0x8011d08c 2c030000 cmpwi r3, 0 | |
┌─< 0x8011d090 40820010 bne 0x8011d0a0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment