Provide a more advanced version of this code. Provide the full thing. Go beyond.
Focus on instruction.rs
main.rs:
mod instruction;

use std::fs::File;
use std::io::Read;
use std::collections::HashMap;
use instruction::{Instruction, Operand};
use goblin::pe::PE;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    println!("Advanced X86_64 Windows Disassembler");

    // Read the binary file
    let mut file = File::open("RobloxPlayerLauncher.exe")?;
    let mut buffer = Vec::new();
    file.read_to_end(&mut buffer)?;

    // Parse the PE file
    let pe = PE::parse(&buffer)?;

    // Find the .text section
    let text_section = pe.sections
        .iter()
        .find(|section| section.name().unwrap_or("") == ".text")
        .ok_or("Failed to find .text section")?;

    let code_offset = text_section.pointer_to_raw_data as usize;
    let code_size = text_section.size_of_raw_data as usize;
    let code = &buffer[code_offset..code_offset + code_size];

    // Calculate the base address of the .text section
    let base_address = pe.image_base as usize + text_section.virtual_address as usize;

    // Create a simple symbol table
    let mut symbol_table = HashMap::new();
    for export in &pe.exports {
        if let Some(name) = export.name {
            symbol_table.insert(export.rva as u64 + pe.image_base as u64, name.to_string());
        }
    }

    // Disassemble the code
    let mut offset = 0;
    while offset < code.len() {
        let rip = base_address as u64 + offset as u64;
        match Instruction::decode(&code[offset..], rip) {
            Ok((instruction, size)) => {
                print!("0x{:016x}: ", rip);
                
                // Resolve symbols for call instructions
                if let Instruction::Call(Operand::Immediate(target)) = &instruction {
                    if let Some(symbol) = symbol_table.get(&(*target as u64)) {
                        println!("{} <{}>", instruction, symbol);
                    } else {
                        println!("{}", instruction);
                    }
                } else {
                    println!("{}", instruction);
                }
                
                offset += size;
            }
            Err(e) => {
                println!("Error decoding instruction at offset 0x{:016x}: {}", rip, e);
                offset += 1;
            }
        }
    }

    Ok(())
}
instruction.rs:
use std::fmt;

#[derive(Debug)]
pub enum Operand {
Register(String),
Immediate(i64),
Memory(String),
}

#[derive(Debug)]
pub enum Instruction {
Mov(Operand, Operand),
Push(Operand),
Pop(Operand),
Call(Operand),
Ret,
Add(Operand, Operand),
Sub(Operand, Operand),
Xor(Operand, Operand),
And(Operand, Operand),
Or(Operand, Operand),
Shl(Operand, Operand),
Shr(Operand, Operand),
Lea(Operand, Operand),
Cmp(Operand, Operand),
Test(Operand, Operand),
Inc(Operand),
Dec(Operand),
Jmp(Operand),
Je(Operand),
Jne(Operand),
Jg(Operand),
Jge(Operand),
Jl(Operand),
Jle(Operand),
Nop,
Syscall,
Cdq,
Imul(Operand, Operand),
Idiv(Operand),
Mul(Operand),
Div(Operand),
Neg(Operand),
Not(Operand),
Movzx(Operand, Operand),
Movsx(Operand, Operand),
Shrd(Operand, Operand, Operand),
ShrdImm(Operand, Operand, i8),
Adc(Operand, Operand),
Sbb(Operand, Operand),
Sar(Operand, Operand),
Unknown(Vec),
}

struct Decoder {
bytes: Vec,
offset: usize,
rex: Option,
}

