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