1 // 2 // Copyright © 2020 Intel Corporation 3 // 4 // SPDX-License-Identifier: Apache-2.0 5 // 6 7 use crate::arch::emulator::{EmulationError, EmulationResult, PlatformEmulator, PlatformError}; 8 use crate::arch::x86::emulator::instructions::*; 9 use crate::arch::x86::regs::*; 10 use crate::arch::x86::*; 11 use crate::arch::x86::{Exception, SegmentRegisterOps}; 12 use crate::x86_64::{SegmentRegister, SpecialRegisters, StandardRegisters}; 13 use anyhow::Context; 14 use iced_x86::*; 15 16 #[macro_use] 17 mod instructions; 18 19 /// x86 CPU modes 20 #[derive(Debug, PartialEq)] 21 pub enum CpuMode { 22 /// Real mode 23 Real, 24 25 /// Virtual 8086 mode 26 Virtual8086, 27 28 /// 16-bit protected mode 29 Protected16, 30 31 /// 32-bit protected mode 32 Protected, 33 34 /// 64-bit mode, a.k.a. long mode 35 Long, 36 } 37 38 /// CpuStateManager manages an x86 CPU state. 39 /// 40 /// Instruction emulation handlers get a mutable reference to 41 /// a `CpuStateManager` implementation, representing the current state of the 42 /// CPU they have to emulate an instruction stream against. Usually those 43 /// handlers will modify the CPU state by modifying `CpuState` and it is up to 44 /// the handler caller to commit those changes back by invoking a 45 /// `PlatformEmulator` implementation `set_state()` method. 46 /// 47 pub trait CpuStateManager: Clone { 48 /// Reads a CPU register. 49 /// 50 /// # Arguments 51 /// 52 /// * `reg` - A general purpose, control or debug register. 53 fn read_reg(&self, reg: Register) -> Result<u64, PlatformError>; 54 55 /// Write to a CPU register. 56 /// 57 /// # Arguments 58 /// 59 /// * `reg` - A general purpose, control or debug register. 60 /// * `val` - The value to load. 61 fn write_reg(&mut self, reg: Register, val: u64) -> Result<(), PlatformError>; 62 63 /// Reads a segment register. 64 /// 65 /// # Arguments 66 /// 67 /// * `reg` - A segment register. 68 fn read_segment(&self, reg: Register) -> Result<SegmentRegister, PlatformError>; 69 70 /// Write to a segment register. 71 /// 72 /// # Arguments 73 /// 74 /// * `reg` - A segment register. 75 /// * `segment_reg` - The segment register value to load. 76 fn write_segment( 77 &mut self, 78 reg: Register, 79 segment_reg: SegmentRegister, 80 ) -> Result<(), PlatformError>; 81 82 /// Get the CPU instruction pointer. 83 fn ip(&self) -> u64; 84 85 /// Set the CPU instruction pointer. 86 /// 87 /// # Arguments 88 /// 89 /// * `ip` - The CPU instruction pointer. 90 fn set_ip(&mut self, ip: u64); 91 92 /// Get the CPU Extended Feature Enable Register. 93 fn efer(&self) -> u64; 94 95 /// Set the CPU Extended Feature Enable Register. 96 /// 97 /// # Arguments 98 /// 99 /// * `efer` - The CPU EFER value. 100 fn set_efer(&mut self, efer: u64); 101 102 /// Get the CPU flags. 103 fn flags(&self) -> u64; 104 105 /// Set the CPU flags. 106 /// 107 /// # Arguments 108 /// 109 /// * `flags` - The CPU flags 110 fn set_flags(&mut self, flags: u64); 111 112 /// Get the CPU mode. 113 fn mode(&self) -> Result<CpuMode, PlatformError>; 114 115 /// Translate a logical (segmented) address into a linear (virtual) one. 116 /// 117 /// # Arguments 118 /// 119 /// * `segment` - Which segment to use for linearization 120 /// * `logical_addr` - The logical address to be translated 121 fn linearize( 122 &self, 123 segment: Register, 124 logical_addr: u64, 125 write: bool, 126 ) -> Result<u64, PlatformError> { 127 let segment_register = self.read_segment(segment)?; 128 let mode = self.mode()?; 129 130 match mode { 131 CpuMode::Long => { 132 // TODO Check that we got a canonical address. 133 Ok(logical_addr 134 .checked_add(segment_register.base) 135 .ok_or_else(|| { 136 PlatformError::InvalidAddress(anyhow!( 137 "Logical address {:#x} can not be linearized with segment {:#x?}", 138 logical_addr, 139 segment_register 140 )) 141 })?) 142 } 143 144 CpuMode::Protected | CpuMode::Real => { 145 let segment_type = segment_register.segment_type(); 146 147 // Must not write to a read-only segment. 148 if segment_type_ro(segment_type) && write { 149 return Err(PlatformError::InvalidAddress(anyhow!( 150 "Can not write to a read-only segment" 151 ))); 152 } 153 154 let logical_addr = logical_addr & 0xffff_ffffu64; 155 let mut segment_limit: u32 = if segment_register.granularity() != 0 { 156 (segment_register.limit << 12) | 0xfff 157 } else { 158 segment_register.limit 159 }; 160 161 // Expand-down segment 162 if segment_type_expand_down(segment_type) { 163 if logical_addr >= segment_limit.into() { 164 return Err(PlatformError::InvalidAddress(anyhow!( 165 "{:#x} is off limits {:#x} (expand down)", 166 logical_addr, 167 segment_limit 168 ))); 169 } 170 171 if segment_register.db() != 0 { 172 segment_limit = 0xffffffff 173 } else { 174 segment_limit = 0xffff 175 } 176 } 177 178 if logical_addr > segment_limit.into() { 179 return Err(PlatformError::InvalidAddress(anyhow!( 180 "{:#x} is off limits {:#x}", 181 logical_addr, 182 segment_limit 183 ))); 184 } 185 186 Ok(logical_addr + segment_register.base) 187 } 188 189 _ => Err(PlatformError::UnsupportedCpuMode(anyhow!("{:?}", mode))), 190 } 191 } 192 } 193 194 const REGISTER_MASK_64: u64 = 0xffff_ffff_ffff_ffffu64; 195 const REGISTER_MASK_32: u64 = 0xffff_ffffu64; 196 const REGISTER_MASK_16: u64 = 0xffffu64; 197 const REGISTER_MASK_8: u64 = 0xffu64; 198 199 macro_rules! set_reg { 200 ($reg:expr, $mask:expr, $value:expr) => { 201 $reg = ($reg & $mask) | $value 202 }; 203 } 204 205 #[derive(Clone, Default, Debug)] 206 /// A minimal, emulated CPU state. 207 /// 208 /// Hypervisors needing x86 emulation can choose to either use their own 209 /// CPU state structures and implement the CpuStateManager interface for it, 210 /// or use `EmulatorCpuState`. The latter implies creating a new state 211 /// `EmulatorCpuState` instance for each platform `cpu_state()` call, which 212 /// might be less efficient. 213 pub struct EmulatorCpuState { 214 pub regs: StandardRegisters, 215 pub sregs: SpecialRegisters, 216 } 217 218 impl CpuStateManager for EmulatorCpuState { 219 fn read_reg(&self, reg: Register) -> Result<u64, PlatformError> { 220 let mut reg_value: u64 = match reg { 221 Register::RAX | Register::EAX | Register::AX | Register::AL | Register::AH => { 222 self.regs.rax 223 } 224 Register::RBX | Register::EBX | Register::BX | Register::BL | Register::BH => { 225 self.regs.rbx 226 } 227 Register::RCX | Register::ECX | Register::CX | Register::CL | Register::CH => { 228 self.regs.rcx 229 } 230 Register::RDX | Register::EDX | Register::DX | Register::DL | Register::DH => { 231 self.regs.rdx 232 } 233 Register::RSP | Register::ESP | Register::SP => self.regs.rsp, 234 Register::RBP | Register::EBP | Register::BP => self.regs.rbp, 235 Register::RSI | Register::ESI | Register::SI | Register::SIL => self.regs.rsi, 236 Register::RDI | Register::EDI | Register::DI | Register::DIL => self.regs.rdi, 237 Register::R8 | Register::R8D | Register::R8W | Register::R8L => self.regs.r8, 238 Register::R9 | Register::R9D | Register::R9W | Register::R9L => self.regs.r9, 239 Register::R10 | Register::R10D | Register::R10W | Register::R10L => self.regs.r10, 240 Register::R11 | Register::R11D | Register::R11W | Register::R11L => self.regs.r11, 241 Register::R12 | Register::R12D | Register::R12W | Register::R12L => self.regs.r12, 242 Register::R13 | Register::R13D | Register::R13W | Register::R13L => self.regs.r13, 243 Register::R14 | Register::R14D | Register::R14W | Register::R14L => self.regs.r14, 244 Register::R15 | Register::R15D | Register::R15W | Register::R15L => self.regs.r15, 245 Register::CR0 => self.sregs.cr0, 246 Register::CR2 => self.sregs.cr2, 247 Register::CR3 => self.sregs.cr3, 248 Register::CR4 => self.sregs.cr4, 249 Register::CR8 => self.sregs.cr8, 250 251 r => { 252 return Err(PlatformError::InvalidRegister(anyhow!( 253 "read_reg invalid GPR {:?}", 254 r 255 ))) 256 } 257 }; 258 259 reg_value = if reg.is_gpr64() || reg.is_cr() { 260 reg_value 261 } else if reg.is_gpr32() { 262 reg_value & REGISTER_MASK_32 263 } else if reg.is_gpr16() { 264 reg_value & REGISTER_MASK_16 265 } else if reg.is_gpr8() { 266 if reg == Register::AH 267 || reg == Register::BH 268 || reg == Register::CH 269 || reg == Register::DH 270 { 271 (reg_value >> 8) & REGISTER_MASK_8 272 } else { 273 reg_value & REGISTER_MASK_8 274 } 275 } else { 276 return Err(PlatformError::InvalidRegister(anyhow!( 277 "read_reg invalid GPR {:?}", 278 reg 279 ))); 280 }; 281 282 debug!("Register read: {:#x} from {:?}", reg_value, reg); 283 284 Ok(reg_value) 285 } 286 287 fn write_reg(&mut self, reg: Register, val: u64) -> Result<(), PlatformError> { 288 debug!("Register write: {:#x} to {:?}", val, reg); 289 290 // SDM Vol 1 - 3.4.1.1 291 // 292 // 8-bit and 16-bit operands generate an 8-bit or 16-bit result. 293 // The upper 56 bits or 48 bits (respectively) of the destination 294 // general-purpose register are not modified by the operation. 295 let (reg_value, mask): (u64, u64) = if reg.is_gpr64() || reg.is_cr() { 296 (val, !REGISTER_MASK_64) 297 } else if reg.is_gpr32() { 298 (val & REGISTER_MASK_32, !REGISTER_MASK_64) 299 } else if reg.is_gpr16() { 300 (val & REGISTER_MASK_16, !REGISTER_MASK_16) 301 } else if reg.is_gpr8() { 302 if reg == Register::AH 303 || reg == Register::BH 304 || reg == Register::CH 305 || reg == Register::DH 306 { 307 ((val & REGISTER_MASK_8) << 8, !(REGISTER_MASK_8 << 8)) 308 } else { 309 (val & REGISTER_MASK_8, !REGISTER_MASK_8) 310 } 311 } else { 312 return Err(PlatformError::InvalidRegister(anyhow!( 313 "write_reg invalid register {:?}", 314 reg 315 ))); 316 }; 317 318 match reg { 319 Register::RAX | Register::EAX | Register::AX | Register::AL | Register::AH => { 320 set_reg!(self.regs.rax, mask, reg_value); 321 } 322 Register::RBX | Register::EBX | Register::BX | Register::BL | Register::BH => { 323 set_reg!(self.regs.rbx, mask, reg_value); 324 } 325 Register::RCX | Register::ECX | Register::CX | Register::CL | Register::CH => { 326 set_reg!(self.regs.rcx, mask, reg_value); 327 } 328 Register::RDX | Register::EDX | Register::DX | Register::DL | Register::DH => { 329 set_reg!(self.regs.rdx, mask, reg_value); 330 } 331 Register::RSP | Register::ESP | Register::SP => { 332 set_reg!(self.regs.rsp, mask, reg_value) 333 } 334 Register::RBP | Register::EBP | Register::BP => { 335 set_reg!(self.regs.rbp, mask, reg_value) 336 } 337 Register::RSI | Register::ESI | Register::SI | Register::SIL => { 338 set_reg!(self.regs.rsi, mask, reg_value) 339 } 340 Register::RDI | Register::EDI | Register::DI | Register::DIL => { 341 set_reg!(self.regs.rdi, mask, reg_value) 342 } 343 Register::R8 | Register::R8D | Register::R8W | Register::R8L => { 344 set_reg!(self.regs.r8, mask, reg_value) 345 } 346 Register::R9 | Register::R9D | Register::R9W | Register::R9L => { 347 set_reg!(self.regs.r9, mask, reg_value) 348 } 349 Register::R10 | Register::R10D | Register::R10W | Register::R10L => { 350 set_reg!(self.regs.r10, mask, reg_value) 351 } 352 Register::R11 | Register::R11D | Register::R11W | Register::R11L => { 353 set_reg!(self.regs.r11, mask, reg_value) 354 } 355 Register::R12 | Register::R12D | Register::R12W | Register::R12L => { 356 set_reg!(self.regs.r12, mask, reg_value) 357 } 358 Register::R13 | Register::R13D | Register::R13W | Register::R13L => { 359 set_reg!(self.regs.r13, mask, reg_value) 360 } 361 Register::R14 | Register::R14D | Register::R14W | Register::R14L => { 362 set_reg!(self.regs.r14, mask, reg_value) 363 } 364 Register::R15 | Register::R15D | Register::R15W | Register::R15L => { 365 set_reg!(self.regs.r15, mask, reg_value) 366 } 367 Register::CR0 => set_reg!(self.sregs.cr0, mask, reg_value), 368 Register::CR2 => set_reg!(self.sregs.cr2, mask, reg_value), 369 Register::CR3 => set_reg!(self.sregs.cr3, mask, reg_value), 370 Register::CR4 => set_reg!(self.sregs.cr4, mask, reg_value), 371 Register::CR8 => set_reg!(self.sregs.cr8, mask, reg_value), 372 _ => { 373 return Err(PlatformError::InvalidRegister(anyhow!( 374 "write_reg invalid register {:?}", 375 reg 376 ))) 377 } 378 } 379 380 Ok(()) 381 } 382 383 fn read_segment(&self, reg: Register) -> Result<SegmentRegister, PlatformError> { 384 if !reg.is_segment_register() { 385 return Err(PlatformError::InvalidRegister(anyhow!( 386 "read_segment {:?} is not a segment register", 387 reg 388 ))); 389 } 390 391 match reg { 392 Register::CS => Ok(self.sregs.cs), 393 Register::DS => Ok(self.sregs.ds), 394 Register::ES => Ok(self.sregs.es), 395 Register::FS => Ok(self.sregs.fs), 396 Register::GS => Ok(self.sregs.gs), 397 Register::SS => Ok(self.sregs.ss), 398 r => Err(PlatformError::InvalidRegister(anyhow!( 399 "read_segment invalid register {:?}", 400 r 401 ))), 402 } 403 } 404 405 fn write_segment( 406 &mut self, 407 reg: Register, 408 segment_register: SegmentRegister, 409 ) -> Result<(), PlatformError> { 410 if !reg.is_segment_register() { 411 return Err(PlatformError::InvalidRegister(anyhow!("{:?}", reg))); 412 } 413 414 match reg { 415 Register::CS => self.sregs.cs = segment_register, 416 Register::DS => self.sregs.ds = segment_register, 417 Register::ES => self.sregs.es = segment_register, 418 Register::FS => self.sregs.fs = segment_register, 419 Register::GS => self.sregs.gs = segment_register, 420 Register::SS => self.sregs.ss = segment_register, 421 r => return Err(PlatformError::InvalidRegister(anyhow!("{:?}", r))), 422 } 423 424 Ok(()) 425 } 426 427 fn ip(&self) -> u64 { 428 self.regs.rip 429 } 430 431 fn set_ip(&mut self, ip: u64) { 432 self.regs.rip = ip; 433 } 434 435 fn efer(&self) -> u64 { 436 self.sregs.efer 437 } 438 439 fn set_efer(&mut self, efer: u64) { 440 self.sregs.efer = efer 441 } 442 443 fn flags(&self) -> u64 { 444 self.regs.rflags 445 } 446 447 fn set_flags(&mut self, flags: u64) { 448 self.regs.rflags = flags; 449 } 450 451 fn mode(&self) -> Result<CpuMode, PlatformError> { 452 let efer = self.efer(); 453 let cr0 = self.read_reg(Register::CR0)?; 454 let mut mode = CpuMode::Real; 455 456 if (cr0 & CR0_PE) == CR0_PE { 457 mode = CpuMode::Protected; 458 } 459 460 if (efer & EFER_LMA) == EFER_LMA { 461 if mode != CpuMode::Protected { 462 return Err(PlatformError::InvalidState(anyhow!( 463 "Protection must be enabled in long mode" 464 ))); 465 } 466 467 mode = CpuMode::Long; 468 } 469 470 Ok(mode) 471 } 472 } 473 474 pub struct Emulator<'a, T: CpuStateManager> { 475 platform: &'a mut dyn PlatformEmulator<CpuState = T>, 476 } 477 478 // Reduce repetition, see its invocation in get_handler(). 479 macro_rules! gen_handler_match { 480 ($value: ident, $( ($module:ident, $code:ident) ),* ) => { 481 match $value { 482 $( 483 Code::$code => Some(Box::new($module::$code)), 484 )* 485 _ => None, 486 } 487 }; 488 } 489 490 impl<'a, T: CpuStateManager> Emulator<'a, T> { 491 pub fn new(platform: &mut dyn PlatformEmulator<CpuState = T>) -> Emulator<T> { 492 Emulator { platform } 493 } 494 495 fn get_handler(code: Code) -> Option<Box<dyn InstructionHandler<T>>> { 496 let handler: Option<Box<dyn InstructionHandler<T>>> = gen_handler_match!( 497 code, 498 // CMP 499 (cmp, Cmp_rm32_r32), 500 (cmp, Cmp_rm8_r8), 501 (cmp, Cmp_rm32_imm8), 502 (cmp, Cmp_rm64_r64), 503 // MOV 504 (mov, Mov_r8_rm8), 505 (mov, Mov_r8_imm8), 506 (mov, Mov_r16_imm16), 507 (mov, Mov_r16_rm16), 508 (mov, Mov_r32_imm32), 509 (mov, Mov_r32_rm32), 510 (mov, Mov_r64_imm64), 511 (mov, Mov_r64_rm64), 512 (mov, Mov_rm8_imm8), 513 (mov, Mov_rm8_r8), 514 (mov, Mov_rm16_imm16), 515 (mov, Mov_rm16_r16), 516 (mov, Mov_rm32_imm32), 517 (mov, Mov_rm32_r32), 518 (mov, Mov_rm64_imm32), 519 (mov, Mov_rm64_r64), 520 // MOVZX 521 (mov, Movzx_r16_rm8), 522 (mov, Movzx_r32_rm8), 523 (mov, Movzx_r64_rm8), 524 (mov, Movzx_r32_rm16), 525 (mov, Movzx_r64_rm16), 526 // MOVS 527 (movs, Movsd_m32_m32), 528 // OR 529 (or, Or_rm8_r8) 530 ); 531 532 handler 533 } 534 535 fn emulate_insn_stream( 536 &mut self, 537 cpu_id: usize, 538 insn_stream: &[u8], 539 num_insn: Option<usize>, 540 ) -> EmulationResult<T, Exception> { 541 let mut state = self 542 .platform 543 .cpu_state(cpu_id) 544 .map_err(EmulationError::PlatformEmulationError)?; 545 let mut decoder = Decoder::new(64, insn_stream, DecoderOptions::NONE); 546 let mut insn = Instruction::default(); 547 let mut num_insn_emulated: usize = 0; 548 let mut fetched_insn_stream: [u8; 16] = [0; 16]; 549 let mut last_decoded_ip: u64 = state.ip(); 550 let mut stop_emulation: bool = false; 551 552 decoder.set_ip(state.ip()); 553 554 while decoder.can_decode() && !stop_emulation { 555 decoder.decode_out(&mut insn); 556 557 if decoder.last_error() == DecoderError::NoMoreBytes { 558 // The decoder is missing some bytes to decode the current 559 // instruction, for example because the instruction stream 560 // crosses a page boundary. 561 // We fetch 16 more bytes from the instruction segment, 562 // decode and emulate the failing instruction and terminate 563 // the emulation loop. 564 debug!( 565 "Fetching {} bytes from {:#x}", 566 fetched_insn_stream.len(), 567 last_decoded_ip 568 ); 569 570 // fetched_insn_stream is 16 bytes long, enough to contain 571 // any complete x86 instruction. 572 self.platform 573 .fetch(last_decoded_ip, &mut fetched_insn_stream) 574 .map_err(EmulationError::PlatformEmulationError)?; 575 576 debug!("Fetched {:x?}", fetched_insn_stream); 577 578 // Once we have the new stream, we must create a new decoder 579 // and emulate one last instruction from the last decoded IP. 580 decoder = Decoder::new(64, &fetched_insn_stream, DecoderOptions::NONE); 581 decoder.decode_out(&mut insn); 582 if decoder.last_error() != DecoderError::None { 583 return Err(EmulationError::InstructionFetchingError(anyhow!( 584 "{:#x?}", 585 insn_format!(insn) 586 ))); 587 } 588 589 stop_emulation = true; 590 } 591 592 // Emulate the decoded instruction 593 Emulator::get_handler(insn.code()) 594 .ok_or_else(|| { 595 EmulationError::UnsupportedInstruction(anyhow!( 596 "{:#x?} {:?} {:?}", 597 insn_format!(insn), 598 insn.mnemonic(), 599 insn.code() 600 )) 601 })? 602 .emulate(&insn, &mut state, self.platform) 603 .context(anyhow!("Failed to emulate {:#x?}", insn_format!(insn)))?; 604 605 last_decoded_ip = decoder.ip(); 606 num_insn_emulated += 1; 607 608 if let Some(num_insn) = num_insn { 609 if num_insn_emulated >= num_insn { 610 // Exit the decoding loop, do not decode the next instruction. 611 stop_emulation = true; 612 } 613 } 614 } 615 616 state.set_ip(decoder.ip()); 617 Ok(state) 618 } 619 620 /// Emulate all instructions from the instructions stream. 621 pub fn emulate(&mut self, cpu_id: usize, insn_stream: &[u8]) -> EmulationResult<T, Exception> { 622 self.emulate_insn_stream(cpu_id, insn_stream, None) 623 } 624 625 /// Only emulate the first instruction from the stream. 626 /// 627 /// This is useful for cases where we get readahead instruction stream 628 /// but implicitly must only emulate the first instruction, and then return 629 /// to the guest. 630 pub fn emulate_first_insn( 631 &mut self, 632 cpu_id: usize, 633 insn_stream: &[u8], 634 ) -> EmulationResult<T, Exception> { 635 self.emulate_insn_stream(cpu_id, insn_stream, Some(1)) 636 } 637 } 638 639 #[cfg(test)] 640 mod mock_vmm { 641 #![allow(unused_mut)] 642 643 use super::*; 644 use crate::arch::emulator::{EmulationError, PlatformEmulator}; 645 use crate::arch::x86::emulator::{Emulator, EmulatorCpuState as CpuState}; 646 use crate::arch::x86::gdt::{gdt_entry, segment_from_gdt}; 647 use crate::arch::x86::Exception; 648 use std::sync::{Arc, Mutex}; 649 650 #[derive(Debug, Clone)] 651 pub struct MockVmm { 652 memory: Vec<u8>, 653 state: Arc<Mutex<CpuState>>, 654 } 655 656 unsafe impl Sync for MockVmm {} 657 658 pub type MockResult = Result<(), EmulationError<Exception>>; 659 660 impl MockVmm { 661 pub fn new(ip: u64, regs: Vec<(Register, u64)>, memory: Option<(u64, &[u8])>) -> MockVmm { 662 let _ = env_logger::try_init(); 663 let cs_reg = segment_from_gdt(gdt_entry(0xc09b, 0, 0xffffffff), 1); 664 let ds_reg = segment_from_gdt(gdt_entry(0xc093, 0, 0xffffffff), 2); 665 let es_reg = segment_from_gdt(gdt_entry(0xc093, 0, 0xffffffff), 3); 666 let mut initial_state = CpuState::default(); 667 initial_state.set_ip(ip); 668 initial_state.write_segment(Register::CS, cs_reg).unwrap(); 669 initial_state.write_segment(Register::DS, ds_reg).unwrap(); 670 initial_state.write_segment(Register::ES, es_reg).unwrap(); 671 for (reg, value) in regs { 672 initial_state.write_reg(reg, value).unwrap(); 673 } 674 675 let mut vmm = MockVmm { 676 memory: vec![0; 8192], 677 state: Arc::new(Mutex::new(initial_state)), 678 }; 679 680 if let Some(mem) = memory { 681 vmm.write_memory(mem.0, mem.1).unwrap(); 682 } 683 684 vmm 685 } 686 687 pub fn emulate_insn( 688 &mut self, 689 cpu_id: usize, 690 insn: &[u8], 691 num_insn: Option<usize>, 692 ) -> MockResult { 693 let ip = self.cpu_state(cpu_id).unwrap().ip(); 694 let mut emulator = Emulator::new(self); 695 696 let new_state = emulator.emulate_insn_stream(cpu_id, insn, num_insn)?; 697 if num_insn.is_none() { 698 assert_eq!(ip + insn.len() as u64, new_state.ip()); 699 } 700 701 self.set_cpu_state(cpu_id, new_state).unwrap(); 702 703 Ok(()) 704 } 705 706 pub fn emulate_first_insn(&mut self, cpu_id: usize, insn: &[u8]) -> MockResult { 707 self.emulate_insn(cpu_id, insn, Some(1)) 708 } 709 } 710 711 impl PlatformEmulator for MockVmm { 712 type CpuState = CpuState; 713 714 fn read_memory(&self, gva: u64, data: &mut [u8]) -> Result<(), PlatformError> { 715 debug!( 716 "Memory read {} bytes from [{:#x} -> {:#x}]", 717 data.len(), 718 gva, 719 gva + data.len() as u64 - 1 720 ); 721 data.copy_from_slice(&self.memory[gva as usize..gva as usize + data.len()]); 722 Ok(()) 723 } 724 725 fn write_memory(&mut self, gva: u64, data: &[u8]) -> Result<(), PlatformError> { 726 debug!( 727 "Memory write {} bytes at [{:#x} -> {:#x}]", 728 data.len(), 729 gva, 730 gva + data.len() as u64 - 1 731 ); 732 self.memory[gva as usize..gva as usize + data.len()].copy_from_slice(data); 733 734 Ok(()) 735 } 736 737 fn cpu_state(&self, _cpu_id: usize) -> Result<CpuState, PlatformError> { 738 Ok(self.state.lock().unwrap().clone()) 739 } 740 741 fn set_cpu_state( 742 &self, 743 _cpu_id: usize, 744 state: Self::CpuState, 745 ) -> Result<(), PlatformError> { 746 *self.state.lock().unwrap() = state; 747 Ok(()) 748 } 749 750 fn gva_to_gpa(&self, gva: u64) -> Result<u64, PlatformError> { 751 Ok(gva) 752 } 753 754 fn fetch(&self, ip: u64, instruction_bytes: &mut [u8]) -> Result<(), PlatformError> { 755 let rip = self 756 .state 757 .lock() 758 .unwrap() 759 .linearize(Register::CS, ip, false)?; 760 self.read_memory(rip, instruction_bytes) 761 } 762 } 763 } 764 765 #[cfg(test)] 766 mod tests { 767 #![allow(unused_mut)] 768 use super::*; 769 use crate::arch::x86::emulator::mock_vmm::*; 770 771 #[test] 772 // Emulate truncated instruction stream, which should cause a fetch. 773 // 774 // mov rax, 0x1000 775 // Test with a first instruction truncated. 776 fn test_fetch_first_instruction() { 777 let ip: u64 = 0x1000; 778 let cpu_id = 0; 779 let memory = [ 780 // Code at IP 781 0x48, 0xc7, 0xc0, 0x00, 0x10, 0x00, 0x00, // mov rax, 0x1000 782 0x48, 0x8b, 0x58, 0x10, // mov rbx, qword ptr [rax+10h] 783 // Padding 784 0x00, 0x00, 0x00, 0x00, 0x00, // Padding is all zeroes 785 // Data at IP + 0x10 (0x1234567812345678 in LE) 786 0x78, 0x56, 0x34, 0x12, 0x78, 0x56, 0x34, 0x12, 787 ]; 788 let insn = [ 789 // First instruction is truncated 790 0x48, 0xc7, 0xc0, 0x00, // mov rax, 0x1000 -- Missing bytes: 0x00, 0x10, 0x00, 0x00, 791 ]; 792 793 let mut vmm = MockVmm::new(ip, vec![], Some((ip, &memory))); 794 assert!(vmm.emulate_insn(cpu_id, &insn, Some(2)).is_ok()); 795 796 let rax: u64 = vmm 797 .cpu_state(cpu_id) 798 .unwrap() 799 .read_reg(Register::RAX) 800 .unwrap(); 801 assert_eq!(rax, ip); 802 } 803 804 #[test] 805 // Emulate truncated instruction stream, which should cause a fetch. 806 // 807 // mov rax, 0x1000 808 // mov rbx, qword ptr [rax+10h] 809 // Test with a 2nd instruction truncated. 810 fn test_fetch_second_instruction() { 811 let target_rax: u64 = 0x1234567812345678; 812 let ip: u64 = 0x1000; 813 let cpu_id = 0; 814 let memory = [ 815 // Code at IP 816 0x48, 0xc7, 0xc0, 0x00, 0x10, 0x00, 0x00, // mov rax, 0x1000 817 0x48, 0x8b, 0x58, 0x10, // mov rbx, qword ptr [rax+10h] 818 // Padding 819 0x00, 0x00, 0x00, 0x00, 0x00, // Padding is all zeroes 820 // Data at IP + 0x10 (0x1234567812345678 in LE) 821 0x78, 0x56, 0x34, 0x12, 0x78, 0x56, 0x34, 0x12, 822 ]; 823 let insn = [ 824 0x48, 0xc7, 0xc0, 0x00, 0x10, 0x00, 0x00, // mov rax, 0x1000 825 0x48, 0x8b, // Truncated mov rbx, qword ptr [rax+10h] -- missing [0x58, 0x10] 826 ]; 827 828 let mut vmm = MockVmm::new(ip, vec![], Some((ip, &memory))); 829 assert!(vmm.emulate_insn(cpu_id, &insn, Some(2)).is_ok()); 830 831 let rbx: u64 = vmm 832 .cpu_state(cpu_id) 833 .unwrap() 834 .read_reg(Register::RBX) 835 .unwrap(); 836 assert_eq!(rbx, target_rax); 837 } 838 839 #[test] 840 // Emulate truncated instruction stream, which should cause a fetch. 841 // 842 // mov rax, 0x1000 843 // Test with a first instruction truncated and a bad fetched instruction. 844 // Verify that the instruction emulation returns an error. 845 fn test_fetch_bad_insn() { 846 let ip: u64 = 0x1000; 847 let cpu_id = 0; 848 let memory = [ 849 // Code at IP 850 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 851 0xff, 0xff, 852 ]; 853 let insn = [ 854 // First instruction is truncated 855 0x48, 0xc7, 0xc0, 0x00, // mov rax, 0x1000 -- Missing bytes: 0x00, 0x10, 0x00, 0x00, 856 ]; 857 858 let mut vmm = MockVmm::new(ip, vec![], Some((ip, &memory))); 859 assert!(vmm.emulate_first_insn(cpu_id, &insn).is_err()); 860 } 861 } 862