impl Decoder {
fn new(bytes: Vec) -> Self {
Self {
bytes,
offset: 0,
rex: None,
}
}


fn next_byte(&mut self) -> Option<u8> {
    if self.offset < self.bytes.len() {
        let byte = self.bytes[self.offset];
        self.offset += 1;
        Some(byte)
    } else {
        None
    }
}

fn peek_byte(&self) -> Option<u8> {
    self.bytes.get(self.offset).copied()
}

fn decode_prefix(&mut self) {
    while let Some(byte) = self.peek_byte() {
        match byte {
            0x66 | 0x67 | 0xf0 | 0xf2 | 0xf3 => {
                self.next_byte();
            }
            0x40..=0x4f => {
                self.rex = self.next_byte();
            }
            _ => break,
        }
    }
}

fn decode_modrm(&mut self) -> Option<(u8, u8, u8)> {
    self.next_byte().map(|modrm| {
        let mode = (modrm >> 6) & 0b11;
        let reg = (modrm >> 3) & 0b111;
        let rm = modrm & 0b111;
        (mode, reg, rm)
    })
}

fn decode_sib(&mut self) -> Option<(u8, u8, u8)> {
    self.next_byte().map(|sib| {
        let scale = (sib >> 6) & 0b11;
        let index = (sib >> 3) & 0b111;
        let base = sib & 0b111;
        (scale, index, base)
    })
}

fn decode_displacement(&mut self, mode: u8) -> Option<i32> {
    match mode {
        0b00 => Some(0),
        0b01 => self.next_byte().map(|b| b as i8 as i32),
        0b10 => {
            let b1 = self.next_byte()? as u32;
            let b2 = self.next_byte()? as u32;
            let b3 = self.next_byte()? as u32;
            let b4 = self.next_byte()? as u32;
            Some((b1 | (b2 << 8) | (b3 << 16) | (b4 << 24)) as i32)
        }
        _ => None,
    }
}

fn decode_immediate(&mut self, size: usize) -> Option<i64> {
    let mut value = 0i64;
    for i in 0..size {
        if let Some(byte) = self.next_byte() {
            value |= (byte as i64) << (i * 8);
        } else {
            return None;
        }
    }
    Some(value)
}

fn decode_operand(&mut self, mode: u8, reg: u8, rm: u8) -> Option<Operand> {
    match mode {
        0b11 => Some(Operand::Register(register_name(rm, self.rex))),
        _ => {
            let base = register_name(rm, self.rex);
            let displacement = self.decode_displacement(mode)?;
            if rm == 0b100 {
                let (scale, index, base) = self.decode_sib()?;
                let index_reg = if index != 0b100 {
                    register_name(index, self.rex)
                } else {
                    "".to_string()
                };
                let base_reg = register_name(base, self.rex);
                Some(Operand::Memory(format!(
                    "[{} + {} * {} + {}]",
                    base_reg,
                    index_reg,
                    1 << scale,
                    displacement
                )))
            } else {
                Some(Operand::Memory(format!("[{} + {}]", base, displacement)))
            }
        }
    }
}
}

impl Instruction {
pub fn decode(bytes: &[u8], rip: u64) -> Result<(Self, usize), &'static str> {
let mut decoder = Decoder::new(bytes.to_vec());
decoder.decode_prefix();


    let opcode = decoder.next_byte().ok_or("Unexpected end of input")?;

