### Disassemble Byte Sequence to Instructions Source: https://context7.com/yrp604/bad64/llms.txt Shows how to disassemble a byte slice into an iterator of decoded ARM64 instructions. The example demonstrates handling pre-index and post-index memory addressing modes for STR and LDR instructions. Each instruction is processed individually through the iterator interface, allowing for efficient sequential disassembly of code blocks. ```rust use bad64::{disasm, Op, Operand, Reg, Imm}; // Disassemble two instructions: // 1000: str x0, [sp, #-16]! (push) // 1004: ldr x0, [sp], #16 (pop) let code = b"\xe0\x0f\x1f\xf8\xe0\x07\x41\xf8"; let mut decoded_iter = disasm(code, 0x1000); // First instruction - STR with pre-index addressing let push = decoded_iter.next().unwrap().unwrap(); assert_eq!(push.address(), 0x1000); assert_eq!(push.op(), Op::STR); assert_eq!(push.operands().len(), 2); assert_eq!(push.operands()[0], Operand::Reg { reg: Reg::X0, arrspec: None }); assert_eq!(push.operands()[1], Operand::MemPreIdx { reg: Reg::SP, imm: Imm::Signed(-16) }); println!("{:04x}: {}", push.address(), push); // Second instruction - LDR with post-index addressing let pop = decoded_iter.next().unwrap().unwrap(); assert_eq!(pop.address(), 0x1004); assert_eq!(pop.op(), Op::LDR); assert_eq!(pop.operands()[0], Operand::Reg { reg: Reg::X0, arrspec: None }); assert_eq!(pop.operands()[1], Operand::MemPostIdxImm { reg: Reg::SP, imm: Imm::Signed(16) }); println!("{:04x}: {}", pop.address(), pop); // Verify no more instructions assert_eq!(decoded_iter.next(), None); ``` -------------------------------- ### Decode Single ARM64 Instruction Source: https://context7.com/yrp604/bad64/llms.txt Demonstrates how to decode a single ARM64 instruction from a u32 opcode value. The example shows decoding NOP and ADD instructions with immediate values, accessing instruction properties like address, opcode, operation type, mnemonic, and operands. The function returns strongly-typed Rust structures representing the decoded instruction. ```rust use bad64::{decode, Op, Operand, Reg, Imm}; // Decode a NOP instruction (0xd503201f in little-endian) let nop = decode(0xd503201f, 0x1000).unwrap(); assert_eq!(nop.address(), 0x1000); assert_eq!(nop.opcode(), 0xd503201f); assert_eq!(nop.op(), Op::NOP); assert_eq!(nop.op().mnem(), "nop"); assert_eq!(nop.operands().len(), 0); println!("{}", nop); // Outputs: "nop" // Decode an ADD instruction with immediate: add x0, x1, #0x41 let add_ins = decode(0x91010420, 0x2000).unwrap(); assert_eq!(add_ins.address(), 0x2000); assert_eq!(add_ins.op(), Op::ADD); assert_eq!(add_ins.operands().len(), 3); // Access individual operands let operands = add_ins.operands(); assert_eq!(operands[0], Operand::Reg { reg: Reg::X0, arrspec: None }); assert_eq!(operands[1], Operand::Reg { reg: Reg::X1, arrspec: None }); assert_eq!(operands[2], Operand::Imm64 { imm: Imm::Unsigned(0x41), shift: None }); println!("{:#x?}", add_ins); // Debug output with full details println!("{}", add_ins); // Outputs: "add x0, x1, #0x41" ``` -------------------------------- ### Pattern Match Instructions and Operands (Rust) Source: https://context7.com/yrp604/bad64/llms.txt Illustrates using Rust's pattern matching capabilities with the bad64 library to filter and analyze decoded ARM64 instructions and their operands. This allows for targeted searching, such as finding instructions that use specific registers or match particular operand structures. Dependencies: bad64 crate. ```rust use bad64::{disasm, Op, Operand, Reg}; let code = b"\x1f\x20\x03\xd5\x20\x00\x02\xca\x1f\x04\x01\xf1"; let base_addr = 0x8000; // Pattern match on specific register usage for ins in disasm(code, base_addr).filter_map(Result::ok) { let ops = ins.operands(); // Find instructions using XZR (zero register) as first operand match ops { &[Operand::Reg { reg: Reg::XZR, .. }, ..] => { println!("Zero reg at {:x} in {}", ins.address(), ins.op()); } _ => {} } } // Pattern match on operation and operands together for ins in disasm(code, base_addr).filter_map(Result::ok) { match (ins.op(), ins.operands()) { (Op::CMP, &[Operand::Reg { reg: Reg::XZR, .. }, ..]) | (Op::CMP, &[Operand::ShiftReg { reg: Reg::XZR, .. }, ..]) => { println!("CMP with XZR at {:x}", ins.address()); } (Op::EOR, operands) if operands.len() == 3 => { println!("EOR instruction at {:x}: {}", ins.address(), ins); } _ => {} } } ``` -------------------------------- ### Access Instruction Properties and Flag Effects (Rust) Source: https://context7.com/yrp604/bad64/llms.txt Demonstrates how to use the bad64 library to decode ARM64 instructions and query their properties, such as the operation type, opcode, and effects on CPU flags. It also shows how to identify instructions that do not set flags. Dependencies: bad64 crate. ```rust use bad64::{decode, Op, FlagEffect}; // CMP instruction sets flags: cmp x0, #0x41 let cmp_ins = decode(0xf101041f, 0x3000).unwrap(); assert_eq!(cmp_ins.op(), Op::CMP); assert_eq!(cmp_ins.flags_set(), Some(FlagEffect::Integer)); assert_eq!(cmp_ins.opcode(), 0xf101041f); println!("Instruction at {:#x}: {}", cmp_ins.address(), cmp_ins); // NOP doesn't set flags let nop_ins = decode(0xd503201f, 0x4000).unwrap(); assert_eq!(nop_ins.flags_set(), None); // EOR instruction: eor x0, x1, x2 let eor_ins = decode(0xca020020, 0x5000).unwrap(); assert_eq!(eor_ins.op(), Op::EOR); assert_eq!(eor_ins.op().mnem(), "eor"); let ops = eor_ins.operands(); assert_eq!(ops.len(), 3); println!("Operation: {}, Operand count: {}", eor_ins.op(), ops.len()); ``` -------------------------------- ### Rust Command-Line Disassembler with bad64 Source: https://context7.com/yrp604/bad64/llms.txt This Rust code implements a command-line tool that takes an ARM64 instruction's hexadecimal opcode and an optional base address as input. It uses the `bad64::decode` function to disassemble the instruction and prints the result. Error handling is included for argument parsing and decoding failures. ```rust use std::env; use std::process; use bad64::decode; fn main() { let args: Vec = env::args().collect(); if args.len() < 2 { eprintln!("Usage: {} [base_address]", args[0]); eprintln!("Example: {} 0xd503201f 0x1000", args[0]); process::exit(1); } // Parse instruction opcode let opcode = u32::from_str_radix( args[1].trim_start_matches("0x"), 16 ).unwrap_or_else(|_| { eprintln!("Could not parse {} as hex u32", args[1]); process::exit(1); }); // Parse optional base address let base_addr = match args.get(2) { Some(arg) => u64::from_str_radix( arg.trim_start_matches("0x"), 16 ).unwrap_or(0x1000), None => 0x1000, }; // Decode and display match decode(opcode, base_addr) { Ok(decoded) => { println!("{:#x?}", decoded); println!("{}", decoded); } Err(e) => { eprintln!("Could not decode {:#x}: {}", opcode, e); process::exit(1); } } } // Example usage: // $ cargo run --example decode 0x91010420 // $ cargo run --example decode 0xd503201f 0x5000 ``` -------------------------------- ### Work with Complex Operand Types (Rust) Source: https://context7.com/yrp604/bad64/llms.txt Explains how to handle various complex ARM64 operand types within the bad64 library, including shifted registers, memory addressing with offsets, and SIMD registers. The code demonstrates how to extract and interpret these operands, and includes a loop to categorize and print different operand types encountered in instructions. Dependencies: bad64 crate. ```rust use bad64::{decode, Operand, Reg, Imm, Shift}; // Instruction with shifted register: add x0, x1, x2, lsl #2 let shifted = decode(0x8b020820, 0x7000).unwrap(); if let Some(Operand::ShiftReg { reg, shift }) = shifted.operands().get(2) { println!("Register {} with shift {}", reg, shift); } // Memory operand with offset: ldr x0, [x1, #8] let mem_load = decode(0xf9400420, 0x7004).unwrap(); if let Some(Operand::MemOffset { reg, offset, .. }) = mem_load.operands().get(1) { println!("Load from [{}], offset: {}", reg, offset); } // Conditional branch: b.eq 0x8000 let branch = decode(0x54000040, 0x8000).unwrap(); println!("Branch: {}", branch); // Iterate and categorize operands for ins in [shifted, mem_load, branch].iter() { for (idx, op) in ins.operands().iter().enumerate() { match op { Operand::Reg { reg, .. } => { println!(" Operand {}: Register {}", idx, reg); } Operand::Imm64 { imm, .. } | Operand::Imm32 { imm, .. } => { println!(" Operand {}: Immediate {}", idx, imm); } Operand::MemOffset { reg, offset, .. } => { println!(" Operand {}: Memory [{}, #{}]", idx, reg, offset); } _ => { println!(" Operand {}: {}", idx, op); } } } } ``` -------------------------------- ### Handle Decoding Errors and Invalid Instructions Source: https://context7.com/yrp604/bad64/llms.txt Demonstrates error handling for ARM64 disassembly operations. Shows how to handle unallocated instructions, decode errors, and incomplete instruction buffers. The library returns Result types that capture various error conditions including short buffers, invalid opcodes, and address information for debugging disassembly failures. ```rust use bad64::{decode, disasm, DecodeError}; // Decoding an invalid instruction match decode(0x41414141, 0x1000) { Ok(ins) => println!("Decoded: {}", ins), Err(DecodeError::Unallocated(addr)) => { println!("Unallocated instruction at {:#x}", addr); } Err(e) => println!("Decode error: {}", e), } // Disassembling with error handling let bad_code = &[0x41_u8; 8]; for result in disasm(bad_code, 0x5000) { match result { Ok(ins) => println!("{:04x}: {}", ins.address(), ins), Err(e) => println!("{:04x}: (bad) - {}", e.address(), e), } } // Short buffer handling let short_buffer = &[0x41_u8; 3]; // Less than 4 bytes let mut iter = disasm(short_buffer, 0x6000); match iter.next() { Some(Err(DecodeError::Short(addr))) => { println!("Incomplete instruction at {:#x}", addr); } _ => {} } ``` -------------------------------- ### Disassemble ARM64 ELF Binaries (Rust) Source: https://context7.com/yrp604/bad64/llms.txt Provides a function to disassemble the '.text' section of an ARM64 ELF binary file using the bad64 and xmas_elf crates. It reads the ELF file, locates the '.text' section, and then iterates through its bytes to print each decoded instruction or indicate decoding errors. Dependencies: bad64, xmas-elf, std::fs. ```rust use std::fs; use xmas_elf::ElfFile; use bad64::disasm; fn disassemble_elf(path: &str) -> Result<(), Box> { // Read and parse ELF file let buf = fs::read(path)?; let elf = ElfFile::new(&buf)?; // Find .text section let text_section = elf.find_section_by_name(".text") .ok_or("No .text section found")?; let base = text_section.address(); let size = text_section.size(); let bytes = text_section.raw_data(&elf); println!("Disassembling {} bytes from .text @ {:#x}", size, base); // Disassemble all instructions for result in disasm(bytes, base) { match result { Ok(decoded) => println!("{:04x}: {}", decoded.address(), decoded), Err(e) => println!("{:04x}: (bad)", e.address()), } } Ok(()) } // Usage: // disassemble_elf("/path/to/arm64-binary")?; ``` -------------------------------- ### Decode ARM64 Instruction with bad64 in Rust Source: https://github.com/yrp604/bad64/blob/main/README.md Demonstrates decoding a given ARM64 instruction using the bad64 crate. It takes an instruction's hexadecimal representation as input and outputs a structured `Instruction` enum, along with its assembly representation. This is useful for static analysis and reverse engineering tasks. ```rust $ cargo run --example decode 0x91010420 Instruction { address: 0x1000, opcode: 0x91010420, op: ADD, num_operands: 0x3, operands: [ Reg { reg: X0, arrspec: None, }, Reg { reg: X1, arrspec: None, }, Imm64 { imm: Unsigned( 0x41, ), shift: None, }, ], flags_set: None, } add x0, x1, #0x41 ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.