    match opcode {
        0x50..=0x57 => {
            let reg = register_name(opcode - 0x50, decoder.rex);
            Ok((
                Instruction::Push(Operand::Register(reg)),
                decoder.offset,
            ))
        }
        0x58..=0x5f => {
            let reg = register_name(opcode - 0x58, decoder.rex);
            Ok((
                Instruction::Pop(Operand::Register(reg)),
                decoder.offset,
            ))
        }
        0x89 | 0x8b => {
            let (mode, reg, rm) = decoder
                .decode_modrm()
                .ok_or("Failed to decode ModR/M")?;
            let src = Operand::Register(register_name(reg, decoder.rex));
            let dst = decoder
                .decode_operand(mode, reg, rm)
                .ok_or("Failed to decode operand")?;
            let instruction = if opcode == 0x89 {
                Instruction::Mov(dst, src)
            } else {
                Instruction::Mov(src, dst)
            };
            Ok((instruction, decoder.offset))
        }
        0xe8 => {
            let offset = decoder
                .decode_immediate(4)
                .ok_or("Failed to decode immediate")? as i32;
            let target = (rip as i64 + offset as i64 + decoder.offset as i64) as u64;
            Ok((
                Instruction::Call(Operand::Immediate(target as i64)),
                decoder.offset,
            ))
        }
        0xc3 => Ok((Instruction::Ret, decoder.offset)),
        0x01 | 0x29 | 0x31 | 0x21 | 0x09 => {
            let (mode, reg, rm) = decoder
                .decode_modrm()
                .ok_or("Failed to decode ModR/M")?;
            let src = Operand::Register(register_name(reg, decoder.rex));
            let dst = decoder
                .decode_operand(mode, reg, rm)
                .ok_or("Failed to decode operand")?;
            let instruction = match opcode {
                0x01 => Instruction::Add(dst, src),
                0x29 => Instruction::Sub(dst, src),
                0x31 => Instruction::Xor(dst, src),
                0x21 => Instruction::And(dst, src),
                0x09 => Instruction::Or(dst, src),
                _ => unreachable!(),
            };
            Ok((instruction, decoder.offset))
        }
        0x81 => {
            let (mode, reg, rm) = decoder
                .decode_modrm()
                .ok_or("Failed to decode ModR/M")?;
            let imm = decoder
                .decode_immediate(4)
                .ok_or("Failed to decode immediate")? as i32;
            let dst = decoder
                .decode_operand(mode, reg, rm)
                .ok_or("Failed to decode operand")?;
            let instruction = match reg {
                0 => Instruction::Add(dst, Operand::Immediate(imm as i64)),
                1 => Instruction::Or(dst, Operand::Immediate(imm as i64)),
                2 => Instruction::Adc(dst, Operand::Immediate(imm as i64)),
                3 => Instruction::Sbb(dst, Operand::Immediate(imm as i64)),
                4 => Instruction::And(dst, Operand::Immediate(imm as i64)),
                5 => Instruction::Sub(dst, Operand::Immediate(imm as i64)),
                6 => Instruction::Xor(dst, Operand::Immediate(imm as i64)),
                7 => Instruction::Cmp(dst, Operand::Immediate(imm as i64)),
                _ => Instruction::Unknown(bytes[..decoder.offset].to_vec()),
            };
            Ok((instruction, decoder.offset))
        }
        0x83 => {
            let (mode, reg, rm) = decoder
                .decode_modrm()
                .ok_or("Failed to decode ModR/M")?;
            let imm = decoder
                .decode_immediate(1)
                .ok_or("Failed to decode immediate")? as i8 as i32;
            let dst = decoder
                .decode_operand(mode, reg, rm)
                .ok_or("Failed to decode operand")?;
            let instruction = match reg {
                0 => Instruction::Add(dst, Operand::Immediate(imm as i64)),
                1 => Instruction::Or(dst, Operand::Immediate(imm as i64)),
                2 => Instruction::Adc(dst, Operand::Immediate(imm as i64)),
                3 => Instruction::Sbb(dst, Operand::Immediate(imm as i64)),
                4 => Instruction::And(dst, Operand::Immediate(imm as i64)),
                5 => Instruction::Sub(dst, Operand::Immediate(imm as i64)),
                6 => Instruction::Xor(dst, Operand::Immediate(imm as i64)),
                7 => Instruction::Cmp(dst, Operand::Immediate(imm as i64)),
                _ => Instruction::Unknown(bytes[..decoder.offset].to_vec()),
            };
            Ok((instruction, decoder.offset))
        }
        0x0f => {
            let extended_opcode = decoder.next_byte().ok_or("Unexpected end of input")?;
            match extended_opcode {
                0x84 | 0x85 | 0x8f | 0x8d | 0x8c | 0x8e => {
                    let offset = decoder
                        .decode_immediate(4)
                        .ok_or("Failed to decode immediate")? as i32;
                    let target = (rip as i64 + offset as i64 + decoder.offset as i64) as u64;
                    let instruction = match extended_opcode {
                        0x84 => Instruction::Je(Operand::Immediate(target as i64)),
                        0x85 => Instruction::Jne(Operand::Immediate(target as i64)),
                        0x8f => Instruction::Jg(Operand::Immediate(target as i64)),
                        0x8d => Instruction::Jge(Operand::Immediate(target as i64)),
                        0x8c => Instruction::Jl(Operand::Immediate(target as i64)),
                        0x8e => Instruction::Jle(Operand::Immediate(target as i64)),
                        _ => unreachable!(),
                    };
                    Ok((instruction, decoder.offset))
                }
                0xaf => {
                    let (mode, reg, rm) = decoder
                        .decode_modrm()
                        .ok_or("Failed to decode ModR/M")?;
                    let dst = Operand::Register(register_name(reg, decoder.rex));
                    let src = decoder
                        .decode_operand(mode, reg, rm)
                        .ok_or("Failed to decode operand")?;
                    Ok((Instruction::Imul(dst, src), decoder.offset))
                }
                0x0e => {
                    // Example for additional extended opcodes
                    // Implement as needed
                    Ok((Instruction::Unknown(vec![0x0f, extended_opcode]), decoder.offset))
                }
                _ => Ok((
                    Instruction::Unknown(bytes[..decoder.offset].to_vec()),
                    decoder.offset,
                )),
            }
        }
        0x90 => Ok((Instruction::Nop, decoder.offset)),
        0x99 => Ok((Instruction::Cdq, decoder.offset)),
        0xf7 => {
            let (mode, reg, rm) = decoder
                .decode_modrm()
                .ok_or("Failed to decode ModR/M")?;
            let operand = decoder
                .decode_operand(mode, reg, rm)
                .ok_or("Failed to decode operand")?;
            let instruction = match reg {
                2 => Instruction::Not(operand),
                3 => Instruction::Neg(operand),
                4 => Instruction::Mul(operand),
                5 => Instruction::Imul(Operand::Register("rax".to_string()), operand),
                6 => Instruction::Div(operand),
                7 => Instruction::Idiv(operand),
                _ => Instruction::Unknown(bytes[..decoder.offset].to_vec()),
            };
            Ok((instruction, decoder.offset))
        }
        0xff => {
            let (mode, reg, rm) = decoder
                .decode_modrm()
                .ok_or("Failed to decode ModR/M")?;
            let operand = decoder
                .decode_operand(mode, reg, rm)
                .ok_or("Failed to decode operand")?;
            let instruction = match reg {
                0 => Instruction::Inc(operand),
                1 => Instruction::Dec(operand),
                2 | 3 => Instruction::Call(operand),
                4 | 5 => Instruction::Jmp(operand),
                _ => Instruction::Unknown(bytes[..decoder.offset].to_vec()),
            };
            Ok((instruction, decoder.offset))
        }
        0x8d => {
            let (mode, reg, rm) = decoder
                .decode_modrm()
                .ok_or("Failed to decode ModR/M")?;
            let dst = Operand::Register(register_name(reg, decoder.rex));
            let src = decoder
                .decode_operand(mode, reg, rm)
                .ok_or("Failed to decode operand")?;
            Ok((Instruction::Lea(dst, src), decoder.offset))
        }
        0x39 | 0x3b => {
            let (mode, reg, rm) = decoder
                .decode_modrm()
                .ok_or("Failed to decode ModR/M")?;
            let src = Operand::Register(register_name(reg, decoder.rex));
            let dst = decoder
                .decode_operand(mode, reg, rm)
                .ok_or("Failed to decode operand")?;
            let instruction = if opcode == 0x39 {
                Instruction::Cmp(dst, src)
            } else {
                Instruction::Cmp(src, dst)
            };
            Ok((instruction, decoder.offset))
        }
        0x85 => {
            let (mode, reg, rm) = decoder
                .decode_modrm()
                .ok_or("Failed to decode ModR/M")?;
            let src = Operand::Register(register_name(reg, decoder.rex));
            let dst = decoder
                .decode_operand(mode, reg, rm)
                .ok_or("Failed to decode operand")?;
            Ok((Instruction::Test(dst, src), decoder.offset))
        }
        0xc1 => {
            let (mode, reg, rm) = decoder
                .decode_modrm()
                .ok_or("Failed to decode ModR/M")?;
            let dst = decoder
                .decode_operand(mode, reg, rm)
                .ok_or("Failed to decode operand")?;
            let imm = decoder
                .decode_immediate(1)
                .ok_or("Failed to decode immediate")? as i8;
            let instruction = match reg {
                4 => Instruction::Shl(dst, Operand::Immediate(imm as i64)),
                5 => Instruction::Shr(dst, Operand::Immediate(imm as i64)),
                7 => Instruction::Sar(dst, Operand::Immediate(imm as i64)),
                _ => Instruction::Unknown(bytes[..decoder.offset].to_vec()),
            };
            Ok((instruction, decoder.offset))
        }
        0xba => {
            // Example: MOV edx, imm32
            let imm = decoder
                .decode_immediate(4)
                .ok_or("Failed to decode immediate")?;
            Ok((
                Instruction::Mov(
                    Operand::Register("edx".to_string()),
                    Operand::Immediate(imm),
                ),
                decoder.offset,
            ))
        }
        // Add more opcodes and their handling as needed
        _ => Ok((
            Instruction::Unknown(bytes[..decoder.offset].to_vec()),
            decoder.offset,
        )),
    }
}
}

fn register_name(index: u8, rex: Option) -> String {
let extended = rex.map_or(false, |r| r & 0b0100 != 0);
match (index, extended) {
(0, false) => "rax".to_string(),
(1, false) => "rcx".to_string(),
(2, false) => "rdx".to_string(),
(3, false) => "rbx".to_string(),
(4, false) => "rsp".to_string(),
(5, false) => "rbp".to_string(),
(6, false) => "rsi".to_string(),
(7, false) => "rdi".to_string(),
(0, true) => "r8".to_string(),
(1, true) => "r9".to_string(),
(2, true) => "r10".to_string(),
(3, true) => "r11".to_string(),
(4, true) => "r12".to_string(),
(5, true) => "r13".to_string(),
(6, true) => "r14".to_string(),
(7, true) => "r15".to_string(),
_ => unreachable!(),
}
}

impl fmt::Display for Instruction {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Instruction::Mov(dst, src) => write!(f, "mov {}, {}", dst, src),
Instruction::Push(op) => write!(f, "push {}", op),
Instruction::Pop(op) => write!(f, "pop {}", op),
Instruction::Call(op) => write!(f, "call {}", op),
Instruction::Ret => write!(f, "ret"),
Instruction::Add(dst, src) => write!(f, "add {}, {}", dst, src),
Instruction::Sub(dst, src) => write!(f, "sub {}, {}", dst, src),
Instruction::Xor(dst, src) => write!(f, "xor {}, {}", dst, src),
Instruction::And(dst, src) => write!(f, "and {}, {}", dst, src),
Instruction::Or(dst, src) => write!(f, "or {}, {}", dst, src),
Instruction::Shl(dst, src) => write!(f, "shl {}, {}", dst, src),
Instruction::Shr(dst, src) => write!(f, "shr {}, {}", dst, src),
Instruction::Lea(dst, src) => write!(f, "lea {}, {}", dst, src),
Instruction::Cmp(dst, src) => write!(f, "cmp {}, {}", dst, src),
Instruction::Test(dst, src) => write!(f, "test {}, {}", dst, src),
Instruction::Inc(op) => write!(f, "inc {}", op),
Instruction::Dec(op) => write!(f, "dec {}", op),
Instruction::Jmp(op) => write!(f, "jmp {}", op),
Instruction::Je(op) => write!(f, "je {}", op),
Instruction::Jne(op) => write!(f, "jne {}", op),
Instruction::Jg(op) => write!(f, "jg {}", op),
Instruction::Jge(op) => write!(f, "jge {}", op),
Instruction::Jl(op) => write!(f, "jl {}", op),
Instruction::Jle(op) => write!(f, "jle {}", op),
Instruction::Nop => write!(f, "nop"),
Instruction::Syscall => write!(f, "syscall"),
Instruction::Cdq => write!(f, "cdq"),
Instruction::Imul(dst, src) => write!(f, "imul {}, {}", dst, src),
Instruction::Idiv(op) => write!(f, "idiv {}", op),
Instruction::Mul(op) => write!(f, "mul {}", op),
Instruction::Div(op) => write!(f, "div {}", op),
Instruction::Neg(op) => write!(f, "neg {}", op),
Instruction::Not(op) => write!(f, "not {}", op),
Instruction::Movzx(dst, src) => write!(f, "movzx {}, {}", dst, src),
Instruction::Movsx(dst, src) => write!(f, "movsx {}, {}", dst, src),
Instruction::Shrd(dst, src, count) => {
write!(f, "shrd {}, {}, {}", dst, src, count)
}
Instruction::ShrdImm(dst, src, imm) => {
write!(f, "shrd {}, {}, {}", dst, src, imm)
}
Instruction::Adc(dst, src) => write!(f, "adc {}, {}", dst, src),
Instruction::Sbb(dst, src) => write!(f, "sbb {}, {}", dst, src),
Instruction::Sar(dst, src) => write!(f, "sar {}, {}", dst, src),
Instruction::Unknown(bytes) => write!(
f,
"db {}",
bytes
.iter()
.map(|b| format!("{:02x}", b))
.collect::<Vec<_>>()
.join(" ")
),
}
}
}

impl fmt::Display for Operand {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Operand::Register(reg) => write!(f, "{}", reg),
Operand::Immediate(imm) => write!(f, "{:#x}", imm),
Operand::Memory(mem) => write!(f, "{}", mem),
}
}
}