From dfbe426ffccdb846adcc225509cb5da1523c56cb Mon Sep 17 00:00:00 2001 From: sha0coder Date: Wed, 12 Jan 2022 10:41:37 +0100 Subject: [PATCH] huge commit, preparing the base for 64bits support --- Cargo.lock | 3 +- Cargo.toml | 3 +- src/config.rs | 12 +- src/emu.rs | 2609 ++++++++++++++----------- src/emu/breakpoint.rs | 20 +- src/emu/console.rs | 11 +- src/emu/constants.rs | 96 +- src/emu/context32.rs | 102 +- src/emu/exception.rs | 4 +- src/emu/flags.rs | 404 +++- src/emu/fpu.rs | 14 +- src/emu/maps.rs | 139 +- src/emu/maps/{mem32.rs => mem.rs.bkp} | 0 src/emu/maps/mem64.rs | 217 ++ src/emu/{regs32.rs => regs32.rs.old} | 0 src/emu/regs64.rs | 878 +++++++++ src/emu/structures.rs | 26 +- src/emu/syscall32.rs | 224 +-- src/emu/winapi/advapi32.rs | 16 +- src/emu/winapi/helper.rs | 20 +- src/emu/winapi/kernel32.rs | 748 +++---- src/emu/winapi/ntdll.rs | 76 +- src/emu/winapi/user32.rs | 12 +- src/emu/winapi/wininet.rs | 184 +- src/emu/winapi/ws2_32.rs | 168 +- src/main.rs | 16 +- 26 files changed, 3794 insertions(+), 2208 deletions(-) rename src/emu/maps/{mem32.rs => mem.rs.bkp} (100%) create mode 100644 src/emu/maps/mem64.rs rename src/emu/{regs32.rs => regs32.rs.old} (100%) create mode 100644 src/emu/regs64.rs diff --git a/Cargo.lock b/Cargo.lock index ec55387..c614342 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -392,13 +392,14 @@ dependencies = [ [[package]] name = "scemu" -version = "0.2.6" +version = "0.3.0" dependencies = [ "attohttpc", "clap", "iced-x86", "lazy_static", "md5", + "rand", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 977475b..73c112a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "scemu" -version = "0.2.6" +version = "0.3.0" authors = ["sha0coder "] edition = "2018" @@ -12,3 +12,4 @@ clap = "2.33.3" md5 = "0.7.0" lazy_static = "1.4.0" attohttpc = "0.18.0" +rand = "0.8.4" diff --git a/src/config.rs b/src/config.rs index d7e269b..31060f2 100644 --- a/src/config.rs +++ b/src/config.rs @@ -10,16 +10,16 @@ pub struct Config { pub loops: bool, // loop mode count the iterations for every instruction, its slow. pub nocolors: bool, // to redirecting the output to a file is better to remove colors. pub trace_string: bool, - pub string_addr: u32, + pub string_addr: u64, pub inspect: bool, pub inspect_seq: String, pub endpoint: bool, pub maps_folder: String, pub console2: bool, - pub console_addr: u32, - pub entry_point: u32, - pub code_base_addr: u32, - pub is_64: bool, // 64bits mode + pub console_addr: u64, + pub entry_point: u64, + pub code_base_addr: u64, + pub is_64bits: bool, // 64bits mode } impl Config { @@ -44,7 +44,7 @@ impl Config { console_addr: 0, entry_point: 0x3c0000, code_base_addr: 0x3c0000, - is_64: false, + is_64bits: false, } } } diff --git a/src/emu.rs b/src/emu.rs index 4375c81..e9e466c 100644 --- a/src/emu.rs +++ b/src/emu.rs @@ -3,12 +3,13 @@ #![allow(dead_code)] #![allow(unused_variables)] #![allow(unused_must_use)] +#![allow(clippy::assertions_on_constants)] mod flags; mod eflags; pub mod maps; -pub mod regs32; +pub mod regs64; mod console; pub mod colors; pub mod constants; @@ -25,7 +26,7 @@ use flags::Flags; use eflags::Eflags; use fpu::FPU; use maps::Maps; -use regs32::Regs32; +use regs64::Regs64; use console::Console; use colors::Colors; use breakpoint::Breakpoint; @@ -35,8 +36,44 @@ use crate::config::Config; use iced_x86::{Decoder, DecoderOptions, Formatter, Instruction, IntelFormatter, Mnemonic, OpKind, InstructionInfoFactory, Register, MemorySize}; + +macro_rules! rotate_left { + ($val:expr, $rot:expr, $bits:expr) => { + ($val << $rot) | ($val >> ($bits-$rot)) + }; +} + +macro_rules! rotate_right { + ($val:expr, $rot:expr, $bits:expr) => { + ($val >> $rot) | ($val << ($bits-$rot)) + }; +} + +macro_rules! get_bit { + ($val:expr, $count:expr) => { + ($val & (1 << $count )) >> $count + }; +} + +macro_rules! set_bit { + ($val:expr, $count:expr, $bit:expr) => { + if $bit == 1 { + $val |= 1 << $count; + } else { + $val &= !(1 << $count); + } + }; +} + +macro_rules! to32 { + ($val:expr) => { + ($val & 0xffffffff) as u32 + }; +} + + pub struct Emu { - regs: Regs32, + regs: Regs64, flags: Flags, eflags: Eflags, fpu: FPU, @@ -44,20 +81,22 @@ pub struct Emu { exp: u64, break_on_alert: bool, bp: Breakpoint, - seh: u32, - veh: u32, + seh: u64, + veh: u64, eh_ctx: u32, cfg: Config, colors: Colors, pos: u64, force_break: bool, tls: Vec, + step: bool, + out: String, } impl Emu { pub fn new() -> Emu { Emu{ - regs: Regs32::new(), + regs: Regs64::new(), flags: Flags::new(), eflags: Eflags::new(), fpu: FPU::new(), @@ -73,41 +112,39 @@ impl Emu { pos: 0, force_break: false, tls: Vec::new(), + step: false, + out: String::new(), } } pub fn init_stack(&mut self) { let stack = self.maps.get_mem("stack"); - stack.set_base(0x22d000); - stack.set_size(0x020000); - self.regs.esp = 0x22e000; - self.regs.ebp = 0x22f000; - - assert!(self.regs.esp < self.regs.ebp); - assert!(self.regs.esp > stack.get_base()); - assert!(self.regs.esp < stack.get_bottom()); - assert!(self.regs.ebp > stack.get_base()); - assert!(self.regs.ebp < stack.get_bottom()); - assert!(stack.inside(self.regs.esp)); - assert!(stack.inside(self.regs.ebp)); + + if self.cfg.is_64bits { + } else { + stack.set_base(0x22d000); + stack.set_size(0x020000); + self.regs.set_esp(0x22e000); + self.regs.set_ebp(0x22f000); + + assert!(self.regs.get_esp() < self.regs.get_ebp()); + assert!(self.regs.get_esp() > stack.get_base()); + assert!(self.regs.get_esp() < stack.get_bottom()); + assert!(self.regs.get_ebp() > stack.get_base()); + assert!(self.regs.get_ebp() < stack.get_bottom()); + assert!(stack.inside(self.regs.get_esp())); + assert!(stack.inside(self.regs.get_ebp())); + } + } pub fn init(&mut self) { println!("initializing regs"); - self.regs.clear(); - //self.regs.esp = 0x22f000; - //self.regs.ebp = 0x00100f00; - self.regs.eip = self.cfg.entry_point; - //TODO: randomize initial register for avoid targeted anti-amulation - self.regs.eax = 0; - self.regs.ebx = 0x0022ee88; - self.regs.ecx = 0x0022ee9c; - self.regs.edx = 0x36b32038; - self.regs.esi = 0x0022f388; - self.regs.edi = 0; + self.regs.clear::<64>(); + self.regs.rand(); + self.regs.set_eip(self.cfg.entry_point); println!("loading memory maps"); - self.maps.create_map("10000"); self.maps.create_map("20000"); self.maps.create_map("stack"); @@ -418,33 +455,32 @@ impl Emu { // some tests - - assert!(self.get_bit(0xffffff00, 0) == 0); - assert!(self.get_bit(0xffffffff, 5) == 1); - assert!(self.get_bit(0xffffff00, 5) == 0); - assert!(self.get_bit(0xffffff00, 7) == 0); - assert!(self.get_bit(0xffffff00, 8) == 1); - - let mut a = 0xffffff00; - self.set_bit(&mut a, 0, 1); - self.set_bit(&mut a, 1, 1); - self.set_bit(&mut a, 2, 1); - self.set_bit(&mut a, 3, 1); - self.set_bit(&mut a, 4, 1); - self.set_bit(&mut a, 5, 1); - self.set_bit(&mut a, 6, 1); - self.set_bit(&mut a, 7, 1); + assert!(get_bit!(0xffffff00u32, 0) == 0); + assert!(get_bit!(0xffffffffu32, 5) == 1); + assert!(get_bit!(0xffffff00u32, 5) == 0); + assert!(get_bit!(0xffffff00u32, 7) == 0); + assert!(get_bit!(0xffffff00u32, 8) == 1); + + let mut a:u32 = 0xffffff00; + set_bit!(a, 0, 1); + set_bit!(a, 1, 1); + set_bit!(a, 2, 1); + set_bit!(a, 3, 1); + set_bit!(a, 4, 1); + set_bit!(a, 5, 1); + set_bit!(a, 6, 1); + set_bit!(a, 7, 1); assert!(a == 0xffffffff); - self.set_bit(&mut a, 0, 0); - self.set_bit(&mut a, 1, 0); - self.set_bit(&mut a, 2, 0); - self.set_bit(&mut a, 3, 0); - self.set_bit(&mut a, 4, 0); - self.set_bit(&mut a, 5, 0); - self.set_bit(&mut a, 6, 0); - self.set_bit(&mut a, 7, 0); + set_bit!(a, 0, 0); + set_bit!(a, 1, 0); + set_bit!(a, 2, 0); + set_bit!(a, 3, 0); + set_bit!(a, 4, 0); + set_bit!(a, 5, 0); + set_bit!(a, 6, 0); + set_bit!(a, 7, 0); assert!(a == 0xffffff00); @@ -459,7 +495,6 @@ impl Emu { eprintln!("It doesn't pass the memory tests!!"); std::process::exit(1); } - } pub fn set_config(&mut self, cfg:Config) { @@ -479,45 +514,82 @@ impl Emu { } } - pub fn stack_push(&mut self, value:u32) { - self.regs.esp -= 4; + pub fn stack_push32(&mut self, value:u32) { + self.regs.set_esp(self.regs.get_esp() - 4); + let stack = self.maps.get_mem("stack"); + if stack.inside(self.regs.get_esp()) { + stack.write_dword(self.regs.get_esp(), value); + } else { + let mem = match self.maps.get_mem_by_addr(self.regs.get_esp()) { + Some(m) => m, + None => { + panic!("pushing stack outside maps esp: 0x{:x}", self.regs.get_esp()); + } + }; + mem.write_dword(self.regs.get_esp().into(), value); + } + } + + pub fn stack_push64(&mut self, value:u64) { + self.regs.rsp -= 8; let stack = self.maps.get_mem("stack"); - if stack.inside(self.regs.esp) { - stack.write_dword(self.regs.esp, value); + if stack.inside(self.regs.rsp) { + stack.write_qword(self.regs.rsp, value); } else { - let mem = match self.maps.get_mem_by_addr(self.regs.esp) { + let mem = match self.maps.get_mem_by_addr(self.regs.rsp) { Some(m) => m, None => { - panic!("pushing stack outside maps esp: 0x{:x}", self.regs.esp); + panic!("pushing stack outside maps esp: 0x{:x}", self.regs.get_esp()); } }; - mem.write_dword(self.regs.esp, value); + mem.write_qword(self.regs.rsp, value); + } + } + + pub fn stack_pop32(&mut self, pop_instruction:bool) -> u32 { + let stack = self.maps.get_mem("stack"); + if stack.inside(self.regs.get_esp()) { + let value = stack.read_dword(self.regs.get_esp()); + if self.cfg.verbose >= 1 && pop_instruction && self.maps.get_mem("code").inside(value.into()) { + println!("/!\\ poping a code address 0x{:x}", value); + } + self.regs.set_esp(self.regs.get_esp() + 4); + return value; } + + let mem = match self.maps.get_mem_by_addr(self.regs.get_esp()) { + Some(m) => m, + None => panic!("poping stack outside map esp: 0x{:x}", self.regs.get_esp() as u32), + }; + + let value = mem.read_dword(self.regs.get_esp()); + self.regs.set_esp(self.regs.get_esp() + 4); + value } - pub fn stack_pop(&mut self, pop_instruction:bool) -> u32 { + pub fn stack_pop64(&mut self, pop_instruction:bool) -> u64 { let stack = self.maps.get_mem("stack"); - if stack.inside(self.regs.esp) { - let value = stack.read_dword(self.regs.esp); - if self.cfg.verbose >= 1 && pop_instruction && self.maps.get_mem("code").inside(value) { + if stack.inside(self.regs.rsp) { + let value = stack.read_qword(self.regs.rsp); + if self.cfg.verbose >= 1 && pop_instruction && self.maps.get_mem("code").inside(value.into()) { println!("/!\\ poping a code address 0x{:x}", value); } - self.regs.esp += 4; + self.regs.rsp += 4; return value; } - let mem = match self.maps.get_mem_by_addr(self.regs.esp) { + let mem = match self.maps.get_mem_by_addr(self.regs.rsp) { Some(m) => m, - None => panic!("poping stack outside map esp: 0x{:x}", self.regs.esp), + None => panic!("poping stack outside map esp: 0x{:x}", self.regs.rsp), }; - let value = mem.read_dword(self.regs.esp); - self.regs.esp += 4; + let value = mem.read_qword(self.regs.rsp); + self.regs.rsp += 4; value } // this is not used on the emulation - pub fn memory_operand_to_address(&mut self, operand:&str) -> u32 { + pub fn memory_operand_to_address(&mut self, operand:&str) -> u64 { let spl:Vec<&str> = operand.split('[').collect::>()[1].split(']').collect::>()[0].split(' ').collect(); if operand.contains("fs:[") || operand.contains("gs:[") { @@ -571,7 +643,7 @@ impl Emu { let reg1_val = self.regs.get_by_name(spl[0]); let reg2_val = self.regs.get_by_name(spl2[0]); - let num = u32::from_str_radix(spl2[1].trim_start_matches("0x"),16).expect("bad num conversion"); + let num = u64::from_str_radix(spl2[1].trim_start_matches("0x"),16).expect("bad num conversion"); if sign != "+" && sign != "-" { panic!("weird sign2 {}", sign); @@ -591,11 +663,11 @@ impl Emu { let reg = spl[0]; let sign = spl[1]; //println!("disp --> {} operand:{}", spl[2], operand); - let disp:u32; - if self.is_reg(spl[2]) { + let disp:u64; + if self.regs.is_reg(spl[2]) { disp = self.regs.get_by_name(spl[2]); } else { - disp = u32::from_str_radix(spl[2].trim_start_matches("0x"),16).expect("bad disp"); + disp = u64::from_str_radix(spl[2].trim_start_matches("0x"),16).expect("bad disp"); } @@ -605,7 +677,7 @@ impl Emu { if sign == "+" { let r:u64 = self.regs.get_by_name(reg) as u64 + disp as u64; - return (r & 0xffffffff) as u32; + return r & 0xffffffff; } else { return self.regs.get_by_name(reg) - disp; } @@ -616,7 +688,7 @@ impl Emu { let reg = spl[0]; if reg.contains("0x") { - let addr:u32 = usize::from_str_radix(reg.trim_start_matches("0x"),16).expect("bad disp2") as u32; + let addr:u64 = u64::from_str_radix(reg.trim_start_matches("0x"),16).expect("bad disp2"); return addr; // weird but could be a hardcoded address [0x11223344] } @@ -630,7 +702,7 @@ impl Emu { } // this is not used on the emulation - pub fn memory_read(&mut self, operand:&str) -> Option { + pub fn memory_read(&mut self, operand:&str) -> Option { if operand.contains("fs:[0]") { if self.cfg.verbose >= 1 { println!("{} Reading SEH fs:[0] 0x{:x}", self.pos, self.seh); @@ -638,7 +710,7 @@ impl Emu { return Some(self.seh); } - let addr:u32 = self.memory_operand_to_address(operand); + let addr:u64 = self.memory_operand_to_address(operand); if operand.contains("fs:[") || operand.contains("gs:[") { return Some(addr); @@ -651,9 +723,9 @@ impl Emu { let stack = self.maps.get_mem("stack"); // could be normal using part of code as stack - if !stack.inside(self.regs.esp) { + if !stack.inside(self.regs.get_esp()) { //hack: redirect stack - self.regs.esp = stack.get_base() + 0x1ff; + self.regs.set_esp(stack.get_base() + 0x1ff); panic!("/!\\ fixing stack.") } @@ -668,7 +740,7 @@ impl Emu { }; println!("mem trace read -> '{}' 0x{:x}: 0x{:x} map:'{}'", operand, addr, v, name); } - return Some(v); + return Some(v.into()); }, None => return None, } @@ -683,7 +755,7 @@ impl Emu { }; println!("mem trace read -> '{}' 0x{:x}: 0x{:x} map:'{}'", operand, addr, v, name); } - return Some((v as u32) & 0xffff); + return Some((v as u64) & 0xffff); }, None => return None, } @@ -698,7 +770,7 @@ impl Emu { }; println!("mem trace read -> '{}' 0x{:x}: 0x{:x} map:'{}'", operand, addr, v, name); } - return Some((v as u32) & 0xff); + return Some((v as u64) & 0xff); }, None => return None, } @@ -709,14 +781,14 @@ impl Emu { } // this is not used on the emulation - pub fn memory_write(&mut self, operand:&str, value:u32) -> bool { + pub fn memory_write(&mut self, operand:&str, value:u64) -> bool { if operand.contains("fs:[0]") { println!("Setting SEH fs:[0] 0x{:x}", value); self.seh = value; return true; } - let addr:u32 = self.memory_operand_to_address(operand); + let addr:u64 = self.memory_operand_to_address(operand); /*if !self.maps.is_mapped(addr) { panic!("writting in non mapped memory"); @@ -740,17 +812,21 @@ impl Emu { let bits = self.get_size(operand); let ret = match bits { - 32 => self.maps.write_dword(addr, value), + 64 => self.maps.write_qword(addr, value), + 32 => self.maps.write_dword(addr, (value & 0xffffffff) as u32), 16 => self.maps.write_word(addr, (value & 0x0000ffff) as u16), 8 => self.maps.write_byte(addr, (value & 0x000000ff) as u8), - _ => panic!("weird size: {}", operand) + _ => unreachable!("weird size: {}", operand) }; ret } + pub fn set_rip(&mut self, addr:u64, is_branch:bool) { + todo!("implement set_rip for 64bits"); + } - pub fn set_eip(&mut self, addr:u32, is_branch:bool) { + pub fn set_eip(&mut self, addr:u64, is_branch:bool) { let name = match self.maps.get_addr_name(addr) { Some(n) => n, @@ -762,57 +838,31 @@ impl Emu { }; if name == "code" || addr < 0x70000000 { - self.regs.eip = addr; + self.regs.set_eip(addr); } else { if self.cfg.verbose >= 1 { println!("/!\\ changing EIP to {} ", name); } - let retaddr = self.stack_pop(false); - - winapi::gateway(addr, name, self); + let retaddr = self.stack_pop32(false); - //self.regs.eip += 2; - self.regs.eip = retaddr; - } - - - //TODO: lanzar memory scan code.scan() y stack.scan() - // escanear en cambios de eip pero no en bucles, evitar escanear en bucles! - } + winapi::gateway(to32!(addr), name, self); - //this is not used on the emulation - pub fn is_reg(&self, operand:&str) -> bool { - match operand { - "eax"|"ebx"|"ecx"|"edx"|"esi"|"edi"|"esp"|"ebp"|"eip"|"ax"|"bx"|"cx"|"dx"|"si"|"di"|"al"|"ah"|"bl"|"bh"|"cl"|"ch"|"dl"|"dh" => true, - &_ => false, + self.regs.set_eip(retaddr.into()); } } - /* - pub fn get_inmediate(&self, operand:&str) -> u32 { - - if operand.contains("0x") { - return u32::from_str_radix(operand.get(2..).unwrap(), 16).unwrap(); - } else if operand.contains("-") { - let num = u32::from_str_radix(operand.get(1..).unwrap(), 16).unwrap(); - return 0xffffffff - num + 1; - } else { - return u32::from_str_radix(operand, 16).unwrap(); - } - }*/ - // this is not used on the emulation pub fn get_size(&self, operand:&str) -> u8 { if operand.contains("byte ptr") { return 8; - } else if operand.contains("dword ptr") { return 32; - } else if operand.contains("word ptr") { return 16; - } + } else if operand.contains("qword ptr") { + return 64; + } let c:Vec = operand.chars().collect(); @@ -837,79 +887,127 @@ impl Emu { panic!("weird size: {}", operand); } + + fn mul64(&mut self, value0:u64) { + let value1:u64 = self.regs.rax; + let value2:u64 = value0; + let res:u128 = value1 as u128 * value2 as u128; + self.regs.rdx = ((res & 0xffffffffffffffff0000000000000000) >> 64) as u64; + self.regs.rax = (res & 0xffffffffffffffff) as u64; + self.flags.f_pf = (res & 0xff) % 2 == 0; + self.flags.f_of = self.regs.rdx != 0; + self.flags.f_cf = self.regs.rdx != 0; + } - fn mul32(&mut self, value0:u32) { - let value1:u32 = self.regs.eax; - let value2:u32 = value0; + fn mul32(&mut self, value0:u64) { + let value1:u32 = to32!(self.regs.get_eax()); + let value2:u32 = value0 as u32; let res:u64 = value1 as u64 * value2 as u64; - self.regs.edx = ((res & 0xffffffff00000000) >> 32) as u32; - self.regs.eax = (res & 0x00000000ffffffff) as u32; + self.regs.set_edx( (res & 0xffffffff00000000) >> 32 ); + self.regs.set_eax( res & 0x00000000ffffffff ); self.flags.f_pf = (res & 0xff) % 2 == 0; - self.flags.f_of = self.regs.edx != 0; - self.flags.f_cf = self.regs.edx != 0; + self.flags.f_of = self.regs.get_edx() != 0; + self.flags.f_cf = self.regs.get_edx() != 0; } - fn mul16(&mut self, value0:u32) { - let value1:u32 = self.regs.get_ax(); - let value2:u32 = value0; + fn mul16(&mut self, value0:u64) { + let value1:u32 = to32!(self.regs.get_ax()); + let value2:u32 = value0 as u32; let res:u32 = value1 * value2; - self.regs.set_dx((res & 0xffff0000) >> 16); - self.regs.set_ax(res & 0xffff); + self.regs.set_dx(((res & 0xffff0000) >> 16).into()); + self.regs.set_ax((res & 0xffff).into()); self.flags.f_pf = (res & 0xff) % 2 == 0; self.flags.f_of = self.regs.get_dx() != 0; self.flags.f_cf = self.regs.get_dx() != 0; } - fn mul8(&mut self, value0:u32) { - let value1:u32 = self.regs.get_al(); - let value2:u32 = value0; + fn mul8(&mut self, value0:u64) { + let value1:u32 = self.regs.get_al() as u32; + let value2:u32 = value0 as u32; let res:u32 = value1 * value2; - self.regs.set_ax(res & 0xffff); + self.regs.set_ax((res & 0xffff).into()); self.flags.f_pf = (res & 0xff) % 2 == 0; self.flags.f_of = self.regs.get_ah() != 0; self.flags.f_cf = self.regs.get_ah() != 0; } - fn imul32p1(&mut self, value0:u32) { - let value1:i32 = self.regs.eax as i32; + fn imul64p1(&mut self, value0:u64) { + let value1:i64 = self.regs.rax as i64; + let value2:i64 = value0 as i64; + let res:i128 = value1 as i128 * value2 as i128; + let ures:u128 = res as u128; + self.regs.rdx = ((ures & 0xffffffffffffffff0000000000000000) >> 64) as u64; + self.regs.rax = (ures & 0xffffffffffffffff) as u64; + self.flags.f_pf = (ures & 0xff) % 2 == 0; + self.flags.f_of = self.regs.get_edx() != 0; + self.flags.f_cf = self.regs.get_edx() != 0; + } + + fn imul32p1(&mut self, value0:u64) { + let value1:i32 = self.regs.get_eax() as i32; let value2:i32 = value0 as i32; let res:i64 = value1 as i64 * value2 as i64; let ures:u64 = res as u64; - self.regs.edx = ((ures & 0xffffffff00000000) >> 32) as u32; - self.regs.eax = (ures & 0x00000000ffffffff) as u32; + self.regs.set_edx((ures & 0xffffffff00000000) >> 32); + self.regs.set_eax(ures & 0x00000000ffffffff); self.flags.f_pf = (ures & 0xff) % 2 == 0; - self.flags.f_of = self.regs.edx != 0; - self.flags.f_cf = self.regs.edx != 0; + self.flags.f_of = self.regs.get_edx() != 0; + self.flags.f_cf = self.regs.get_edx() != 0; } - fn imul16p1(&mut self, value0:u32) { + fn imul16p1(&mut self, value0:u64) { let value1:i32 = self.regs.get_ax() as i32; let value2:i32 = value0 as i32; let res:i32 = value1 * value2; let ures:u32 = res as u32; - self.regs.set_dx((ures & 0xffff0000) >> 16); - self.regs.set_ax(ures & 0xffff); + self.regs.set_dx(((ures & 0xffff0000) >> 16).into()); + self.regs.set_ax((ures & 0xffff).into()); self.flags.f_pf = (ures & 0xff) % 2 == 0; self.flags.f_of = self.regs.get_dx() != 0; self.flags.f_cf = self.regs.get_dx() != 0; } - fn imul8p1(&mut self, value0:u32) { + fn imul8p1(&mut self, value0:u64) { let value1:i32 = self.regs.get_al() as i32; let value2:i32 = value0 as i32; let res:i32 = value1 * value2; let ures:u32 = res as u32; - self.regs.set_ax(ures & 0xffff); + self.regs.set_ax((ures & 0xffff).into()); self.flags.f_pf = (ures & 0xff) % 2 == 0; self.flags.f_of = self.regs.get_ah() != 0; self.flags.f_cf = self.regs.get_ah() != 0; } - fn div32(&mut self, value0:u32) { - let mut value1:u64 = self.regs.edx as u64; + fn div64(&mut self, value0:u64) { + let mut value1:u128 = self.regs.rdx as u128; + value1 <<= 64; + value1 += self.regs.rax as u128; + let value2:u128 = value0 as u128; + + if value2 == 0 { + self.flags.f_tf = true; + println!("/!\\ division by 0 exception"); + self.exception(); + self.force_break = true; + return; + } + + let resq:u128 = value1 / value2; + let resr:u128 = value1 % value2; + self.regs.rax = resq as u64; + self.regs.rdx = resr as u64; + self.flags.f_pf = (resq & 0xff) % 2 == 0; + self.flags.f_of = resq > 0xffffffffffffffff; + if self.flags.f_of { + println!("/!\\ int overflow on division"); + } + } + + fn div32(&mut self, value0:u64) { + let mut value1:u64 = self.regs.get_edx(); value1 <<= 32; - value1 += self.regs.eax as u64; - let value2:u64 = value0 as u64; + value1 += self.regs.get_eax(); + let value2:u64 = value0; if value2 == 0 { self.flags.f_tf = true; @@ -921,8 +1019,8 @@ impl Emu { let resq:u64 = value1 / value2; let resr:u64 = value1 % value2; - self.regs.eax = resq as u32; - self.regs.edx = resr as u32; + self.regs.set_eax(resq); + self.regs.set_edx(resr); self.flags.f_pf = (resq & 0xff) % 2 == 0; self.flags.f_of = resq > 0xffffffff; if self.flags.f_of { @@ -930,9 +1028,9 @@ impl Emu { } } - fn div16(&mut self, value0:u32) { - let value1:u32 = (self.regs.get_dx() << 16) + self.regs.get_ax(); - let value2:u32 = value0; + fn div16(&mut self, value0:u64) { + let value1:u32 = to32!((self.regs.get_dx() << 16) + self.regs.get_ax()); + let value2:u32 = value0 as u32; if value2 == 0 { self.flags.f_tf = true; @@ -944,20 +1042,19 @@ impl Emu { let resq:u32 = value1 / value2; let resr:u32 = value1 % value2; - self.regs.set_ax(resq); - self.regs.set_dx(resr); + self.regs.set_ax(resq.into()); + self.regs.set_dx(resr.into()); self.flags.f_pf = (resq & 0xff) % 2 == 0; self.flags.f_of = resq > 0xffff; self.flags.f_tf = false; if self.flags.f_of { println!("/!\\ int overflow on division"); } - } - fn div8(&mut self, value0:u32) { - let value1:u32 = self.regs.get_ax(); - let value2:u32 = value0; + fn div8(&mut self, value0:u64) { + let value1:u32 = self.regs.get_ax() as u32; + let value2:u32 = value0 as u32; if value2 == 0 { self.flags.f_tf = true; println!("/!\\ division by 0 exception"); @@ -968,8 +1065,8 @@ impl Emu { let resq:u32 = value1 / value2; let resr:u32 = value1 % value2; - self.regs.set_al(resq); - self.regs.set_ah(resr); + self.regs.set_al(resq.into()); + self.regs.set_ah(resr.into()); self.flags.f_pf = (resq & 0xff) % 2 == 0; self.flags.f_of = resq > 0xff; self.flags.f_tf = false; @@ -978,11 +1075,41 @@ impl Emu { } } - fn idiv32(&mut self, value0:u32) { - let mut value1:u64 = self.regs.edx as u64; + fn idiv64(&mut self, value0:u64) { + let mut value1:u128 = self.regs.rdx as u128; + value1 <<= 64; + value1 += self.regs.rax as u128; + let value2:u128 = value0 as u128; + if value2 == 0 { + self.flags.f_tf = true; + println!("/!\\ division by 0 exception"); + self.exception(); + self.force_break = true; + return; + } + + let resq:u128 = value1 / value2; + let resr:u128 = value1 % value2; + self.regs.rax = resq as u64; + self.regs.rdx = resr as u64; + self.flags.f_pf = (resq & 0xff) % 2 == 0; + if resq > 0xffffffffffffffff { + println!("/!\\ int overflow exception on division"); + if self.break_on_alert { + panic!(); + } + } else if ((value1 as i128) > 0 && (resq as i64) < 0) || ((value1 as i128) < 0 && (resq as i64) > 0) { + println!("/!\\ sign change exception on division"); + self.exception(); + self.force_break = true; + } + } + + fn idiv32(&mut self, value0:u64) { + let mut value1:u64 = self.regs.get_edx(); value1 <<= 32; - value1 += self.regs.eax as u64; - let value2:u64 = value0 as u64; + value1 += self.regs.get_eax(); + let value2:u64 = value0; if value2 == 0 { self.flags.f_tf = true; println!("/!\\ division by 0 exception"); @@ -993,27 +1120,24 @@ impl Emu { let resq:u64 = value1 / value2; let resr:u64 = value1 % value2; - self.regs.eax = resq as u32; - self.regs.edx = resr as u32; + self.regs.set_eax(resq); + self.regs.set_edx(resr); self.flags.f_pf = (resq & 0xff) % 2 == 0; if resq > 0xffffffff { println!("/!\\ int overflow exception on division"); if self.break_on_alert { panic!(); } - } else { - - if ((value1 as i64) > 0 && (resq as i32) < 0) || ((value1 as i64) < 0 && (resq as i32) > 0) { - println!("/!\\ sign change exception on division"); - self.exception(); - self.force_break = true; - } + } else if ((value1 as i64) > 0 && (resq as i32) < 0) || ((value1 as i64) < 0 && (resq as i32) > 0) { + println!("/!\\ sign change exception on division"); + self.exception(); + self.force_break = true; } } - fn idiv16(&mut self, value0:u32) { - let value1:u32 = (self.regs.get_dx() << 16) + self.regs.get_ax(); - let value2:u32 = value0; + fn idiv16(&mut self, value0:u64) { + let value1:u32 = to32!((self.regs.get_dx() << 16) + self.regs.get_ax()); + let value2:u32 = value0 as u32; if value2 == 0 { self.flags.f_tf = true; println!("/!\\ division by 0 exception"); @@ -1024,8 +1148,8 @@ impl Emu { let resq:u32 = value1 / value2; let resr:u32 = value1 % value2; - self.regs.set_ax(resq); - self.regs.set_dx(resr); + self.regs.set_ax(resq.into()); + self.regs.set_dx(resr.into()); self.flags.f_pf = (resq & 0xff) % 2 == 0; self.flags.f_tf = false; if resq > 0xffff { @@ -1033,18 +1157,16 @@ impl Emu { if self.break_on_alert { panic!(); } - } else { - if ((value1 as i32) > 0 && (resq as i16) < 0) || ((value1 as i32) < 0 && (resq as i16) > 0) { - println!("/!\\ sign change exception on division"); - self.exception(); - self.force_break = true; - } + } else if ((value1 as i32) > 0 && (resq as i16) < 0) || ((value1 as i32) < 0 && (resq as i16) > 0) { + println!("/!\\ sign change exception on division"); + self.exception(); + self.force_break = true; } } - fn idiv8(&mut self, value0:u32) { - let value1:u32 = self.regs.get_ax(); - let value2:u32 = value0; + fn idiv8(&mut self, value0:u64) { + let value1:u32 = to32!(self.regs.get_ax()); + let value2:u32 = value0 as u32; if value2 == 0 { self.flags.f_tf = true; println!("/!\\ division by 0 exception"); @@ -1055,8 +1177,8 @@ impl Emu { let resq:u32 = value1 / value2; let resr:u32 = value1 % value2; - self.regs.set_al(resq); - self.regs.set_ah(resr); + self.regs.set_al(resq.into()); + self.regs.set_ah(resr.into()); self.flags.f_pf = (resq & 0xff) % 2 == 0; self.flags.f_tf = false; if resq > 0xff { @@ -1064,87 +1186,62 @@ impl Emu { if self.break_on_alert { panic!(); } - } else { - if ((value1 as i16) > 0 && (resq as i8) < 0) || ((value1 as i16) < 0 && (resq as i8) > 0) { - println!("/!\\ sign change exception on division"); - self.exception(); - self.force_break = true; - } - } - } - - - pub fn rotate_left(&self, val:u32, rot:u32, bits:u32) -> u32 { - (val << rot) | (val >> (bits-rot)) - } - - pub fn rotate_right(&self, val:u32, rot:u32, bits:u32) -> u32 { - //TODO: care with overflow - (val >> rot) | (val << (bits-rot)) - } - - - fn get_bit(&self, val:u32, count:u32) -> u32 { - (val & (1 << count )) >> count - } - - fn set_bit(&self, val:&mut u32, count:u32, bit:u32) { - if bit == 1 { - *val |= 1 << count; - } else { - *val &= !(1 << count); + } else if ((value1 as i16) > 0 && (resq as i8) < 0) || ((value1 as i16) < 0 && (resq as i8) > 0) { + println!("/!\\ sign change exception on division"); + self.exception(); + self.force_break = true; } } - pub fn shrd(&mut self, value0:u32, value1:u32, counter:u16, size:u32) -> u32 { - let mut storage0:u32 = value0; - self.flags.f_cf = self.get_bit(value0, counter as u32 - 1) == 1; + pub fn shrd(&mut self, value0:u64, value1:u64, counter:u64, size:u8) -> u64 { + let mut storage0:u64 = value0; + self.flags.f_cf = get_bit!(value0, counter - 1) == 1; if counter == 0 { return storage0; } - if counter as u32 > size { + if counter as u8 > size { println!("SHRD bad params."); return 0; } - for i in 0..=(size-1-counter as u32) { - let bit = self.get_bit(storage0, i as u32 + counter as u32); - self.set_bit(&mut storage0, i as u32, bit); + for i in 0..=(size as u64 - 1 - counter) { + let bit = get_bit!(storage0, i as u32 + counter as u32); + set_bit!(storage0, i as u32, bit); } - for i in (size-counter as u32)..size { - let bit = self.get_bit(value1, i as u32 + counter as u32 - 32); - self.set_bit(&mut storage0, i as u32, bit); + for i in (size as u64 - counter)..size as u64 { + let bit = get_bit!(value1, i as u32 + counter as u32 - 32); + set_bit!(storage0, i as u32, bit); } self.flags.calc_flags(storage0, size as u8); storage0 } - pub fn shld(&mut self, value0:u32, value1:u32, counter:u16, size:u32) -> u32 { - let mut storage0:u32 = value0; + pub fn shld(&mut self, value0:u64, value1:u64, counter:u64, size:u8) -> u64 { + let mut storage0:u64 = value0; - self.flags.f_cf = self.get_bit(value0, size - counter as u32) == 1; + self.flags.f_cf = get_bit!(value0, (size as u64) - counter) == 1; if counter == 0 { return storage0; } - if counter as u32 > size { + if counter as u8 > size { println!("SHLD bad params."); return 0; } - for i in ((counter as u32)..=(size-1)).rev() { - let bit = self.get_bit(storage0, i - counter as u32); - self.set_bit(&mut storage0, i, bit); + for i in (counter..=((size as u64)-1)).rev() { + let bit = get_bit!(storage0, i - counter); + set_bit!(storage0, i, bit); } - for i in (0..=(counter as u32 - 1)).rev() { - let bit = self.get_bit(value1, i - counter as u32 + size); - self.set_bit(&mut storage0, i, bit); + for i in (0..=(counter - 1)).rev() { + let bit = get_bit!(value1, i - counter + (size as u64)); + set_bit!(storage0, i, bit); } self.flags.calc_flags(storage0, size as u8); @@ -1158,16 +1255,28 @@ impl Emu { match cmd.as_str() { "q" => std::process::exit(1), "h" => con.help(), - "r" => self.featured_regs(), + "r" => { + self.featured_regs32(); + self.featured_regs64(); + }, + "r rax" => self.regs.show_rax(&self.maps, 0), + "r rbx" => self.regs.show_rbx(&self.maps, 0), + "r rcx" => self.regs.show_rcx(&self.maps, 0), + "r rdx" => self.regs.show_rdx(&self.maps, 0), + "r rsi" => self.regs.show_rsi(&self.maps, 0), + "r rdi" => self.regs.show_rdi(&self.maps, 0), + "r rbp" => println!("\trbp: 0x{:x}", self.regs.rbp), + "r rsp" => println!("\trsp: 0x{:x}", self.regs.rsp), + "r rip" => println!("\trip: 0x{:x}", self.regs.rip), "r eax" => self.regs.show_eax(&self.maps, 0), "r ebx" => self.regs.show_ebx(&self.maps, 0), "r ecx" => self.regs.show_ecx(&self.maps, 0), "r edx" => self.regs.show_edx(&self.maps, 0), "r esi" => self.regs.show_esi(&self.maps, 0), "r edi" => self.regs.show_edi(&self.maps, 0), - "r esp" => println!("\tesp: 0x{:x}", self.regs.esp), - "r ebp" => println!("\tebp: 0x{:x}", self.regs.ebp), - "r eip" => println!("\teip: 0x{:x}", self.regs.eip), + "r esp" => println!("\tesp: 0x{:x}", self.regs.get_esp() as u32), + "r ebp" => println!("\tebp: 0x{:x}", self.regs.get_ebp() as u32), + "r eip" => println!("\teip: 0x{:x}", self.regs.get_eip() as u32), "r xmm0" => println!("\txmm0: 0x{:x}", self.regs.xmm0), "r xmm1" => println!("\txmm1: 0x{:x}", self.regs.xmm1), "r xmm2" => println!("\txmm2: 0x{:x}", self.regs.xmm2), @@ -1181,14 +1290,19 @@ impl Emu { con.print("register name"); let reg = con.cmd(); con.print("value"); - let svalue = con.cmd(); - let value = u32::from_str_radix(svalue.as_str().trim_start_matches("0x"), 16).expect("bad num conversion"); + let value = match con.cmd_hex64() { + Ok(v) => v, + Err(_) => { + println!("bad hex value"); + continue; + } + }; self.regs.set_by_name(reg.as_str(), value); }, "mr"|"rm" => { con.print("memory argument"); let operand = con.cmd(); - let addr:u32 = self.memory_operand_to_address(operand.as_str()); + let addr:u64 = self.memory_operand_to_address(operand.as_str()); let value = match self.memory_read(operand.as_str()) { Some(v) => v, None => { @@ -1196,13 +1310,13 @@ impl Emu { continue; }, }; - println!("0x{:x}: 0x{:x}", addr, value); + println!("0x{:x}: 0x{:x}", to32!(addr), value); }, "mw"|"wm" => { con.print("memory argument"); let operand = con.cmd(); con.print("value"); - let value = match con.cmd_hex() { + let value = match con.cmd_hex64() { Ok(v) => v, Err(_) => { println!("bad hex value."); @@ -1218,7 +1332,7 @@ impl Emu { }, "ba" => { con.print("address"); - let addr = match con.cmd_hex() { + let addr = match con.cmd_hex64() { Ok(v) => v, Err(_) => { println!("bad hex value."); @@ -1230,7 +1344,7 @@ impl Emu { "bmr" => { con.print("address"); - let addr = match con.cmd_hex() { + let addr = match con.cmd_hex64() { Ok(v) => v, Err(_) => { println!("bad hex value."); @@ -1242,7 +1356,7 @@ impl Emu { "bmw" => { con.print("address"); - let addr = match con.cmd_hex() { + let addr = match con.cmd_hex64() { Ok(v) => v, Err(_) => { println!("bad hex value."); @@ -1268,8 +1382,8 @@ impl Emu { self.exp = self.pos+1; }, "cls" => println!("{}", self.colors.clear_screen), - "s" => self.maps.dump_dwords(self.regs.esp), - "v" => self.maps.get_mem("stack").print_dwords_from_to(self.regs.ebp, self.regs.ebp+0x100), + "s" => self.maps.dump_dwords(self.regs.get_esp()), + "v" => self.maps.get_mem("stack").print_dwords_from_to(self.regs.get_ebp(), self.regs.get_ebp()+0x100), "c" => return, "f" => self.flags.print(), "fc" => self.flags.clear(), @@ -1279,7 +1393,7 @@ impl Emu { con.print("name "); let name = con.cmd(); con.print("base address "); - let addr = match con.cmd_hex() { + let addr = match con.cmd_hex64() { Ok(v) => v, Err(_) => { println!("bad hex value."); @@ -1298,7 +1412,7 @@ impl Emu { }, "mn" => { con.print("address"); - let addr = match con.cmd_hex() { + let addr = match con.cmd_hex64() { Ok(v) => v, Err(_) => { println!("bad hex value."); @@ -1314,7 +1428,7 @@ impl Emu { }; let mem = self.maps.get_mem(name.as_str()); - println!("map: {} 0x{:x}-0x{:x} ({})", name, mem.get_base(), mem.get_bottom(), mem.size()); + println!("map: {} 0x{:x}-0x{:x} ({})", name, to32!(mem.get_base()), to32!(mem.get_bottom()), mem.size()); }, "ma" => { @@ -1322,7 +1436,7 @@ impl Emu { }, "md" => { con.print("address"); - let addr = match con.cmd_hex() { + let addr = match con.cmd_hex64() { Ok(v) => v, Err(_) => { println!("bad hex value."); @@ -1333,7 +1447,7 @@ impl Emu { }, "mrd" => { con.print("address"); - let addr = match con.cmd_hex() { + let addr = match con.cmd_hex64() { Ok(v) => v, Err(_) => { println!("bad hex value."); @@ -1345,7 +1459,7 @@ impl Emu { }, "mds" => { con.print("address"); - let addr = match con.cmd_hex() { + let addr = match con.cmd_hex64() { Ok(v) => v, Err(_) => { println!("bad hex value."); @@ -1356,7 +1470,7 @@ impl Emu { }, "mdw" => { con.print("address"); - let addr = match con.cmd_hex() { + let addr = match con.cmd_hex64() { Ok(v) => v, Err(_) => { println!("bad hex value."); @@ -1367,7 +1481,7 @@ impl Emu { }, "mdd" => { con.print("address"); - let addr = match con.cmd_hex() { + let addr = match con.cmd_hex64() { Ok(v) => v, Err(_) => { println!("bad hex value."); @@ -1397,7 +1511,7 @@ impl Emu { } "eip" => { con.print("="); - let addr = match con.cmd_hex() { + let addr = match con.cmd_hex64() { Ok(v) => v, Err(_) => { println!("bad hex value"); @@ -1405,23 +1519,39 @@ impl Emu { } }; self.force_break = true; - self.regs.eip = addr; + self.regs.set_eip(addr); }, "push" => { con.print("value"); - let value = match con.cmd_hex() { - Ok(v) => v, - Err(_) => { - println!("bad hex value"); - continue; - } - }; - self.stack_push(value); + if self.cfg.is_64bits { + let value = match con.cmd_hex64() { + Ok(v) => v, + Err(_) => { + println!("bad hex value"); + continue; + } + }; + self.stack_push64(value); + } else { + let value = match con.cmd_hex32() { + Ok(v) => v, + Err(_) => { + println!("bad hex value"); + continue; + } + }; + self.stack_push32(value); + } println!("pushed."); }, "pop" => { - let value = self.stack_pop(false); - println!("poped value 0x{:x}", value); + if self.cfg.is_64bits { + let value = self.stack_pop64(false); + println!("poped value 0x{:x}", value); + } else { + let value = self.stack_pop32(false); + println!("poped value 0x{:x}", value); + } }, "fpu" => { self.fpu.print(); @@ -1446,7 +1576,11 @@ impl Emu { } }; for addr in result.iter() { - println!("found 0x{:x} '{}'", addr, self.maps.read_string(*addr)); + if self.cfg.is_64bits { + println!("found 0x{:x} '{}'", *addr, self.maps.read_string(*addr)); + } else { + println!("found 0x{:x} '{}'", *addr as u32, self.maps.read_string(*addr)); + } } }, "sb" => { @@ -1479,7 +1613,7 @@ impl Emu { }, "ll" => { con.print("ptr"); - let ptr1:u32 = match con.cmd_hex() { + let ptr1 = match con.cmd_hex64() { Ok(v) => v, Err(_) => { println!("bad hex value"); @@ -1490,7 +1624,7 @@ impl Emu { loop { println!("- 0x{:x}", ptr); ptr = match self.maps.read_dword(ptr) { - Some(v) => v, + Some(v) => v.into(), None => break, }; if ptr == 0 || ptr == ptr1 { @@ -1505,7 +1639,7 @@ impl Emu { "m" => self.maps.print_maps(), "d" => { con.print("address"); - let addr = match con.cmd_hex() { + let addr = match con.cmd_hex64() { Ok(v) => v, Err(_) => { println!("bad hex value"); @@ -1518,7 +1652,7 @@ impl Emu { con.print("structure"); let struc = con.cmd(); con.print("address"); - let addr = match con.cmd_hex() { + let addr = match con.cmd_hex64() { Ok(v) => v, Err(_) => { println!("bad hex value"); @@ -1564,28 +1698,40 @@ impl Emu { } - } + } // end dt command _ => println!("command not found, type h"), - } - } - } + } // match commands + } // end loop + } // end commands function - fn featured_regs(&self) { + fn featured_regs32(&self) { self.regs.show_eax(&self.maps, 0); self.regs.show_ebx(&self.maps, 0); self.regs.show_ecx(&self.maps, 0); self.regs.show_edx(&self.maps, 0); self.regs.show_esi(&self.maps, 0); self.regs.show_edi(&self.maps, 0); - println!("\tesp: 0x{:x}", self.regs.esp); - println!("\tebp: 0x{:x}", self.regs.ebp); - println!("\teip: 0x{:x}", self.regs.eip); + println!("\tesp: 0x{:x}", self.regs.get_esp() as u32); + println!("\tebp: 0x{:x}", self.regs.get_ebp() as u32); + println!("\teip: 0x{:x}", self.regs.get_eip() as u32); + } + + fn featured_regs64(&self) { + self.regs.show_rax(&self.maps, 0); + self.regs.show_rbx(&self.maps, 0); + self.regs.show_rcx(&self.maps, 0); + self.regs.show_rdx(&self.maps, 0); + self.regs.show_rsi(&self.maps, 0); + self.regs.show_rdi(&self.maps, 0); + println!("\trsp: 0x{:x}", self.regs.rsp); + println!("\trbp: 0x{:x}", self.regs.rbp); + println!("\trip: 0x{:x}", self.regs.rip); } fn exception(&mut self) { - let addr:u32; - let next:u32; + let addr:u64; + let next:u64; if self.veh > 0 { addr = self.veh; @@ -1593,7 +1739,6 @@ impl Emu { exception::enter(self); self.set_eip(addr, false); - } else { if self.seh == 0 { @@ -1605,16 +1750,15 @@ impl Emu { // SEH next = match self.maps.read_dword(self.seh) { - Some(value) => value, + Some(value) => value.into(), None => panic!("exception wihout correct SEH"), }; addr = match self.maps.read_dword(self.seh + 4) { - Some(value) => value, + Some(value) => value.into(), None => panic!("exception without correct SEH."), }; - let con = Console::new(); con.print("jump the exception pointer (y/n)?"); let cmd = con.cmd(); @@ -1627,11 +1771,13 @@ impl Emu { } } - pub fn disasemble(&mut self, addr:u32, amount:u32) { + pub fn disasemble(&mut self, addr:u64, amount:u32) { let map_name = self.maps.get_addr_name(addr).expect("address not mapped"); let code = self.maps.get_mem(map_name.as_str()); let block = code.read_from(addr); - let mut decoder = Decoder::with_ip(32, block, addr as u64, DecoderOptions::NONE); + let bits:u32; + if self.cfg.is_64bits { bits = 64 } else { bits = 32 } + let mut decoder = Decoder::with_ip(bits, block, addr, DecoderOptions::NONE); let mut formatter = IntelFormatter::new(); formatter.options_mut().set_digit_separator(""); formatter.options_mut().set_first_operand_char_index(6); @@ -1642,7 +1788,11 @@ impl Emu { decoder.decode_out(&mut instruction); output.clear(); formatter.format(&instruction, &mut output); - println!("0x{:x}: {}", instruction.ip32(), output); + if self.cfg.is_64bits { + println!("0x{:x}: {}", instruction.ip(), output); + } else { + println!("0x{:x}: {}", instruction.ip32(), output); + } count += 1; if count == amount { break; @@ -1650,21 +1800,22 @@ impl Emu { } } - - pub fn get_operand_value(&mut self, ins:&Instruction, noperand:u32, do_derref:bool) -> Option { + pub fn get_operand_value(&mut self, ins:&Instruction, noperand:u32, do_derref:bool) -> Option { assert!(ins.op_count() > noperand); - let value:u32 = match ins.op_kind(noperand) { - OpKind::NearBranch32 => ins.near_branch32(), - OpKind::NearBranch16 => ins.near_branch16() as u32, - OpKind::FarBranch32 => ins.far_branch32(), - OpKind::FarBranch16 => ins.far_branch16() as u32, - OpKind::Immediate8 => ins.immediate8() as u32, - OpKind::Immediate16 => ins.immediate16() as u32, - OpKind::Immediate32 => ins.immediate32(), - OpKind::Immediate8to32 => ins.immediate8to32() as u32, - OpKind::Immediate8to16 => ins.immediate8to16() as u32, + let value:u64 = match ins.op_kind(noperand) { + OpKind::NearBranch64 => ins.near_branch64(), + OpKind::NearBranch32 => ins.near_branch32().into(), + OpKind::NearBranch16 => ins.near_branch16().into(), + OpKind::FarBranch32 => ins.far_branch32().into(), + OpKind::FarBranch16 => ins.far_branch16().into(), + OpKind::Immediate64 => ins.immediate64(), + OpKind::Immediate8 => ins.immediate8().into(), + OpKind::Immediate16 => ins.immediate16().into(), + OpKind::Immediate32 => ins.immediate32().into(), + OpKind::Immediate8to32 => ins.immediate8to32() as u64, + OpKind::Immediate8to16 => ins.immediate8to16() as u64, OpKind::Register => self.regs.get_reg(ins.op_register(noperand)), OpKind::Memory => { let mut derref = do_derref; @@ -1677,12 +1828,12 @@ impl Emu { Some(0) } else { - Some(self.regs.get_reg(reg) as u64) + Some(self.regs.get_reg(reg)) } - }).expect("error reading memory") as u32; + }).expect("error reading memory"); if fs { - let value:u32 = match mem_addr { + let value:u64 = match mem_addr { 0x30 => { let peb = self.maps.get_mem("peb"); if self.cfg.verbose >= 1 { @@ -1708,25 +1859,30 @@ impl Emu { mem_addr = value; } - let value:u32; + let value:u64; if derref { let sz = self.get_operand_sz(ins, noperand); value = match sz { - 32 => match self.maps.read_dword(mem_addr) { + 64 => match self.maps.read_qword(mem_addr) { Some(v) => v, + None => { self.exception(); return None; } + } + + 32 => match self.maps.read_dword(mem_addr) { + Some(v) => v.into(), None => { self.exception(); return None; } } 16 => match self.maps.read_word(mem_addr) { - Some(v) => v as u32, + Some(v) => v.into(), None => { self.exception(); return None; } } 8 => match self.maps.read_byte(mem_addr) { - Some(v) => v as u32, + Some(v) => v.into(), None => { self.exception(); return None; } } @@ -1757,7 +1913,7 @@ impl Emu { Some(value) } - pub fn set_operand_value(&mut self, ins:&Instruction, noperand:u32, value:u32) -> bool { + pub fn set_operand_value(&mut self, ins:&Instruction, noperand:u32, value:u64) -> bool { assert!(ins.op_count() > noperand); @@ -1781,33 +1937,28 @@ impl Emu { } else { Some(self.regs.get_reg(reg) as u64) } - }).unwrap() as u32; + }).unwrap(); if write { let sz = self.get_operand_sz(ins, noperand); match sz { 64 => { - if !self.maps.write_dword(mem_addr, value) { - println!("exception dereferencing bad address. 0x{:x}", mem_addr); - self.exception(); - return false; - } - if !self.maps.write_dword(mem_addr+4, value) { //TODO: this value should be the other dword + if !self.maps.write_qword(mem_addr, value) { println!("exception dereferencing bad address. 0x{:x}", mem_addr); self.exception(); return false; } } 32 => { - if !self.maps.write_dword(mem_addr, value) { + if !self.maps.write_dword(mem_addr, to32!(value)) { println!("exception dereferencing bad address. 0x{:x}", mem_addr); self.exception(); return false; } } 16 => { - if !self.maps.write_word(mem_addr, value as u16) { + if !self.maps.write_word(mem_addr, value as u16) { println!("exception dereferencing bad address. 0x{:x}", mem_addr); self.exception(); return false; @@ -1873,7 +2024,7 @@ impl Emu { }; if do_derref { - let value:u128 = match self.maps.read_128bits_le(mem_addr as u32) { + let value:u128 = match self.maps.read_128bits_le(mem_addr) { Some(v) => v, None => { self.exception(); @@ -1908,7 +2059,7 @@ impl Emu { }; for (i,b) in value.to_le_bytes().iter().enumerate() { - self.maps.write_byte(mem_addr as u32 + i as u32, *b); + self.maps.write_byte(mem_addr + i as u64, *b); } } @@ -1916,13 +2067,14 @@ impl Emu { }; } - fn get_operand_sz(&self, ins:&Instruction, noperand:u32) -> usize { + fn get_operand_sz(&self, ins:&Instruction, noperand:u32) -> u8 { let reg:Register = ins.op_register(noperand); if reg.is_xmm() { return 128; } - let size:usize = match ins.op_kind(noperand) { + let size:u8 = match ins.op_kind(noperand) { + OpKind::NearBranch64 => 64, OpKind::NearBranch32 => 32, OpKind::NearBranch16 => 16, OpKind::FarBranch32 => 32, @@ -1930,6 +2082,7 @@ impl Emu { OpKind::Immediate8 => 8, OpKind::Immediate16 => 16, OpKind::Immediate32 => 32, + OpKind::Immediate64 => 64, OpKind::Immediate8to32 => 32, OpKind::Immediate8to16 => 16, OpKind::Register => self.regs.get_size(ins.op_register(noperand)), @@ -1938,7 +2091,7 @@ impl Emu { let info = info_factory.info(ins); let mem = info.used_memory()[0]; - let size2:usize = match mem.memory_size() { + let size2:u8 = match mem.memory_size() { MemorySize::Float16 => 16, MemorySize::Float32 => 32, MemorySize::Float64 => 64, @@ -1949,15 +2102,12 @@ impl Emu { MemorySize::Int32 => 32, MemorySize::Int16 => 16, MemorySize::Int8 => 8, + MemorySize::QwordOffset => 64, MemorySize::DwordOffset => 32, MemorySize::WordOffset => 16, - _ => 0, + _ => unimplemented!("memory size {:?}", mem.memory_size()), }; - if size2 == 0 { - unimplemented!("weird size {:?}", mem.memory_size()); - } - size2 } _ => unimplemented!("operand type {:?}", ins.op_kind(noperand)), @@ -1966,14 +2116,41 @@ impl Emu { size } + pub fn show_instruction(&self, color:&str, ins:&Instruction) { + if !self.step { + if self.cfg.is_64bits { + println!("{}{} 0x{:x}: {}{}", color, self.pos, ins.ip(), self.out, self.colors.nc); + } else { + println!("{}{} 0x{:x}: {}{}", color, self.pos, ins.ip32(), self.out, self.colors.nc); + } + } + } + + pub fn show_instruction_taken(&self, color:&str, ins:&Instruction) { + if !self.step { + if self.cfg.is_64bits { + println!("{}{} 0x{:x}: {} taken {}", color, self.pos, ins.ip(), self.out, self.colors.nc); + } else { + println!("{}{} 0x{:x}: {} taken {}", color, self.pos, ins.ip32(), self.out, self.colors.nc); + } + } + } + pub fn show_instruction_not_taken(&self, color:&str, ins:&Instruction) { + if !self.step { + if self.cfg.is_64bits { + println!("{}{} 0x{:x}: {} not taken {}", color, self.pos, ins.ip(), self.out, self.colors.nc); + } else { + println!("{}{} 0x{:x}: {} not taken {}", color, self.pos, ins.ip32(), self.out, self.colors.nc); + } + } + } /// RUN ENGINE /// pub fn run(&mut self) { println!(" ----- emulation -----"); let mut looped:Vec = Vec::new(); - let mut out = String::new(); //let ins = Instruction::default(); let mut formatter = IntelFormatter::new(); formatter.options_mut().set_digit_separator(""); @@ -1982,29 +2159,34 @@ impl Emu { self.pos = 0; loop { - let code = match self.maps.get_mem_by_addr(self.regs.eip) { + let code = match self.maps.get_mem_by_addr(self.regs.get_eip()) { Some(c) => c, - None => panic!("redirecting code flow to non maped address 0x{:x}", self.regs.eip), + None => panic!("redirecting code flow to non maped address 0x{:x}", self.regs.get_eip()), }; - let block = code.read_from(self.regs.eip).to_vec(); - let mut decoder = Decoder::with_ip(32, &block, self.regs.eip as u64, DecoderOptions::NONE); + let block = code.read_from(self.regs.get_eip()).to_vec(); + let mut decoder; + if self.cfg.is_64bits { + decoder = Decoder::with_ip(64, &block, self.regs.rip, DecoderOptions::NONE); + } else { + decoder = Decoder::with_ip(32, &block, self.regs.get_eip(), DecoderOptions::NONE); + } for ins in decoder.iter() { let sz = ins.len(); - let addr = ins.ip32() as u32; - let mut step = false; - out.clear(); - formatter.format(&ins, &mut out); + let addr = ins.ip(); + self.step = false; + self.out.clear(); + formatter.format(&ins, &mut self.out); self.pos += 1; if self.exp == self.pos || self.bp.get_bp() == addr || (self.cfg.console2 && self.cfg.console_addr == addr) { self.cfg.console2 = false; - step = true; + self.step = true; println!("-------"); - println!("{} 0x{:x}: {}", self.pos, ins.ip32(), out); + println!("{} 0x{:x}: {}", self.pos, ins.ip32(), self.out); self.spawn_console(); if self.force_break { self.force_break = false; @@ -2014,10 +2196,10 @@ impl Emu { if self.cfg.loops { // loop detector - looped.push(addr as u64); + looped.push(addr); let mut count:u32 = 0; for a in looped.iter() { - if addr as u64 == *a { + if addr == *a { count += 1; } } @@ -2032,7 +2214,9 @@ impl Emu { } if self.cfg.trace_regs { - println!("\teax: 0x{:x} ebx: 0x{:x} ecx: 0x{:x} edx: 0x{:x} esi: 0x{:x} edi: 0x{:x} ebp: 0x{:x}", self.regs.eax, self.regs.ebx, self.regs.ecx, self.regs.edx, self.regs.esi, self.regs.edi, self.regs.ebp); + println!("\teax: 0x{:x} ebx: 0x{:x} ecx: 0x{:x} edx: 0x{:x} esi: 0x{:x} edi: 0x{:x} ebp: 0x{:x}", + self.regs.get_eax() as u32, self.regs.get_ebx() as u32, self.regs.get_ecx() as u32, + self.regs.get_edx() as u32, self.regs.get_esi() as u32, self.regs.get_edi() as u32, self.regs.get_ebp() as u32); } if self.cfg.trace_reg { @@ -2043,37 +2227,37 @@ impl Emu { "edx" => self.regs.show_edx(&self.maps, self.pos), "esi" => self.regs.show_esi(&self.maps, self.pos), "edi" => self.regs.show_edi(&self.maps, self.pos), - "esp" => println!("\t{} esp: 0x{:}", self.pos, self.regs.esp), - "ebp" => println!("\t{} ebp: 0x{:}", self.pos, self.regs.ebp), - "eip" => println!("\t{} eip: 0x{:}", self.pos, self.regs.eip), + "esp" => println!("\t{} esp: 0x{:}", self.pos, self.regs.get_esp() as u32), + "ebp" => println!("\t{} ebp: 0x{:}", self.pos, self.regs.get_ebp() as u32), + "eip" => println!("\t{} eip: 0x{:}", self.pos, self.regs.get_eip() as u32), _ => panic!("invalid register."), } } if self.cfg.verbose < 2 { - step = true; + self.step = true; } if self.cfg.trace_string { let s = self.maps.read_string(self.cfg.string_addr); if s.len() >= 2 && s.len() < 80 { - println!("\ttrace string -> 0x{:x}: '{}'", self.cfg.string_addr, s); + println!("\ttrace string -> 0x{:x}: '{}'", self.cfg.string_addr as u32, s); } else { let w = self.maps.read_wide_string(self.cfg.string_addr); if w.len() < 80 { - println!("\ttrace wide string -> 0x{:x}: '{}'", self.cfg.string_addr, w); + println!("\ttrace wide string -> 0x{:x}: '{}'", self.cfg.string_addr as u32, w); } else { - println!("\ttrace wide string -> 0x{:x}: ''", self.cfg.string_addr); + println!("\ttrace wide string -> 0x{:x}: ''", self.cfg.string_addr as u32); } } } if self.cfg.inspect { - let addr:u32 = self.memory_operand_to_address(self.cfg.inspect_seq.clone().as_str()); + let addr:u64 = self.memory_operand_to_address(self.cfg.inspect_seq.clone().as_str()); let bits = self.get_size(self.cfg.inspect_seq.clone().as_str()); let value = self.memory_read(self.cfg.inspect_seq.clone().as_str()).unwrap_or(0); - println!("\t{} {} (0x{:x}): 0x{:x} {} '{}' {{{}}}", self.pos, self.cfg.inspect_seq, addr, value, value, + println!("\t{} {} (0x{:x}): 0x{:x} {} '{}' {{{}}}", self.pos, self.cfg.inspect_seq, addr as u32, value, value, self.maps.read_string(addr), self.maps.read_string_of_bytes(addr, constants::NUM_BYTES_TRACE)); } @@ -2086,9 +2270,7 @@ impl Emu { match ins.mnemonic() { Mnemonic::Jmp => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.yellow, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.yellow, &ins); if ins.op_count() != 1 { unimplemented!("weird variant of jmp"); @@ -2103,9 +2285,7 @@ impl Emu { } Mnemonic::Call => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.yellow, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.yellow, &ins); if ins.op_count() != 1 { unimplemented!("weird variant of call"); @@ -2116,82 +2296,81 @@ impl Emu { None => break }; - self.stack_push(self.regs.eip + sz as u32); + self.stack_push32(self.regs.get_eip() as u32 + sz as u32); self.set_eip(addr, false); break; } Mnemonic::Push => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.blue, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.blue, &ins); let value = match self.get_operand_value(&ins, 0, true) { Some(v) => v, None => break }; - self.stack_push(value); + self.stack_push32(to32!(value)); } Mnemonic::Pop => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.blue, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.blue, &ins); - let value = self.stack_pop(true); - if !self.set_operand_value(&ins, 0, value) { + let value = self.stack_pop32(true); + if !self.set_operand_value(&ins, 0, value as u64) { break; } } Mnemonic::Pushad => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.blue, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.blue, &ins); - let tmp_esp = self.regs.esp; - self.stack_push(self.regs.eax); - self.stack_push(self.regs.ecx); - self.stack_push(self.regs.edx); - self.stack_push(self.regs.ebx); - self.stack_push(tmp_esp); - self.stack_push(self.regs.ebp); - self.stack_push(self.regs.esi); - self.stack_push(self.regs.edi); + let tmp_esp = self.regs.get_esp() as u32; + self.stack_push32(self.regs.get_eax() as u32); + self.stack_push32(self.regs.get_ecx() as u32); + self.stack_push32(self.regs.get_edx() as u32); + self.stack_push32(self.regs.get_ebx() as u32); + self.stack_push32(tmp_esp); + self.stack_push32(self.regs.get_ebp() as u32); + self.stack_push32(self.regs.get_esi() as u32); + self.stack_push32(self.regs.get_edi() as u32); } Mnemonic::Popad => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.blue, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.blue, &ins); + let mut poped:u64; + + + poped = self.stack_pop32(false) as u64; + self.regs.set_edi(poped); + poped = self.stack_pop32(false) as u64; + self.regs.set_esi(poped); + poped = self.stack_pop32(false) as u64; + self.regs.set_ebp(poped); - self.regs.edi = self.stack_pop(false); - self.regs.esi = self.stack_pop(false); - self.regs.ebp = self.stack_pop(false); - self.regs.esp += 4; // skip esp - self.regs.ebx = self.stack_pop(false); - self.regs.edx = self.stack_pop(false); - self.regs.ecx = self.stack_pop(false); - self.regs.eax = self.stack_pop(false); + self.regs.set_esp(self.regs.get_esp() + 4); // skip esp + + poped = self.stack_pop32(false) as u64; + self.regs.set_ebx(poped); + poped = self.stack_pop32(false) as u64; + self.regs.set_edx(poped); + poped = self.stack_pop32(false) as u64; + self.regs.set_ecx(poped); + poped = self.stack_pop32(false) as u64; + self.regs.set_eax(poped); } Mnemonic::Cdq => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.blue, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.blue, &ins); - let num:i64 = self.regs.eax as i32 as i64; // sign-extend + let num:i64 = self.regs.get_eax() as u32 as i32 as i64; // sign-extend let unum:u64 = num as u64; - self.regs.edx = ((unum & 0xffffffff00000000) >> 32) as u32; - self.regs.eax = (unum & 0xffffffff) as u32; + self.regs.set_edx((unum & 0xffffffff00000000) >> 32); + self.regs.set_eax(unum & 0xffffffff); } Mnemonic::Ret => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.yellow, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.yellow, &ins); - let ret_addr = self.stack_pop(false); // return address + let ret_addr = self.stack_pop32(false) as u64; // return address if ins.op_count() > 0 { let mut arg = self.get_operand_value(&ins, 0, true).expect("weird crash on ret"); @@ -2204,7 +2383,7 @@ impl Emu { arg /= 4; for _ in 0..arg { - self.stack_pop(false); + self.stack_pop32(false); } } @@ -2218,9 +2397,7 @@ impl Emu { } Mnemonic::Xchg => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.light_cyan, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.light_cyan, &ins); assert!(ins.op_count() == 2); @@ -2243,9 +2420,7 @@ impl Emu { } Mnemonic::Mov => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.light_cyan, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.light_cyan, &ins); assert!(ins.op_count() == 2); @@ -2260,9 +2435,7 @@ impl Emu { } Mnemonic::Xor => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); assert!(ins.op_count() == 2); @@ -2287,9 +2460,7 @@ impl Emu { } Mnemonic::Add => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.cyan, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.cyan, &ins); assert!(ins.op_count() == 2); @@ -2303,8 +2474,9 @@ impl Emu { None => break, }; - let res:u32; + let res:u64; match self.get_operand_sz(&ins, 1) { + 64 => res = self.flags.add64(value0, value1), 32 => res = self.flags.add32(value0, value1), 16 => res = self.flags.add16(value0, value1), 8 => res = self.flags.add8(value0, value1), @@ -2318,13 +2490,11 @@ impl Emu { } Mnemonic::Adc => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.cyan, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.cyan, &ins); assert!(ins.op_count() == 2); - let cf:u32; + let cf:u64; if self.flags.f_cf { cf = 1 } else { @@ -2341,11 +2511,12 @@ impl Emu { None => break, }; - let res:u32; + let res:u64; match self.get_operand_sz(&ins, 1) { - 32 => res = self.flags.add32(value0, value1+cf), - 16 => res = self.flags.add16(value0, value1+cf), - 8 => res = self.flags.add8(value0, value1+cf), + 64 => res = self.flags.add64(value0, value1 + cf), + 32 => res = self.flags.add32(value0, value1 + cf), + 16 => res = self.flags.add16(value0, value1 + cf), + 8 => res = self.flags.add8(value0, value1 + cf), _ => panic!("weird size") } @@ -2356,13 +2527,11 @@ impl Emu { } Mnemonic::Sbb => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.cyan, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.cyan, &ins); assert!(ins.op_count() == 2); - let cf:u32; + let cf:u64; if self.flags.f_cf { cf = 1 } else { @@ -2379,11 +2548,12 @@ impl Emu { None => break, }; - let res:u32; + let res:u64; match self.get_operand_sz(&ins, 1) { - 32 => res = self.flags.sub32(value0, value1+cf), - 16 => res = self.flags.sub16(value0, value1+cf), - 8 => res = self.flags.sub8(value0, value1+cf), + 64 => res = self.flags.sub64(value0, value1 + cf), + 32 => res = self.flags.sub32(value0, value1 + cf), + 16 => res = self.flags.sub16(value0, value1 + cf), + 8 => res = self.flags.sub8(value0, value1 + cf), _ => panic!("weird size") } @@ -2394,9 +2564,7 @@ impl Emu { } Mnemonic::Sub => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.cyan, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.cyan, &ins); assert!(ins.op_count() == 2); @@ -2410,8 +2578,9 @@ impl Emu { None => break, }; - let res:u32; + let res:u64; match self.get_operand_sz(&ins, 1) { + 64 => res = self.flags.sub64(value0, value1), 32 => res = self.flags.sub32(value0, value1), 16 => res = self.flags.sub16(value0, value1), 8 => res = self.flags.sub8(value0, value1), @@ -2425,9 +2594,7 @@ impl Emu { } Mnemonic::Inc => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.cyan, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.cyan, &ins); assert!(ins.op_count() == 1); @@ -2436,7 +2603,8 @@ impl Emu { None => break, }; - let res:u32 = match self.get_operand_sz(&ins, 0) { + let res = match self.get_operand_sz(&ins, 0) { + 64 => self.flags.inc64(value0), 32 => self.flags.inc32(value0), 16 => self.flags.inc16(value0), 8 => self.flags.inc8(value0), @@ -2449,9 +2617,7 @@ impl Emu { } Mnemonic::Dec => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.cyan, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.cyan, &ins); assert!(ins.op_count() == 1); @@ -2460,7 +2626,8 @@ impl Emu { None => break, }; - let res:u32 = match self.get_operand_sz(&ins, 0) { + let res = match self.get_operand_sz(&ins, 0) { + 64 => self.flags.dec64(value0), 32 => self.flags.dec32(value0), 16 => self.flags.dec16(value0), 8 => self.flags.dec8(value0), @@ -2473,9 +2640,7 @@ impl Emu { } Mnemonic::Neg => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); assert!(ins.op_count() == 1); @@ -2484,7 +2649,8 @@ impl Emu { None => break, }; - let res:u32 = match self.get_operand_sz(&ins, 0) { + let res = match self.get_operand_sz(&ins, 0) { + 64 => self.flags.neg64(value0), 32 => self.flags.neg32(value0), 16 => self.flags.neg16(value0), 8 => self.flags.neg8(value0), @@ -2497,9 +2663,7 @@ impl Emu { } Mnemonic::Not => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); assert!(ins.op_count() == 1); @@ -2511,15 +2675,13 @@ impl Emu { let mut ival = value0 as i32; ival = !ival; - if !self.set_operand_value(&ins, 0, ival as u32) { + if !self.set_operand_value(&ins, 0, ival as u64) { break; } } Mnemonic::And => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); assert!(ins.op_count() == 2); @@ -2546,9 +2708,7 @@ impl Emu { } Mnemonic::Or => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); assert!(ins.op_count() == 2); @@ -2566,7 +2726,6 @@ impl Emu { //println!("0x{:x} or 0x{:x} = 0x{:x}", value0, value1, result); - self.flags.calc_flags(result, self.get_operand_sz(&ins, 0) as u8); self.flags.f_of = false; self.flags.f_cf = false; @@ -2577,9 +2736,7 @@ impl Emu { } Mnemonic::Sal => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); assert!(ins.op_count() == 1 || ins.op_count() == 2); @@ -2590,7 +2747,8 @@ impl Emu { if ins.op_count() == 1 { // 1 param - let result:u32 = match self.get_operand_sz(&ins, 0) { + let result = match self.get_operand_sz(&ins, 0) { + 64 => self.flags.sal1p64(value0), 32 => self.flags.sal1p32(value0), 16 => self.flags.sal1p16(value0), 8 => self.flags.sal1p8(value0), @@ -2604,13 +2762,13 @@ impl Emu { } else { // 2 params - let value1 = match self.get_operand_value(&ins, 1, true) { Some(v) => v, None => break, }; - let result:u32 = match self.get_operand_sz(&ins, 0) { + let result = match self.get_operand_sz(&ins, 0) { + 64 => self.flags.sal2p64(value0, value1), 32 => self.flags.sal2p32(value0, value1), 16 => self.flags.sal2p16(value0, value1), 8 => self.flags.sal2p8(value0, value1), @@ -2625,9 +2783,7 @@ impl Emu { } Mnemonic::Sar => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); assert!(ins.op_count() == 1 || ins.op_count() == 2); @@ -2638,7 +2794,8 @@ impl Emu { if ins.op_count() == 1 { // 1 param - let result:u32 = match self.get_operand_sz(&ins, 0) { + let result = match self.get_operand_sz(&ins, 0) { + 64 => self.flags.sar1p64(value0), 32 => self.flags.sar1p32(value0), 16 => self.flags.sar1p16(value0), 8 => self.flags.sar1p8(value0), @@ -2657,7 +2814,8 @@ impl Emu { None => break, }; - let result:u32 = match self.get_operand_sz(&ins, 0) { + let result = match self.get_operand_sz(&ins, 0) { + 64 => self.flags.sar2p64(value0, value1), 32 => self.flags.sar2p32(value0, value1), 16 => self.flags.sar2p16(value0, value1), 8 => self.flags.sar2p8(value0, value1), @@ -2672,9 +2830,7 @@ impl Emu { } Mnemonic::Shl => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); assert!(ins.op_count() == 1 || ins.op_count() == 2); @@ -2685,7 +2841,8 @@ impl Emu { if ins.op_count() == 1 { // 1 param - let result:u32 = match self.get_operand_sz(&ins, 0) { + let result = match self.get_operand_sz(&ins, 0) { + 64 => self.flags.shl1p64(value0), 32 => self.flags.shl1p32(value0), 16 => self.flags.shl1p16(value0), 8 => self.flags.shl1p8(value0), @@ -2704,7 +2861,8 @@ impl Emu { None => break, }; - let result:u32 = match self.get_operand_sz(&ins, 0) { + let result = match self.get_operand_sz(&ins, 0) { + 64 => self.flags.shl2p64(value0, value1), 32 => self.flags.shl2p32(value0, value1), 16 => self.flags.shl2p16(value0, value1), 8 => self.flags.shl2p8(value0, value1), @@ -2721,9 +2879,7 @@ impl Emu { } Mnemonic::Shr => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); assert!(ins.op_count() == 1 || ins.op_count() == 2); @@ -2734,7 +2890,8 @@ impl Emu { if ins.op_count() == 1 { // 1 param - let result:u32 = match self.get_operand_sz(&ins, 0) { + let result = match self.get_operand_sz(&ins, 0) { + 64 => self.flags.shr1p64(value0), 32 => self.flags.shr1p32(value0), 16 => self.flags.shr1p16(value0), 8 => self.flags.shr1p8(value0), @@ -2745,7 +2902,6 @@ impl Emu { break; } - } else { // 2 params let value1 = match self.get_operand_value(&ins, 1, true) { @@ -2753,7 +2909,8 @@ impl Emu { None => break, }; - let result:u32 = match self.get_operand_sz(&ins, 0) { + let result = match self.get_operand_sz(&ins, 0) { + 64 => self.flags.shr2p64(value0, value1), 32 => self.flags.shr2p32(value0, value1), 16 => self.flags.shr2p16(value0, value1), 8 => self.flags.shr2p8(value0, value1), @@ -2770,13 +2927,11 @@ impl Emu { } Mnemonic::Ror => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); assert!(ins.op_count() == 1 || ins.op_count() == 2); - let result:u32; + let result:u64; let sz = self.get_operand_sz(&ins, 0); @@ -2786,7 +2941,7 @@ impl Emu { None => break, }; - result = self.rotate_right(value0, 1, sz as u32); + result = rotate_right!(value0, 1, sz as u64); } else { // 2 params let value0 = match self.get_operand_value(&ins, 0, true) { @@ -2799,25 +2954,22 @@ impl Emu { None => break, }; - - result = self.rotate_right(value0, value1, sz as u32); + result = rotate_right!(value0, value1, sz as u64); } if !self.set_operand_value(&ins, 0, result) { break; } - self.flags.calc_flags(result, sz as u8); + self.flags.calc_flags(result, sz); } Mnemonic::Rol => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); assert!(ins.op_count() == 1 || ins.op_count() == 2); - let result:u32; + let result:u64; let sz = self.get_operand_sz(&ins, 0); @@ -2827,7 +2979,7 @@ impl Emu { None => break, }; - result = self.rotate_left(value0, 1, sz as u32); + result = rotate_left!(value0, 1, sz as u64); } else { // 2 params let value0 = match self.get_operand_value(&ins, 0, true) { @@ -2841,7 +2993,7 @@ impl Emu { }; - result = self.rotate_left(value0, value1, sz as u32); + result = rotate_left!(value0, value1, sz as u64); } if !self.set_operand_value(&ins, 0, result) { @@ -2852,9 +3004,7 @@ impl Emu { } Mnemonic::Mul => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.cyan, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.cyan, &ins); assert!(ins.op_count() == 1); @@ -2864,6 +3014,7 @@ impl Emu { }; match self.get_operand_sz(&ins, 0) { + 64 => self.mul64(value0), 32 => self.mul32(value0), 16 => self.mul16(value0), 8 => self.mul8(value0), @@ -2872,9 +3023,7 @@ impl Emu { } Mnemonic::Div => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.cyan, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.cyan, &ins); assert!(ins.op_count() == 1); @@ -2884,6 +3033,7 @@ impl Emu { }; match self.get_operand_sz(&ins, 0) { + 64 => self.div64(value0), 32 => self.div32(value0), 16 => self.div16(value0), 8 => self.div8(value0), @@ -2892,9 +3042,7 @@ impl Emu { } Mnemonic::Idiv => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.cyan, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.cyan, &ins); assert!(ins.op_count() == 1); @@ -2904,6 +3052,7 @@ impl Emu { }; match self.get_operand_sz(&ins, 0) { + 64 => self.idiv64(value0), 32 => self.idiv32(value0), 16 => self.idiv16(value0), 8 => self.idiv8(value0), @@ -2912,9 +3061,7 @@ impl Emu { } Mnemonic::Imul => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.cyan, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.cyan, &ins); assert!(ins.op_count() == 1 || ins.op_count() == 2 || ins.op_count() == 3); @@ -2926,6 +3073,7 @@ impl Emu { }; match self.get_operand_sz(&ins, 0) { + 64 => self.imul64p1(value0), 32 => self.imul32p1(value0), 16 => self.imul16p1(value0), 8 => self.imul8p1(value0), @@ -2944,9 +3092,10 @@ impl Emu { }; let result = match self.get_operand_sz(&ins, 0) { + 64 => self.flags.imul64p2(value0, value1), 32 => self.flags.imul32p2(value0, value1), - 16 => self.flags.imul16p2(value0 as u16, value1 as u16), - 8 => self.flags.imul8p2(value0 as u8, value1 as u8), + 16 => self.flags.imul16p2(value0, value1), + 8 => self.flags.imul8p2(value0, value1), _ => unimplemented!("wrong size"), }; @@ -2967,9 +3116,10 @@ impl Emu { }; let result = match self.get_operand_sz(&ins, 0) { + 64 => self.flags.imul64p2(value1, value2), 32 => self.flags.imul32p2(value1, value2), - 16 => self.flags.imul16p2(value1 as u16, value2 as u16), - 8 => self.flags.imul8p2(value1 as u8, value2 as u8), + 16 => self.flags.imul16p2(value1, value2), + 8 => self.flags.imul8p2(value1, value2), _ => unimplemented!("wrong size"), }; @@ -2981,9 +3131,7 @@ impl Emu { } Mnemonic::Movsx => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.light_cyan, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.light_cyan, &ins); assert!(ins.op_count() == 2); @@ -2998,21 +3146,32 @@ impl Emu { assert!((sz0 == 16 && sz1 == 8) || (sz0 == 32 && sz1 == 8) || - (sz0 == 32 && sz1 == 16)); + (sz0 == 32 && sz1 == 16) || + (sz0 == 64 && sz1 == 32) || + (sz0 == 64 && sz1 == 16) || + (sz0 == 64 && sz1 == 8)); - let mut result:u32 = 0; + let mut result:u64 = 0; if sz0 == 16 { assert!(sz1 == 8); - result = value1 as u8 as i8 as i16 as u16 as u32; + result = value1 as u8 as i8 as i16 as u16 as u64; } else if sz0 == 32 { if sz1 == 8 { - result = value1 as u8 as i8 as i32 as u32; + result = value1 as u8 as i8 as i64 as u64; } else if sz1 == 16 { - result = value1 as u8 as i8 as i16 as u16 as u32; + result = value1 as u8 as i8 as i16 as u16 as u64; } - } + } else if sz0 == 64 { + if sz1 == 8 { + result = value1 as u8 as i8 as i64 as u64; + } else if sz1 == 16 { + result = value1 as u16 as i16 as i64 as u64; + } else if sz1 == 32 { + result = value1 as u32 as i32 as i64 as u64; + } + } if !self.set_operand_value(&ins, 0, result) { break; @@ -3021,9 +3180,7 @@ impl Emu { } Mnemonic::Movzx => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.light_cyan, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.light_cyan, &ins); assert!(ins.op_count() == 2); @@ -3037,27 +3194,14 @@ impl Emu { assert!((sz0 == 16 && sz1 == 8) || (sz0 == 32 && sz1 == 8) || - (sz0 == 32 && sz1 == 16)); - - - let result:u32; + (sz0 == 32 && sz1 == 16) || + (sz0 == 64 && sz1 == 32) || + (sz0 == 64 && sz1 == 16) || + (sz0 == 64 && sz1 == 8)); - /* - if sz0 == 16 && sz1 == 8 { - value0 = value0 & 0x0000ff00; - value1 = value1 & 0x000000ff; - } else if sz0 == 32 && sz1 == 8 { - value0 = value0 & 0xffffff00; - value1 = value1 & 0x000000ff; + let result:u64; - } else if sz0 == 32 && sz1 == 16 { - value0 = value0 & 0xffff0000; - value1 = value1 & 0x0000ffff; - - } else { - unreachable!("impossible"); - }*/ result = value1; @@ -3070,165 +3214,282 @@ impl Emu { } Mnemonic::Movsb => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.light_cyan, self.pos, ins.ip32(), out, self.colors.nc); - } - - if ins.has_rep_prefix() { - loop { - let val = self.maps.read_byte(self.regs.esi).expect("cannot read memory"); - self.maps.write_byte(self.regs.edi, val); + self.show_instruction(&self.colors.light_cyan, &ins); + + if self.cfg.is_64bits { + if ins.has_rep_prefix() { + loop { + let val = self.maps.read_byte(self.regs.rsi).expect("cannot read memory"); + self.maps.write_byte(self.regs.rdi, val); + + if !self.flags.f_df { + self.regs.rsi += 1; + self.regs.rdi += 1; + } else { + self.regs.rsi -= 1; + self.regs.rdi -= 1; + } + + self.regs.rcx -= 1; + if self.regs.rcx == 0 { + break + } + } + } else { + let val = self.maps.read_byte(self.regs.rsi).expect("cannot read memory"); + self.maps.write_byte(self.regs.rdi, val); if !self.flags.f_df { - self.regs.esi += 1; - self.regs.edi += 1; + self.regs.rsi += 1; + self.regs.rdi += 1; } else { - self.regs.esi -= 1; - self.regs.edi -= 1; - } - - self.regs.ecx -= 1; - if self.regs.ecx == 0 { - break + self.regs.rsi -= 1; + self.regs.rdi -= 1; } } + } else { // 32bits + + if ins.has_rep_prefix() { + loop { + let val = self.maps.read_byte(self.regs.get_esi()).expect("cannot read memory"); + self.maps.write_byte(self.regs.get_edi(), val); + + if !self.flags.f_df { + self.regs.set_esi(self.regs.get_esi() + 1); + self.regs.set_edi(self.regs.get_edi() + 1); + } else { + self.regs.set_esi(self.regs.get_esi() - 1); + self.regs.set_edi(self.regs.get_edi() - 1); + } + + self.regs.set_ecx(self.regs.get_ecx() - 1); + if self.regs.get_ecx() == 0 { + break + } + } - } else { - let val = self.maps.read_byte(self.regs.esi).expect("cannot read memory"); - self.maps.write_byte(self.regs.edi, val); - if !self.flags.f_df { - self.regs.esi += 1; - self.regs.edi += 1; } else { - self.regs.esi -= 1; - self.regs.edi -= 1; + let val = self.maps.read_byte(self.regs.get_esi()).expect("cannot read memory"); + self.maps.write_byte(self.regs.get_edi(), val); + if !self.flags.f_df { + self.regs.set_esi(self.regs.get_esi() + 1); + self.regs.set_edi(self.regs.get_edi() + 1); + } else { + self.regs.set_esi(self.regs.get_esi() - 1); + self.regs.set_edi(self.regs.get_edi() - 1); + } } } } Mnemonic::Movsw => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.light_cyan, self.pos, ins.ip32(), out, self.colors.nc); - } - - if ins.has_rep_prefix() { - loop { - let val = self.maps.read_word(self.regs.esi).expect("cannot read memory"); - self.maps.write_word(self.regs.edi, val); + self.show_instruction(&self.colors.light_cyan, &ins); + + if self.cfg.is_64bits { + if ins.has_rep_prefix() { + loop { + let val = self.maps.read_word(self.regs.rsi).expect("cannot read memory"); + self.maps.write_word(self.regs.rdi, val); + + if !self.flags.f_df { + self.regs.rsi += 2; + self.regs.rdi += 2; + } else { + self.regs.rsi -= 2; + self.regs.rdi -= 2; + } + + self.regs.rcx -= 1; + if self.regs.rcx == 0 { + break + } + } + } else { + let val = self.maps.read_word(self.regs.rsi).expect("cannot read memory"); + self.maps.write_word(self.regs.rdi, val); if !self.flags.f_df { - self.regs.esi += 2; - self.regs.edi += 2; + self.regs.rsi += 2; + self.regs.rdi += 2; } else { - self.regs.esi -= 2; - self.regs.edi -= 2; + self.regs.rsi -= 2; + self.regs.rdi -= 2; } + } - self.regs.ecx -= 1; - if self.regs.ecx == 0 { - break + } else { // 32bits + + if ins.has_rep_prefix() { + loop { + let val = self.maps.read_word(self.regs.get_esi()).expect("cannot read memory"); + self.maps.write_word(self.regs.get_edi(), val); + + if !self.flags.f_df { + self.regs.set_esi(self.regs.get_esi() + 2); + self.regs.set_edi(self.regs.get_edi() + 2); + } else { + self.regs.set_esi(self.regs.get_esi() - 2); + self.regs.set_edi(self.regs.get_edi() - 2); + } + + self.regs.set_ecx(self.regs.get_ecx() - 1); + if self.regs.get_ecx() == 0 { + break + } } - } - } else { - let val = self.maps.read_word(self.regs.esi).expect("cannot read memory"); - self.maps.write_word(self.regs.edi, val); - if !self.flags.f_df { - self.regs.esi += 2; - self.regs.edi += 2; } else { - self.regs.esi -= 2; - self.regs.edi -= 2; - } + let val = self.maps.read_word(self.regs.get_esi()).expect("cannot read memory"); + self.maps.write_word(self.regs.get_edi(), val); + if !self.flags.f_df { + self.regs.set_esi(self.regs.get_esi() + 2); + self.regs.set_edi(self.regs.get_edi() + 2); + } else { + self.regs.set_esi(self.regs.get_esi() - 2); + self.regs.set_edi(self.regs.get_edi() - 2); + } + } } } - Mnemonic::Movsd => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.light_cyan, self.pos, ins.ip32(), out, self.colors.nc); - } - - if ins.has_rep_prefix() { - loop { - let val = self.maps.read_dword(self.regs.esi).expect("cannot read memory"); - self.maps.write_dword(self.regs.edi, val); + self.show_instruction(&self.colors.light_cyan, &ins); + + if self.cfg.is_64bits { + if ins.has_rep_prefix() { + loop { + let val = self.maps.read_dword(self.regs.rsi).expect("cannot read memory"); + self.maps.write_dword(self.regs.rdi, val); + + if !self.flags.f_df { + self.regs.rsi += 4; + self.regs.rdi += 4; + } else { + self.regs.rsi -= 4; + self.regs.rdi -= 4; + } + + self.regs.rcx -= 1; + if self.regs.rcx == 0 { + break + } + } + } else { + let val = self.maps.read_dword(self.regs.rsi).expect("cannot read memory"); + self.maps.write_dword(self.regs.rdi, val); if !self.flags.f_df { - self.regs.esi += 4; - self.regs.edi += 4; + self.regs.rsi += 4; + self.regs.rdi += 4; } else { - self.regs.esi -= 4; - self.regs.edi -= 4; - } - - self.regs.ecx -= 1; - if self.regs.ecx == 0 { - break + self.regs.rsi -= 4; + self.regs.rdi -= 4; } } + } else { // 32bits + + if ins.has_rep_prefix() { + loop { + let val = self.maps.read_dword(self.regs.get_esi()).expect("cannot read memory"); + self.maps.write_dword(self.regs.get_edi(), val); + + if !self.flags.f_df { + self.regs.set_esi(self.regs.get_esi() + 4); + self.regs.set_edi(self.regs.get_edi() + 4); + } else { + self.regs.set_esi(self.regs.get_esi() - 4); + self.regs.set_edi(self.regs.get_edi() - 4); + } + + self.regs.set_ecx(self.regs.get_ecx() - 1); + if self.regs.get_ecx() == 0 { + break + } + } - } else { - let val = self.maps.read_dword(self.regs.esi).expect("cannot read memory"); - self.maps.write_dword(self.regs.edi, val); - if !self.flags.f_df { - self.regs.esi += 4; - self.regs.edi += 4; } else { - self.regs.esi -= 4; - self.regs.edi -= 4; + let val = self.maps.read_dword(self.regs.get_esi()).expect("cannot read memory"); + self.maps.write_dword(self.regs.get_edi(), val); + if !self.flags.f_df { + self.regs.set_esi(self.regs.get_esi() + 4); + self.regs.set_edi(self.regs.get_edi() + 4); + } else { + self.regs.set_esi(self.regs.get_esi() - 4); + self.regs.set_edi(self.regs.get_edi() - 4); + } } } } Mnemonic::Stosb => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.light_cyan, self.pos, ins.ip32(), out, self.colors.nc); - } - - self.maps.write_byte(self.regs.edi, self.regs.get_al() as u8); - - if self.flags.f_df { - self.regs.edi -= 1; - } else { - self.regs.edi += 1; + self.show_instruction(&self.colors.light_cyan, &ins); + + + if self.cfg.is_64bits { + self.maps.write_byte(self.regs.rdi, self.regs.get_al() as u8); + if self.flags.f_df { + self.regs.rdi -= 1; + } else { + self.regs.rdi += 1; + } + } else { // 32bits + self.maps.write_byte(self.regs.get_edi(), self.regs.get_al() as u8); + if self.flags.f_df { + self.regs.set_edi(self.regs.get_edi() - 1); + } else { + self.regs.set_edi(self.regs.get_edi() + 1); + } } } Mnemonic::Stosw => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.light_cyan, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.light_cyan, &ins); - self.maps.write_word(self.regs.edi, self.regs.get_ax() as u16); + if self.cfg.is_64bits { + self.maps.write_word(self.regs.rdi, self.regs.get_ax() as u16); - if self.flags.f_df { - self.regs.edi -= 2; - } else { - self.regs.edi += 2; + if self.flags.f_df { + self.regs.rdi -= 2; + } else { + self.regs.rdi += 2; + } + } else { // 32bits + self.maps.write_word(self.regs.get_edi(), self.regs.get_ax() as u16); + + if self.flags.f_df { + self.regs.set_edi(self.regs.get_edi() - 2); + } else { + self.regs.set_edi(self.regs.get_edi() + 2); + } } } Mnemonic::Stosd => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.light_cyan, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.light_cyan, &ins); - self.maps.write_dword(self.regs.edi, self.regs.eax); + if self.cfg.is_64bits { + self.maps.write_dword(self.regs.rdi, self.regs.get_eax() as u32); - if self.flags.f_df { - self.regs.edi -= 4; - } else { - self.regs.edi += 4; + if self.flags.f_df { + self.regs.rdi -= 4; + } else { + self.regs.rdi += 4; + } + } else { // 32bits + self.maps.write_dword(self.regs.get_edi(), self.regs.get_eax() as u32); + + if self.flags.f_df { + self.regs.set_edi(self.regs.get_edi() - 4); + } else { + self.regs.set_edi(self.regs.get_edi() + 4); + } } } Mnemonic::Test => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.orange, &ins); assert!(ins.op_count() == 2); @@ -3248,9 +3509,7 @@ impl Emu { } Mnemonic::Cmpxchg => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.orange, &ins); let value0 = match self.get_operand_value(&ins, 0, true) { Some(v) => v, @@ -3262,21 +3521,31 @@ impl Emu { None => break, }; - if value0 == self.regs.eax { - self.flags.f_zf = true; - if !self.set_operand_value(&ins, 0, value1) { - break; + if self.cfg.is_64bits { + if value0 == self.regs.rax { + self.flags.f_zf = true; + if !self.set_operand_value(&ins, 0, value1) { + break; + } + } else { + self.flags.f_zf = false; + self.regs.rax = value1; + } + } else { // 32bits + if value0 == self.regs.get_eax() { + self.flags.f_zf = true; + if !self.set_operand_value(&ins, 0, value1) { + break; + } + } else { + self.flags.f_zf = false; + self.regs.set_eax(value1); } - } else { - self.flags.f_zf = false; - self.regs.eax = value1; } } Mnemonic::Cmpxchg8b => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.orange, &ins); let value0 = match self.get_operand_value(&ins, 0, true) { Some(v) => v, @@ -3301,9 +3570,7 @@ impl Emu { Mnemonic::Cmpxchg16b => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.orange, &ins); let value0 = match self.get_operand_value(&ins, 0, true) { Some(v) => v, @@ -3327,9 +3594,7 @@ impl Emu { } Mnemonic::Cmp => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.orange, &ins); assert!(ins.op_count() == 2); @@ -3343,7 +3608,7 @@ impl Emu { None => break, }; - if !step { + if !self.step { if value0 > value1 { println!("\tcmp: 0x{:x} > 0x{:x}", value0, value1); } else if value0 < value1 { @@ -3354,6 +3619,7 @@ impl Emu { } match self.get_operand_sz(&ins, 0) { + 64 => { self.flags.sub64(value0, value1); }, 32 => { self.flags.sub32(value0, value1); }, 16 => { self.flags.sub16(value0, value1); }, 8 => { self.flags.sub8(value0, value1); }, @@ -3363,14 +3629,22 @@ impl Emu { } Mnemonic::Cmpsd => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); + self.show_instruction(&self.colors.orange, &ins); + + let value0:u32; + let value1:u32; + + if self.cfg.is_64bits { + value0 = self.maps.read_dword(self.regs.rsi).expect("cannot read esi"); + value1 = self.maps.read_dword(self.regs.rdi).expect("cannot read edi"); + } else { // 32bits + value0 = self.maps.read_dword(self.regs.get_esi()).expect("cannot read esi"); + value1 = self.maps.read_dword(self.regs.get_edi()).expect("cannot read edi"); } - let value0 = self.maps.read_dword(self.regs.esi).expect("cannot read esi"); - let value1 = self.maps.read_dword(self.regs.edi).expect("cannot read edi"); + self.flags.sub32(value0 as u64, value1 as u64); - if !step { + if !self.step { if value0 > value1 { println!("\tcmp: 0x{:x} > 0x{:x}", value0, value1); } else if value0 < value1 { @@ -3380,18 +3654,25 @@ impl Emu { } } - self.flags.sub32(value0, value1); } Mnemonic::Cmpsw => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); + self.show_instruction(&self.colors.orange, &ins); + + let value0:u16; + let value1:u16; + + if self.cfg.is_64bits { + value0 = self.maps.read_word(self.regs.rsi).expect("cannot read esi"); + value1 = self.maps.read_word(self.regs.rdi).expect("cannot read edi"); + } else { // 32bits + value0 = self.maps.read_word(self.regs.get_esi()).expect("cannot read esi"); + value1 = self.maps.read_word(self.regs.get_edi()).expect("cannot read edi"); } - let value0 = self.maps.read_dword(self.regs.esi).expect("cannot read esi"); - let value1 = self.maps.read_dword(self.regs.edi).expect("cannot read edi"); + self.flags.sub16(value0 as u64, value1 as u64); - if !step { + if !self.step { if value0 > value1 { println!("\tcmp: 0x{:x} > 0x{:x}", value0, value1); } else if value0 < value1 { @@ -3400,19 +3681,25 @@ impl Emu { println!("\tcmp: 0x{:x} == 0x{:x}", value0, value1); } } - - self.flags.sub16(value0, value1); } Mnemonic::Cmpsb => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); + self.show_instruction(&self.colors.orange, &ins); + + let value0:u8; + let value1:u8; + + if self.cfg.is_64bits { + value0 = self.maps.read_byte(self.regs.rsi).expect("cannot read esi"); + value1 = self.maps.read_byte(self.regs.rdi).expect("cannot read edi"); + } else { // 32bits + value0 = self.maps.read_byte(self.regs.get_esi()).expect("cannot read esi"); + value1 = self.maps.read_byte(self.regs.get_edi()).expect("cannot read edi"); } - let value0 = self.maps.read_dword(self.regs.esi).expect("cannot read esi"); - let value1 = self.maps.read_dword(self.regs.edi).expect("cannot read edi"); + self.flags.sub8(value0 as u64, value1 as u64); - if !step { + if !self.step { if value0 > value1 { println!("\tcmp: 0x{:x} > 0x{:x}", value0, value1); } else if value0 < value1 { @@ -3421,9 +3708,6 @@ impl Emu { println!("\tcmp: 0x{:x} == 0x{:x}", value0, value1); } } - - - self.flags.sub8(value0, value1); } @@ -3439,18 +3723,21 @@ impl Emu { assert!(ins.op_count() == 1); if self.flags.f_of { - if !step { - println!("{}{} 0x{:x}: {} taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_taken(&self.colors.orange, &ins); + let addr = match self.get_operand_value(&ins, 0, true) { Some(v) => v, None => break, }; - self.set_eip(addr, true); + if self.cfg.is_64bits { + self.set_rip(addr, true); + } else { + self.set_eip(addr, true); + } break; - } else if !step { - println!("{}{} 0x{:x}: {} not taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); + } else { + self.show_instruction_not_taken(&self.colors.orange, &ins); } } @@ -3459,20 +3746,21 @@ impl Emu { assert!(ins.op_count() == 1); if !self.flags.f_of { - if !step { - println!("{}{} 0x{:x}: {} taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_taken(&self.colors.orange, &ins); + let addr = match self.get_operand_value(&ins, 0, true) { Some(v) => v, None => break, }; - self.set_eip(addr, true); + if self.cfg.is_64bits { + self.set_rip(addr, true); + } else { + self.set_eip(addr, true); + } break; } else { - if !step { - println!("{}{} 0x{:x}: {} not taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_not_taken(&self.colors.orange, &ins); } } @@ -3481,20 +3769,20 @@ impl Emu { assert!(ins.op_count() == 1); if self.flags.f_sf { - if !step { - println!("{}{} 0x{:x}: {} taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_taken(&self.colors.orange, &ins); let addr = match self.get_operand_value(&ins, 0, true) { Some(v) => v, None => break, }; - self.set_eip(addr, true); + if self.cfg.is_64bits { + self.set_rip(addr, true); + } else { + self.set_eip(addr, true); + } break; } else { - if !step { - println!("{}{} 0x{:x}: {} not taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_not_taken(&self.colors.orange, &ins); } } @@ -3503,20 +3791,20 @@ impl Emu { assert!(ins.op_count() == 1); if !self.flags.f_sf { - if !step { - println!("{}{} 0x{:x}: {} taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_taken(&self.colors.orange, &ins); let addr = match self.get_operand_value(&ins, 0, true) { Some(v) => v, None => break, }; - self.set_eip(addr, true); + if self.cfg.is_64bits { + self.set_rip(addr, true); + } else { + self.set_eip(addr, true); + } break; } else { - if !step { - println!("{}{} 0x{:x}: {} not taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_not_taken(&self.colors.orange, &ins); } } @@ -3525,20 +3813,20 @@ impl Emu { assert!(ins.op_count() == 1); if self.flags.f_zf { - if !step { - println!("{}{} 0x{:x}: {} taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_taken(&self.colors.orange, &ins); let addr = match self.get_operand_value(&ins, 0, true) { Some(v) => v, None => break, }; - self.set_eip(addr, true); + if self.cfg.is_64bits { + self.set_rip(addr, true); + } else { + self.set_eip(addr, true); + } break; } else { - if !step { - println!("{}{} 0x{:x}: {} not taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_not_taken(&self.colors.orange, &ins); } } @@ -3547,20 +3835,20 @@ impl Emu { assert!(ins.op_count() == 1); if !self.flags.f_zf { - if !step { - println!("{}{} 0x{:x}: {} taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_taken(&self.colors.orange, &ins); let addr = match self.get_operand_value(&ins, 0, true) { Some(v) => v, None => break, }; - self.set_eip(addr, true); + if self.cfg.is_64bits { + self.set_rip(addr, true); + } else { + self.set_eip(addr, true); + } break; } else { - if !step { - println!("{}{} 0x{:x}: {} not taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_not_taken(&self.colors.orange, &ins); } } @@ -3569,20 +3857,20 @@ impl Emu { assert!(ins.op_count() == 1); if self.flags.f_cf { - if !step { - println!("{}{} 0x{:x}: {} taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_taken(&self.colors.orange, &ins); let addr = match self.get_operand_value(&ins, 0, true) { Some(v) => v, None => break, }; - self.set_eip(addr, true); + if self.cfg.is_64bits { + self.set_rip(addr, true); + } else { + self.set_eip(addr, true); + } break; } else { - if !step { - println!("{}{} 0x{:x}: {} not taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_not_taken(&self.colors.orange, &ins); } } @@ -3591,20 +3879,20 @@ impl Emu { assert!(ins.op_count() == 1); if !self.flags.f_cf { - if !step { - println!("{}{} 0x{:x}: {} taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_taken(&self.colors.orange, &ins); let addr = match self.get_operand_value(&ins, 0, true) { Some(v) => v, None => break, }; - self.set_eip(addr, true); + if self.cfg.is_64bits { + self.set_rip(addr, true); + } else { + self.set_eip(addr, true); + } break; } else { - if !step { - println!("{}{} 0x{:x}: {} not taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_not_taken(&self.colors.orange, &ins); } } @@ -3613,20 +3901,20 @@ impl Emu { assert!(ins.op_count() == 1); if self.flags.f_cf || self.flags.f_zf { - if !step { - println!("{}{} 0x{:x}: {} taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_taken(&self.colors.orange, &ins); let addr = match self.get_operand_value(&ins, 0, true) { Some(v) => v, None => break, }; - self.set_eip(addr, true); + if self.cfg.is_64bits { + self.set_rip(addr, true); + } else { + self.set_eip(addr, true); + } break; } else { - if !step { - println!("{}{} 0x{:x}: {} not taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_not_taken(&self.colors.orange, &ins); } } @@ -3635,20 +3923,20 @@ impl Emu { assert!(ins.op_count() == 1); if !self.flags.f_cf && !self.flags.f_zf { - if !step { - println!("{}{} 0x{:x}: {} taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_taken(&self.colors.orange, &ins); let addr = match self.get_operand_value(&ins, 0, true) { Some(v) => v, None => break, }; - self.set_eip(addr, true); + if self.cfg.is_64bits { + self.set_rip(addr, true); + } else { + self.set_eip(addr, true); + } break; } else { - if !step { - println!("{}{} 0x{:x}: {} not taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_not_taken(&self.colors.orange, &ins); } } @@ -3657,20 +3945,20 @@ impl Emu { assert!(ins.op_count() == 1); if self.flags.f_sf != self.flags.f_of { - if !step { - println!("{}{} 0x{:x}: {} taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_taken(&self.colors.orange, &ins); let addr = match self.get_operand_value(&ins, 0, true) { Some(v) => v, None => break, }; - self.set_eip(addr, true); + if self.cfg.is_64bits { + self.set_rip(addr, true); + } else { + self.set_eip(addr, true); + } break; } else { - if !step { - println!("{}{} 0x{:x}: {} not taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_not_taken(&self.colors.orange, &ins); } } @@ -3679,20 +3967,20 @@ impl Emu { assert!(ins.op_count() == 1); if self.flags.f_sf == self.flags.f_of { - if !step { - println!("{}{} 0x{:x}: {} taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_taken(&self.colors.orange, &ins); let addr = match self.get_operand_value(&ins, 0, true) { Some(v) => v, None => break, }; - self.set_eip(addr, true); + if self.cfg.is_64bits { + self.set_rip(addr, true); + } else { + self.set_eip(addr, true); + } break; } else { - if !step { - println!("{}{} 0x{:x}: {} not taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_not_taken(&self.colors.orange, &ins); } } @@ -3701,20 +3989,20 @@ impl Emu { assert!(ins.op_count() == 1); if self.flags.f_zf || self.flags.f_sf != self.flags.f_of { - if !step { - println!("{}{} 0x{:x}: {} taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_taken(&self.colors.orange, &ins); let addr = match self.get_operand_value(&ins, 0, true) { Some(v) => v, None => break, }; - self.set_eip(addr, true); + if self.cfg.is_64bits { + self.set_rip(addr, true); + } else { + self.set_eip(addr, true); + } break; } else { - if !step { - println!("{}{} 0x{:x}: {} not taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_not_taken(&self.colors.orange, &ins); } } @@ -3723,20 +4011,20 @@ impl Emu { assert!(ins.op_count() == 1); if !self.flags.f_zf && self.flags.f_sf == self.flags.f_of { - if !step { - println!("{}{} 0x{:x}: {} taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_taken(&self.colors.orange, &ins); let addr = match self.get_operand_value(&ins, 0, true) { Some(v) => v, None => break, }; - self.set_eip(addr, true); + if self.cfg.is_64bits { + self.set_rip(addr, true); + } else { + self.set_eip(addr, true); + } break; } else { - if !step { - println!("{}{} 0x{:x}: {} not taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_not_taken(&self.colors.orange, &ins); } } @@ -3745,20 +4033,20 @@ impl Emu { assert!(ins.op_count() == 1); if self.flags.f_pf { - if !step { - println!("{}{} 0x{:x}: {} taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_taken(&self.colors.orange, &ins); let addr = match self.get_operand_value(&ins, 0, true) { Some(v) => v, None => break, }; - self.set_eip(addr, true); + if self.cfg.is_64bits { + self.set_rip(addr, true); + } else { + self.set_eip(addr, true); + } break; } else { - if !step { - println!("{}{} 0x{:x}: {} not taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_not_taken(&self.colors.orange, &ins); } } @@ -3767,20 +4055,20 @@ impl Emu { assert!(ins.op_count() == 1); if !self.flags.f_pf { - if !step { - println!("{}{} 0x{:x}: {} taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_taken(&self.colors.orange, &ins); let addr = match self.get_operand_value(&ins, 0, true) { Some(v) => v, None => break, }; - self.set_eip(addr, true); + if self.cfg.is_64bits { + self.set_rip(addr, true); + } else { + self.set_eip(addr, true); + } break; } else { - if !step { - println!("{}{} 0x{:x}: {} not taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_not_taken(&self.colors.orange, &ins); } } @@ -3789,20 +4077,20 @@ impl Emu { assert!(ins.op_count() == 1); if self.regs.get_cx() == 0 { - if !step { - println!("{}{} 0x{:x}: {} taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_taken(&self.colors.orange, &ins); let addr = match self.get_operand_value(&ins, 0, true) { Some(v) => v, None => break, }; - self.set_eip(addr, true); + if self.cfg.is_64bits { + self.set_rip(addr, true); + } else { + self.set_eip(addr, true); + } break; } else { - if !step { - println!("{}{} 0x{:x}: {} not taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_not_taken(&self.colors.orange, &ins); } } @@ -3811,137 +4099,123 @@ impl Emu { assert!(ins.op_count() == 1); if self.regs.get_cx() == 0 { - if !step { - println!("{}{} 0x{:x}: {} taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_taken(&self.colors.orange, &ins); let addr = match self.get_operand_value(&ins, 0, true) { Some(v) => v, None => break, }; - self.set_eip(addr, true); + if self.cfg.is_64bits { + self.set_rip(addr, true); + } else { + self.set_eip(addr, true); + } break; } else { - if !step { - println!("{}{} 0x{:x}: {} not taken {}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction_not_taken(&self.colors.orange, &ins); } } Mnemonic::Int3 => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.red, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.red, &ins); println!("/!\\ int 3 sigtrap!!!!"); self.exception(); break; } Mnemonic::Nop => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.light_gray, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.light_gray, &ins); } Mnemonic::Mfence|Mnemonic::Lfence|Mnemonic::Sfence => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.red, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.red, &ins); } Mnemonic::Cpuid => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.red, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.red, &ins); // guloader checks bit31 which is if its hipervisor with command // https://c9x.me/x86/html/file_module_x86_id_45.html // TODO: implement 0x40000000 -> get the virtualization vendor - match self.regs.eax { + match self.regs.rax { 0x00 => { - self.regs.eax = 16; - self.regs.ebx = 0x756e6547; - self.regs.ecx = 0x6c65746e; - self.regs.edx = 0x49656e69; + self.regs.rax = 16; + self.regs.rbx = 0x756e6547; + self.regs.rcx = 0x6c65746e; + self.regs.rdx = 0x49656e69; }, 0x01 => { - self.regs.eax = 0x906ed; - self.regs.ebx = 0x5100800; - self.regs.ecx = 0x7ffafbbf; - self.regs.edx = 0xbfebfbff; + self.regs.rax = 0x906ed; + self.regs.rbx = 0x5100800; + self.regs.rcx = 0x7ffafbbf; + self.regs.rdx = 0xbfebfbff; }, 0x02 => { - self.regs.eax = 0x76036301; - self.regs.ebx = 0xf0b5ff; - self.regs.ecx = 0; - self.regs.edx = 0xc30000; + self.regs.rax = 0x76036301; + self.regs.rbx = 0xf0b5ff; + self.regs.rcx = 0; + self.regs.rdx = 0xc30000; }, 0x03 => { - self.regs.eax = 0; - self.regs.ebx = 0; - self.regs.ecx = 0; - self.regs.edx = 0; + self.regs.rax = 0; + self.regs.rbx = 0; + self.regs.rcx = 0; + self.regs.rdx = 0; }, 0x04 => { - self.regs.eax = 0; - self.regs.ebx = 0x1c0003f; - self.regs.ecx = 0x3f; - self.regs.edx = 0; + self.regs.rax = 0; + self.regs.rbx = 0x1c0003f; + self.regs.rcx = 0x3f; + self.regs.rdx = 0; }, 0x05 => { - self.regs.eax = 0x40; - self.regs.ebx = 0x40; - self.regs.ecx = 3; - self.regs.edx = 0x11142120; + self.regs.rax = 0x40; + self.regs.rbx = 0x40; + self.regs.rcx = 3; + self.regs.rdx = 0x11142120; }, 0x06 => { - self.regs.eax = 0x27f7; - self.regs.ebx = 2; - self.regs.ecx = 9; - self.regs.edx = 0; + self.regs.rax = 0x27f7; + self.regs.rbx = 2; + self.regs.rcx = 9; + self.regs.rdx = 0; }, 0x07..=0x6d => { - self.regs.eax = 0; - self.regs.ebx = 0; - self.regs.ecx = 0; - self.regs.edx = 0; + self.regs.rax = 0; + self.regs.rbx = 0; + self.regs.rcx = 0; + self.regs.rdx = 0; }, 0x6e => { - self.regs.eax = 0x960; - self.regs.ebx = 0x1388; - self.regs.ecx = 0x64; - self.regs.edx = 0; + self.regs.rax = 0x960; + self.regs.rbx = 0x1388; + self.regs.rcx = 0x64; + self.regs.rdx = 0; }, 0x80000000 => { - self.regs.eax = 0x80000008; - self.regs.ebx = 0; - self.regs.ecx = 0; - self.regs.edx = 0; + self.regs.rax = 0x80000008; + self.regs.rbx = 0; + self.regs.rcx = 0; + self.regs.rdx = 0; }, - _ => unimplemented!("unimplemented cpuid call 0x{:x}", self.regs.eax), + _ => unimplemented!("unimplemented cpuid call 0x{:x}", self.regs.rax), } } Mnemonic::Clc => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.light_gray, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.light_gray, &ins); self.flags.f_cf = false; } Mnemonic::Rdtsc => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.red, self.pos, ins.ip32(), out, self.colors.nc); - } - self.regs.edx = 0; - self.regs.eax = 0; + self.show_instruction(&self.colors.red, &ins); + self.regs.rdx = 0; + self.regs.rax = 0; } Mnemonic::Loop => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.yellow, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.yellow, &ins); assert!(ins.op_count() == 1); @@ -3950,15 +4224,31 @@ impl Emu { None => break, }; - if addr > 0xffff { - if self.regs.ecx == 0 { - self.regs.ecx = 0xffffffff; + if addr > 0xffffffff { + if self.regs.rcx == 0 { + self.regs.rcx = 0xffffffffffffffff; } else { - self.regs.ecx -= 1; + self.regs.rcx -= 1; } - if self.regs.ecx > 0 { - self.set_eip(addr, false); + if self.regs.rcx > 0 { + self.set_rip(addr, false); + break; + } + + } else if addr > 0xffff { + if self.regs.get_ecx() == 0 { + self.regs.set_ecx(0xffffffff); + } else { + self.regs.set_ecx(self.regs.get_ecx() - 1); + } + + if self.regs.get_ecx() > 0 { + if self.cfg.is_64bits { + self.set_rip(addr, false); + } else { + self.set_eip(addr, false); + } break; } @@ -3977,9 +4267,7 @@ impl Emu { } Mnemonic::Loope => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.yellow, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.yellow, &ins); assert!(ins.op_count() == 1); @@ -3988,14 +4276,25 @@ impl Emu { None => break, }; - if addr > 0xffff { - if self.regs.ecx == 0 { - self.regs.ecx = 0xffffffff; + if addr > 0xffffffff { + if self.regs.rcx == 0 { + self.regs.rcx = 0xffffffffffffffff; + } else { + self.regs.rcx -= 1; + } + + if self.regs.rcx > 0 && self.flags.f_zf { + self.set_rip(addr, false); + break; + } + } else if addr > 0xffff { + if self.regs.get_ecx() == 0 { + self.regs.set_ecx(0xffffffff); } else { - self.regs.ecx -= 1; + self.regs.set_ecx(self.regs.get_ecx() - 1); } - if self.regs.ecx > 0 && self.flags.f_zf { + if self.regs.get_ecx() > 0 && self.flags.f_zf { self.set_eip(addr, false); break; } @@ -4003,7 +4302,7 @@ impl Emu { if self.regs.get_cx() == 0 { self.regs.set_cx(0xffff); } else { - self.regs.set_cx(self.regs.get_cx() -1); + self.regs.set_cx(self.regs.get_cx() - 1); } if self.regs.get_cx() > 0 && self.flags.f_zf { @@ -4014,9 +4313,7 @@ impl Emu { } Mnemonic::Loopne => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.yellow, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.yellow, &ins); assert!(ins.op_count() == 1); @@ -4024,18 +4321,31 @@ impl Emu { Some(v) => v, None => break, }; - - if addr > 0xffff { - if self.regs.ecx == 0 { - self.regs.ecx = 0xffffffff; + + if addr > 0xffffffff { + if self.regs.rcx == 0 { + self.regs.rcx = 0xffffffffffffffff; + } else { + self.regs.rcx -= 1; + } + + if self.regs.rcx > 0 && !self.flags.f_zf { + self.set_rip(addr, false); + break; + } + + } else if addr > 0xffff { + if self.regs.get_ecx() == 0 { + self.regs.set_ecx(0xffffffff); } else { - self.regs.ecx -= 1; + self.regs.set_ecx(self.regs.get_ecx() - 1); } - if self.regs.ecx > 0 && !self.flags.f_zf { + if self.regs.get_ecx() > 0 && !self.flags.f_zf { self.set_eip(addr, false); break; } + } else { if self.regs.get_cx() == 0 { self.regs.set_cx(0xffff); @@ -4051,9 +4361,7 @@ impl Emu { } Mnemonic::Lea => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.light_cyan, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.light_cyan, &ins); assert!(ins.op_count() == 2); @@ -4068,18 +4376,20 @@ impl Emu { } Mnemonic::Leave => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.red, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.red, &ins); - self.regs.esp = self.regs.ebp; - self.regs.ebp = self.stack_pop(true); + if self.cfg.is_64bits { + self.regs.rsp = self.regs.rbp; + self.regs.rbp = self.stack_pop64(true); + } else { + self.regs.set_esp(self.regs.get_ebp()); + let val = self.stack_pop32(true); + self.regs.set_ebp(val as u64); + } } Mnemonic::Int => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.red, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.red, &ins); assert!(ins.op_count() == 1); @@ -4095,81 +4405,140 @@ impl Emu { } Mnemonic::Std => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.blue, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.blue, &ins); self.flags.f_df = true; } Mnemonic::Cld => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.blue, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.blue, &ins); self.flags.f_df = false; } - Mnemonic::Lodsd => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.cyan, self.pos, ins.ip32(), out, self.colors.nc); - } + Mnemonic::Lodsq => { + self.show_instruction(&self.colors.cyan, &ins); + //TODO: crash if arrive to zero or max value + + if self.cfg.is_64bits { + let val = match self.maps.read_qword(self.regs.rsi) { + Some(v) => v, + None => panic!("lodsw: memory read error"), + }; - let val = match self.maps.read_dword(self.regs.esi) { - Some(v) => v, - None => panic!("lodsw: memory read error"), - }; + self.regs.rax = val; + if self.flags.f_df { + self.regs.rsi -= 4; + } else { + self.regs.rsi += 4; + } - self.regs.eax = val; - if self.flags.f_df { - self.regs.esi -= 4; } else { - self.regs.esi += 4; + unreachable!("lodsq dont exists in 32bit"); } + } + Mnemonic::Lodsd => { + self.show_instruction(&self.colors.cyan, &ins); + //TODO: crash if arrive to zero or max value + + if self.cfg.is_64bits { + let val = match self.maps.read_dword(self.regs.rsi) { + Some(v) => v, + None => panic!("lodsw: memory read error"), + }; + + self.regs.set_eax(val as u64); + if self.flags.f_df { + self.regs.rsi -= 4; + } else { + self.regs.rsi += 4; + } + + } else { + + let val = match self.maps.read_dword(self.regs.get_esi()) { + Some(v) => v, + None => panic!("lodsw: memory read error"), + }; + + self.regs.set_eax(val as u64); + if self.flags.f_df { + self.regs.set_esi(self.regs.get_esi() - 4); + } else { + self.regs.set_esi(self.regs.get_esi() + 4); + } + } } Mnemonic::Lodsw => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.cyan, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.cyan, &ins); + //TODO: crash if arrive to zero or max value + + if self.cfg.is_64bits { + let val = match self.maps.read_word(self.regs.rsi) { + Some(v) => v, + None => panic!("lodsw: memory read error"), + }; - let val = match self.maps.read_word(self.regs.esi) { - Some(v) => v, - None => panic!("lodsw: memory read error"), - }; + self.regs.set_ax(val as u64); + if self.flags.f_df { + self.regs.rsi -= 2; + } else { + self.regs.rsi += 2; + } - self.regs.eax = val as u32; - if self.flags.f_df { - self.regs.esi -= 2; } else { - self.regs.esi += 2; + + let val = match self.maps.read_word(self.regs.get_esi()) { + Some(v) => v, + None => panic!("lodsw: memory read error"), + }; + + self.regs.set_ax(val as u64); + if self.flags.f_df { + self.regs.set_esi(self.regs.get_esi() - 2); + } else { + self.regs.set_esi(self.regs.get_esi() + 2); + } } } Mnemonic::Lodsb => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.cyan, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.cyan, &ins); + //TODO: crash if arrive to zero or max value + + if self.cfg.is_64bits { + let val = match self.maps.read_byte(self.regs.rsi) { + Some(v) => v, + None => panic!("lodsw: memory read error"), + }; - let val = match self.maps.read_byte(self.regs.esi) { - Some(v) => v, - None => panic!("lodsw: memory read error"), - }; + self.regs.set_al(val as u64); + if self.flags.f_df { + self.regs.rsi -= 1; + } else { + self.regs.rsi += 1; + } - self.regs.set_ax(val as u32); - if self.flags.f_df { - self.regs.esi -= 1; } else { - self.regs.esi += 1; + + let val = match self.maps.read_byte(self.regs.get_esi()) { + Some(v) => v, + None => panic!("lodsw: memory read error"), + }; + + self.regs.set_al(val as u64); + if self.flags.f_df { + self.regs.set_esi(self.regs.get_esi() - 1); + } else { + self.regs.set_esi(self.regs.get_esi() + 1); + } } } ///// FPU ///// https://github.com/radare/radare/blob/master/doc/xtra/fpu Mnemonic::Ffree => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } - + self.show_instruction(&self.colors.green, &ins); match ins.op_register(0) { Register::ST0 => self.fpu.clear_st(0), @@ -4183,102 +4552,86 @@ impl Emu { _ => unimplemented!("impossible case"), } - self.fpu.set_eip(self.regs.eip); + self.fpu.set_ip(self.regs.rip); } Mnemonic::Fnstenv => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); let addr = match self.get_operand_value(&ins, 0, false) { Some(v) => v, None => break, }; - let env = self.fpu.get_env(); - for i in 0..4 { - self.maps.write_dword(addr+(i*4), env[i as usize]); + if self.cfg.is_64bits { + todo!("fpu for 64bits") + } else { + let env = self.fpu.get_env32(); + for i in 0..4 { + self.maps.write_dword(addr+(i*4), env[i as usize]); + } } - self.fpu.set_eip(self.regs.eip); + self.fpu.set_ip(self.regs.rip); } Mnemonic::Fld => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); - self.fpu.set_eip(self.regs.eip); + self.fpu.set_ip(self.regs.rip); } Mnemonic::Fldz => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); self.fpu.push(0.0); - self.fpu.set_eip(self.regs.eip); + self.fpu.set_ip(self.regs.rip); } Mnemonic::Fld1 => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); self.fpu.push(1.0); - self.fpu.set_eip(self.regs.eip); + self.fpu.set_ip(self.regs.rip); } Mnemonic::Fldpi => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); self.fpu.push(std::f32::consts::PI); - self.fpu.set_eip(self.regs.eip); + self.fpu.set_ip(self.regs.rip); } Mnemonic::Fldl2t => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); self.fpu.push(10f32.log2()); - self.fpu.set_eip(self.regs.eip); + self.fpu.set_ip(self.regs.rip); } Mnemonic::Fldlg2 => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); self.fpu.push(2f32.log10()); - self.fpu.set_eip(self.regs.eip); + self.fpu.set_ip(self.regs.rip); } Mnemonic::Fldln2 => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); self.fpu.push(2f32.log(std::f32::consts::E)); - self.fpu.set_eip(self.regs.eip); + self.fpu.set_ip(self.regs.rip); } Mnemonic::Fldl2e => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); self.fpu.push(std::f32::consts::E.log2()); - self.fpu.set_eip(self.regs.eip); + self.fpu.set_ip(self.regs.rip); } Mnemonic::Fcmove => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); if self.flags.f_zf { match ins.op_register(0) { @@ -4294,13 +4647,11 @@ impl Emu { } } - self.fpu.set_eip(self.regs.eip); + self.fpu.set_ip(self.regs.rip); } Mnemonic::Fcmovb => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); if self.flags.f_cf { match ins.op_register(0) { @@ -4316,13 +4667,11 @@ impl Emu { } } - self.fpu.set_eip(self.regs.eip); + self.fpu.set_ip(self.regs.rip); } Mnemonic::Fcmovbe => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); if self.flags.f_cf || self.flags.f_zf { match ins.op_register(0) { @@ -4338,13 +4687,11 @@ impl Emu { } } - self.fpu.set_eip(self.regs.eip); + self.fpu.set_ip(self.regs.rip); } Mnemonic::Fcmovu => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); if self.flags.f_pf { match ins.op_register(0) { @@ -4360,13 +4707,11 @@ impl Emu { } } - self.fpu.set_eip(self.regs.eip); + self.fpu.set_ip(self.regs.rip); } Mnemonic::Fcmovnb => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); if !self.flags.f_cf { match ins.op_register(0) { @@ -4382,13 +4727,11 @@ impl Emu { } } - self.fpu.set_eip(self.regs.eip); + self.fpu.set_ip(self.regs.rip); } Mnemonic::Fcmovne => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); if !self.flags.f_zf { match ins.op_register(0) { @@ -4404,13 +4747,11 @@ impl Emu { } } - self.fpu.set_eip(self.regs.eip); + self.fpu.set_ip(self.regs.rip); } Mnemonic::Fcmovnbe => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); if !self.flags.f_cf && !self.flags.f_zf { match ins.op_register(0) { @@ -4426,13 +4767,11 @@ impl Emu { } } - self.fpu.set_eip(self.regs.eip); + self.fpu.set_ip(self.regs.rip); } Mnemonic::Fcmovnu => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); if !self.flags.f_pf { match ins.op_register(0) { @@ -4448,15 +4787,13 @@ impl Emu { } } - self.fpu.set_eip(self.regs.eip); + self.fpu.set_ip(self.regs.rip); } Mnemonic::Popf => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.blue, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.blue, &ins); - let flags:u16 = match self.maps.read_word(self.regs.esp) { + let flags:u16 = match self.maps.read_word(self.regs.rsp) { Some(v) => v, None => { eprintln!("popf cannot read the stack"); @@ -4467,23 +4804,22 @@ impl Emu { let flags2:u32 = (self.flags.dump() & 0xffff0000) + (flags as u32); self.flags.load(flags2); - self.regs.esp += 2; + self.regs.rsp += 2; } Mnemonic::Popfd => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.blue, self.pos, ins.ip32(), out, self.colors.nc); + self.show_instruction(&self.colors.blue, &ins); + + if self.cfg.is_64bits { + todo!("popfd 64bits"); + } else { + let flags = self.stack_pop32(true); + self.flags.load(flags); } - - - let flags = self.stack_pop(true); - self.flags.load(flags); } Mnemonic::Sete => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.orange, &ins); if self.flags.f_zf { self.set_operand_value(&ins, 0, 1); @@ -4491,9 +4827,7 @@ impl Emu { } Mnemonic::Daa => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); let old_al = self.regs.get_al(); let old_cf = self.flags.f_cf; @@ -4523,9 +4857,7 @@ impl Emu { } Mnemonic::Shld => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); let value0 = match self.get_operand_value(&ins, 0, true) { Some(v) => v, @@ -4538,12 +4870,12 @@ impl Emu { }; let counter = match self.get_operand_value(&ins, 2, true) { - Some(v) => v as u16, + Some(v) => v, None => break, }; let sz = self.get_operand_sz(&ins, 0); - let result = self.shld(value0, value1, counter, sz as u32); + let result = self.shld(value0, value1, counter, sz); //println!("0x{:x} SHLD 0x{:x}, 0x{:x}, 0x{:x} = 0x{:x}", ins.ip32(), value0, value1, counter, result); @@ -4553,9 +4885,7 @@ impl Emu { } Mnemonic::Shrd => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); let value0 = match self.get_operand_value(&ins, 0, true) { Some(v) => v, @@ -4568,12 +4898,12 @@ impl Emu { }; let counter = match self.get_operand_value(&ins, 2, true) { - Some(v) => v as u16, + Some(v) => v, None => break, }; let sz = self.get_operand_sz(&ins, 0); - let result = self.shrd(value0, value1, counter, sz as u32); + let result = self.shrd(value0, value1, counter, sz); //println!("0x{:x} SHRD 0x{:x}, 0x{:x}, 0x{:x} = 0x{:x}", ins.ip32(), value0, value1, counter, result); @@ -4584,7 +4914,7 @@ impl Emu { Mnemonic::Sysenter => { - println!("{}{} 0x{:x}: {}{}", self.colors.red, self.pos, ins.ip32(), out, self.colors.nc); + println!("{}{} 0x{:x}: {}{}", self.colors.red, self.pos, ins.ip32(), self.out, self.colors.nc); return; } @@ -4597,9 +4927,7 @@ impl Emu { Mnemonic::Pxor => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); assert!(ins.op_count() == 2); @@ -4607,15 +4935,13 @@ impl Emu { let value1 = self.get_operand_xmm_value_128(&ins, 0, true).expect("error getting xmm value1"); let result:u128 = value0 ^ value1; - self.flags.calc_flags(result as u32, 32); + self.flags.calc_flags(result as u64, 32); self.set_operand_xmm_value_128(&ins, 0, result); } Mnemonic::Xorps => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); let value0 = self.get_operand_xmm_value_128(&ins, 0, true).expect("error getting value0"); let value1 = self.get_operand_xmm_value_128(&ins, 1, true).expect("error getting velue1"); @@ -4631,9 +4957,7 @@ impl Emu { } Mnemonic::Xorpd => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); let value0 = self.get_operand_xmm_value_128(&ins, 0, true).expect("error getting value0"); let value1 = self.get_operand_xmm_value_128(&ins, 1, true).expect("error getting velue1"); @@ -4648,9 +4972,7 @@ impl Emu { // movlpd: packed double, movlps: packed simple, cvtsi2sd: int to scalar double 32b to 64b, // cvtsi2ss: int to scalar single copy 32b to 32b, movd: doubleword move Mnemonic::Movlpd | Mnemonic::Movlps | Mnemonic::Cvtsi2sd | Mnemonic::Cvtsi2ss | Mnemonic::Movd => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.cyan, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.cyan, &ins); let sz0 = self.get_operand_sz(&ins, 0); let sz1 = self.get_operand_sz(&ins, 1); @@ -4665,7 +4987,7 @@ impl Emu { } else if sz0 == 32 && sz1 == 128 { let value1 = self.get_operand_xmm_value_128(&ins, 1, true).expect("error getting xmm value1"); - self.set_operand_value(&ins, 0, value1 as u32); + self.set_operand_value(&ins, 0, value1 as u64); } else if sz0 == 128 && sz1 == 64 { let addr = self.get_operand_value(&ins, 1, false).expect("error getting the address"); @@ -4674,7 +4996,7 @@ impl Emu { } else if sz0 == 64 && sz1 == 128 { let value1 = self.get_operand_xmm_value_128(&ins, 1, true).expect("error getting xmm value"); - self.set_operand_value(&ins, 0, value1 as u32); + self.set_operand_value(&ins, 0, value1 as u64); } else { panic!("SSE with other size combinations sz0:{} sz1:{}", sz0, sz1); @@ -4682,9 +5004,7 @@ impl Emu { } Mnemonic::Andpd => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); let value0 = self.get_operand_xmm_value_128(&ins, 0, true).expect("error getting value0"); let value1 = self.get_operand_xmm_value_128(&ins, 1, true).expect("error getting velue1"); @@ -4695,9 +5015,7 @@ impl Emu { } Mnemonic::Orpd => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); let value0 = self.get_operand_xmm_value_128(&ins, 0, true).expect("error getting value0"); let value1 = self.get_operand_xmm_value_128(&ins, 1, true).expect("error getting velue1"); @@ -4708,9 +5026,7 @@ impl Emu { } Mnemonic::Addps => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); let value0 = self.get_operand_xmm_value_128(&ins, 0, true).expect("error getting value0"); let value1 = self.get_operand_xmm_value_128(&ins, 1, true).expect("error getting velue1"); @@ -4726,9 +5042,7 @@ impl Emu { } Mnemonic::Addpd => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); let value0 = self.get_operand_xmm_value_128(&ins, 0, true).expect("error getting value0"); let value1 = self.get_operand_xmm_value_128(&ins, 1, true).expect("error getting velue1"); @@ -4741,9 +5055,7 @@ impl Emu { } Mnemonic::Addsd => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); let value0 = self.get_operand_xmm_value_128(&ins, 0, true).expect("error getting value0"); let value1 = self.get_operand_xmm_value_128(&ins, 1, true).expect("error getting velue1"); @@ -4754,9 +5066,7 @@ impl Emu { } Mnemonic::Addss => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); let value0 = self.get_operand_xmm_value_128(&ins, 0, true).expect("error getting value0"); let value1 = self.get_operand_xmm_value_128(&ins, 1, true).expect("error getting velue1"); @@ -4767,9 +5077,7 @@ impl Emu { } Mnemonic::Subps => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); let value0 = self.get_operand_xmm_value_128(&ins, 0, true).expect("error getting value0"); let value1 = self.get_operand_xmm_value_128(&ins, 1, true).expect("error getting velue1"); @@ -4785,9 +5093,7 @@ impl Emu { } Mnemonic::Subpd => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); let value0 = self.get_operand_xmm_value_128(&ins, 0, true).expect("error getting value0"); let value1 = self.get_operand_xmm_value_128(&ins, 1, true).expect("error getting velue1"); @@ -4800,9 +5106,7 @@ impl Emu { } Mnemonic::Subsd => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); let value0 = self.get_operand_xmm_value_128(&ins, 0, true).expect("error getting value0"); let value1 = self.get_operand_xmm_value_128(&ins, 1, true).expect("error getting velue1"); @@ -4813,9 +5117,7 @@ impl Emu { } Mnemonic::Subss => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); let value0 = self.get_operand_xmm_value_128(&ins, 0, true).expect("error getting value0"); let value1 = self.get_operand_xmm_value_128(&ins, 1, true).expect("error getting velue1"); @@ -4826,9 +5128,7 @@ impl Emu { } Mnemonic::Mulpd => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); let value0 = self.get_operand_xmm_value_128(&ins, 0, true).expect("error getting value0"); let value1 = self.get_operand_xmm_value_128(&ins, 1, true).expect("error getting velue1"); @@ -4841,9 +5141,7 @@ impl Emu { } Mnemonic::Mulps => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); let value0 = self.get_operand_xmm_value_128(&ins, 0, true).expect("error getting value0"); let value1 = self.get_operand_xmm_value_128(&ins, 1, true).expect("error getting velue1"); @@ -4859,9 +5157,7 @@ impl Emu { } Mnemonic::Mulsd => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); let value0 = self.get_operand_xmm_value_128(&ins, 0, true).expect("error getting value0"); let value1 = self.get_operand_xmm_value_128(&ins, 1, true).expect("error getting velue1"); @@ -4872,9 +5168,7 @@ impl Emu { } Mnemonic::Mulss => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); let value0 = self.get_operand_xmm_value_128(&ins, 0, true).expect("error getting value0"); let value1 = self.get_operand_xmm_value_128(&ins, 1, true).expect("error getting velue1"); @@ -4888,9 +5182,7 @@ impl Emu { Mnemonic::Arpl => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.orange, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.green, &ins); let value0 = match self.get_operand_value(&ins, 0, true) { Some(v) => v, @@ -4908,51 +5200,41 @@ impl Emu { } Mnemonic::Pushf => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.blue, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.blue, &ins); let val:u16 = (self.flags.dump() & 0xffff) as u16; - self.regs.esp -= 2; + self.regs.rsp -= 2; - if !self.maps.write_word(self.regs.esp, val) { + if !self.maps.write_word(self.regs.rsp, val) { self.exception(); break; } } Mnemonic::Pushfd => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.blue, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.blue, &ins); let flags = self.flags.dump(); - self.stack_push(flags); + self.stack_push32(flags); } Mnemonic::Bound => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.red, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.red, &ins); let val0_src = self.get_operand_value(&ins, 0, true); } Mnemonic::Lahf => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.red, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.red, &ins); - self.regs.set_ah(self.flags.dump() & 0xff); + self.regs.set_ah((self.flags.dump() & 0xff).into()); } Mnemonic::Salc => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.red, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.red, &ins); if self.flags.f_cf { self.regs.set_al(1); @@ -4965,38 +5247,43 @@ impl Emu { //// Ring0 //// Mnemonic::Rdmsr => { - if !step { - println!("{}{} 0x{:x}: {}{}", self.colors.green, self.pos, ins.ip32(), out, self.colors.nc); - } + self.show_instruction(&self.colors.red, &ins); - match self.regs.ecx { + match self.regs.rcx { 0x176 => { - self.regs.edx = 0; - self.regs.eax = self.cfg.code_base_addr + 0x42; + self.regs.rdx = 0; + self.regs.rax = self.cfg.code_base_addr + 0x42; }, - _ => unimplemented!("/!\\ unimplemented rdmsr with value {}", self.regs.ecx), + _ => unimplemented!("/!\\ unimplemented rdmsr with value {}", self.regs.rcx), } } - _ => { - println!("{}{} 0x{:x}: {}{}", self.colors.red, self.pos, ins.ip32(), out, self.colors.nc); + _ => { + if self.cfg.is_64bits { + println!("{}{} 0x{:x}: {}{}", self.colors.red, self.pos, ins.ip(), self.out, self.colors.nc); + } else { + println!("{}{} 0x{:x}: {}{}", self.colors.red, self.pos, ins.ip32(), self.out, self.colors.nc); + } self.exception(); //unimplemented!("unimplemented instruction"); }, - } - self.regs.eip += sz as u32; + } // end mnemonics + + if self.cfg.is_64bits { + self.regs.rip += sz as u64; + } else { + self.regs.set_eip(self.regs.get_eip() + sz as u64); + } if self.force_break { self.force_break = false; break; } - } - } - - - } + } // end decoder + } // end loop + } // end run } diff --git a/src/emu/breakpoint.rs b/src/emu/breakpoint.rs index ed0c85e..94451f4 100644 --- a/src/emu/breakpoint.rs +++ b/src/emu/breakpoint.rs @@ -1,8 +1,8 @@ pub struct Breakpoint { - addr:u32, - mem_read_addr:u32, - mem_write_addr:u32, + addr:u64, + mem_read_addr:u64, + mem_write_addr:u64, } impl Breakpoint { @@ -14,7 +14,7 @@ impl Breakpoint { } } - pub fn set_bp(&mut self, addr:u32) { + pub fn set_bp(&mut self, addr:u64) { self.addr = addr; } @@ -24,23 +24,23 @@ impl Breakpoint { self.mem_write_addr = 0; } - pub fn set_mem_read(&mut self, addr:u32) { + pub fn set_mem_read(&mut self, addr:u64) { self.mem_read_addr = addr; } - pub fn set_mem_write(&mut self, addr:u32) { + pub fn set_mem_write(&mut self, addr:u64) { self.mem_write_addr = addr; } - pub fn get_bp(&self) -> u32 { + pub fn get_bp(&self) -> u64 { return self.addr; } - pub fn get_mem_read(&self) -> u32 { + pub fn get_mem_read(&self) -> u64 { return self.mem_read_addr; } - pub fn get_mem_write(&self) -> u32 { + pub fn get_mem_write(&self) -> u64 { return self.mem_write_addr; } -} \ No newline at end of file +} diff --git a/src/emu/console.rs b/src/emu/console.rs index d1e7901..d170ab3 100644 --- a/src/emu/console.rs +++ b/src/emu/console.rs @@ -26,7 +26,7 @@ impl Console { line.to_lowercase() } - pub fn cmd_hex(&self) -> Result { + pub fn cmd_hex32(&self) -> Result { let mut x = self.cmd(); if x.ends_with('h') { @@ -51,10 +51,15 @@ impl Console { return u64::from_str_radix(x.as_str(), 16); } - pub fn cmd_num(&self) -> Result { - self.cmd().as_str().parse::() + pub fn cmd_num(&self) -> Result { + u64::from_str_radix(self.cmd().as_str(), 16) } +/* + pub fn cmd_num(&self) -> Result { + self.cmd().as_str().parse::() + }*/ + pub fn help(&self) { println!("--- help ---"); println!("q ...................... quit"); diff --git a/src/emu/constants.rs b/src/emu/constants.rs index 150c10f..b305dd1 100644 --- a/src/emu/constants.rs +++ b/src/emu/constants.rs @@ -1,18 +1,18 @@ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55 #![allow(dead_code)] -pub const STATUS_SUCCESS:u32 = 0x00000000; -pub const STATUS_ACCESS_DENIED:u32 = 0xC0000022; -pub const STATUS_INVALID_HANDLE:u32 = 0xC0000008; -pub const STATUS_NO_MEMORY:u32 = 0xC0000017; -pub const STATUS_ACCESS_VIOLATION:u32 = 0xC0000005; -pub const STATUS_INVALID_PARAMETER:u32 = 0xC000000D; +pub const STATUS_SUCCESS:u64 = 0x00000000; +pub const STATUS_ACCESS_DENIED:u64 = 0xC0000022; +pub const STATUS_INVALID_HANDLE:u64 = 0xC0000008; +pub const STATUS_NO_MEMORY:u64 = 0xC0000017; +pub const STATUS_ACCESS_VIOLATION:u64 = 0xC0000005; +pub const STATUS_INVALID_PARAMETER:u64 = 0xC000000D; pub const NUM_BYTES_TRACE:usize = 16; -pub const VERSION:u32 = 0x1db10106; +pub const VERSION:u64 = 0x1db10106; -pub const WAIT_TIMEOUT:u32 = 0x00000102; -pub const WAIT_FAILED:u32 = 0xFFFFFFFF; +pub const WAIT_TIMEOUT:u64 = 0x00000102; +pub const WAIT_FAILED:u64 = 0xFFFFFFFF; //vectored exception handler pub const CALL_FIRST:u32 = 1; @@ -44,11 +44,11 @@ pub const INTERNET_OPTION_DATA_RECEIVE_TIMEOUT:u32 = 8; pub const INTERNET_OPTION_DATA_SEND_TIMEOUT:u32 = 7; // https://docs.microsoft.com/en-us/windows/win32/wininet/api-flags -pub const INTERNET_FLAG_SECURE:u32 = 0x00800000; +pub const INTERNET_FLAG_SECURE:u64 = 0x00800000; -pub const ERROR_NO_MORE_FILES:u32 = 18; -pub const CREATE_SUSPENDED:u32 = 0x00000004; -pub const EXCEPTION_EXECUTE_HANDLER:u32 = 1; +pub const ERROR_NO_MORE_FILES:u64 = 18; +pub const CREATE_SUSPENDED:u64 = 0x00000004; +pub const EXCEPTION_EXECUTE_HANDLER:u64 = 1; pub const PAGE_NOACCESS:u32 = 0x01; pub const PAGE_EXECUTE:u32 = 0x00; @@ -66,41 +66,41 @@ pub const MEM_PRIVATE:u32 = 0x20000; //// LINUX //// -pub const ENOTSOCK:u32 = -1i32 as u32; /* not open sock */ -pub const EPERM:u32 = -1i32 as u32; /* permissions error */ -pub const ENOENT:u32 = -2i32 as u32; /* No such file or directory */ -pub const ESRCH:u32 = -3i32 as u32; /* No such process */ -pub const EINTR:u32 = -4i32 as u32; /* Interrupted system call */ -pub const EIO:u32 = -5i32 as u32; /* I/O error */ -pub const ENXIO:u32 = -6i32 as u32; /* No such device or address */ -pub const E2BIG:u32 = -7i32 as u32; /* Argument list too long */ -pub const ENOEXEC:u32 = -8i32 as u32; /* Exec format error */ -pub const EBADF:u32 = -9i32 as u32; /* Bad file number */ -pub const ECHILD:u32 = -10i32 as u32; /* No child processes */ -pub const EAGAIN:u32 = -11i32 as u32; /* Try again */ -pub const ENOMEM:u32 = -12i32 as u32; /* Out of memory */ -pub const EACCES:u32 = -13i32 as u32; /* Permission denied */ -pub const EFAULT:u32 = -14i32 as u32; /* Bad address */ -pub const ENOTBLK:u32 = -15i32 as u32; /* Block device required */ -pub const EBUSY:u32 = -16i32 as u32; /* Device or resource busy */ -pub const EEXIST:u32 = -17i32 as u32; /* File exists */ -pub const EXDEV:u32 = -18i32 as u32; /* Cross-device link */ -pub const ENODEV:u32 = -19i32 as u32; /* No such device */ -pub const ENOTDIR:u32 = -20i32 as u32; /* Not a directory */ -pub const EISDIR:u32 = -21i32 as u32; /* Is a directory */ -pub const EINVAL:u32 = -22i32 as u32; /* Invalid argument */ -pub const ENFILE:u32 = -23i32 as u32; /* File table overflow */ -pub const EMFILE:u32 = -24i32 as u32; /* Too many open files */ -pub const ENOTTY:u32 = -25i32 as u32; /* Not a typewriter */ -pub const ETXTBSY:u32 = -26i32 as u32; /* Text file busy */ -pub const EFBIG:u32 = -27i32 as u32; /* File too large */ -pub const ENOSPC:u32 = -28i32 as u32; /* No space left on device */ -pub const ESPIPE:u32 = -29i32 as u32; /* Illegal seek */ -pub const EROFS:u32 = -30i32 as u32; /* Read-only file system */ -pub const EMLINK:u32 = -31i32 as u32; /* Too many links */ -pub const EPIPE:u32 = -32i32 as u32; /* Broken pipe */ -pub const EDOM:u32 = -33i32 as u32; /* Math argument out of domain of func */ -pub const ERANGE:u32 = -34i32 as u32; /* Math result not representable */ +pub const ENOTSOCK:u64 = -1i64 as u64; /* not open sock */ +pub const EPERM:u64 = -1i64 as u64; /* permissions error */ +pub const ENOENT:u64 = -2i64 as u64; /* No such file or directory */ +pub const ESRCH:u64 = -3i64 as u64; /* No such process */ +pub const EINTR:u64 = -4i64 as u64; /* Interrupted system call */ +pub const EIO:u64 = -5i64 as u64; /* I/O error */ +pub const ENXIO:u64 = -6i64 as u64; /* No such device or address */ +pub const E2BIG:u64 = -7i64 as u64; /* Argument list too long */ +pub const ENOEXEC:u64 = -8i64 as u64; /* Exec format error */ +pub const EBADF:u64 = -9i64 as u64; /* Bad file number */ +pub const ECHILD:u64 = -10i64 as u64; /* No child processes */ +pub const EAGAIN:u64 = -11i64 as u64; /* Try again */ +pub const ENOMEM:u64 = -12i64 as u64; /* Out of memory */ +pub const EACCES:u64 = -13i64 as u64; /* Permission denied */ +pub const EFAULT:u64 = -14i64 as u64; /* Bad address */ +pub const ENOTBLK:u64 = -15i64 as u64; /* Block device required */ +pub const EBUSY:u64 = -16i64 as u64; /* Device or resource busy */ +pub const EEXIST:u64 = -17i64 as u64; /* File exists */ +pub const EXDEV:u64 = -18i64 as u64; /* Cross-device link */ +pub const ENODEV:u64 = -19i64 as u64; /* No such device */ +pub const ENOTDIR:u64 = -20i64 as u64; /* Not a directory */ +pub const EISDIR:u64 = -21i64 as u64; /* Is a directory */ +pub const EINVAL:u64 = -22i64 as u64; /* Invalid argument */ +pub const ENFILE:u64 = -23i64 as u64; /* File table overflow */ +pub const EMFILE:u64 = -24i64 as u64; /* Too many open files */ +pub const ENOTTY:u64 = -25i64 as u64; /* Not a typewriter */ +pub const ETXTBSY:u64 = -26i64 as u64; /* Text file busy */ +pub const EFBIG:u64 = -27i64 as u64; /* File too large */ +pub const ENOSPC:u64 = -28i64 as u64; /* No space left on device */ +pub const ESPIPE:u64 = -29i64 as u64; /* Illegal seek */ +pub const EROFS:u64 = -30i64 as u64; /* Read-only file system */ +pub const EMLINK:u64 = -31i64 as u64; /* Too many links */ +pub const EPIPE:u64 = -32i64 as u64; /* Broken pipe */ +pub const EDOM:u64 = -33i64 as u64; /* Math argument out of domain of func */ +pub const ERANGE:u64 = -34i64 as u64; /* Math result not representable */ diff --git a/src/emu/context32.rs b/src/emu/context32.rs index f0a61c5..d94eeb0 100644 --- a/src/emu/context32.rs +++ b/src/emu/context32.rs @@ -1,5 +1,5 @@ use crate::emu::fpu::FPU; -use crate::emu::regs32::Regs32; +use crate::emu::regs64::Regs64; use crate::emu::maps::Maps; pub struct Context32 { @@ -30,7 +30,7 @@ pub struct Context32 { } impl Context32 { - pub fn new(regs:&Regs32) -> Context32 { + pub fn new(regs:&Regs64) -> Context32 { Context32 { ctx_flags: 0, dr0: 0, @@ -44,69 +44,69 @@ impl Context32 { seg_fd: 0, seg_es: 0, seg_ds: 0, - edi: regs.edi, - esi: regs.esi, - ebx: regs.ebx, - edx: regs.edx, - ecx: regs.ecx, - eax: regs.eax, - ebp: regs.ebp, - eip: regs.eip, + edi: regs.get_edi() as u32, + esi: regs.get_esi() as u32, + ebx: regs.get_ebx() as u32, + edx: regs.get_edx() as u32, + ecx: regs.get_ecx() as u32, + eax: regs.get_eax() as u32, + ebp: regs.get_ebp() as u32, + eip: regs.get_eip() as u32, seg_cs: 0, eflags: 0, - esp: regs.esp, + esp: regs.get_esp() as u32, seg_ss: 0, } } pub fn save(&self, addr:u32, maps:&mut Maps) { - maps.write_dword(addr+4, self.dr0); - maps.write_dword(addr+8, self.dr1); - maps.write_dword(addr+12, self.dr2); - maps.write_dword(addr+16, self.dr3); - maps.write_dword(addr+20, self.dr6); - maps.write_dword(addr+24, self.dr7); + maps.write_dword((addr+4) as u64, self.dr0); + maps.write_dword((addr+8) as u64, self.dr1); + maps.write_dword((addr+12) as u64, self.dr2); + maps.write_dword((addr+16) as u64, self.dr3); + maps.write_dword((addr+20) as u64, self.dr6); + maps.write_dword((addr+24) as u64, self.dr7); - maps.write_dword(addr+0x9c, self.edi); - maps.write_dword(addr+0xa0, self.esi); - maps.write_dword(addr+0xa4, self.ebx); - maps.write_dword(addr+0xa8, self.edx); - maps.write_dword(addr+0xac, self.ecx); - maps.write_dword(addr+0xb0, self.eax); - maps.write_dword(addr+0xb4, self.ebp); - maps.write_dword(addr+0xb8, self.eip); - maps.write_dword(addr+0xc4, self.esp); + maps.write_dword((addr+0x9c) as u64, self.edi); + maps.write_dword((addr+0xa0) as u64, self.esi); + maps.write_dword((addr+0xa4) as u64, self.ebx); + maps.write_dword((addr+0xa8) as u64, self.edx); + maps.write_dword((addr+0xac) as u64, self.ecx); + maps.write_dword((addr+0xb0) as u64, self.eax); + maps.write_dword((addr+0xb4) as u64, self.ebp); + maps.write_dword((addr+0xb8) as u64, self.eip); + maps.write_dword((addr+0xc4) as u64, self.esp); } pub fn load(&mut self, addr:u32, maps:&mut Maps) { - self.dr0 = maps.read_dword(addr+4).expect("cannot read dr0 from ctx"); - self.dr1 = maps.read_dword(addr+8).expect("cannot read dr1 from ctx"); - self.dr2 = maps.read_dword(addr+12).expect("cannot read dr2 from ctx"); - self.dr3 = maps.read_dword(addr+16).expect("cannot read dr3 from ctx"); - self.dr6 = maps.read_dword(addr+20).expect("cannot read dr6 from ctx"); - self.dr7 = maps.read_dword(addr+24).expect("cannot read dr7 from ctx"); + self.dr0 = maps.read_dword((addr+4) as u64).expect("cannot read dr0 from ctx"); + self.dr1 = maps.read_dword((addr+8) as u64).expect("cannot read dr1 from ctx"); + self.dr2 = maps.read_dword((addr+12) as u64).expect("cannot read dr2 from ctx"); + self.dr3 = maps.read_dword((addr+16) as u64).expect("cannot read dr3 from ctx"); + self.dr6 = maps.read_dword((addr+20) as u64).expect("cannot read dr6 from ctx"); + self.dr7 = maps.read_dword((addr+24) as u64).expect("cannot read dr7 from ctx"); - self.edi = maps.read_dword(addr+0x9c).expect("cannot read edi from ctx"); - self.esi = maps.read_dword(addr+0xa0).expect("cannot read esi from ctx"); - self.ebx = maps.read_dword(addr+0xa4).expect("cannot read ebx from ctx"); - self.edx = maps.read_dword(addr+0xa8).expect("cannot read edx from ctx"); - self.ecx = maps.read_dword(addr+0xac).expect("cannot read ecx from ctx"); - self.eax = maps.read_dword(addr+0xb0).expect("cannot read eax from ctx"); - self.ebp = maps.read_dword(addr+0xb4).expect("cannot read ebp from ctx"); - self.eip = maps.read_dword(addr+0xb8).expect("cannot read eip from ctx"); - self.esp = maps.read_dword(addr+0xc4).expect("cannot read esp from ctx"); + self.edi = maps.read_dword((addr+0x9c) as u64).expect("cannot read edi from ctx"); + self.esi = maps.read_dword((addr+0xa0) as u64).expect("cannot read esi from ctx"); + self.ebx = maps.read_dword((addr+0xa4) as u64).expect("cannot read ebx from ctx"); + self.edx = maps.read_dword((addr+0xa8) as u64).expect("cannot read edx from ctx"); + self.ecx = maps.read_dword((addr+0xac) as u64).expect("cannot read ecx from ctx"); + self.eax = maps.read_dword((addr+0xb0) as u64).expect("cannot read eax from ctx"); + self.ebp = maps.read_dword((addr+0xb4) as u64).expect("cannot read ebp from ctx"); + self.eip = maps.read_dword((addr+0xb8) as u64).expect("cannot read eip from ctx"); + self.esp = maps.read_dword((addr+0xc4) as u64).expect("cannot read esp from ctx"); } - pub fn sync(&self, regs:&mut Regs32) { - regs.eax = self.eax; - regs.ebx = self.ebx; - regs.ecx = self.ecx; - regs.edx = self.edx; - regs.esi = self.esi; - regs.edi = self.edi; - regs.esp = self.esp; - regs.ebp = self.ebp; - regs.eip = self.eip; + pub fn sync(&self, regs:&mut Regs64) { + regs.set_eax(self.eax as u64); + regs.set_ebx(self.ebx as u64); + regs.set_ecx(self.ecx as u64); + regs.set_edx(self.edx as u64); + regs.set_esi(self.esi as u64); + regs.set_edi(self.edi as u64); + regs.set_esp(self.esp as u64); + regs.set_ebp(self.ebp as u64); + regs.set_eip(self.eip as u64); } } diff --git a/src/emu/exception.rs b/src/emu/exception.rs index 51abbc1..0271a6f 100644 --- a/src/emu/exception.rs +++ b/src/emu/exception.rs @@ -2,8 +2,8 @@ use crate::emu; use crate::emu::context32::Context32; pub fn enter(emu: &mut emu::Emu) { - emu.stack_push(0x10f00); - emu.stack_push(emu.regs.eip); + emu.stack_push32(0x10f00); + emu.stack_push32(emu.regs.get_eip() as u32); emu.eh_ctx = 0x10f08; emu.maps.write_dword(0x10f04, emu.eh_ctx); diff --git a/src/emu/flags.rs b/src/emu/flags.rs index 58983d9..6bab2b9 100644 --- a/src/emu/flags.rs +++ b/src/emu/flags.rs @@ -13,6 +13,10 @@ pub const MAX_I32:i32 = 0x7fffffff; pub const MIN_U32:u32 = 0; pub const MAX_U32:u32 = 0xffffffff; +pub const MIN_I64:i64 = -9223372036854775808; +pub const MAX_I64:i64 = 0x7fffffffffffffff; +pub const MIN_U64:u64 = 0; +pub const MAX_U64:u64 = 0xffffffffffffffff; pub struct Flags { pub f_cf: bool, @@ -106,11 +110,11 @@ impl Flags { - pub fn check_carry_sub_byte(&mut self, a:u32, b:u32) { + pub fn check_carry_sub_byte(&mut self, a:u64, b:u64) { self.f_cf = (b as u8) > (a as u8); } - pub fn check_overflow_sub_byte(&mut self, a:u32, b:u32) -> i8 { + pub fn check_overflow_sub_byte(&mut self, a:u64, b:u64) -> i8 { let cf = false; let rs:i16; @@ -125,11 +129,11 @@ impl Flags { (((rs as u16) & 0xff) as u8) as i8 } - pub fn check_carry_sub_word(&mut self, a:u32, b:u32) { + pub fn check_carry_sub_word(&mut self, a:u64, b:u64) { self.f_cf = (b as u16) > (a as u16); } - pub fn check_overflow_sub_word(&mut self, a:u32, b:u32) -> i16 { + pub fn check_overflow_sub_word(&mut self, a:u64, b:u64) -> i16 { let cf = false; let rs:i32; @@ -143,11 +147,29 @@ impl Flags { (((rs as u32) & 0xffff) as u16) as i16 } - pub fn check_carry_sub_dword(&mut self, a:u32, b:u32) { + pub fn check_carry_sub_qword(&mut self, a:u64, b:u64) { + self.f_cf = b > a; + } + + pub fn check_carry_sub_dword(&mut self, a:u64, b:u64) { self.f_cf = (b as u32) > (a as u32); } - pub fn check_overflow_sub_dword(&mut self, a:u32, b:u32) -> i32 { + pub fn check_overflow_sub_qword(&mut self, a:u64, b:u64) -> i64 { + let cf = false; + let rs:i128; + + if cf { + rs = (a as i64) as i128 - (b as i64) as i128 - 1; + } else { + rs = (a as i64) as i128 - (b as i64) as i128; + } + + self.f_of = rs < MIN_I64 as i128 || rs > MAX_I64 as i128; + (((rs as u128) & 0xffffffff) as u64) as i64 + } + + pub fn check_overflow_sub_dword(&mut self, a:u64, b:u64) -> i32 { let cf = false; let rs:i64; @@ -162,9 +184,10 @@ impl Flags { } - pub fn calc_flags(&mut self, final_value:u32, bits:u8) { + pub fn calc_flags(&mut self, final_value:u64, bits:u8) { match bits { + 64 => self.f_sf = (final_value as i64) < 0, 32 => self.f_sf = (final_value as i32) < 0, 16 => self.f_sf = (final_value as i16) < 0, 8 => self.f_sf = (final_value as i8) < 0, @@ -178,9 +201,20 @@ impl Flags { + pub fn add64(&mut self, value1:u64, value2:u64) -> u64 { + let unsigned:u128 = value1 as u128 + value2 as u128; + + self.f_sf = (unsigned as i64) < 0; + self.f_zf = unsigned == 0; + self.f_pf = (unsigned & 0xff) % 2 == 0; + self.f_of = (value1 as i64) > 0 && (unsigned as i64) < 0; + self.f_cf = unsigned > 0xffffffff; + + (unsigned & 0xffffffff) as u64 + } - pub fn add32(&mut self, value1:u32, value2:u32) -> u32 { - let unsigned:u64 = value1 as u64 + value2 as u64; + pub fn add32(&mut self, value1:u64, value2:u64) -> u64 { + let unsigned:u64 = value1 + value2; self.f_sf = (unsigned as i32) < 0; self.f_zf = unsigned == 0; @@ -188,10 +222,10 @@ impl Flags { self.f_of = (value1 as i32) > 0 && (unsigned as i32) < 0; self.f_cf = unsigned > 0xffffffff; - (unsigned & 0xffffffff) as u32 + unsigned & 0xffffffff } - pub fn add16(&mut self, value1:u32, value2:u32) -> u32 { + pub fn add16(&mut self, value1:u64, value2:u64) -> u64 { if value1 > 0xffff || value2 > 0xffff { panic!("add16 with a bigger precision"); } @@ -204,10 +238,10 @@ impl Flags { self.f_of = (value1 as i16) > 0 && (unsigned as i16) < 0; self.f_cf = unsigned > 0xffff; - (unsigned & 0xffff) as u32 + (unsigned & 0xffff) as u64 } - pub fn add8(&mut self, value1:u32, value2:u32) -> u32 { + pub fn add8(&mut self, value1:u64, value2:u64) -> u64 { if value1 > 0xff || value2 > 0xff { panic!("add8 with a bigger precision"); } @@ -220,12 +254,24 @@ impl Flags { self.f_of = (value1 as i8) > 0 && (unsigned as i8) < 0; self.f_cf = unsigned > 0xff; - (unsigned & 0xff) as u32 + (unsigned & 0xff) as u64 } - pub fn sub32(&mut self, value1:u32, value2:u32) -> u32 { - let r:i32; + pub fn sub64(&mut self, value1:u64, value2:u64) -> u64 { + let r:i64; + + self.check_carry_sub_qword(value1, value2); + r = self.check_overflow_sub_qword(value1, value2); + self.f_zf = value1 == value2; + self.f_sf = r < 0; + self.f_pf = ((r as u64) & 0xff) % 2 == 0; + + r as u64 + } + + pub fn sub32(&mut self, value1:u64, value2:u64) -> u64 { + let r:i32; self.check_carry_sub_dword(value1, value2); r = self.check_overflow_sub_dword(value1, value2); @@ -234,13 +280,12 @@ impl Flags { self.f_sf = r < 0; self.f_pf = ((r as u32) & 0xff) % 2 == 0; - r as u32 + r as u64 } - pub fn sub16(&mut self, value1:u32, value2:u32) -> u32 { + pub fn sub16(&mut self, value1:u64, value2:u64) -> u64 { let r:i16; - self.check_carry_sub_word(value1, value2); r = self.check_overflow_sub_word(value1, value2); self.f_zf = value1 == value2; @@ -248,10 +293,10 @@ impl Flags { self.f_sf = r < 0; self.f_pf = ((r as u16) & 0xff) % 2 == 0; - (r as u16) as u32 + (r as u16) as u64 } - pub fn sub8(&mut self, value1:u32, value2:u32) -> u32 { + pub fn sub8(&mut self, value1:u64, value2:u64) -> u64 { let r:i8; self.check_carry_sub_byte(value1, value2); @@ -260,10 +305,24 @@ impl Flags { self.f_sf = r < 0; self.f_pf = (r as u8) % 2 == 0; - (r as u8) as u32 + (r as u8) as u64 } - pub fn inc32(&mut self, value:u32) -> u32 { + pub fn inc64(&mut self, value:u64) -> u64 { + if value == 0xffffffffffffffff { + self.f_zf = true; + self.f_pf = true; + self.f_af = true; + return 0; + } + self.f_of = value == 0x7fffffffffffffff; + self.f_sf = value > 0x7fffffffffffffff; + self.f_pf = (((value as i64) +1) & 0xff) % 2 == 0; + self.f_zf = false; + value + 1 + } + + pub fn inc32(&mut self, value:u64) -> u64 { if value == 0xffffffff { self.f_zf = true; self.f_pf = true; @@ -277,7 +336,7 @@ impl Flags { value + 1 } - pub fn inc16(&mut self, value:u32) -> u32 { + pub fn inc16(&mut self, value:u64) -> u64 { if value == 0xffff { self.f_zf = true; self.f_pf = true; @@ -291,7 +350,7 @@ impl Flags { value + 1 } - pub fn inc8(&mut self, value:u32) -> u32 { + pub fn inc8(&mut self, value:u64) -> u64 { if value == 0xff { self.f_zf = true; self.f_pf = true; @@ -305,7 +364,24 @@ impl Flags { value + 1 } - pub fn dec32(&mut self, value:u32) -> u32 { + pub fn dec64(&mut self, value:u64) -> u64 { + if value == 0 { + self.f_pf = true; + self.f_af = true; + self.f_sf = true; + return 0xffffffffffffffff; + } + self.f_of = value == 0x8000000000000000; + self.f_pf = (((value as i64) -1) & 0xff) % 2 == 0; + self.f_af = false; + self.f_sf = false; + + self.f_zf = value == 1; + + value - 1 + } + + pub fn dec32(&mut self, value:u64) -> u64 { if value == 0 { self.f_pf = true; self.f_af = true; @@ -322,7 +398,7 @@ impl Flags { value - 1 } - pub fn dec16(&mut self, value:u32) -> u32 { + pub fn dec16(&mut self, value:u64) -> u64 { if value == 0 { self.f_pf = true; self.f_af = true; @@ -339,7 +415,7 @@ impl Flags { value - 1 } - pub fn dec8(&mut self, value:u32) -> u32 { + pub fn dec8(&mut self, value:u64) -> u64 { if value == 0 { self.f_pf = true; self.f_af = true; @@ -356,40 +432,53 @@ impl Flags { value - 1 } - pub fn neg32(&mut self, value:u32) -> u32 { + pub fn neg64(&mut self, value:u64) -> u64 { + self.f_of = value == 0x8000000000000000; + self.f_cf = true; + + let mut ival = value as i32; + ival = -ival; + + let res = ival as u64; + + self.calc_flags(res, 64); + res + } + + pub fn neg32(&mut self, value:u64) -> u64 { self.f_of = value == 0x80000000; self.f_cf = true; let mut ival = value as i32; ival = -ival; - let res = ival as u32; + let res = ival as u64; self.calc_flags(res, 32); res } - pub fn neg16(&mut self, value:u32) -> u32 { + pub fn neg16(&mut self, value:u64) -> u64 { self.f_of = value == 0x8000; self.f_cf = true; let mut ival = value as i16; ival = -ival; - let res = ival as u16 as u32; + let res = ival as u16 as u64; self.calc_flags(res, 16); res } - pub fn neg8(&mut self, value:u32) -> u32 { + pub fn neg8(&mut self, value:u64) -> u64 { self.f_of = value == 0x80; self.f_cf = true; let mut ival = value as i8; ival = -ival; - let res = ival as u8 as u32; + let res = ival as u8 as u64; self.calc_flags(res, 8); res @@ -397,70 +486,104 @@ impl Flags { //// sal sar signed //// - pub fn sal2p32(&mut self, value0:u32, value1:u32) -> u32 { - let mut unsigned64:u64 = value0 as u64; + pub fn sal2p64(&mut self, value0:u64, value1:u64) -> u64 { + let mut unsigned128:u128 = value0 as u128; + + for _ in 0..value1 { + unsigned128 *= 2; + } + + self.f_cf = unsigned128 > 0xffffffffffffffff; + let result = (unsigned128 & 0xffffffffffffffff) as u64; + self.calc_flags(result, 32); + result + } + + pub fn sal2p32(&mut self, value0:u64, value1:u64) -> u64 { + let mut unsigned64:u64 = value0; for _ in 0..value1 { unsigned64 *= 2; } self.f_cf = unsigned64 > 0xffffffff; - let result = (unsigned64 & 0xffffffff) as u32; + let result = unsigned64 & 0xffffffff; self.calc_flags(result, 32); result } - pub fn sal2p16(&mut self, value0:u32, value1:u32) -> u32 { - let mut unsigned64:u64 = value0 as u64; + pub fn sal2p16(&mut self, value0:u64, value1:u64) -> u64 { + let mut unsigned64:u64 = value0; for _ in 0..value1 { unsigned64 *= 2; } self.f_cf = unsigned64 > 0xffff; - let result = (unsigned64 & 0xffff) as u32; + let result = unsigned64 & 0xffff; self.calc_flags(result, 16); result } - pub fn sal2p8(&mut self, value0:u32, value1:u32) -> u32 { - let mut unsigned64:u64 = value0 as u64; + pub fn sal2p8(&mut self, value0:u64, value1:u64) -> u64 { + let mut unsigned64:u64 = value0; for _ in 0..value1 { unsigned64 *= 2; } self.f_cf = unsigned64 > 0xff; - let result = (unsigned64 & 0xff) as u32; + let result = unsigned64 & 0xff; self.calc_flags(result, 8); result } - pub fn sal1p32(&mut self, value:u32) -> u32 { - let unsigned64:u64 = (value as u64) * 2; + pub fn sal1p64(&mut self, value:u64) -> u64 { + let unsigned64:u128 = value as u128 * 2; + self.f_cf = unsigned64 > 0xffffffffffffffff; + let res = (unsigned64 & 0xffffffffffffffff) as u64; + self.calc_flags(res, 64); + res + } + + pub fn sal1p32(&mut self, value:u64) -> u64 { + let unsigned64:u64 = value * 2; self.f_cf = unsigned64 > 0xffffffff; - let res = (unsigned64 & 0xffffffff) as u32; + let res = unsigned64 & 0xffffffff; self.calc_flags(res, 32); res } - pub fn sal1p16(&mut self, value:u32) -> u32 { - let unsigned64:u64 = (value as u64) * 2; + pub fn sal1p16(&mut self, value:u64) -> u64 { + let unsigned64:u64 = value * 2; self.f_cf = unsigned64 > 0xffff; - let res = (unsigned64 & 0xffff) as u32; + let res = unsigned64 & 0xffff; self.calc_flags(res, 16); res } - pub fn sal1p8(&mut self, value:u32) -> u32 { - let unsigned64:u64 = (value as u64) * 2; + pub fn sal1p8(&mut self, value:u64) -> u64 { + let unsigned64:u64 = value * 2; self.f_cf = unsigned64 > 0xff; - let res = (unsigned64 & 0xff) as u32; + let res = unsigned64 & 0xff; self.calc_flags(res, 8); res } - pub fn sar2p32(&mut self, value0:u32, value1:u32) -> u32 { + pub fn sar2p64(&mut self, value0:u64, value1:u64) -> u64 { + let mut signed64:i64 = value0 as i64; + + for _ in 0..value1 { + signed64 /= 2; + } + + self.f_cf = signed64 > 0xffffffff; + let result = signed64 as i32 as u32 as u64; + self.calc_flags(result, 32); + result + } + + pub fn sar2p32(&mut self, value0:u64, value1:u64) -> u64 { let mut signed64:i64 = value0 as i32 as i64; for _ in 0..value1 { @@ -468,12 +591,12 @@ impl Flags { } self.f_cf = signed64 > 0xffffffff; - let result = signed64 as i32 as u32; + let result = signed64 as i32 as u32 as u64; self.calc_flags(result, 32); result } - pub fn sar2p16(&mut self, value0:u32, value1:u32) -> u32 { + pub fn sar2p16(&mut self, value0:u64, value1:u64) -> u64 { let mut signed64:i64 = value0 as i32 as i64; for _ in 0..value1 { @@ -481,12 +604,12 @@ impl Flags { } self.f_cf = signed64 > 0xffff; - let result = signed64 as i32 as u32; + let result = signed64 as i32 as u32 as u64; self.calc_flags(result, 16); result } - pub fn sar2p8(&mut self, value0:u32, value1:u32) -> u32 { + pub fn sar2p8(&mut self, value0:u64, value1:u64) -> u64 { let mut signed64:i64 = value0 as i32 as i64; for _ in 0..value1 { @@ -494,102 +617,145 @@ impl Flags { } self.f_cf = signed64 > 0xff; - let result = signed64 as i32 as u32; + let result = signed64 as i32 as u32 as u64; self.calc_flags(result, 8); result } - pub fn sar1p32(&mut self, value:u32) -> u32 { + pub fn sar1p64(&mut self, value:u64) -> u64 { + let signed128:i128 = (value as i64 as i128) / 2; + self.f_cf = signed128 > 0xffffffffffffffff; + let res = signed128 as i64 as u64; + self.calc_flags(res, 64); + res + } + + pub fn sar1p32(&mut self, value:u64) -> u64 { let signed64:i64 = (value as i32 as i64) / 2; self.f_cf = signed64 > 0xffffffff; - let res = signed64 as i32 as u32; + let res = signed64 as i32 as u32 as u64; self.calc_flags(res, 32); res } - pub fn sar1p16(&mut self, value:u32) -> u32 { + pub fn sar1p16(&mut self, value:u64) -> u64 { let signed64:i64 = (value as i32 as i64) / 2; self.f_cf = signed64 > 0xffff; - let res = signed64 as i32 as u32; + let res = signed64 as i32 as u32 as u64; self.calc_flags(res, 16); res } - pub fn sar1p8(&mut self, value:u32) -> u32 { + pub fn sar1p8(&mut self, value:u64) -> u64 { let signed64:i64 = (value as i32 as i64) / 2; self.f_cf = signed64 > 0xff; - let res = signed64 as i32 as u32; + let res = signed64 as i32 as u32 as u64; self.calc_flags(res, 8); res } //// shr shl unsigned //// - pub fn shl2p32(&mut self, value0:u32, value1:u32) -> u32 { - let mut unsigned64:u64 = value0 as u64; + pub fn shl2p64(&mut self, value0:u64, value1:u64) -> u64 { + let mut unsigned128:u128 = value0 as u128; + + for _ in 0..value1 { + unsigned128 *= 2; + } + + self.f_cf = unsigned128 > 0xffffffffffffffff; + let result = (unsigned128 & 0xffffffffffffffff) as u64; + self.calc_flags(result, 64); + + result + } + + pub fn shl2p32(&mut self, value0:u64, value1:u64) -> u64 { + let mut unsigned64:u64 = value0; for _ in 0..value1 { unsigned64 *= 2; } self.f_cf = unsigned64 > 0xffffffff; - let result = (unsigned64 & 0xffffffff) as u32; + let result = unsigned64 & 0xffffffff; self.calc_flags(result, 32); result } - pub fn shl2p16(&mut self, value0:u32, value1:u32) -> u32 { - let mut unsigned64:u64 = value0 as u64; + pub fn shl2p16(&mut self, value0:u64, value1:u64) -> u64 { + let mut unsigned64:u64 = value0; for _ in 0..value1 { unsigned64 *= 2; } self.f_cf = unsigned64 > 0xffff; - let result = (unsigned64 & 0xffff) as u32; + let result = unsigned64 & 0xffff; self.calc_flags(result, 16); result } - pub fn shl2p8(&mut self, value0:u32, value1:u32) -> u32 { - let mut unsigned64:u64 = value0 as u64; + pub fn shl2p8(&mut self, value0:u64, value1:u64) -> u64 { + let mut unsigned64:u64 = value0; for _ in 0..value1 { unsigned64 *= 2; } self.f_cf = unsigned64 > 0xff; - let result = (unsigned64 & 0xff) as u32; + let result = unsigned64 & 0xff; self.calc_flags(result, 8); result } + + pub fn shl1p64(&mut self, value:u64) -> u64 { + let unsigned64:u128 = value as u128 * 2; + self.f_cf = unsigned64 > 0xffffffffffffffff; + let res = (unsigned64 & 0xffffffffffffffff) as u64; + self.calc_flags(res, 64); + res + } - pub fn shl1p32(&mut self, value:u32) -> u32 { - let unsigned64:u64 = (value as u64) * 2; + pub fn shl1p32(&mut self, value:u64) -> u64 { + let unsigned64:u64 = value * 2; self.f_cf = unsigned64 > 0xffffffff; - let res = (unsigned64 & 0xffffffff) as u32; + let res = unsigned64 & 0xffffffff; self.calc_flags(res, 32); res } - pub fn shl1p16(&mut self, value:u32) -> u32 { - let unsigned64:u64 = (value as u64) * 2; + pub fn shl1p16(&mut self, value:u64) -> u64 { + let unsigned64:u64 = value * 2; self.f_cf = unsigned64 > 0xffff; - let res = (unsigned64 & 0xffff) as u32; + let res = unsigned64 & 0xffff; self.calc_flags(res, 16); res } - pub fn shl1p8(&mut self, value:u32) -> u32 { - let unsigned64:u64 = (value as u64) * 2; + pub fn shl1p8(&mut self, value:u64) -> u64 { + let unsigned64:u64 = value * 2; self.f_cf = unsigned64 > 0xff; - let res = (unsigned64 & 0xff) as u32; + let res = unsigned64 & 0xff; self.calc_flags(res, 8); res } - pub fn shr2p32(&mut self, value0:u32, value1:u32) -> u32 { + pub fn shr2p64(&mut self, value0:u64, value1:u64) -> u64 { + let mut unsigned128:u128 = value0 as u128; + + for _ in 0..value1 { + unsigned128 /= 2; + } + + self.f_cf = unsigned128 > 0xffffffffffffffff; + let result = unsigned128 as u64; + self.calc_flags(result, 64); + result + } + + pub fn shr2p32(&mut self, value0:u64, value1:u64) -> u64 { let mut unsigned64:u64 = value0 as u64; for _ in 0..value1 { @@ -597,25 +763,25 @@ impl Flags { } self.f_cf = unsigned64 > 0xffffffff; - let result = (unsigned64 & 0xffffffff) as u32; + let result = unsigned64 & 0xffffffff; self.calc_flags(result, 32); result } - pub fn shr2p16(&mut self, value0:u32, value1:u32) -> u32 { - let mut unsigned64:u64 = value0 as u64; + pub fn shr2p16(&mut self, value0:u64, value1:u64) -> u64 { + let mut unsigned64:u64 = value0; for _ in 0..value1 { unsigned64 /= 2; } self.f_cf = unsigned64 > 0xffff; - let result = (unsigned64 & 0xffff) as u32; + let result = unsigned64 & 0xffff; self.calc_flags(result, 16); result } - pub fn shr2p8(&mut self, value0:u32, value1:u32) -> u32 { + pub fn shr2p8(&mut self, value0:u64, value1:u64) -> u64 { let mut unsigned64:u64 = value0 as u64; for _ in 0..value1 { @@ -623,37 +789,45 @@ impl Flags { } self.f_cf = unsigned64 > 0xff; - let result = (unsigned64 & 0xff) as u32; + let result = unsigned64 & 0xff; self.calc_flags(result, 8); result } - pub fn shr1p32(&mut self, value:u32) -> u32 { - let unsigned64:u64 = (value as u64) / 2; + pub fn shr1p64(&mut self, value:u64) -> u64 { + let unsigned128:u128 = (value as u128) / 2; + self.f_cf = unsigned128 > 0xffffffffffffffff; + let res = unsigned128 as u64; + self.calc_flags(res, 64); + res + } + + pub fn shr1p32(&mut self, value:u64) -> u64 { + let unsigned64:u64 = value / 2; self.f_cf = unsigned64 > 0xffffffff; - let res = (unsigned64 & 0xffffffff) as u32; + let res = unsigned64 & 0xffffffff; self.calc_flags(res, 32); res } - pub fn shr1p16(&mut self, value:u32) -> u32 { - let unsigned64:u64 = (value as u64) / 2; + pub fn shr1p16(&mut self, value:u64) -> u64 { + let unsigned64:u64 = value / 2; self.f_cf = unsigned64 > 0xffff; - let res = (unsigned64 & 0xffff) as u32; + let res = unsigned64 & 0xffff; self.calc_flags(res, 16); res } - pub fn shr1p8(&mut self, value:u32) -> u32 { - let unsigned64:u64 = (value as u64) / 2; + pub fn shr1p8(&mut self, value:u64) -> u64 { + let unsigned64:u64 = value / 2; self.f_cf = unsigned64 > 0xff; - let res = (unsigned64 & 0xff) as u32; + let res = unsigned64 & 0xff; self.calc_flags(res, 8); res } - pub fn test(&mut self, value0:u32, value1:u32, sz:usize) { - let result:u32 = value0 & value1; + pub fn test(&mut self, value0:u64, value1:u64, sz:u8) { + let result:u64 = value0 & value1; self.f_zf = result == 0; self.f_cf = false; @@ -661,16 +835,32 @@ impl Flags { self.f_pf = (result & 0xff) % 2 == 0; match sz { + 64 => self.f_sf = (result as i64) < 0, 32 => self.f_sf = (result as i32) < 0, 16 => self.f_sf = (result as i16) < 0, 8 => self.f_sf = (result as i8) < 0, - _ => panic!("weird size") + _ => unreachable!("weird size") } } //// imul //// + + pub fn imul64p2(&mut self, value0:u64, value1:u64) -> u64 { + let result:i128 = value0 as i64 as i128 * value1 as i64 as i128; + let uresult:u128 = result as u128; + + if uresult > 0xffffffffffffffff { + self.f_cf = true; + self.f_of = true; + } + + let res:u64 = (uresult & 0xffffffffffffffff) as u64; + + self.calc_flags(res, 64); + res + } - pub fn imul32p2(&mut self, value0:u32, value1:u32) -> u32 { + pub fn imul32p2(&mut self, value0:u64, value1:u64) -> u64 { let result:i64 = value0 as i32 as i64 * value1 as i32 as i64; let uresult:u64 = result as u64; @@ -679,13 +869,13 @@ impl Flags { self.f_of = true; } - let res:u32 = (uresult & 0xffffffff) as u32; + let res:u64 = uresult & 0xffffffff; self.calc_flags(res, 32); res } - pub fn imul16p2(&mut self, value0:u16, value1:u16) -> u32 { + pub fn imul16p2(&mut self, value0:u64, value1:u64) -> u64 { let result:i32 = value0 as i16 as i32 * value1 as i16 as i32; let uresult:u32 = result as u32; @@ -694,13 +884,13 @@ impl Flags { self.f_of = true; } - let res:u32 = (uresult & 0xffff) as u32; + let res = (uresult & 0xffff) as u64; self.calc_flags(res, 16); res } - pub fn imul8p2(&mut self, value0:u8, value1:u8) -> u32 { + pub fn imul8p2(&mut self, value0:u64, value1:u64) -> u64 { let result:i16 = value0 as i8 as i16 * value1 as i8 as i16; let uresult:u16 = result as u16; @@ -709,7 +899,7 @@ impl Flags { self.f_of = true; } - let res:u32 = (uresult & 0xff) as u32; + let res = (uresult & 0xff) as u64; self.calc_flags(res, 8); res diff --git a/src/emu/fpu.rs b/src/emu/fpu.rs index 3ba31b6..4e9af1e 100644 --- a/src/emu/fpu.rs +++ b/src/emu/fpu.rs @@ -5,7 +5,7 @@ pub struct FPU { tag:u16, stat:u16, ctrl:u16, - eip:u32, + ip:u64, err_off:u32, err_sel:u32, stack:Vec @@ -18,18 +18,18 @@ impl FPU { tag: 0xffff, stat: 0, ctrl: 0x027f, - eip: 0, + ip: 0, err_off: 0, err_sel: 0, stack: Vec::new(), } } - pub fn set_eip(&mut self, eip:u32) { - self.eip = eip; + pub fn set_ip(&mut self, ip:u64) { + self.ip = ip; } - pub fn get_env(&self) -> Vec { + pub fn get_env32(&self) -> Vec { let mut r:Vec = Vec::new(); let mut r1:u32 = self.tag as u32; r1 = r1 << 16; @@ -37,7 +37,7 @@ impl FPU { r.push(r1); r.push(0xffff0000); r.push(0xffffffff); - r.push(self.eip); + r.push(self.ip as u32); return r; } @@ -49,7 +49,7 @@ impl FPU { println!("stat: 0x{:x}", self.stat); println!("ctrl: 0x{:x}", self.ctrl); - println!("eip: 0x{:x}", self.eip); + println!("eip: 0x{:x}", self.ip); println!("--------"); } diff --git a/src/emu/maps.rs b/src/emu/maps.rs index 92a63d4..7a32a3d 100644 --- a/src/emu/maps.rs +++ b/src/emu/maps.rs @@ -1,33 +1,35 @@ -mod mem32; +mod mem64; -use mem32::Mem32; +use mem64::Mem64; use std::collections::HashMap; use std::str; pub struct Maps { - pub maps: HashMap, + pub maps: HashMap, + pub is_64bits: bool, } impl Maps { pub fn new() -> Maps { Maps { maps: HashMap::new(), + is_64bits: false, } } - pub fn get_map_by_name(&self, name:&str) -> Option<&Mem32> { + pub fn get_map_by_name(&self, name:&str) -> Option<&Mem64> { let s = name.to_string(); self.maps.get(&s) } - pub fn create_map(&mut self, name:&str) -> &mut Mem32 { - let mem = Mem32::new(); + pub fn create_map(&mut self, name:&str) -> &mut Mem64 { + let mem = Mem64::new(); self.maps.insert(name.to_string(), mem); return self.maps.get_mut(name).expect("incorrect memory map name"); } - pub fn write_qword(&mut self, addr:u32, value:u64) -> bool { + pub fn write_qword(&mut self, addr:u64, value:u64) -> bool { for (_,mem) in self.maps.iter_mut() { if mem.inside(addr) { mem.write_qword(addr, value); @@ -39,7 +41,7 @@ impl Maps { } - pub fn write_dword(&mut self, addr:u32, value:u32) -> bool { + pub fn write_dword(&mut self, addr:u64, value:u32) -> bool { for (_,mem) in self.maps.iter_mut() { if mem.inside(addr) { mem.write_dword(addr, value); @@ -50,7 +52,7 @@ impl Maps { false } - pub fn write_word(&mut self, addr:u32, value:u16) -> bool { + pub fn write_word(&mut self, addr:u64, value:u16) -> bool { for (_,mem) in self.maps.iter_mut() { if mem.inside(addr) { mem.write_word(addr, value); @@ -61,7 +63,7 @@ impl Maps { false } - pub fn write_byte(&mut self, addr:u32, value:u8) -> bool { + pub fn write_byte(&mut self, addr:u64, value:u8) -> bool { for (_,mem) in self.maps.iter_mut() { if mem.inside(addr) { mem.write_byte(addr, value); @@ -72,7 +74,7 @@ impl Maps { false } - pub fn read_128bits_be(&self, addr:u32) -> Option { + pub fn read_128bits_be(&self, addr:u64) -> Option { for (_,mem) in self.maps.iter() { if mem.inside(addr) { let mut n:u128 = 0; @@ -86,7 +88,7 @@ impl Maps { None } - pub fn read_128bits_le(&self, addr:u32) -> Option { + pub fn read_128bits_le(&self, addr:u64) -> Option { for (_,mem) in self.maps.iter() { if mem.inside(addr) { let mut n:u128 = 0; @@ -100,7 +102,7 @@ impl Maps { None } - pub fn read_qword(&self, addr:u32) -> Option { + pub fn read_qword(&self, addr:u64) -> Option { for (_,mem) in self.maps.iter() { if mem.inside(addr) { return Some(mem.read_qword(addr)); @@ -109,7 +111,7 @@ impl Maps { None } - pub fn read_dword(&self, addr:u32) -> Option { + pub fn read_dword(&self, addr:u64) -> Option { for (_,mem) in self.maps.iter() { if mem.inside(addr) { return Some(mem.read_dword(addr)); @@ -118,7 +120,7 @@ impl Maps { None } - pub fn read_word(&self, addr:u32) -> Option { + pub fn read_word(&self, addr:u64) -> Option { for (_,mem) in self.maps.iter() { if mem.inside(addr) { return Some(mem.read_word(addr)); @@ -127,7 +129,7 @@ impl Maps { None } - pub fn read_byte(&self, addr:u32) -> Option { + pub fn read_byte(&self, addr:u64) -> Option { for (_,mem) in self.maps.iter() { if mem.inside(addr) { return Some(mem.read_byte(addr)); @@ -136,15 +138,15 @@ impl Maps { None } - pub fn get_mem_ref(&self, name:&str) -> &Mem32 { + pub fn get_mem_ref(&self, name:&str) -> &Mem64 { return self.maps.get(&name.to_string()).expect("incorrect memory map name"); } - pub fn get_mem(&mut self, name:&str) -> &mut Mem32 { + pub fn get_mem(&mut self, name:&str) -> &mut Mem64 { return self.maps.get_mut(&name.to_string()).expect("incorrect memory map name"); } - pub fn get_mem_by_addr(&mut self, addr:u32) -> Option<&mut Mem32> { + pub fn get_mem_by_addr(&mut self, addr:u64) -> Option<&mut Mem64> { for (_,mem) in self.maps.iter_mut() { if mem.inside(addr) { return Some(mem); @@ -153,45 +155,45 @@ impl Maps { None } - pub fn memset(&mut self, addr:u32, b:u8, amount:usize) { + pub fn memset(&mut self, addr:u64, b:u8, amount:usize) { for i in 0..amount { - self.write_byte(addr+i as u32, b); + self.write_byte(addr+i as u64, b); } } - pub fn memcpy(&mut self, to:u32, from:u32, size:usize) -> bool { + pub fn memcpy(&mut self, to:u64, from:u64, size:usize) -> bool { let mut b:u8; for i in 0..size { - b = match self.read_byte(from+i as u32) { + b = match self.read_byte(from+i as u64) { Some(v) => v, None => return false, }; - if !self.write_byte(to+i as u32, b) { + if !self.write_byte(to+i as u64, b) { return false; } } true } - pub fn write_string(&mut self, to:u32, from:&str) { + pub fn write_string(&mut self, to:u64, from:&str) { let bs:Vec = from.bytes().collect(); for (i, bsi) in bs.iter().enumerate() { - self.write_byte(to + i as u32, *bsi); + self.write_byte(to + i as u64, *bsi); } } - pub fn write_buffer(&mut self, to:u32, from:&[u8]) { + pub fn write_buffer(&mut self, to:u64, from:&[u8]) { for (i,fromi) in from.iter().enumerate() { - self.write_byte(to + i as u32, *fromi); + self.write_byte(to + i as u64, *fromi); } } - pub fn read_buffer(&mut self, from:u32, sz:usize) -> Vec { + pub fn read_buffer(&mut self, from:u64, sz:usize) -> Vec { let mut buff:Vec = Vec::new(); for i in 0..sz { - let b = match self.read_byte(from + i as u32) { + let b = match self.read_byte(from + i as u64) { Some(v) => v, None => { break; } }; @@ -221,7 +223,7 @@ impl Maps { println!("---"); } - pub fn get_addr_base(&self, addr:u32) -> Option { + pub fn get_addr_base(&self, addr:u64) -> Option { for (_, mem) in self.maps.iter() { if mem.inside(addr) { return Some(mem.get_base()); @@ -230,7 +232,7 @@ impl Maps { None } - pub fn is_mapped(&self, addr:u32) -> bool { + pub fn is_mapped(&self, addr:u64) -> bool { for (_,mem) in self.maps.iter() { if mem.inside(addr) { return true; @@ -239,7 +241,7 @@ impl Maps { false } - pub fn get_addr_name(&self, addr:u32) -> Option { + pub fn get_addr_name(&self, addr:u64) -> Option { for (name,mem) in self.maps.iter() { if mem.inside(addr) { return Some(name.to_string()); @@ -248,7 +250,7 @@ impl Maps { None } - pub fn dump(&self, addr:u32) { + pub fn dump(&self, addr:u64) { let mut count = 0; for i in 0..8 { let mut bytes:Vec = Vec::new(); @@ -271,7 +273,7 @@ impl Maps { } #[deprecated] - pub fn dump2(&self, addr:u32) { + pub fn dump2(&self, addr:u64) { let mut count = 0; for _ in 0..8 { let mut bytes:Vec = Vec::new(); @@ -302,8 +304,9 @@ impl Maps { } } - pub fn dump_dwords(&self, addr:u32) { + pub fn dump_dwords(&self, addr:u64) { let mut value:u32; + for i in 0..10 { let a = addr + i * 4; value = match self.read_dword(a) { @@ -311,16 +314,20 @@ impl Maps { None => break, }; - let name = match self.get_addr_name(value) { - Some(v) => v, - None => "".to_string(), - }; + if !self.is_64bits { + // only in 32bits make sense derreference dwords in memory + let name = match self.get_addr_name(value.into()) { + Some(v) => v, + None => "".to_string(), + }; + + println!("0x{:x}: 0x{:x} ({}) '{}'", a, value, name, self.filter_replace_string(&self.read_string(value.into()))); + } - println!("0x{:x}: 0x{:x} ({}) '{}'", a, value, name, self.filter_replace_string(&self.read_string(value))); } } - pub fn read_bytes(&mut self, addr:u32, sz:usize) -> &[u8] { + pub fn read_bytes(&mut self, addr:u64, sz:usize) -> &[u8] { let mem = match self.get_mem_by_addr(addr) { Some(v) => v, None => return &[0;0], @@ -328,7 +335,7 @@ impl Maps { mem.read_bytes(addr, sz) } - pub fn read_string_of_bytes(&mut self, addr:u32, sz:usize) -> String { + pub fn read_string_of_bytes(&mut self, addr:u64, sz:usize) -> String { let mut svec:Vec = Vec::new(); let bytes = self.read_bytes(addr, sz); for bs in bytes.iter() { @@ -338,10 +345,10 @@ impl Maps { s } - pub fn read_string(&self, addr:u32) -> String { + pub fn read_string(&self, addr:u64) -> String { let mut bytes:Vec = Vec::new(); let mut b:u8; - let mut i:u32 = 0; + let mut i:u64 = 0; loop { b = match self.read_byte(addr+i) { @@ -361,10 +368,10 @@ impl Maps { s } - pub fn read_wide_string(&self, addr:u32) -> String { + pub fn read_wide_string(&self, addr:u64) -> String { let mut bytes:Vec = Vec::new(); let mut b:u8; - let mut i:u32 = 0; + let mut i:u64 = 0; loop { b = match self.read_byte(addr+i) { @@ -384,8 +391,8 @@ impl Maps { s } - pub fn search_string(&self, kw:&str, map_name:&str) -> Option> { - let mut found:Vec = Vec::new(); + pub fn search_string(&self, kw:&str, map_name:&str) -> Option> { + let mut found:Vec = Vec::new(); for (name,mem) in self.maps.iter() { if name == map_name { @@ -394,7 +401,7 @@ impl Maps { let mut c = 0; for (i, bkwi) in bkw.iter().enumerate() { - let b = mem.read_byte(addr+(i as u32)); + let b = mem.read_byte(addr+(i as u64)); if b == *bkwi { c+=1; } else { @@ -419,7 +426,7 @@ impl Maps { None } - pub fn write_spaced_bytes(&mut self, addr:u32, sbs:String) -> bool { + pub fn write_spaced_bytes(&mut self, addr:u64, sbs:String) -> bool { let bs:Vec<&str> = sbs.split(' ').collect(); for bsi in bs.iter() { let b = u8::from_str_radix(bsi, 16).expect("bad num conversion"); @@ -451,9 +458,9 @@ impl Maps { self.search_bytes(bytes, map_name) } - pub fn search_space_bytes_in_all(&self, sbs:&str) -> Vec { + pub fn search_space_bytes_in_all(&self, sbs:&str) -> Vec { let bytes = self.spaced_bytes_to_bytes(sbs); - let mut found:Vec = Vec::new(); + let mut found:Vec = Vec::new(); for (name, mem) in self.maps.iter() { for addr in mem.get_base()..mem.get_bottom() { @@ -461,7 +468,7 @@ impl Maps { let mut c = 0; for (i, bi) in bytes.iter().enumerate() { - let addri = addr + (i as u32); + let addri = addr + (i as u64); if !mem.inside(addri) { break; } @@ -499,7 +506,11 @@ impl Maps { }; for addr in results.iter() { - println!("found at 0x{:x} '{}'", addr, self.read_string(*addr)); + if self.is_64bits { + println!("found at 0x{:x} '{}'", addr, self.read_string(*addr)); + } else { + println!("found at 0x{:x} '{}'", *addr as u32, self.read_string(*addr)); + } found = true; } } @@ -518,9 +529,9 @@ impl Maps { let mut c = 0; for (i, bkwn) in bkw.iter().enumerate() { - let b = mem.read_byte(addr+(i as u32)); + let b = mem.read_byte(addr+(i as u64)); if b == *bkwn { - c+=1; + c += 1; } else { break; } @@ -548,7 +559,7 @@ impl Maps { sz } - pub fn overlapps(&self, addr:u32, sz:u32) -> bool { + pub fn overlapps(&self, addr:u64, sz:u64) -> bool { for a in addr..addr+sz { if self.is_mapped(a) { return true; @@ -565,16 +576,13 @@ impl Maps { } } - pub fn alloc(&self, sz:u32) -> Option { + pub fn alloc(&self, sz:u64) -> Option { // super simple memory allocator - let mut addr:u32 = 100; - - //println!("ALLOCATOR sz:{}", sz); + let mut addr:u64 = 100; loop { addr += sz; - //println!("trying 0x{:x}", addr); if addr >= 0x70000000 { return None; @@ -593,7 +601,7 @@ impl Maps { } } - pub fn save(&mut self, addr:u32, size:u32, filename:String) { + pub fn save(&mut self, addr:u64, size:u64, filename:String) { match self.get_mem_by_addr(addr) { Some(m) => { m.save(addr, size as usize, filename); @@ -673,7 +681,6 @@ impl Maps { } pub fn mem_test(&self) -> bool { - for (name1, mem1) in self.maps.iter() { for (name2, mem2) in self.maps.iter() { @@ -690,7 +697,7 @@ impl Maps { } } - if (mem1.get_base() + (mem1.size() as u32)) != mem1.get_bottom() { + if (mem1.get_base() + (mem1.size() as u64)) != mem1.get_bottom() { println!("/!\\ memory bottom dont match, mem: {}", name1); return false; } diff --git a/src/emu/maps/mem32.rs b/src/emu/maps/mem.rs.bkp similarity index 100% rename from src/emu/maps/mem32.rs rename to src/emu/maps/mem.rs.bkp diff --git a/src/emu/maps/mem64.rs b/src/emu/maps/mem64.rs new file mode 100644 index 0000000..d998268 --- /dev/null +++ b/src/emu/maps/mem64.rs @@ -0,0 +1,217 @@ +/* + Little endian 64 bits and inferior bits memory. +*/ + +use std::io::BufReader; +use std::fs::File; +use std::io::Read; +use std::io::Write; +use md5; + +pub struct Mem64 { + base_addr: u64, + bottom_addr: u64, + pub mem: Vec, +} + +impl Mem64 { + pub fn new() -> Mem64 { + Mem64 { + base_addr: 0, + bottom_addr: 0, + mem: Vec::new(), + } + } + + pub fn alloc(&mut self, amount:usize) { + self.mem = vec![0; amount]; + } + + pub fn size(&self) -> usize { + self.mem.len() + } + + pub fn get_base(&self) -> u64 { + self.base_addr + } + + pub fn get_bottom(&self) -> u64 { + self.bottom_addr + } + + pub fn inside(&self, addr:u64) -> bool { + if addr >= self.base_addr && addr < self.bottom_addr { + return true; + } + false + } + + pub fn set_base(&mut self, base_addr:u64) { + self.base_addr = base_addr; + self.bottom_addr = base_addr; + } + + pub fn set_bottom(&mut self, bottom_addr:u64) { + self.bottom_addr = bottom_addr; + let size = self.bottom_addr - self.base_addr; + self.alloc(size as usize); + } + + pub fn set_size(&mut self, size:u64) { + self.bottom_addr = self.base_addr + size; + self.alloc(size as usize); + } + + pub fn read_from(&self, addr:u64) -> &[u8] { + let idx = (addr - self.base_addr) as usize; + let max_sz = (self.bottom_addr - self.base_addr) as usize; + /* + let mut sz = idx + 5; + if sz > max_sz { + sz = max_sz; + }*/ + return self.mem.get(idx..max_sz).unwrap(); + } + + pub fn read_bytes(&self, addr:u64, sz:usize) -> &[u8] { + let idx = (addr - self.base_addr) as usize; + let sz2 = idx as usize + sz; + if sz2 > self.mem.len() { + return &[0;0]; + } + return self.mem.get(idx..sz2).unwrap(); + } + + pub fn read_byte(&self, addr:u64) -> u8 { + + assert!(self.inside(addr)); + + let idx = (addr - self.base_addr) as usize; + if idx < self.mem.len() { + self.mem[idx] + } else { + panic!("reading at 0x{:x}", addr); + } + } + + pub fn read_word(&self, addr:u64) -> u16 { + let idx = (addr - self.base_addr) as usize; + (self.mem[idx] as u16) + + ((self.mem[idx+1] as u16) << 8) + } + + pub fn read_dword(&self, addr:u64) -> u32 { + let idx = (addr - self.base_addr) as usize; + (self.mem[idx] as u32) + + ((self.mem[idx+1] as u32) << 8) + + ((self.mem[idx+2] as u32) << 16) + + ((self.mem[idx+3] as u32) << 24) + } + + + pub fn read_qword(&self, addr:u64) -> u64 { + let idx = (addr - self.base_addr) as usize; + let mut r:u64 = 0; + + for i in 0..8 { + r += (self.mem[idx+i] as u64) << (8*i); + } + + r + } + + pub fn write_qword(&mut self, addr:u64, value:u64) { + let idx = (addr - self.base_addr) as usize; + + for i in 0..8 { + self.mem[idx+i] = (value & (0xff<> 8) as u8; + } + + pub fn write_dword(&mut self, addr:u64, value:u32) { + let idx = (addr - self.base_addr) as usize; + self.mem[idx] = (value & 0x000000ff) as u8; + self.mem[idx+1] = ((value & 0x0000ff00) >> 8) as u8; + self.mem[idx+2] = ((value & 0x00ff0000) >> 16) as u8; + self.mem[idx+3] = ((value & 0xff000000) >> 24) as u8; + } + + pub fn print_bytes(&self) { + println!("---mem---"); + for b in self.mem.iter() { + print!("{}", b); + } + println!("---"); + } + + pub fn print_dwords(&self) { + self.print_dwords_from_to(self.get_base(), self.get_bottom()); + } + + pub fn print_dwords_from_to(&self, from:u64, to:u64) { + println!("---mem---"); + for addr in (from..to).step_by(4) { + println!("0x{:x}", self.read_dword(addr)) + } + + println!("---"); + } + + pub fn md5(&self) -> md5::Digest { + md5::compute(&self.mem) + } + + pub fn load(&mut self, filename: &str) -> bool { + let f = match File::open(&filename) { + Ok(f) => f, + Err(_) => { return false; } + }; + let len = f.metadata().unwrap().len(); + self.bottom_addr = self.base_addr + len; + let mut reader = BufReader::new(&f); + reader.read_to_end(&mut self.mem).expect("cannot load map file"); + f.sync_all(); // thanks Alberto Segura + true + } + + pub fn save(&self, addr:u64, size:usize, filename:String) { + let idx = (addr - self.base_addr) as usize; + let sz2 = idx as usize + size; + if sz2 > self.mem.len() { + println!("size too big"); + return; + } + + let mut f = match File::create(filename) { + Ok(f) => f, + Err(e) => { + println!("cannot create the file {}", e); + return; + } + }; + + let blob = self.mem.get(idx..sz2).unwrap(); + + match f.write_all(blob) { + Ok(_) => println!("saved."), + Err(_) => println!("couldn't save the file"), + } + + f.sync_all().unwrap(); + } + + +} + diff --git a/src/emu/regs32.rs b/src/emu/regs32.rs.old similarity index 100% rename from src/emu/regs32.rs rename to src/emu/regs32.rs.old diff --git a/src/emu/regs64.rs b/src/emu/regs64.rs new file mode 100644 index 0000000..197d910 --- /dev/null +++ b/src/emu/regs64.rs @@ -0,0 +1,878 @@ +use crate::emu::maps::Maps; +use iced_x86::Register; +use rand; + +macro_rules! set_reg32 { + ($reg:expr, $val:expr) => ( + $reg &= 0xffffffff00000000; + $reg += ($val & 0x00000000ffffffff); + ) +} + +macro_rules! set_reg16 { + ($reg:expr, $val:expr) => ( + $reg &= 0xffffffffffff0000; + $reg += ($val & 0x000000000000ffff); + ) +} + +macro_rules! set_reg8l { + ($reg:expr, $val:expr) => ( + $reg &= 0xffffffffffffff00; + $reg += ($val & 0x00000000000000ff); + ) +} + +macro_rules! set_reg8h { + ($reg:expr, $val:expr) => ( + $reg &= 0xffffffffffff00ff; + $reg = $reg + (($val & 0x00000000000000ff) << 8); + ) +} + +macro_rules! get_reg32 { + ($reg:expr) => ( + return $reg & 0x00000000ffffffff; + ) +} + +macro_rules! get_reg16 { + ($reg:expr) => ( + return $reg & 0x000000000000ffff; + ) +} + +macro_rules! get_reg8l { + ($reg:expr) => ( + return $reg & 0x00000000000000ff; + ) +} + +macro_rules! get_reg8h { + ($reg:expr) => ( + return ($reg & 0x000000000000ff00) >> 8; + ) +} +// https://wiki.osdev.org/CPU_Registers_x86-64 +pub struct Regs64 { + pub dr0: u64, // bp + pub dr1: u64, // bp + pub dr2: u64, // bp + pub dr3: u64, // bp + pub dr6: u64, // dbg stat + pub dr7: u64, // dbg ctrl + + pub rax: u64, + pub rbx: u64, + pub rcx: u64, + pub rdx: u64, + pub rsi: u64, + pub rdi: u64, + pub rbp: u64, + pub rsp: u64, + pub rip: u64, + + pub r8: u64, + pub r9: u64, + pub r10: u64, + pub r11: u64, + pub r12: u64, + pub r13: u64, + pub r14: u64, + pub r15: u64, + + pub cr0: u64, + pub cr1: u64, // reserved + pub cr2: u64, + pub cr3: u64, + pub cr4: u64, + pub cr5: u64, // reserved + pub cr6: u64, // reserved + pub cr7: u64, // reserved + pub cr8: u64, + pub cr9: u64, // reserved + pub cr10: u64, // reserved + pub cr11: u64, // reserved + pub cr12: u64, // reserved + pub cr13: u64, // reserved + pub cr14: u64, // reserved + pub cr15: u64, // reserved + + pub msr: u64, + + pub tr3: u64, + pub tr4: u64, + pub tr5: u64, + pub tr6: u64, + pub tr7: u64, + + pub xmm0: u128, + pub xmm1: u128, + pub xmm2: u128, + pub xmm3: u128, + pub xmm4: u128, + pub xmm5: u128, + pub xmm6: u128, + pub xmm7: u128, +} + +impl Regs64 { + pub fn new() -> Regs64 { + Regs64{ + dr0: 0, + dr1: 0, + dr2: 0, + dr3: 0, + dr6: 0, + dr7: 0, + + rax: 0, + rbx: 0, + rcx: 0, + rdx: 0, + rsi: 0, + rdi: 0, + rbp: 0, + rsp: 0, + rip: 0, + + r8: 0, + r9: 0, + r10: 0, + r11: 0, + r12: 0, + r13: 0, + r14: 0, + r15: 0, + + cr0: 0, + cr1: 0, + cr2: 0, + cr3: 0, + cr4: 0, + cr5: 0, + cr6: 0, + cr7: 0, + cr8: 0, + cr9: 0, + cr10: 0, + cr11: 0, + cr12: 0, + cr13: 0, + cr14: 0, + cr15: 0, + + msr: 0, + + tr3: 0, + tr4: 0, + tr5: 0, + tr6: 0, + tr7: 0, + + xmm0: 0, + xmm1: 0, + xmm2: 0, + xmm3: 0, + xmm4: 0, + xmm5: 0, + xmm6: 0, + xmm7: 0, + } + } + + pub fn clear(&mut self) { + match B { + 64 => { + self.rax = 0; + self.rbx = 0; + self.rcx = 0; + self.rdx = 0; + self.rsi = 0; + self.rdi = 0; + self.rbp = 0; + self.rsp = 0; + self.rip = 0; + } + 32 => { + self.set_eax(0); + self.set_ebx(0); + self.set_ecx(0); + self.set_edx(0); + self.set_esi(0); + self.set_edi(0); + self.set_esp(0); + self.set_ebp(0); + self.set_eip(0); + } + 16 => { + self.set_ax(0); + self.set_bx(0); + self.set_cx(0); + self.set_dx(0); + self.set_si(0); + self.set_di(0); + self.set_sp(0); + self.set_bp(0); + self.set_ip(0); + } + _ => unimplemented!(), + } + } + + pub fn rand(&mut self) { + self.rax = rand::random::(); + self.rbx = rand::random::(); + self.rcx = rand::random::(); + self.rdx = rand::random::(); + self.rsi = rand::random::(); + self.rdi = rand::random::(); + self.rbp = rand::random::(); + self.rsp = rand::random::(); + self.rip = rand::random::(); + } + + pub fn print(&self) { + println!("regs:"); + + match B { + 64 => { + println!(" rax: 0x{:x}", self.rax); + println!(" rbx: 0x{:x}", self.rbx); + println!(" rcx: 0x{:x}", self.rcx); + println!(" rdx: 0x{:x}", self.rdx); + println!(" rsi: 0x{:x}", self.rsi); + println!(" rdi: 0x{:x}", self.rdi); + println!(" rbp: 0x{:x}", self.rbp); + println!(" rsp: 0x{:x}", self.rsp); + println!(" rip: 0x{:x}", self.rip); + } + 32 => { + println!(" eax: 0x{:x}", self.get_eax()); + println!(" ebx: 0x{:x}", self.get_ebx()); + println!(" ecx: 0x{:x}", self.get_ecx()); + println!(" edx: 0x{:x}", self.get_edx()); + println!(" esi: 0x{:x}", self.get_esi()); + println!(" edi: 0x{:x}", self.get_edi()); + println!(" ebp: 0x{:x}", self.get_ebp()); + println!(" esp: 0x{:x}", self.get_esp()); + println!(" eip: 0x{:x}", self.get_eip()); + } + _ => unimplemented!(), + } + + println!("---"); + } + + pub fn print_xmm(&self) { + println!("xmm regs:"); + println!(" xmm0: {}", self.xmm0); + println!(" xmm1: {}", self.xmm1); + println!(" xmm2: {}", self.xmm2); + println!(" xmm3: {}", self.xmm3); + println!(" xmm4: {}", self.xmm4); + println!(" xmm5: {}", self.xmm5); + println!(" xmm6: {}", self.xmm6); + println!(" xmm7: {}", self.xmm7); + } + + pub fn get_ax(&self) -> u64 { + get_reg16!(self.rax); + } + + pub fn get_bx(&self) -> u64 { + get_reg16!(self.rbx); + } + + pub fn get_cx(&self) -> u64 { + get_reg16!(self.rcx); + } + + pub fn get_dx(&self) -> u64 { + get_reg16!(self.rdx); + } + + pub fn get_si(&self) -> u64 { + get_reg16!(self.rsi); + } + + pub fn get_di(&self) -> u64 { + get_reg16!(self.rdi); + } + + pub fn get_sp(&self) -> u64 { + get_reg16!(self.rsp); + } + + pub fn get_bp(&self) -> u64 { + get_reg16!(self.rbp); + } + + pub fn get_ip(&self) -> u64 { + get_reg16!(self.rip); + } + + pub fn get_ah(&self) -> u64 { + get_reg8h!(self.rax); + } + + pub fn get_al(&self) -> u64 { + get_reg8l!(self.rax); + } + + pub fn get_bh(&self) -> u64 { + get_reg8h!(self.rbx); + } + + pub fn get_bl(&self) -> u64 { + get_reg8l!(self.rbx); + } + + pub fn get_ch(&self) -> u64 { + get_reg8h!(self.rcx); + } + + pub fn get_cl(&self) -> u64 { + get_reg8l!(self.rcx); + } + + pub fn get_dh(&self) -> u64 { + get_reg8h!(self.rdx); + } + + pub fn get_dl(&self) -> u64 { + get_reg8l!(self.rdx); + } + + pub fn get_eax(&self) -> u64 { + get_reg32!(self.rax); + } + + pub fn get_ebx(&self) -> u64 { + get_reg32!(self.rbx); + } + + pub fn get_ecx(&self) -> u64 { + get_reg32!(self.rcx); + } + + pub fn get_edx(&self) -> u64 { + get_reg32!(self.rdx); + } + + pub fn get_esi(&self) -> u64 { + get_reg32!(self.rsi); + } + + pub fn get_edi(&self) -> u64 { + get_reg32!(self.rdi); + } + + pub fn get_esp(&self) -> u64 { + get_reg32!(self.rsp); + } + + pub fn get_ebp(&self) -> u64 { + get_reg32!(self.rbp); + } + + pub fn get_eip(&self) -> u64 { + get_reg32!(self.rip); + } + + pub fn set_ax(&mut self, val:u64) { + set_reg16!(self.rax, val); + } + + pub fn set_bx(&mut self, val:u64) { + set_reg16!(self.rbx, val); + } + + pub fn set_cx(&mut self, val:u64) { + set_reg16!(self.rcx, val); + } + + pub fn set_dx(&mut self, val:u64) { + set_reg16!(self.rdx, val); + } + + pub fn set_si(&mut self, val:u64) { + set_reg16!(self.rsi, val); + } + + pub fn set_di(&mut self, val:u64) { + set_reg16!(self.rdi, val); + } + + pub fn set_sp(&mut self, val:u64) { + set_reg16!(self.rsp, val); + } + + pub fn set_bp(&mut self, val:u64) { + set_reg16!(self.rbp, val); + } + + pub fn set_ip(&mut self, val:u64) { + set_reg16!(self.rip, val); + } + + pub fn set_eax(&mut self, val:u64) { + set_reg32!(self.rax, val); + } + + pub fn set_ebx(&mut self, val:u64) { + set_reg32!(self.rbx, val); + } + + pub fn set_ecx(&mut self, val:u64) { + set_reg32!(self.rcx, val); + } + + pub fn set_edx(&mut self, val:u64) { + set_reg32!(self.rdx, val); + } + + pub fn set_esi(&mut self, val:u64) { + set_reg32!(self.rsi, val); + } + + pub fn set_edi(&mut self, val:u64) { + set_reg32!(self.rdi, val); + } + + pub fn set_ebp(&mut self, val:u64) { + set_reg32!(self.rbp, val); + } + + pub fn set_esp(&mut self, val:u64) { + set_reg32!(self.rsp, val); + } + + pub fn set_eip(&mut self, val:u64) { + set_reg32!(self.rip, val); + } + + pub fn set_ah(&mut self, val:u64) { + set_reg8h!(self.rax, val); + } + + pub fn set_bh(&mut self, val:u64) { + set_reg8h!(self.rbx, val); + } + + pub fn set_ch(&mut self, val:u64) { + set_reg8h!(self.rcx, val); + } + + pub fn set_dh(&mut self, val:u64) { + set_reg8h!(self.rdx, val); + } + + pub fn set_al(&mut self, val:u64) { + set_reg8l!(self.rax, val); + } + + pub fn set_bl(&mut self, val:u64) { + set_reg8l!(self.rbx, val); + } + + pub fn set_cl(&mut self, val:u64) { + set_reg8l!(self.rcx, val); + } + + pub fn set_dl(&mut self, val:u64) { + set_reg8l!(self.rdx, val); + } + + pub fn is_xmm(&self, reg:Register) -> bool { + let result = match reg { + Register::XMM0 => true, + Register::XMM1 => true, + Register::XMM2 => true, + Register::XMM3 => true, + Register::XMM4 => true, + Register::XMM5 => true, + Register::XMM6 => true, + Register::XMM7 => true, + _ => false, + }; + return result; + } + + pub fn get_xmm_reg(&self, reg:Register) -> u128 { + let value = match reg { + Register::XMM0 => self.xmm0, + Register::XMM1 => self.xmm1, + Register::XMM2 => self.xmm2, + Register::XMM3 => self.xmm3, + Register::XMM4 => self.xmm4, + Register::XMM5 => self.xmm5, + Register::XMM6 => self.xmm6, + Register::XMM7 => self.xmm7, + _ => unimplemented!("SSE XMM re gister: {:?} ", reg), + }; + return value; + } + + pub fn set_xmm_reg(&mut self, reg:Register, value:u128) { + match reg { + Register::XMM0 => self.xmm0 = value, + Register::XMM1 => self.xmm1 = value, + Register::XMM2 => self.xmm2 = value, + Register::XMM3 => self.xmm3 = value, + Register::XMM4 => self.xmm4 = value, + Register::XMM5 => self.xmm5 = value, + Register::XMM6 => self.xmm6 = value, + Register::XMM7 => self.xmm7 = value, + _ => unimplemented!("SSE XMM re gister: {:?} ", reg), + }; + } + + pub fn get_reg(&self, reg:Register) -> u64 { + let value = match reg { + Register::RAX => self.rax, + Register::RBX => self.rbx, + Register::RCX => self.rcx, + Register::RDX => self.rdx, + Register::RSI => self.rsi, + Register::RDI => self.rdi, + Register::RSP => self.rsp, + Register::RBP => self.rbp, + Register::RIP => self.rip, + Register::EAX => self.get_eax(), + Register::EBX => self.get_ebx(), + Register::ECX => self.get_ecx(), + Register::EDX => self.get_edx(), + Register::ESI => self.get_esi(), + Register::EDI => self.get_edi(), + Register::ESP => self.get_esp(), + Register::EBP => self.get_ebp(), + Register::EIP => self.get_eip(), + Register::AX => self.get_ax(), + Register::BX => self.get_bx(), + Register::CX => self.get_cx(), + Register::DX => self.get_dx(), + Register::SI => self.get_si(), + Register::DI => self.get_di(), + Register::AH => self.get_ah(), + Register::AL => self.get_al(), + Register::BH => self.get_bh(), + Register::BL => self.get_bl(), + Register::CH => self.get_ch(), + Register::CL => self.get_cl(), + Register::DH => self.get_dh(), + Register::DL => self.get_dl(), + Register::DS => 0, + Register::CS => 0, + Register::SS => 0, + Register::SP => 0, + Register::BP => 0, + Register::ES => 0, + Register::FS => 0, + Register::GS => 0, + _ => unimplemented!("unimplemented register {:?}", reg), + }; + + return value; + } + + pub fn set_reg(&mut self, reg:Register, value:u64) { + match reg { + Register::RAX => self.rax = value, + Register::RBX => self.rbx = value, + Register::RCX => self.rcx = value, + Register::RDX => self.rdx = value, + Register::RSI => self.rsi = value, + Register::RDI => self.rdi = value, + Register::RSP => self.rsp = value, + Register::RBP => self.rbp = value, + Register::RIP => self.rip = value, + Register::EAX => self.set_eax(value), + Register::EBX => self.set_ebx(value), + Register::ECX => self.set_ecx(value), + Register::EDX => self.set_edx(value), + Register::ESI => self.set_esi(value), + Register::EDI => self.set_edi(value), + Register::ESP => self.set_esp(value), + Register::EBP => self.set_ebp(value), + Register::EIP => self.set_eip(value), + Register::AX => self.set_ax(value), + Register::BX => self.set_bx(value), + Register::CX => self.set_cx(value), + Register::DX => self.set_dx(value), + Register::SI => self.set_si(value), + Register::DI => self.set_di(value), + Register::AH => self.set_ah(value), + Register::AL => self.set_al(value), + Register::BH => self.set_bh(value), + Register::BL => self.set_bl(value), + Register::CH => self.set_ch(value), + Register::CL => self.set_cl(value), + Register::DH => self.set_dh(value), + Register::DL => self.set_dl(value), + Register::SP => { }, + Register::SS => { }, + Register::BP => { }, + Register::ES => { }, + Register::FS => { }, + Register::GS => { }, + _ => unimplemented!("unimplemented register {:?}", reg), + }; + } + + pub fn get_size(&self, reg:Register) -> u8 { + let sz:u8 = match reg { + Register::RAX => 64, + Register::RBX => 64, + Register::RCX => 64, + Register::RDX => 64, + Register::RSI => 64, + Register::RDI => 64, + Register::RSP => 64, + Register::RBP => 64, + Register::RIP => 64, + Register::EAX => 32, + Register::EBX => 32, + Register::ECX => 32, + Register::EDX => 32, + Register::ESI => 32, + Register::EDI => 32, + Register::ESP => 32, + Register::EBP => 32, + Register::EIP => 32, + Register::AX => 16, + Register::BX => 16, + Register::CX => 16, + Register::DX => 16, + Register::SI => 16, + Register::DI => 16, + Register::AH => 8, + Register::AL => 8, + Register::BH => 8, + Register::BL => 8, + Register::CH => 8, + Register::CL => 8, + Register::DH => 8, + Register::DL => 8, + _ => unimplemented!("unimplemented register {:?}", reg), + }; + + return sz; + } + + pub fn get_by_name(&self, reg_name:&str) -> u64 { + match reg_name { + "rax" => return self.rax, + "rbx" => return self.rbx, + "rcx" => return self.rcx, + "rdx" => return self.rdx, + "rsi" => return self.rsi, + "rdi" => return self.rdi, + "rbp" => return self.rbp, + "rsp" => return self.rsp, + "rip" => return self.rip, + "eax" => return self.get_eax(), + "ebx" => return self.get_ebx(), + "ecx" => return self.get_ecx(), + "edx" => return self.get_edx(), + "esi" => return self.get_esi(), + "edi" => return self.get_edi(), + "ebp" => return self.get_ebp(), + "esp" => return self.get_esp(), + "eip" => return self.get_eip(), + "ax" => return self.get_ax(), + "bx" => return self.get_bx(), + "cx" => return self.get_cx(), + "dx" => return self.get_dx(), + "si" => return self.get_si(), + "di" => return self.get_di(), + "ah" => return self.get_ah(), + "al" => return self.get_al(), + "bh" => return self.get_bh(), + "bl" => return self.get_bl(), + "ch" => return self.get_ch(), + "cl" => return self.get_cl(), + "dh" => return self.get_dh(), + "dl" => return self.get_dl(), + &_ => panic!("weird register name parsed {}", reg_name), + } + } + + pub fn set_by_name(&mut self, reg_name:&str, value:u64) { + match reg_name { + "rax" => self.rax = value, + "rbx" => self.rbx = value, + "rcx" => self.rcx = value, + "rdx" => self.rdx = value, + "rsi" => self.rsi = value, + "rdi" => self.rdi = value, + "rbp" => self.rbp = value, + "rsp" => self.rsp = value, + "rip" => self.rip = value, + "eax" => self.set_eax(value), + "ebx" => self.set_ebx(value), + "ecx" => self.set_ecx(value), + "edx" => self.set_edx(value), + "esi" => self.set_esi(value), + "edi" => self.set_edi(value), + "ebp" => self.set_ebp(value), + "esp" => self.set_esp(value), + "eip" => self.set_eip(value), + "ax" => self.set_ax(value), + "bx" => self.set_bx(value), + "cx" => self.set_cx(value), + "dx" => self.set_dx(value), + "di" => self.set_di(value), + "si" => self.set_si(value), + "ah" => self.set_ah(value), + "al" => self.set_al(value), + "bh" => self.set_bh(value), + "bl" => self.set_bl(value), + "ch" => self.set_ch(value), + "cl" => self.set_cl(value), + "dh" => self.set_dh(value), + "dl" => self.set_dl(value), + &_ => panic!("weird register name parsed {}", reg_name), + } + } + + pub fn show_reg64(&self, maps:&Maps, sreg:&str, value:u64, pos:u64) { + if maps.is_mapped(value) { + + let mut s = maps.read_string(value); + if s.len() < 2 { + s = maps.read_wide_string(value); + } + + maps.filter_string(&mut s); + + if s.len() > 50 { + s = s[..50].to_string(); + } + + let name = match maps.get_addr_name(value) { + Some(v) => format!("({})", v), + None => "".to_string(), + }; + + if s.len() > 1 { + if pos > 0 { + println!("\t{} {}: 0x{:x} {} '{}' {}", pos, sreg, value, value, s, name); + } else { + println!("\t{}: 0x{:x} {} '{}' {}", sreg, value, value, s, name); + } + } else { + if pos > 0 { + println!("\t{} {}: 0x{:x} {} {}", pos, sreg, value, value, name); + } else { + println!("\t{}: 0x{:x} {} {}", sreg, value, value, name); + } + } + + } else { + if pos > 0 { + println!("\t{} {}: 0x{:x} {}", pos, sreg, value, value); + } else { + println!("\t{}: 0x{:x} {}", sreg, value, value); + } + } + } + + pub fn show_reg32(&self, maps:&Maps, sreg:&str, value:u64, pos:u64) { + if maps.is_mapped(value) { + + let mut s = maps.read_string(value); + if s.len() < 2 { + s = maps.read_wide_string(value); + } + + maps.filter_string(&mut s); + + if s.len() > 50 { + s = s[..50].to_string(); + } + + let name = match maps.get_addr_name(value) { + Some(v) => format!("({})", v), + None => "".to_string(), + }; + + if s.len() > 1 { + if pos > 0 { + println!("\t{} {}: 0x{:x} {} '{}' {}", pos, sreg, value as u32, value as u32, s, name); + } else { + println!("\t{}: 0x{:x} {} '{}' {}", sreg, value as u32, value as u32, s, name); + } + } else { + if pos > 0 { + println!("\t{} {}: 0x{:x} {} {}", pos, sreg, value as u32, value as u32, name); + } else { + println!("\t{}: 0x{:x} {} {}", sreg, value as u32, value as u32, name); + } + } + + } else { + if pos > 0 { + println!("\t{} {}: 0x{:x} {}", pos, sreg, value as u32, value as u32); + } else { + println!("\t{}: 0x{:x} {}", sreg, value as u32, value as u32); + } + } + } + + + pub fn show_eax(&self, maps:&Maps, pos:u64) { + self.show_reg32(maps, "eax", self.get_eax(), pos); + } + + pub fn show_ebx(&self, maps:&Maps, pos:u64) { + self.show_reg32(maps, "ebx", self.get_ebx(), pos); + } + + pub fn show_ecx(&self, maps:&Maps, pos:u64) { + self.show_reg32(maps, "ecx", self.get_ecx(), pos); + } + + pub fn show_edx(&self, maps:&Maps, pos:u64) { + self.show_reg32(maps, "edx", self.get_edx(), pos); + } + + pub fn show_esi(&self, maps:&Maps, pos:u64) { + self.show_reg32(maps, "esi", self.get_esi(), pos); + } + + pub fn show_edi(&self, maps:&Maps, pos:u64) { + self.show_reg32(maps, "edi", self.get_edi(), pos); + } + + pub fn show_rax(&self, maps:&Maps, pos:u64) { + self.show_reg64(maps, "rax", self.rax, pos); + } + + pub fn show_rbx(&self, maps:&Maps, pos:u64) { + self.show_reg64(maps, "rbx", self.rbx, pos); + } + + pub fn show_rcx(&self, maps:&Maps, pos:u64) { + self.show_reg64(maps, "rcx", self.rcx, pos); + } + + pub fn show_rdx(&self, maps:&Maps, pos:u64) { + self.show_reg64(maps, "rdx", self.rdx, pos); + } + + pub fn show_rsi(&self, maps:&Maps, pos:u64) { + self.show_reg64(maps, "rsi", self.rsi, pos); + } + + pub fn show_rdi(&self, maps:&Maps, pos:u64) { + self.show_reg64(maps, "rdi", self.rdi, pos); + } + + pub fn is_reg(&self, reg:&str) -> bool { + match reg { + "rax"|"rbx"|"rcx"|"rdx"|"rsi"|"rdi"|"rbp"|"rsp"|"rip"|"eax"|"ebx"|"ecx"|"edx"|"esi"|"edi"|"esp"|"ebp"|"eip"|"ax"|"bx"|"cx"|"dx"|"si"|"di"|"al"|"ah"|"bl"|"bh"|"cl"|"ch"|"dl"|"dh" => true, + &_ => false, + } + } +} diff --git a/src/emu/structures.rs b/src/emu/structures.rs index f780fa3..fe5fe2e 100644 --- a/src/emu/structures.rs +++ b/src/emu/structures.rs @@ -10,7 +10,7 @@ pub struct ListEntry { } impl ListEntry { - pub fn load(addr:u32, maps:&Maps) -> ListEntry { + pub fn load(addr:u64, maps:&Maps) -> ListEntry { ListEntry{ flink: maps.read_dword(addr).unwrap(), blink: maps.read_dword(addr+4).unwrap(), @@ -41,7 +41,7 @@ pub struct LdrDataTableEntry { impl LdrDataTableEntry { - pub fn load(addr:u32, maps:&Maps) -> LdrDataTableEntry { + pub fn load(addr:u64, maps:&Maps) -> LdrDataTableEntry { LdrDataTableEntry { reserved1: [maps.read_dword(addr).unwrap(), maps.read_dword(addr + 4).unwrap()], in_memory_order_module_links: ListEntry::load(addr + 8, &maps), @@ -78,7 +78,7 @@ pub struct PebLdrData { } impl PebLdrData { - pub fn load(addr:u32, maps:&Maps) -> PebLdrData { + pub fn load(addr:u64, maps:&Maps) -> PebLdrData { PebLdrData { length: maps.read_dword(addr).unwrap(), initializated: maps.read_dword(addr + 4).unwrap(), @@ -119,7 +119,7 @@ pub struct PEB { } impl PEB { - pub fn load(addr:u32, maps:&Maps) -> PEB { + pub fn load(addr:u64, maps:&Maps) -> PEB { PEB { reserved1: [0;2], being_debugged: maps.read_byte(addr + 2).unwrap(), @@ -173,7 +173,7 @@ pub struct PScopeTableEntry { } impl PScopeTableEntry { - pub fn load(addr:u32, maps:&Maps) -> PScopeTableEntry { + pub fn load(addr:u64, maps:&Maps) -> PScopeTableEntry { PScopeTableEntry { enclosing_level: maps.read_dword(addr).unwrap(), filter_func: maps.read_dword(addr + 4).unwrap(), @@ -181,7 +181,7 @@ impl PScopeTableEntry { } } - pub fn size() -> u32 { + pub fn size() -> u64 { return 12; } @@ -203,7 +203,7 @@ pub struct CppEhRecord { } impl CppEhRecord { - pub fn load(addr:u32, maps:&Maps) -> CppEhRecord { + pub fn load(addr:u64, maps:&Maps) -> CppEhRecord { CppEhRecord{ old_esp: maps.read_dword(addr).unwrap(), exc_ptr: maps.read_dword(addr + 4).unwrap(), @@ -227,14 +227,14 @@ pub struct ExceptionPointers { } impl ExceptionPointers { - pub fn load(addr:u32, maps:&Maps) -> ExceptionPointers { + pub fn load(addr:u64, maps:&Maps) -> ExceptionPointers { ExceptionPointers { exception_record: maps.read_dword(addr).unwrap(), context_record: maps.read_dword(addr + 4).unwrap(), } } - pub fn size() -> u32 { + pub fn size() -> u64 { return 8; } @@ -252,7 +252,7 @@ pub struct Eh3ExceptionRegistration { } impl Eh3ExceptionRegistration { - pub fn load(addr:u32, maps:&Maps) -> Eh3ExceptionRegistration { + pub fn load(addr:u64, maps:&Maps) -> Eh3ExceptionRegistration { Eh3ExceptionRegistration { next: maps.read_dword(addr).unwrap(), exception_handler: maps.read_dword(addr + 4).unwrap(), @@ -280,7 +280,7 @@ pub struct MemoryBasicInformation { impl MemoryBasicInformation { - pub fn load(addr:u32, maps:&Maps) -> MemoryBasicInformation { + pub fn load(addr:u64, maps:&Maps) -> MemoryBasicInformation { MemoryBasicInformation { base_address: maps.read_dword(addr).unwrap(), allocation_base: maps.read_dword(addr + 4).unwrap(), @@ -293,11 +293,11 @@ impl MemoryBasicInformation { } } - pub fn size() -> usize { + pub fn size() -> u64 { 30 } - pub fn save(&self, addr:u32, maps:&mut Maps) { + pub fn save(&self, addr:u64, maps:&mut Maps) { maps.write_dword(addr, self.base_address); maps.write_dword(addr + 4, self.allocation_base); maps.write_dword(addr + 8, self.allocation_protect); diff --git a/src/emu/syscall32.rs b/src/emu/syscall32.rs index a1ed357..868f3aa 100644 --- a/src/emu/syscall32.rs +++ b/src/emu/syscall32.rs @@ -9,7 +9,7 @@ use crate::emu::endpoint; pub fn gateway(emu:&mut emu::Emu) { - match emu.regs.eax { + match emu.regs.get_eax() { 1 => { println!("{}** {} syscall exit() {}", emu.colors.light_red, emu.pos, emu.colors.nc); @@ -22,30 +22,30 @@ pub fn gateway(emu:&mut emu::Emu) { } 3 => { - let fd = emu.regs.ebx; - let buff = emu.regs.ecx; - let sz = emu.regs.edx; - emu.regs.eax = buff; + let fd = emu.regs.rbx; + let buff = emu.regs.rcx; + let sz = emu.regs.rdx; + emu.regs.rax = buff; println!("{}** {} syscall read() fd: {} buf: 0x{:x} sz: {} {}", emu.colors.light_red, emu.pos, fd, buff, sz, emu.colors.nc); } 4 => { - let fd = emu.regs.ebx; - let buff = emu.regs.ecx; - let sz = emu.regs.edx; - emu.regs.eax = sz; + let fd = emu.regs.rbx; + let buff = emu.regs.rcx; + let sz = emu.regs.rdx; + emu.regs.rax = sz; println!("{}** {} syscall write() fd: {} buf: 0x{:x} sz: {} {}", emu.colors.light_red, emu.pos, fd, buff, sz, emu.colors.nc); } 5 => { - let file_path = emu.maps.read_string(emu.regs.ebx); + let file_path = emu.maps.read_string(emu.regs.rbx); let fd = helper::socket_create(); - emu.regs.eax = fd; + emu.regs.rax = fd as u64; println!("{}** {} syscall open() file: {} fd:{} {}", emu.colors.light_red, emu.pos, file_path, fd, emu.colors.nc); } 6 => { - let fd = emu.regs.ebx; + let fd = emu.regs.rbx; println!("{}** {} syscall close() fd: {} {}", emu.colors.light_red, emu.pos, fd, emu.colors.nc); helper::socket_close(fd); endpoint::sock_close(); @@ -68,13 +68,13 @@ pub fn gateway(emu:&mut emu::Emu) { } 11 => { - let cmd = emu.maps.read_string(emu.regs.ebx); + let cmd = emu.maps.read_string(emu.regs.rbx); println!("{}** {} syscall execve() cmd: {} {}", emu.colors.light_red, emu.pos, cmd, emu.colors.nc); - emu.regs.eax = 0; + emu.regs.rax = 0; } 12 => { - let path = emu.maps.read_string(emu.regs.ebx); + let path = emu.maps.read_string(emu.regs.rbx); println!("{}** {} syscall chdir() path: {} {}", emu.colors.light_red, emu.pos, path, emu.colors.nc); } @@ -87,8 +87,8 @@ pub fn gateway(emu:&mut emu::Emu) { } 15 => { - let file_path = emu.maps.read_string(emu.regs.ebx); - let perm = emu.regs.ecx; + let file_path = emu.maps.read_string(emu.regs.rbx); + let perm = emu.regs.rcx; println!("{}** {} syscall chmod() file: {} perm: {} {}", emu.colors.light_red, emu.pos, file_path, perm, emu.colors.nc); } @@ -105,7 +105,7 @@ pub fn gateway(emu:&mut emu::Emu) { } 19 => { - let fd = emu.regs.ebx; + let fd = emu.regs.rbx; println!("{}** {} syscall lseek() fd: {} {}", emu.colors.light_red, emu.pos, fd, emu.colors.nc); } @@ -178,8 +178,8 @@ pub fn gateway(emu:&mut emu::Emu) { } 37 => { - let pid = emu.regs.ebx; - let sig = emu.regs.ecx; + let pid = emu.regs.rbx; + let sig = emu.regs.rcx; println!("{}** {} syscall kill() pid: {} sig: {} {}", emu.colors.light_red, emu.pos, pid, sig, emu.colors.nc); } @@ -196,7 +196,7 @@ pub fn gateway(emu:&mut emu::Emu) { } 41 => { - let fd = emu.regs.ebx; + let fd = emu.regs.rbx; println!("{}** {} syscall dup() fd: {} {}", emu.colors.light_red, emu.pos, fd, emu.colors.nc); } @@ -285,8 +285,8 @@ pub fn gateway(emu:&mut emu::Emu) { } 63 => { - let old_fd = emu.regs.ebx; - let new_fd = emu.regs.ecx; + let old_fd = emu.regs.rbx; + let new_fd = emu.regs.rcx; println!("{}** {} syscall dup2() oldfd: {} newfd: {} {}", emu.colors.light_red, emu.pos, old_fd, new_fd, emu.colors.nc); } @@ -444,54 +444,54 @@ pub fn gateway(emu:&mut emu::Emu) { 102 => { - match emu.regs.ebx { + match emu.regs.rbx as u32 { constants::SYS_SOCKET => { let sock = helper::socket_create(); - let fam = emu.maps.read_dword(emu.regs.esp).expect("socket() cannot read family"); - let typ = emu.maps.read_dword(emu.regs.esp+4).expect("socket() cannot ready type"); - let proto = emu.maps.read_dword(emu.regs.esp+8).expect("socket() cannot read proto"); + let fam = emu.maps.read_dword(emu.regs.get_esp()).expect("socket() cannot read family"); + let typ = emu.maps.read_dword(emu.regs.get_esp()+4).expect("socket() cannot ready type"); + let proto = emu.maps.read_dword(emu.regs.get_esp()+8).expect("socket() cannot read proto"); println!("{}** {} syscall socketcall socket() fam: {} type: {} proto: {} sock: {} {}", emu.colors.light_red, emu.pos, fam, typ, proto, sock, emu.colors.nc); - emu.regs.eax = sock; + emu.regs.rax = sock; } constants::SYS_BIND => { - let sock = emu.maps.read_dword(emu.regs.esp).expect("bind() cannot read sock"); - let sockaddr = emu.maps.read_dword(emu.regs.esp+4).expect("bind() cannot read sockaddr"); - let len = emu.maps.read_dword(emu.regs.esp+8).expect("bind() cannot read len"); + let sock = emu.maps.read_dword(emu.regs.get_esp()).expect("bind() cannot read sock"); + let sockaddr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("bind() cannot read sockaddr"); + let len = emu.maps.read_dword(emu.regs.get_esp()+8).expect("bind() cannot read len"); - let fam:u16 = emu.maps.read_word(sockaddr).expect("cannot read family id"); - let port:u16 = emu.maps.read_word(sockaddr+2).expect("cannot read the port").to_be(); - let ip:u32 = emu.maps.read_dword(sockaddr+4).expect("cannot read the ip"); + let fam:u16 = emu.maps.read_word(sockaddr as u64).expect("cannot read family id"); + let port:u16 = emu.maps.read_word((sockaddr + 2) as u64).expect("cannot read the port").to_be(); + let ip:u32 = emu.maps.read_dword((sockaddr + 4) as u64).expect("cannot read the ip"); let sip = format!("{}.{}.{}.{}", ip&0xff, (ip&0xff00)>>8, (ip&0xff0000)>>16, (ip&0xff000000)>>24); println!("{}** {} syscall socketcall bind() sock: {} fam: {} {}:{} {}", emu.colors.light_red, emu.pos, sock, fam, sip, port , emu.colors.nc); - if !helper::socket_exist(sock) { + if !helper::socket_exist(sock as u64) { println!("\tbad socket/"); - emu.regs.eax = constants::ENOTSOCK; + emu.regs.rax = constants::ENOTSOCK; } else { - emu.regs.eax = 0; + emu.regs.rax = 0; } } constants::SYS_CONNECT => { - let sock = emu.maps.read_dword(emu.regs.esp).expect("connect() cannot read sock"); - let sockaddr = emu.maps.read_dword(emu.regs.esp+4).expect("connect() cannot read sockaddr"); - let len = emu.maps.read_dword(emu.regs.esp+8).expect("connect() cannot read len"); + let sock = emu.maps.read_dword(emu.regs.get_esp()).expect("connect() cannot read sock"); + let sockaddr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("connect() cannot read sockaddr"); + let len = emu.maps.read_dword(emu.regs.get_esp()+8).expect("connect() cannot read len"); - let fam:u16 = emu.maps.read_word(sockaddr).expect("cannot read family id"); - let port:u16 = emu.maps.read_word(sockaddr+2).expect("cannot read the port").to_be(); - let ip:u32 = emu.maps.read_dword(sockaddr+4).expect("cannot read the ip"); + let fam:u16 = emu.maps.read_word(sockaddr as u64).expect("cannot read family id"); + let port:u16 = emu.maps.read_word((sockaddr+2) as u64).expect("cannot read the port").to_be(); + let ip:u32 = emu.maps.read_dword((sockaddr+4) as u64).expect("cannot read the ip"); let sip = format!("{}.{}.{}.{}", ip&0xff, (ip&0xff00)>>8, (ip&0xff0000)>>16, (ip&0xff000000)>>24); println!("{}** {} syscall socketcall connect() sock: {} fam: {} {}:{} {}", emu.colors.light_red, emu.pos, sock, fam, sip, port, emu.colors.nc); - if !helper::socket_exist(sock) { + if !helper::socket_exist(sock as u64) { println!("\tbad socket/"); - emu.regs.eax = constants::ENOTSOCK; + emu.regs.rax = constants::ENOTSOCK; return; } @@ -503,48 +503,48 @@ pub fn gateway(emu:&mut emu::Emu) { } } - emu.regs.eax = 0; + emu.regs.rax = 0; } constants::SYS_LISTEN => { - let sock = emu.maps.read_dword(emu.regs.esp).expect("listen() cannot read sock"); - let conns = emu.maps.read_dword(emu.regs.esp+4).expect("listen() cannot read num of conns"); + let sock = emu.maps.read_dword(emu.regs.get_esp()).expect("listen() cannot read sock"); + let conns = emu.maps.read_dword(emu.regs.get_esp()+4).expect("listen() cannot read num of conns"); println!("{}** {} syscall socketcall listen() sock: {} conns: {} {}", emu.colors.light_red, emu.pos, sock, conns, emu.colors.nc); - if !helper::socket_exist(sock) { + if !helper::socket_exist(sock as u64) { println!("\tbad socket/"); - emu.regs.eax = constants::ENOTSOCK; + emu.regs.rax = constants::ENOTSOCK; } else { - emu.regs.eax = 0; + emu.regs.rax = 0; } } constants::SYS_ACCEPT => { - let sock = emu.maps.read_dword(emu.regs.esp).expect("accept() cannot read sock"); - let sockaddr = emu.maps.read_dword(emu.regs.esp+4).expect("accept() cannot read sockaddr"); - let len = emu.maps.read_dword(emu.regs.esp+8).expect("accept() cannot read len"); + let sock = emu.maps.read_dword(emu.regs.get_esp()).expect("accept() cannot read sock"); + let sockaddr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("accept() cannot read sockaddr"); + let len = emu.maps.read_dword(emu.regs.get_esp()+8).expect("accept() cannot read len"); let port:u16 = 8080; let incoming_ip:u32 = 0x11223344; - if sockaddr != 0 && emu.maps.is_mapped(sockaddr) { - emu.maps.write_word(sockaddr, 0x0002); - emu.maps.write_word(sockaddr+2, port.to_le()); //TODO: port should be the same than bind() - emu.maps.write_dword(sockaddr+4, incoming_ip); + if sockaddr != 0 && emu.maps.is_mapped(sockaddr as u64) { + emu.maps.write_word(sockaddr as u64, 0x0002); + emu.maps.write_word((sockaddr+2) as u64, port.to_le()); //TODO: port should be the same than bind() + emu.maps.write_dword((sockaddr+4) as u64, incoming_ip); } println!("{}** {} syscall socketcall accept() {}", emu.colors.light_red, emu.pos, emu.colors.nc); - if !helper::socket_exist(sock) { + if !helper::socket_exist(sock as u64) { println!("\tbad socket/"); - emu.regs.eax = constants::ENOTSOCK; + emu.regs.rax = constants::ENOTSOCK; } else { - emu.regs.eax = 0; + emu.regs.rax = 0; } } constants::SYS_GETSOCKNAME => { - let sock = emu.maps.read_dword(emu.regs.esp).expect("getsockname() cannot read sock"); + let sock = emu.maps.read_dword(emu.regs.get_esp()).expect("getsockname() cannot read sock"); println!("{}** {} syscall socketcall getsockname() sock: {} {}", emu.colors.light_red, emu.pos, sock, emu.colors.nc); todo!("implement this"); } @@ -558,40 +558,40 @@ pub fn gateway(emu:&mut emu::Emu) { } constants::SYS_SEND => { - let sock = emu.maps.read_dword(emu.regs.esp).expect("send() cannot read sock"); - let buf = emu.maps.read_dword(emu.regs.esp+4).expect("send() cannot read buff"); - let len = emu.maps.read_dword(emu.regs.esp+8).expect("send() cannot read len"); - let flags = emu.maps.read_dword(emu.regs.esp+12).expect("send() cannot read flags"); + let sock = emu.maps.read_dword(emu.regs.get_esp()).expect("send() cannot read sock"); + let buf = emu.maps.read_dword(emu.regs.get_esp()+4).expect("send() cannot read buff"); + let len = emu.maps.read_dword(emu.regs.get_esp()+8).expect("send() cannot read len"); + let flags = emu.maps.read_dword(emu.regs.get_esp()+12).expect("send() cannot read flags"); println!("{}** {} syscall socketcall send() sock: {} buff: {} len: {} {}", emu.colors.light_red, emu.pos, sock, buf, len, emu.colors.nc); - if !helper::socket_exist(sock) { + if !helper::socket_exist(sock as u64) { println!("\tbad socket/"); - emu.regs.eax = constants::ENOTSOCK; + emu.regs.rax = constants::ENOTSOCK; return; } if emu.cfg.endpoint { - let buffer = emu.maps.read_buffer(buf, len as usize); + let buffer = emu.maps.read_buffer(buf as u64, len as usize); let n = endpoint::sock_send(&buffer); println!("\tsent {} bytes.", n); - emu.regs.eax = n as u32; + emu.regs.rax = n as u64; } else { - emu.regs.eax = len; + emu.regs.rax = len as u64; } } constants::SYS_RECV => { - let sock = emu.maps.read_dword(emu.regs.esp).expect("recv() cannot read sock"); - let buf = emu.maps.read_dword(emu.regs.esp+4).expect("recv() cannot read buff"); - let len = emu.maps.read_dword(emu.regs.esp+8).expect("recv() cannot read len"); - let flags = emu.maps.read_dword(emu.regs.esp+12).expect("recv() cannot read flags"); + let sock = emu.maps.read_dword(emu.regs.get_esp()).expect("recv() cannot read sock"); + let buf = emu.maps.read_dword(emu.regs.get_esp()+4).expect("recv() cannot read buff"); + let len = emu.maps.read_dword(emu.regs.get_esp()+8).expect("recv() cannot read len"); + let flags = emu.maps.read_dword(emu.regs.get_esp()+12).expect("recv() cannot read flags"); println!("{}** {} syscall socketcall recv() sock: {} buff: {} len: {} {}", emu.colors.light_red, emu.pos, sock, buf, len, emu.colors.nc); - if !helper::socket_exist(sock) { + if !helper::socket_exist(sock as u64) { println!("\tbad socket/"); - emu.regs.eax = constants::ENOTSOCK; + emu.regs.rax = constants::ENOTSOCK; return; } @@ -599,27 +599,27 @@ pub fn gateway(emu:&mut emu::Emu) { let mut rbuff:Vec = vec![0;len as usize]; let n = endpoint::sock_recv(&mut rbuff); - emu.maps.write_buffer(buf, &rbuff); + emu.maps.write_buffer(buf as u64, &rbuff); println!("\nreceived {} bytes from the endpoint.", n); - emu.regs.eax = n as u32; + emu.regs.rax = n as u64; } else { - emu.regs.eax = len; //TODO: avoid loops + emu.regs.rax = len as u64; //TODO: avoid loops } } constants::SYS_SENDTO => { - let sock = emu.maps.read_dword(emu.regs.esp).expect("sendto() cannot read sock"); - let buf = emu.maps.read_dword(emu.regs.esp+4).expect("sendto() cannot read buff"); - let len = emu.maps.read_dword(emu.regs.esp+8).expect("sendto() cannot read len"); - let flags = emu.maps.read_dword(emu.regs.esp+12).expect("sendto() cannot read flags"); - let sockaddr = emu.maps.read_dword(emu.regs.esp+16).expect("sendto() cannot read sockaddr"); - let addrlen = emu.maps.read_dword(emu.regs.esp+20).expect("sendto() cannot read addrlen"); - - if sockaddr != 0 && emu.maps.is_mapped(sockaddr) { - let fam:u16 = emu.maps.read_word(sockaddr).expect("cannot read family id"); - let port:u16 = emu.maps.read_word(sockaddr+2).expect("cannot read the port").to_be(); - let ip:u32 = emu.maps.read_dword(sockaddr+4).expect("cannot read the ip"); + let sock = emu.maps.read_dword(emu.regs.get_esp()).expect("sendto() cannot read sock"); + let buf = emu.maps.read_dword(emu.regs.get_esp()+4).expect("sendto() cannot read buff"); + let len = emu.maps.read_dword(emu.regs.get_esp()+8).expect("sendto() cannot read len"); + let flags = emu.maps.read_dword(emu.regs.get_esp()+12).expect("sendto() cannot read flags"); + let sockaddr = emu.maps.read_dword(emu.regs.get_esp()+16).expect("sendto() cannot read sockaddr"); + let addrlen = emu.maps.read_dword(emu.regs.get_esp()+20).expect("sendto() cannot read addrlen"); + + if sockaddr != 0 && emu.maps.is_mapped(sockaddr as u64) { + let fam:u16 = emu.maps.read_word(sockaddr as u64).expect("cannot read family id"); + let port:u16 = emu.maps.read_word((sockaddr+2) as u64).expect("cannot read the port").to_be(); + let ip:u32 = emu.maps.read_dword((sockaddr+4) as u64).expect("cannot read the ip"); let sip = format!("{}.{}.{}.{}", ip&0xff, (ip&0xff00)>>8, (ip&0xff0000)>>16, (ip&0xff000000)>>24); println!("{}** {} syscall socketcall sendto() sock: {} buff: {} len: {} fam: {} {}:{} {}", emu.colors.light_red, emu.pos, sock, buf, len, fam, sip, port, emu.colors.nc); @@ -627,39 +627,39 @@ pub fn gateway(emu:&mut emu::Emu) { println!("{}** {} syscall socketcall sendto() sock: {} buff: {} len: {} {}", emu.colors.light_red, emu.pos, sock, buf, len, emu.colors.nc); } - if !helper::socket_exist(sock) { + if !helper::socket_exist(sock as u64) { println!("\tbad socket/"); - emu.regs.eax = constants::ENOTSOCK; + emu.regs.rax = constants::ENOTSOCK; } else { - emu.regs.eax = len; + emu.regs.rax = len as u64; } } constants::SYS_RECVFROM => { - let sock = emu.maps.read_dword(emu.regs.esp).expect("recvfrom() cannot read sock"); - let buf = emu.maps.read_dword(emu.regs.esp+8).expect("recvfrom() cannot read buff"); - let len = emu.maps.read_dword(emu.regs.esp+12).expect("recvfrom() cannot read len"); - let flags = emu.maps.read_dword(emu.regs.esp+16).expect("recvfrom() cannot read flags"); - let sockaddr = emu.maps.read_dword(emu.regs.esp+20).expect("recvfrom() cannot read sockaddr"); - let addrlen = emu.maps.read_dword(emu.regs.esp+24).expect("recvfrom() cannot read sockaddr len"); - - if sockaddr != 0 && emu.maps.is_mapped(sockaddr) { + let sock = emu.maps.read_dword(emu.regs.get_esp()).expect("recvfrom() cannot read sock"); + let buf = emu.maps.read_dword(emu.regs.get_esp()+8).expect("recvfrom() cannot read buff"); + let len = emu.maps.read_dword(emu.regs.get_esp()+12).expect("recvfrom() cannot read len"); + let flags = emu.maps.read_dword(emu.regs.get_esp()+16).expect("recvfrom() cannot read flags"); + let sockaddr = emu.maps.read_dword(emu.regs.get_esp()+20).expect("recvfrom() cannot read sockaddr"); + let addrlen = emu.maps.read_dword(emu.regs.get_esp()+24).expect("recvfrom() cannot read sockaddr len"); + + if sockaddr != 0 && emu.maps.is_mapped(sockaddr as u64) { let port:u16 = 8080; let incoming_ip:u32 = 0x11223344; - emu.maps.write_word(sockaddr, 0x0002); - emu.maps.write_word(sockaddr+2, port.to_le()); //TODO: port should be the same than bind() - emu.maps.write_dword(sockaddr+4, incoming_ip); + emu.maps.write_word(sockaddr as u64, 0x0002); + emu.maps.write_word((sockaddr+2) as u64, port.to_le()); //TODO: port should be the same than bind() + emu.maps.write_dword((sockaddr+4) as u64, incoming_ip); } println!("{}** {} syscall socketcall recvfrom() sock: {} buff: {} len: {} {}", emu.colors.light_red, emu.pos, sock, buf, len, emu.colors.nc); - if !helper::socket_exist(sock) { + if !helper::socket_exist(sock as u64) { println!("\tbad socket/"); - emu.regs.eax = constants::ENOTSOCK; + emu.regs.rax = constants::ENOTSOCK; } else { - emu.regs.eax = len; //TODO: avoid loops + emu.regs.rax = len as u64; //TODO: avoid loops } } @@ -696,7 +696,7 @@ pub fn gateway(emu:&mut emu::Emu) { println!("{}** {} syscall socketcall sendmsg() {}", emu.colors.light_red, emu.pos, emu.colors.nc); } - _=> panic!("invalid socket call {} ", emu.regs.ebx), + _=> panic!("invalid socket call {} ", emu.regs.rbx), } @@ -1156,10 +1156,10 @@ pub fn gateway(emu:&mut emu::Emu) { _ => { let data:Vec = vec!["restart_syscall".to_string(), "exit".to_string(), "fork".to_string(), "read".to_string(), "write".to_string(), "open".to_string(), "close".to_string(), "waitpid".to_string(), "creat".to_string(), "link".to_string(), "unlink".to_string(), "execve".to_string(), "chdir".to_string(), "time".to_string(), "mknod".to_string(), "chmod".to_string(), "lchown".to_string(), "break".to_string(), "oldstat".to_string(), "lseek".to_string(), "getpid".to_string(), "mount".to_string(), "umount".to_string(), "setuid".to_string(), "getuid".to_string(), "stime".to_string(), "ptrace".to_string(), "alarm".to_string(), "oldfstat".to_string(), "pause".to_string(), "utime".to_string(), "stty".to_string(), "gtty".to_string(), "access".to_string(), "nice".to_string(), "ftime".to_string(), "sync".to_string(), "kill".to_string(), "rename".to_string(), "mkdir".to_string(), "rmdir".to_string(), "dup".to_string(), "pipe".to_string(), "times".to_string(), "prof".to_string(), "brk".to_string(), "setgid".to_string(), "getgid".to_string(), "signal".to_string(), "geteuid".to_string(), "getegid".to_string(), "acct".to_string(), "umount2".to_string(), "lock".to_string(), "ioctl".to_string(), "fcntl".to_string(), "mpx".to_string(), "setpgid".to_string(), "ulimit".to_string(), "oldolduname".to_string(), "umask".to_string(), "chroot".to_string(), "ustat".to_string(), "dup2".to_string(), "getppid".to_string(), "getpgrp".to_string(), "setsid".to_string(), "sigaction".to_string(), "sgetmask".to_string(), "ssetmask".to_string(), "setreuid".to_string(), "setregid".to_string(), "sigsuspend".to_string(), "sigpending".to_string(), "sethostname".to_string(), "setrlimit".to_string(), "getrlimit".to_string(), "getrusage".to_string(), "gettimeofday".to_string(), "settimeofday".to_string(), "getgroups".to_string(), "setgroups".to_string(), "select".to_string(), "symlink".to_string(), "oldlstat".to_string(), "readlink".to_string(), "uselib".to_string(), "swapon".to_string(), "reboot".to_string(), "readdir".to_string(), "mmap".to_string(), "munmap".to_string(), "truncate".to_string(), "ftruncate".to_string(), "fchmod".to_string(), "fchown".to_string(), "getpriority".to_string(), "setpriority".to_string(), "profil".to_string(), "statfs".to_string(), "fstatfs".to_string(), "ioperm".to_string(), "socketcall".to_string(), "syslog".to_string(), "setitimer".to_string(), "getitimer".to_string(), "stat".to_string(), "lstat".to_string(), "fstat".to_string(), "olduname".to_string(), "iopl".to_string(), "vhangup".to_string(), "idle".to_string(), "vm86old".to_string(), "wait4".to_string(), "swapoff".to_string(), "sysinfo".to_string(), "ipc".to_string(), "fsync".to_string(), "sigreturn".to_string(), "clone".to_string(), "setdomainname".to_string(), "uname".to_string(), "modify_ldt".to_string(), "adjtimex".to_string(), "mprotect".to_string(), "sigprocmask".to_string(), "create_module".to_string(), "init_module".to_string(), "delete_module".to_string(), "get_kernel_syms".to_string(), "quotactl".to_string(), "getpgid".to_string(), "fchdir".to_string(), "bdflush".to_string(), "sysfs".to_string(), "personality".to_string(), "afs_syscall".to_string(), "setfsuid".to_string(), "setfsgid".to_string(), "_llseek".to_string(), "getdents".to_string(), "_newselect".to_string(), "flock".to_string(), "msync".to_string(), "readv".to_string(), "writev".to_string(), "getsid".to_string(), "fdatasync".to_string(), "_sysctl".to_string(), "mlock".to_string(), "munlock".to_string(), "mlockall".to_string(), "munlockall".to_string(), "sched_setparam".to_string(), "sched_getparam".to_string(), "sched_setscheduler".to_string(), "sched_getscheduler".to_string(), "sched_yield".to_string(), "sched_get_priority_max".to_string(), "sched_get_priority_min".to_string(), "sched_rr_get_interval".to_string(), "nanosleep".to_string(), "mremap".to_string(), "setresuid".to_string(), "getresuid".to_string(), "vm86".to_string(), "query_module".to_string(), "poll".to_string(), "nfsservctl".to_string(), "setresgid".to_string(), "getresgid".to_string(), "prctl".to_string(), "rt_sigreturn".to_string(), "rt_sigaction".to_string(), "rt_sigprocmask".to_string(), "rt_sigpending".to_string(), "rt_sigtimedwait".to_string(), "rt_sigqueueinfo".to_string(), "rt_sigsuspend".to_string(), "pread64".to_string(), "pwrite64".to_string(), "chown".to_string(), "getcwd".to_string(), "capget".to_string(), "capset".to_string(), "sigaltstack".to_string(), "sendfile".to_string(), "getpmsg".to_string(), "putpmsg".to_string(), "vfork".to_string(), "ugetrlimit".to_string(), "mmap2".to_string(), "truncate64".to_string(), "ftruncate64".to_string(), "stat64".to_string(), "lstat64".to_string(), "fstat64".to_string(), "lchown32".to_string(), "getuid32".to_string(), "getgid32".to_string(), "geteuid32".to_string(), "getegid32".to_string(), "setreuid32".to_string(), "setregid32".to_string(), "getgroups32".to_string(), "setgroups32".to_string(), "fchown32".to_string(), "setresuid32".to_string(), "getresuid32".to_string(), "setresgid32".to_string(), "getresgid32".to_string(), "chown32".to_string(), "setuid32".to_string(), "setgid32".to_string(), "setfsuid32".to_string(), "setfsgid32".to_string(), "pivot_root".to_string(), "mincore".to_string(), "madvise".to_string(), "getdents64".to_string(), "fcntl64".to_string(), "gettid".to_string(), "readahead".to_string(), "setxattr".to_string(), "lsetxattr".to_string(), "fsetxattr".to_string(), "getxattr".to_string(), "lgetxattr".to_string(), "fgetxattr".to_string(), "listxattr".to_string(), "llistxattr".to_string(), "flistxattr".to_string(), "removexattr".to_string(), "lremovexattr".to_string(), "fremovexattr".to_string(), "tkill".to_string(), "sendfile64".to_string(), "futex".to_string(), "sched_setaffinity".to_string(), "sched_getaffinity".to_string(), "set_thread_area".to_string(), "get_thread_area".to_string(), "io_setup".to_string(), "io_destroy".to_string(), "io_getevents".to_string(), "io_submit".to_string(), "io_cancel".to_string(), "fadvise64".to_string(), "exit_group".to_string(), "lookup_dcookie".to_string(), "epoll_create".to_string(), "epoll_ctl".to_string(), "epoll_wait".to_string(), "remap_file_pages".to_string(), "set_tid_address".to_string(), "timer_create".to_string(), "timer_settime".to_string(), "timer_gettime".to_string(), "timer_getoverrun".to_string(), "timer_delete".to_string(), "clock_settime".to_string(), "clock_gettime".to_string(), "clock_getres".to_string(), "clock_nanosleep".to_string(), "statfs64".to_string(), "fstatfs64".to_string(), "tgkill".to_string(), "utimes".to_string(), "fadvise64_64".to_string(), "vserver".to_string(), "mbind".to_string(), "get_mempolicy".to_string(), "set_mempolicy".to_string(), "mq_open".to_string(), "mq_unlink".to_string(), "mq_timedsend".to_string(), "mq_timedreceive".to_string(), "mq_notify".to_string(), "mq_getsetattr".to_string(), "kexec_load".to_string(), "waitid".to_string(), "add_key".to_string(), "request_key".to_string(), "keyctl".to_string(), "ioprio_set".to_string(), "ioprio_get".to_string(), "inotify_init".to_string(), "inotify_add_watch".to_string(), "inotify_rm_watch".to_string(), "migrate_pages".to_string(), "openat".to_string(), "mkdirat".to_string(), "mknodat".to_string(), "fchownat".to_string(), "futimesat".to_string(), "fstatat64".to_string(), "unlinkat".to_string(), "renameat".to_string(), "linkat".to_string(), "symlinkat".to_string(), "readlinkat".to_string(), "fchmodat".to_string(), "faccessat".to_string(), "pselect6".to_string(), "ppoll".to_string(), "unshare".to_string(), "set_robust_list".to_string(), "get_robust_list".to_string(), "splice".to_string(), "sync_file_range".to_string(), "tee".to_string(), "vmsplice".to_string(), "move_pages".to_string(), "getcpu".to_string(), "epoll_pwait".to_string(), "utimensat".to_string(), "signalfd".to_string(), "timerfd_create".to_string(), "eventfd".to_string(), "fallocate".to_string(), "timerfd_settime".to_string(), "timerfd_gettime".to_string(), "signalfd4".to_string(), "eventfd2".to_string(), "epoll_create1".to_string(), "dup3".to_string(), "pipe2".to_string(), "inotify_init1".to_string(), "preadv".to_string(), "pwritev".to_string(), "rt_tgsigqueueinfo".to_string(), "perf_event_open".to_string(), "recvmmsg".to_string(), "fanotify_init".to_string(), "fanotify_mark".to_string(), "prlimit64".to_string(), "name_to_handle_at".to_string(), "open_by_handle_at".to_string(), "clock_adjtime".to_string(), "syncfs".to_string(), "sendmmsg".to_string(), "setns".to_string(), "process_vm_readv".to_string(), "process_vm_writev".to_string(), "kcmp".to_string(), "finit_module".to_string(), "sched_setattr".to_string(), "sched_getattr".to_string(), "renameat2".to_string(), "seccomp".to_string(), "getrandom".to_string(), "memfd_create".to_string(), "bpf".to_string(), "execveat".to_string(), "socket".to_string(), "socketpair".to_string(), "bind".to_string(), "connect".to_string(), "listen".to_string(), "accept4".to_string(), "getsockopt".to_string(), "setsockopt".to_string(), "getsockname".to_string(), "getpeername".to_string(), "sendto".to_string(), "sendmsg".to_string(), "recvfrom".to_string(), "recvmsg".to_string(), "shutdown".to_string(), "userfaultfd".to_string(), "membarrier".to_string(), "mlock2".to_string(), "copy_file_range".to_string(), "preadv2".to_string(), "pwritev2".to_string(), "pkey_mprotect".to_string(), "pkey_alloc".to_string(), "pkey_free".to_string(), "statx".to_string(), "arch_prctl".to_string(), "io_pgetevents".to_string(), "rseq".to_string(), "semget".to_string(), "semctl".to_string(), "shmget".to_string(), "shmctl".to_string(), "shmat".to_string(), "shmdt".to_string(), "msgget".to_string(), "msgsnd".to_string(), "msgrcv".to_string(), "msgctl".to_string(), "clock_gettime64".to_string(), "clock_settime64".to_string(), "clock_adjtime64".to_string(), "clock_getres_time64".to_string(), "clock_nanosleep_time64".to_string(), "timer_gettime64".to_string(), "timer_settime64".to_string(), "timerfd_gettime64".to_string(), "timerfd_settime64".to_string(), "utimensat_time64".to_string(), "pselect6_time64".to_string(), "ppoll_time64".to_string(), "io_pgetevents_time64".to_string(), "recvmmsg_time64".to_string(), "mq_timedsend_time64".to_string(), "mq_timedreceive_time64".to_string(), "semtimedop_time64".to_string(), "rt_sigtimedwait_time64".to_string(), "futex_time64".to_string(), "sched_rr_get_interval_time64".to_string(), "pidfd_send_signal".to_string(), "io_uring_setup".to_string(), "io_uring_enter".to_string(), "io_uring_register".to_string(), "open_tree".to_string(), "move_mount".to_string(), "fsopen".to_string(), "fsconfig".to_string(), "fsmount".to_string(), "fspick".to_string(), "pidfd_open".to_string(), "clone3".to_string(), "close_range".to_string(), "openat2".to_string(), "pidfd_getfd".to_string(), "faccessat2".to_string(), "process_madvise".to_string(), "epoll_pwait2".to_string(), "mount_setattr".to_string(), "quotactl_fd".to_string(), "landlock_create_ruleset".to_string(), "landlock_add_rule".to_string(), "landlock_restrict_self".to_string(), "memfd_secret".to_string(), "process_mrelease".to_string()]; - if emu.regs.eax >= data.len() as u32 { - println!("{}** interrupt 0x80 bad eax value 0x{:x} {}", emu.colors.light_red, emu.regs.eax, emu.colors.nc); + if emu.regs.rax >= data.len() as u64 { + println!("{}** interrupt 0x80 bad rax value 0x{:x} {}", emu.colors.light_red, emu.regs.rax, emu.colors.nc); } else { - println!("{}** interrupt 0x80 function:{} {}", emu.colors.light_red, data[emu.regs.eax as usize], emu.colors.nc); + println!("{}** interrupt 0x80 function:{} {}", emu.colors.light_red, data[emu.regs.rax as usize], emu.colors.nc); } } } diff --git a/src/emu/winapi/advapi32.rs b/src/emu/winapi/advapi32.rs index 2530dc5..726a5d6 100644 --- a/src/emu/winapi/advapi32.rs +++ b/src/emu/winapi/advapi32.rs @@ -10,18 +10,18 @@ pub fn gateway(addr:u32, emu:&mut emu::Emu) { } fn StartServiceCtrlDispatcherA(emu:&mut emu::Emu) { - let service_table_entry_ptr = emu.maps.read_dword(emu.regs.esp).expect("advapi32!StartServiceCtrlDispatcherA error reading service_table_entry pointer"); + let service_table_entry_ptr = emu.maps.read_dword(emu.regs.get_esp()).expect("advapi32!StartServiceCtrlDispatcherA error reading service_table_entry pointer"); - let service_name = emu.maps.read_dword(service_table_entry_ptr).expect("advapi32!StartServiceCtrlDispatcherA error reading service_name"); - let service_name = emu.maps.read_dword(service_table_entry_ptr+4).expect("advapi32!StartServiceCtrlDispatcherA error reading service_name"); + let service_name = emu.maps.read_dword(service_table_entry_ptr as u64).expect("advapi32!StartServiceCtrlDispatcherA error reading service_name"); + let service_name = emu.maps.read_dword((service_table_entry_ptr+4) as u64).expect("advapi32!StartServiceCtrlDispatcherA error reading service_name"); - emu.stack_pop(false); - emu.regs.eax = 1; + emu.stack_pop32(false); + emu.regs.set_eax(1); } fn StartServiceCtrlDispatcherW(emu:&mut emu::Emu) { - let service_table_entry_ptr = emu.maps.read_dword(emu.regs.esp).expect("advapi32!StartServiceCtrlDispatcherW error reading service_table_entry pointer"); + let service_table_entry_ptr = emu.maps.read_dword(emu.regs.get_esp()).expect("advapi32!StartServiceCtrlDispatcherW error reading service_table_entry pointer"); - emu.stack_pop(false); - emu.regs.eax = 1; + emu.stack_pop32(false); + emu.regs.set_eax(1); } diff --git a/src/emu/winapi/helper.rs b/src/emu/winapi/helper.rs index 72f654f..64358cd 100644 --- a/src/emu/winapi/helper.rs +++ b/src/emu/winapi/helper.rs @@ -2,13 +2,13 @@ use lazy_static::lazy_static; use std::sync::Mutex; lazy_static! { - static ref HANDLERS:Mutex> = Mutex::new(vec![0;0]); - static ref SOCKETS:Mutex> = Mutex::new(vec![0;0]); + static ref HANDLERS:Mutex> = Mutex::new(vec![0;0]); + static ref SOCKETS:Mutex> = Mutex::new(vec![0;0]); } -pub fn handler_create() -> u32 { - let new_handle:u32; +pub fn handler_create() -> u64 { + let new_handle:u64; let mut handles = HANDLERS.lock().unwrap(); if handles.len() == 0 { @@ -22,7 +22,7 @@ pub fn handler_create() -> u32 { return new_handle; } -pub fn handler_close(hndl:u32) -> bool { +pub fn handler_close(hndl:u64) -> bool { let mut handles = HANDLERS.lock().unwrap(); let idx = match handles.iter().position(|h| *h == hndl) { Some(i) => i, @@ -39,7 +39,7 @@ pub fn handler_print() { } } -pub fn handler_exist(hndl:u32) -> bool { +pub fn handler_exist(hndl:u64) -> bool { let handles = HANDLERS.lock().unwrap(); match handles.iter().position(|h| *h == hndl) { Some(_) => return true, @@ -48,8 +48,8 @@ pub fn handler_exist(hndl:u32) -> bool { } -pub fn socket_create() -> u32 { - let new_socket:u32; +pub fn socket_create() -> u64 { + let new_socket:u64; let mut sockets = SOCKETS.lock().unwrap(); if sockets.len() == 0 { @@ -66,7 +66,7 @@ pub fn socket_create() -> u32 { return new_socket; } -pub fn socket_close(sock:u32) -> bool { +pub fn socket_close(sock:u64) -> bool { let mut sockets = SOCKETS.lock().unwrap(); let idx = match sockets.iter().position(|s| *s == sock) { Some(i) => i, @@ -76,7 +76,7 @@ pub fn socket_close(sock:u32) -> bool { return true; } -pub fn socket_exist(sock:u32) -> bool { +pub fn socket_exist(sock:u64) -> bool { let sockets = SOCKETS.lock().unwrap(); match sockets.iter().position(|s| *s == sock) { Some(_) => return true, diff --git a/src/emu/winapi/kernel32.rs b/src/emu/winapi/kernel32.rs index ee3fb0d..ac01a68 100644 --- a/src/emu/winapi/kernel32.rs +++ b/src/emu/winapi/kernel32.rs @@ -101,70 +101,70 @@ lazy_static! { fn GetProcAddress(emu:&mut emu::Emu) { - let hndl = emu.maps.read_dword(emu.regs.esp).expect("kernel32!GetProcAddress cannot read the handle"); - let func_ptr = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!GetProcAddress cannot read the func name"); + let hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!GetProcAddress cannot read the handle") as u64; + let func_ptr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!GetProcAddress cannot read the func name") as u64; let func = emu.maps.read_string(func_ptr).to_lowercase(); //println!("looking for '{}'", func); - emu.stack_pop(false); - emu.stack_pop(false); + emu.stack_pop32(false); + emu.stack_pop32(false); // https://github.com/ssherei/asm/blob/master/get_api.asm let peb = emu.maps.get_mem("peb"); let peb_base = peb.get_base(); - let ldr = peb.read_dword(peb_base + 0x0c); - let mut flink = emu.maps.read_dword(ldr + 0x14).expect("kernel32!GetProcAddress error reading flink"); + let ldr = peb.read_dword(peb_base + 0x0c) as u64; + let mut flink = emu.maps.read_dword(ldr + 0x14).expect("kernel32!GetProcAddress error reading flink") as u64; loop { // walk modules - let mod_name_ptr = emu.maps.read_dword(flink + 0x28).expect("kernel32!GetProcAddress error reading mod_name_ptr"); - let mod_base = emu.maps.read_dword(flink + 0x10).expect("kernel32!GetProcAddress error reading mod_addr"); + let mod_name_ptr = emu.maps.read_dword(flink + 0x28).expect("kernel32!GetProcAddress error reading mod_name_ptr") as u64; + let mod_base = emu.maps.read_dword(flink + 0x10).expect("kernel32!GetProcAddress error reading mod_addr") as u64; let mod_name = emu.maps.read_wide_string(mod_name_ptr); let pe_hdr = match emu.maps.read_dword(mod_base + 0x3c) { //.expect("kernel32!GetProcAddress error reading pe_hdr"); - Some(hdr) => hdr, - None => { emu.regs.eax = 0; return; } + Some(hdr) => hdr as u64, + None => { emu.regs.rax = 0; return; } }; - let export_table_rva = emu.maps.read_dword(mod_base + pe_hdr + 0x78).expect("kernel32!GetProcAddress error reading export_table_rva"); + let export_table_rva = emu.maps.read_dword(mod_base + pe_hdr + 0x78).expect("kernel32!GetProcAddress error reading export_table_rva") as u64; if export_table_rva == 0 { - flink = emu.maps.read_dword(flink).expect("kernel32!GetProcAddress error reading next flink"); + flink = emu.maps.read_dword(flink).expect("kernel32!GetProcAddress error reading next flink") as u64; continue; } let export_table = export_table_rva + mod_base; - let mut num_of_funcs = emu.maps.read_dword(export_table + 0x18).expect("kernel32!GetProcAddress error reading the num_of_funcs"); + let mut num_of_funcs = emu.maps.read_dword(export_table + 0x18).expect("kernel32!GetProcAddress error reading the num_of_funcs") as u64; - let func_name_tbl_rva = emu.maps.read_dword(export_table + 0x20).expect("kernel32!GetProcAddress error reading func_name_tbl_rva"); + let func_name_tbl_rva = emu.maps.read_dword(export_table + 0x20).expect("kernel32!GetProcAddress error reading func_name_tbl_rva") as u64; let func_name_tbl = func_name_tbl_rva + mod_base; if num_of_funcs == 0 { - flink = emu.maps.read_dword(flink).expect("kernel32!GetProcAddress error reading next flink"); + flink = emu.maps.read_dword(flink).expect("kernel32!GetProcAddress error reading next flink") as u64; continue; } loop { // walk functions num_of_funcs -= 1; - let func_name_rva = emu.maps.read_dword(func_name_tbl + num_of_funcs * 4).expect("kernel32!GetProcAddress error reading func_rva"); + let func_name_rva = emu.maps.read_dword(func_name_tbl + num_of_funcs * 4).expect("kernel32!GetProcAddress error reading func_rva") as u64; let func_name_va = func_name_rva + mod_base; let func_name = emu.maps.read_string(func_name_va).to_lowercase(); if func_name == func { - let ordinal_tbl_rva = emu.maps.read_dword(export_table + 0x24).expect("kernel32!GetProcAddress error reading ordinal_tbl_rva"); + let ordinal_tbl_rva = emu.maps.read_dword(export_table + 0x24).expect("kernel32!GetProcAddress error reading ordinal_tbl_rva") as u64; let ordinal_tbl = ordinal_tbl_rva + mod_base; - let ordinal = emu.maps.read_word(ordinal_tbl + 2 * num_of_funcs).expect("kernel32!GetProcAddress error reading ordinal"); - let func_addr_tbl_rva = emu.maps.read_dword(export_table + 0x1c).expect("kernel32!GetProcAddress error reading func_addr_tbl_rva"); + let ordinal = emu.maps.read_word(ordinal_tbl + 2 * num_of_funcs).expect("kernel32!GetProcAddress error reading ordinal") as u64; + let func_addr_tbl_rva = emu.maps.read_dword(export_table + 0x1c).expect("kernel32!GetProcAddress error reading func_addr_tbl_rva") as u64; let func_addr_tbl = func_addr_tbl_rva + mod_base; - let func_rva = emu.maps.read_dword(func_addr_tbl + 4 * ordinal as u32).expect("kernel32!GetProcAddress error reading func_rva"); + let func_rva = emu.maps.read_dword(func_addr_tbl + 4 * ordinal).expect("kernel32!GetProcAddress error reading func_rva") as u64; let func_va = func_rva + mod_base; - emu.regs.eax = func_va; + emu.regs.rax = func_va; - println!("{}** {} kernel32!GetProcAddress `{}!{}` =0x{:x} {}", emu.colors.light_red, emu.pos, mod_name, func_name, emu.regs.eax, emu.colors.nc); + println!("{}** {} kernel32!GetProcAddress `{}!{}` =0x{:x} {}", emu.colors.light_red, emu.pos, mod_name, func_name, emu.regs.get_eax() as u32, emu.colors.nc); return; } @@ -173,30 +173,30 @@ fn GetProcAddress(emu:&mut emu::Emu) { } } - flink = emu.maps.read_dword(flink).expect("kernel32!GetProcAddress error reading next flink"); + flink = emu.maps.read_dword(flink).expect("kernel32!GetProcAddress error reading next flink") as u64; } } fn LoadLibraryA(emu:&mut emu::Emu) { - let dllptr = emu.maps.read_dword(emu.regs.esp).expect("bad LoadLibraryA parameter"); + let dllptr = emu.maps.read_dword(emu.regs.get_esp()).expect("bad LoadLibraryA parameter") as u64; let dll = emu.maps.read_string(dllptr); match dll.to_lowercase().as_str() { - "ntdll"|"ntdll.dll" => emu.regs.eax = emu.maps.get_mem("ntdll").get_base(), - "ws2_32"|"ws2_32.dll" => emu.regs.eax = emu.maps.get_mem("ws2_32").get_base(), - "wininet"|"wininet.dll" => emu.regs.eax = emu.maps.get_mem("wininet").get_base(), - "advapi32"|"advapi32.dll" => emu.regs.eax = emu.maps.get_mem("advapi32").get_base(), - "kernel32"|"kernel32.dll" => emu.regs.eax = emu.maps.get_mem("kernel32").get_base(), + "ntdll"|"ntdll.dll" => emu.regs.rax = emu.maps.get_mem("ntdll").get_base(), + "ws2_32"|"ws2_32.dll" => emu.regs.rax = emu.maps.get_mem("ws2_32").get_base(), + "wininet"|"wininet.dll" => emu.regs.rax = emu.maps.get_mem("wininet").get_base(), + "advapi32"|"advapi32.dll" => emu.regs.rax = emu.maps.get_mem("advapi32").get_base(), + "kernel32"|"kernel32.dll" => emu.regs.rax = emu.maps.get_mem("kernel32").get_base(), _ => unimplemented!("/!\\ kernel32!LoadLibraryA: lib not found {}", dll), } - println!("{}** {} kernel32!LoadLibraryA '{}' =0x{:x} {}", emu.colors.light_red, emu.pos, dll, emu.regs.eax, emu.colors.nc); + println!("{}** {} kernel32!LoadLibraryA '{}' =0x{:x} {}", emu.colors.light_red, emu.pos, dll, emu.regs.get_eax() as u32, emu.colors.nc); - emu.stack_pop(false); + emu.stack_pop32(false); } fn LoadLibraryExA(emu:&mut emu::Emu) { - let libname_ptr = emu.maps.read_dword(emu.regs.esp).expect("kernel32_LoadLibraryExA: error reading libname ptr param"); + let libname_ptr = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32_LoadLibraryExA: error reading libname ptr param") as u64; let libname = emu.maps.read_string(libname_ptr); println!("{}** {} LoadLibraryExA '{}' {}", emu.colors.light_red, emu.pos, libname, emu.colors.nc); @@ -208,35 +208,35 @@ fn LoadLibraryExW(emu:&mut emu::Emu) { } fn LoadLibraryW(emu:&mut emu::Emu) { - let dllptr = match emu.maps.read_dword(emu.regs.esp) { - Some(v) => v, + let dllptr = match emu.maps.read_dword(emu.regs.get_esp()) { + Some(v) => v as u64, None => panic!("bad LoadLibraryW parameter"), }; let dll = emu.maps.read_wide_string(dllptr); println!("{}** {} LoadLibraryW '{}' {}", emu.colors.light_red, emu.pos, dll, emu.colors.nc); if dll == "ntdll.dll" { - emu.regs.eax = emu.maps.get_mem("ntdll").get_base(); + emu.regs.rax = emu.maps.get_mem("ntdll").get_base(); } - emu.stack_pop(false); + emu.stack_pop32(false); } fn WinExec(emu:&mut emu::Emu) { - let cmdline_ptr = emu.maps.read_dword(emu.regs.esp).expect("cannot read the cmdline parameter of WinExec"); + let cmdline_ptr = emu.maps.read_dword(emu.regs.get_esp()).expect("cannot read the cmdline parameter of WinExec") as u64; let cmdline = emu.maps.read_string(cmdline_ptr); //emu.spawn_console(); println!("{}** {} WinExec '{}' {}", emu.colors.light_red, emu.pos, cmdline, emu.colors.nc); - emu.regs.eax = 0; - emu.stack_pop(false); + emu.regs.rax = 0; + emu.stack_pop32(false); } fn GetVersion(emu:&mut emu::Emu) { - emu.regs.eax = emu::constants::VERSION; - println!("{}** {} kernel32!GetVersion =0x{:x} {}", emu.colors.light_red, emu.pos, emu.regs.eax, emu.colors.nc); + emu.regs.rax = emu::constants::VERSION; + println!("{}** {} kernel32!GetVersion =0x{:x} {}", emu.colors.light_red, emu.pos, emu.regs.get_eax() as u32, emu.colors.nc); } fn CreateProcessA(emu:&mut emu::Emu) { @@ -245,36 +245,36 @@ fn CreateProcessA(emu:&mut emu::Emu) { [in, out, optional] LPSTR lpCommandLine, */ - let appname_ptr = emu.maps.read_dword(emu.regs.esp).expect("kernel32!CreateProcessA: cannot read stack"); - let cmdline_ptr = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!CreateProcessA: cannot read stack2"); + let appname_ptr = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!CreateProcessA: cannot read stack") as u64; + let cmdline_ptr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!CreateProcessA: cannot read stack2") as u64; let appname = emu.maps.read_string(appname_ptr); let cmdline = emu.maps.read_string(cmdline_ptr); println!("{}** {} kernel32!CreateProcessA {} {} {}", emu.colors.light_red, emu.pos, appname, cmdline, emu.colors.nc); for _ in 0..10 { - emu.stack_pop(false); + emu.stack_pop32(false); } - emu.regs.eax = 1; + emu.regs.rax = 1; } fn WaitForSingleObject(emu:&mut emu::Emu) { - let handle = emu.maps.read_dword(emu.regs.esp).expect("kernel32!WaitForSingleObject error reading handle"); - let millis = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!WaitForSingleObject error reading millis"); + let handle = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!WaitForSingleObject error reading handle") as u64; + let millis = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!WaitForSingleObject error reading millis"); println!("{}** {} kernel32!WaitForSingleObject hndl: {} millis: {} {}", emu.colors.light_red, emu.pos, handle, millis, emu.colors.nc); - emu.stack_pop(false); - emu.stack_pop(false); - emu.regs.eax = emu::constants::WAIT_TIMEOUT; + emu.stack_pop32(false); + emu.stack_pop32(false); + emu.regs.rax = emu::constants::WAIT_TIMEOUT; } fn VirtualAlloc(emu:&mut emu::Emu) { - let addr = emu.maps.read_dword(emu.regs.esp).expect("kernel32!VirtualAlloc error reading addr"); - let size = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!VirtualAlloc error reading size ptr"); - let atype = emu.maps.read_dword(emu.regs.esp+8).expect("kernel32!VirtualAlloc error reading type"); - let protect = emu.maps.read_dword(emu.regs.esp+12).expect("kernel32!VirtualAlloc error reading protect"); + let addr = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!VirtualAlloc error reading addr") as u64; + let size = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!VirtualAlloc error reading size ptr") as u64; + let atype = emu.maps.read_dword(emu.regs.get_esp()+8).expect("kernel32!VirtualAlloc error reading type"); + let protect = emu.maps.read_dword(emu.regs.get_esp()+12).expect("kernel32!VirtualAlloc error reading protect"); let base = emu.maps.alloc(size).expect("kernel32!VirtualAlloc out of memory"); let alloc = emu.maps.create_map(format!("alloc_{:x}", base).as_str()); @@ -283,19 +283,19 @@ fn VirtualAlloc(emu:&mut emu::Emu) { println!("{}** {} kernel32!VirtualAlloc sz: {} addr: 0x{:x} {}", emu.colors.light_red, emu.pos, size, base, emu.colors.nc); - emu.regs.eax = base; + emu.regs.rax = base; for _ in 0..4 { - emu.stack_pop(false); + emu.stack_pop32(false); } } fn VirtualAllocEx(emu:&mut emu::Emu) { - let proc_hndl = emu.maps.read_dword(emu.regs.esp).expect("kernel32!VirtualAllocEx cannot read the proc handle"); - let addr = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!VirtualAllocEx cannot read the address"); - let size = emu.maps.read_dword(emu.regs.esp+8).expect("kernel32!VirtualAllocEx cannot read the size"); - let alloc_type = emu.maps.read_dword(emu.regs.esp+12).expect("kernel32!VirtualAllocEx cannot read the type"); - let protect = emu.maps.read_dword(emu.regs.esp+16).expect("kernel32!VirtualAllocEx cannot read the protect"); + let proc_hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!VirtualAllocEx cannot read the proc handle") as u64; + let addr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!VirtualAllocEx cannot read the address") as u64; + let size = emu.maps.read_dword(emu.regs.get_esp()+8).expect("kernel32!VirtualAllocEx cannot read the size") as u64; + let alloc_type = emu.maps.read_dword(emu.regs.get_esp()+12).expect("kernel32!VirtualAllocEx cannot read the type"); + let protect = emu.maps.read_dword(emu.regs.get_esp()+16).expect("kernel32!VirtualAllocEx cannot read the protect"); println!("{}** {} kernel32!VirtualAllocEx hproc: 0x{:x} addr: 0x{:x} {}", emu.colors.light_red, emu.pos, proc_hndl, addr, emu.colors.nc); @@ -304,78 +304,78 @@ fn VirtualAllocEx(emu:&mut emu::Emu) { alloc.set_base(base); alloc.set_size(size); - emu.regs.eax = base; + emu.regs.rax = base; for _ in 0..5 { - emu.stack_pop(false); + emu.stack_pop32(false); } } fn WriteProcessMemory(emu:&mut emu::Emu) { - let proc_hndl = emu.maps.read_dword(emu.regs.esp).expect("kernel32!WriteProcessMemory cannot read the proc handle"); - let addr = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!WriteProcessMemory cannot read the address"); - let buff = emu.maps.read_dword(emu.regs.esp+8).expect("kernel32!WriteProcessMemory cannot read the buffer"); - let size = emu.maps.read_dword(emu.regs.esp+12).expect("kernel32!WriteProcessMemory cannot read the size"); - let written_ptr = emu.maps.read_dword(emu.regs.esp+16).expect("kernel32!WriteProcessMemory cannot read the ptr of num of written bytes"); + let proc_hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!WriteProcessMemory cannot read the proc handle") as u64; + let addr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!WriteProcessMemory cannot read the address") as u64; + let buff = emu.maps.read_dword(emu.regs.get_esp()+8).expect("kernel32!WriteProcessMemory cannot read the buffer") as u64; + let size = emu.maps.read_dword(emu.regs.get_esp()+12).expect("kernel32!WriteProcessMemory cannot read the size") as u64; + let written_ptr = emu.maps.read_dword(emu.regs.get_esp()+16).expect("kernel32!WriteProcessMemory cannot read the ptr of num of written bytes"); println!("{}** {} kernel32!WriteProcessMemory hproc: 0x{:x} from: 0x{:x } to: 0x{:x} sz: {} {}", emu.colors.light_red, emu.pos, proc_hndl, buff, addr, size, emu.colors.nc); if emu.maps.memcpy(buff, addr, size as usize) { - emu.regs.eax = 1; + emu.regs.rax = 1; println!("{}\twritten succesfully{}", emu.colors.light_red, emu.colors.nc); } else { - emu.regs.eax = 0; + emu.regs.rax = 0; println!("{}\tcouldnt write the bytes{}", emu.colors.light_red, emu.colors.nc); } for _ in 0..5 { - emu.stack_pop(false); + emu.stack_pop32(false); } } fn CreateRemoteThread(emu:&mut emu::Emu) { - let proc_hndl = emu.maps.read_dword(emu.regs.esp).expect("kernel32!CreateRemoteThread cannot read the proc handle"); - let sec = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!CreateRemoteThread cannot read the proc security thread attributs"); - let stack_size = emu.maps.read_dword(emu.regs.esp+8).expect("kernel32!CreateRemoteThread cannot read the stack size"); - let addr = emu.maps.read_dword(emu.regs.esp+12).expect("kernel32!CreateRemoteThread cannot read the addr"); - let param = emu.maps.read_dword(emu.regs.esp+16).expect("kernel32!CreateRemoteThread cannot read the param"); - let flags = emu.maps.read_dword(emu.regs.esp+20).expect("kernel32!CreateRemoteThread cannot read the flags"); - let out_tid = emu.maps.read_dword(emu.regs.esp+24).expect("kernel32!CreateRemoteThread cannot read the tid"); + let proc_hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!CreateRemoteThread cannot read the proc handle") as u64; + let sec = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!CreateRemoteThread cannot read the proc security thread attributs") as u64; + let stack_size = emu.maps.read_dword(emu.regs.get_esp()+8).expect("kernel32!CreateRemoteThread cannot read the stack size") as u64; + let addr = emu.maps.read_dword(emu.regs.get_esp()+12).expect("kernel32!CreateRemoteThread cannot read the addr") as u64; + let param = emu.maps.read_dword(emu.regs.get_esp()+16).expect("kernel32!CreateRemoteThread cannot read the param"); + let flags = emu.maps.read_dword(emu.regs.get_esp()+20).expect("kernel32!CreateRemoteThread cannot read the flags"); + let out_tid = emu.maps.read_dword(emu.regs.get_esp()+24).expect("kernel32!CreateRemoteThread cannot read the tid") as u64; println!("{}** {} kernel32!CreateRemoteThread hproc: 0x{:x} addr: 0x{:x} {}", emu.colors.light_red, emu.pos, proc_hndl, addr, emu.colors.nc); emu.maps.write_dword(out_tid, 0x123); - emu.regs.eax = helper::handler_create(); + emu.regs.rax = helper::handler_create(); for _ in 0..7 { - emu.stack_pop(false); + emu.stack_pop32(false); } } fn CreateNamedPipeA(emu:&mut emu::Emu) { - let name_ptr = emu.maps.read_dword(emu.regs.esp).expect("kernel32!CreateNamedPipeA cannot read the name_ptr"); - let open_mode = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!CreateNamedPipeA cannot read the open_mode"); - let pipe_mode = emu.maps.read_dword(emu.regs.esp+8).expect("kernel32!CreateNamedPipeA cannot read the pipe_mode"); - let instances = emu.maps.read_dword(emu.regs.esp+12).expect("kernel32!CreateNamedPipeA cannot read the instances"); - let out_buff_sz = emu.maps.read_dword(emu.regs.esp+16).expect("kernel32!CreateNamedPipeA cannot read the to_buff_sz"); - let in_buff_sz = emu.maps.read_dword(emu.regs.esp+20).expect("kernel32!CreateNamedPipeA cannot read the in_buff_sz"); - let timeout = emu.maps.read_dword(emu.regs.esp+24).expect("kernel32!CreateNamedPipeA cannot read the timeout"); - let security = emu.maps.read_dword(emu.regs.esp+28).expect("kernel32!CreateNamedPipeA cannot read the security"); + let name_ptr = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!CreateNamedPipeA cannot read the name_ptr") as u64; + let open_mode = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!CreateNamedPipeA cannot read the open_mode"); + let pipe_mode = emu.maps.read_dword(emu.regs.get_esp()+8).expect("kernel32!CreateNamedPipeA cannot read the pipe_mode"); + let instances = emu.maps.read_dword(emu.regs.get_esp()+12).expect("kernel32!CreateNamedPipeA cannot read the instances"); + let out_buff_sz = emu.maps.read_dword(emu.regs.get_esp()+16).expect("kernel32!CreateNamedPipeA cannot read the to_buff_sz"); + let in_buff_sz = emu.maps.read_dword(emu.regs.get_esp()+20).expect("kernel32!CreateNamedPipeA cannot read the in_buff_sz"); + let timeout = emu.maps.read_dword(emu.regs.get_esp()+24).expect("kernel32!CreateNamedPipeA cannot read the timeout"); + let security = emu.maps.read_dword(emu.regs.get_esp()+28).expect("kernel32!CreateNamedPipeA cannot read the security"); let name = emu.maps.read_string(name_ptr); println!("{}** {} kernel32!CreateNamedPipeA name:{} in: 0x{:x} out: 0x{:x} {}", emu.colors.light_red, emu.pos, name, in_buff_sz, out_buff_sz, emu.colors.nc); for _ in 0..8 { - emu.stack_pop(false); + emu.stack_pop32(false); } - emu.regs.eax = helper::handler_create(); + emu.regs.rax = helper::handler_create(); } fn ConnectNamedPipe(emu:&mut emu::Emu) { - let handle = emu.maps.read_dword(emu.regs.esp).expect("kernel32!ConnectNamedPipe cannot read the handle"); - let overlapped = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!ConnectNamedPipe cannot read the overlapped"); + let handle = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!ConnectNamedPipe cannot read the handle") as u64; + let overlapped = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!ConnectNamedPipe cannot read the overlapped"); println!("{}** {} kernel32!ConnectNamedPipe hndl: 0x{:x} {}", emu.colors.light_red, emu.pos, handle, emu.colors.nc); if !helper::handler_exist(handle) { @@ -384,26 +384,26 @@ fn ConnectNamedPipe(emu:&mut emu::Emu) { for _ in 0..2 { - emu.stack_pop(false); + emu.stack_pop32(false); } - emu.regs.eax = 1; + emu.regs.rax = 1; } fn DisconnectNamedPipe(emu:&mut emu::Emu) { - let handle = emu.maps.read_dword(emu.regs.esp).expect("kernel32!DisconnectNamedPipe cannot read the handle"); + let handle = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!DisconnectNamedPipe cannot read the handle"); println!("{}** {} kernel32!DisconnectNamedPipe hndl: 0x{:x} {}", emu.colors.light_red, emu.pos, handle, emu.colors.nc); - emu.stack_pop(false); - emu.regs.eax = 1; + emu.stack_pop32(false); + emu.regs.rax = 1; } fn ReadFile(emu:&mut emu::Emu) { - let file_hndl = emu.maps.read_dword(emu.regs.esp).expect("kernel32!ReadFile cannot read the file_hndl"); - let buff = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!ReadFile cannot read the buff"); - let size = emu.maps.read_dword(emu.regs.esp+8).expect("kernel32!ReadFile cannot read the size"); - let bytes_read = emu.maps.read_dword(emu.regs.esp+12).expect("kernel32!ReadFile cannot read the bytes_read"); - let overlapped = emu.maps.read_dword(emu.regs.esp+16).expect("kernel32!ReadFile cannot read the overlapped"); + let file_hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!ReadFile cannot read the file_hndl") as u64; + let buff = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!ReadFile cannot read the buff") as u64; + let size = emu.maps.read_dword(emu.regs.get_esp()+8).expect("kernel32!ReadFile cannot read the size"); + let bytes_read = emu.maps.read_dword(emu.regs.get_esp()+12).expect("kernel32!ReadFile cannot read the bytes_read") as u64; + let overlapped = emu.maps.read_dword(emu.regs.get_esp()+16).expect("kernel32!ReadFile cannot read the overlapped"); let mut count = COUNT_READ.lock().unwrap(); *count += 1; @@ -416,11 +416,11 @@ fn ReadFile(emu:&mut emu::Emu) { if *count < 3 { // keep reading bytes emu.maps.write_dword(bytes_read, size); - emu.regs.eax = 1; + emu.regs.rax = 1; } else { // try to force finishing reading and continue the malware logic emu.maps.write_dword(bytes_read, 0); - emu.regs.eax = 0; + emu.regs.rax = 0; } //TODO: write some random bytes to the buffer @@ -433,17 +433,17 @@ fn ReadFile(emu:&mut emu::Emu) { } for _ in 0..5 { - emu.stack_pop(false); + emu.stack_pop32(false); } } fn WriteFile(emu:&mut emu::Emu) { - let file_hndl = emu.maps.read_dword(emu.regs.esp).expect("kernel32!WriteFile cannot read the file_hndl"); - let buff = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!WriteFile cannot read the buff"); - let size = emu.maps.read_dword(emu.regs.esp+8).expect("kernel32!WriteFile cannot read the size"); - let bytes_written = emu.maps.read_dword(emu.regs.esp+12).expect("kernel32!WriteFile cannot read the bytes_written"); - let overlapped = emu.maps.read_dword(emu.regs.esp+16).expect("kernel32!WriteFile cannot read the overlapped"); + let file_hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!WriteFile cannot read the file_hndl") as u64; + let buff = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!WriteFile cannot read the buff") as u64; + let size = emu.maps.read_dword(emu.regs.get_esp()+8).expect("kernel32!WriteFile cannot read the size"); + let bytes_written = emu.maps.read_dword(emu.regs.get_esp()+12).expect("kernel32!WriteFile cannot read the bytes_written") as u64; + let overlapped = emu.maps.read_dword(emu.regs.get_esp()+16).expect("kernel32!WriteFile cannot read the overlapped"); let mut count = COUNT_WRITE.lock().unwrap(); *count += 1; @@ -457,62 +457,62 @@ fn WriteFile(emu:&mut emu::Emu) { } for _ in 0..5 { - emu.stack_pop(false); + emu.stack_pop32(false); } - emu.regs.eax = 1; + emu.regs.rax = 1; } fn CloseHandle(emu:&mut emu::Emu) { - let hndl = emu.maps.read_dword(emu.regs.esp).expect("kernel32!CloseHandle cannot read the handle"); + let hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!CloseHandle cannot read the handle") as u64; println!("{}** {} kernel32!CloseHandle 0x{:X} {}", emu.colors.light_red, emu.pos, hndl, emu.colors.nc); if !helper::handler_close(hndl) { println!("\tinvalid handle.") } - emu.stack_pop(false); - emu.regs.eax = 1; + emu.stack_pop32(false); + emu.regs.rax = 1; - emu.stack_pop(false); + emu.stack_pop32(false); } fn ExitProcess(emu:&mut emu::Emu) { - let code = emu.maps.read_dword(emu.regs.esp).expect("kernel32!ExitProcess cannot read the exit code"); + let code = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!ExitProcess cannot read the exit code"); println!("{}** {} kernel32!ExitProcess code: {} {}", emu.colors.light_red, emu.pos, code, emu.colors.nc); - emu.stack_pop(false); + emu.stack_pop32(false); std::process::exit(1); } fn TerminateProcess(emu:&mut emu::Emu) { - let hndl = emu.maps.read_dword(emu.regs.esp).expect("kernel32!TerminateProcess cannot read the handle"); - let code = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!TerminateProcess cannot read the exit code"); + let hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!TerminateProcess cannot read the handle"); + let code = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!TerminateProcess cannot read the exit code"); println!("{}** {} kernel32!TerminateProcess hndl: {} code: {} {}", emu.colors.light_red, emu.pos, hndl, code, emu.colors.nc); - emu.stack_pop(false); - emu.stack_pop(false); + emu.stack_pop32(false); + emu.stack_pop32(false); } fn GetThreadContext(emu:&mut emu::Emu) { - let hndl = emu.maps.read_dword(emu.regs.esp).expect("kernel32!GetThreadContext cannot read the handle"); - let ctx_ptr = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!GetThreadContext cannot read the ctx"); + let hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!GetThreadContext cannot read the handle"); + let ctx_ptr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!GetThreadContext cannot read the ctx"); let ctx = context32::Context32::new(&emu.regs); ctx.save(ctx_ptr, &mut emu.maps); println!("{}** {} kernel32!GetThreadContext {}", emu.colors.light_red, emu.pos, emu.colors.nc); - emu.stack_pop(false); - emu.stack_pop(false); + emu.stack_pop32(false); + emu.stack_pop32(false); - emu.regs.eax = 1; + emu.regs.rax = 1; } fn SetThreadContext(emu:&mut emu::Emu) { - let hndl = emu.maps.read_dword(emu.regs.esp).expect("kernel32!SetThreadContext cannot read the handle"); - let ctx_ptr = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!SetThreadContext cannot read the ctx_ptr"); + let hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!SetThreadContext cannot read the handle"); + let ctx_ptr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!SetThreadContext cannot read the ctx_ptr"); println!("{}** {} kernel32!SetThreadContext {}", emu.colors.light_red, emu.pos, emu.colors.nc); @@ -526,180 +526,180 @@ fn SetThreadContext(emu:&mut emu::Emu) { ctx.sync(&mut emu.regs); } - emu.stack_pop(false); - emu.stack_pop(false); + emu.stack_pop32(false); + emu.stack_pop32(false); - emu.regs.eax = 1; + emu.regs.rax = 1; } fn ReadProcessMemory(emu:&mut emu::Emu) { - let hndl = emu.maps.read_dword(emu.regs.esp).expect("kernel32!ReadProcessMemory cannot read the handle"); - let addr = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!ReadProcessMemory cannot read the base address"); - let buff = emu.maps.read_dword(emu.regs.esp+8).expect("kernel32!ReadProcessMemory cannot read buff"); - let size = emu.maps.read_dword(emu.regs.esp+12).expect("kernel32!ReadProcessMemory cannot read size"); - let bytes = emu.maps.read_dword(emu.regs.esp+16).expect("kernel32!ReadProcessMemory cannot read bytes"); + let hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!ReadProcessMemory cannot read the handle"); + let addr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!ReadProcessMemory cannot read the base address"); + let buff = emu.maps.read_dword(emu.regs.get_esp()+8).expect("kernel32!ReadProcessMemory cannot read buff"); + let size = emu.maps.read_dword(emu.regs.get_esp()+12).expect("kernel32!ReadProcessMemory cannot read size"); + let bytes = emu.maps.read_dword(emu.regs.get_esp()+16).expect("kernel32!ReadProcessMemory cannot read bytes") as u64; println!("{}** {} kernel32!ReadProcessMemory hndl: {} from: 0x{:x} to: 0x{:x} sz: {} {}", emu.colors.light_red, emu.pos, hndl, addr, buff, size, emu.colors.nc); emu.maps.write_dword(bytes, size); for _ in 0..5 { - emu.stack_pop(false); + emu.stack_pop32(false); } - emu.regs.eax = 1; + emu.regs.rax = 1; } fn GetCurrentDirectoryW(emu:&mut emu::Emu) { - let buff_len = emu.maps.read_dword(emu.regs.esp).expect("kernel32!GetCurrentDirectoryW cannot read buff_len"); - let buff_ptr = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!GetCurrentDirectoryW cannot read buff_ptr"); + let buff_len = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!GetCurrentDirectoryW cannot read buff_len"); + let buff_ptr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!GetCurrentDirectoryW cannot read buff_ptr") as u64; emu.maps.write_string(buff_ptr, "c\x00:\x00\\\x00\x00\x00\x00\x00"); println!("{}** {} kernel32!GetCurrentDirectoryW {}", emu.colors.light_red, emu.pos, emu.colors.nc); - emu.stack_pop(false); - emu.stack_pop(false); + emu.stack_pop32(false); + emu.stack_pop32(false); - emu.regs.eax = 6; + emu.regs.rax = 6; } fn GetCurrentDirectoryA(emu:&mut emu::Emu) { - let buff_len = emu.maps.read_dword(emu.regs.esp).expect("kernel32!GetCurrentDirectoryW cannot read buff_len"); - let buff_ptr = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!GetCurrentDirectoryW cannot read buff_ptr"); + let buff_len = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!GetCurrentDirectoryW cannot read buff_len"); + let buff_ptr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!GetCurrentDirectoryW cannot read buff_ptr") as u64; emu.maps.write_string(buff_ptr, "c:\\\x00"); println!("{}** {} kernel32!GetCurrentDirectoryA {}", emu.colors.light_red, emu.pos, emu.colors.nc); - emu.stack_pop(false); - emu.stack_pop(false); + emu.stack_pop32(false); + emu.stack_pop32(false); - emu.regs.eax = 3; + emu.regs.rax = 3; } fn VirtualProtect(emu:&mut emu::Emu) { - let addr = emu.maps.read_dword(emu.regs.esp).expect("kernel32!VirtualProtect cannot read addr"); - let size = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!VirtualProtect cannot read size"); - let new_prot = emu.maps.read_dword(emu.regs.esp+8).expect("kernel32!VirtualProtect cannot read new_prot"); - let old_prot_ptr = emu.maps.read_dword(emu.regs.esp+12).expect("kernel32!VirtualProtect cannot read old_prot"); + let addr = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!VirtualProtect cannot read addr") as u64; + let size = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!VirtualProtect cannot read size"); + let new_prot = emu.maps.read_dword(emu.regs.get_esp()+8).expect("kernel32!VirtualProtect cannot read new_prot"); + let old_prot_ptr = emu.maps.read_dword(emu.regs.get_esp()+12).expect("kernel32!VirtualProtect cannot read old_prot") as u64; emu.maps.write_dword(old_prot_ptr, new_prot); println!("{}** {} kernel32!VirtualProtect addr: 0x{:x} sz: {} prot: {} {}", emu.colors.light_red, emu.pos, addr, size, new_prot, emu.colors.nc); for _ in 0..4 { - emu.stack_pop(false); + emu.stack_pop32(false); } - emu.regs.eax = 1; + emu.regs.rax = 1; } fn VirtualProtectEx(emu:&mut emu::Emu) { - let hproc = emu.maps.read_dword(emu.regs.esp).expect("kernel32!VirtualProtectEx cannot read hproc"); - let addr = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!VirtualProtectEx cannot read addr"); - let size = emu.maps.read_dword(emu.regs.esp+8).expect("kernel32!VirtualProtectEx cannot read size"); - let new_prot = emu.maps.read_dword(emu.regs.esp+12).expect("kernel32!VirtualProtectEx cannot read new_prot"); - let old_prot_ptr = emu.maps.read_dword(emu.regs.esp+16).expect("kernel32!VirtualProtectEx cannot read old_prot"); + let hproc = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!VirtualProtectEx cannot read hproc") as u64; + let addr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!VirtualProtectEx cannot read addr") as u64; + let size = emu.maps.read_dword(emu.regs.get_esp()+8).expect("kernel32!VirtualProtectEx cannot read size"); + let new_prot = emu.maps.read_dword(emu.regs.get_esp()+12).expect("kernel32!VirtualProtectEx cannot read new_prot"); + let old_prot_ptr = emu.maps.read_dword(emu.regs.get_esp()+16).expect("kernel32!VirtualProtectEx cannot read old_prot") as u64; emu.maps.write_dword(old_prot_ptr, new_prot); println!("{}** {} kernel32!VirtualProtectEx hproc: {} addr: 0x{:x} sz: {} prot: {} {}", emu.colors.light_red, emu.pos, hproc, addr, size, new_prot, emu.colors.nc); for _ in 0..5 { - emu.stack_pop(false); + emu.stack_pop32(false); } - emu.regs.eax = 1; + emu.regs.rax = 1; } fn ResumeThread(emu:&mut emu::Emu) { - let hndl = emu.maps.read_dword(emu.regs.esp).expect("kernel32!ResumeThread cannot read the handle"); + let hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!ResumeThread cannot read the handle"); println!("{}** {} kernel32!ResumeThread hndl: {} {}", emu.colors.light_red, emu.pos, hndl, emu.colors.nc); - emu.stack_pop(false); + emu.stack_pop32(false); - emu.regs.eax = 1; // previous suspend count + emu.regs.rax = 1; // previous suspend count } fn GetFullPathNameA(emu:&mut emu::Emu) { - let file_ptr = emu.maps.read_dword(emu.regs.esp).expect("kernel32!GetFullPathNameA cannot read file_ptr"); - let size = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!GetFullPathNameA cannot read size"); - let buff = emu.maps.read_dword(emu.regs.esp+8).expect("kernel32!GetFullPathNameA cannot read buff"); - let path = emu.maps.read_dword(emu.regs.esp+12).expect("kernel32!GetFullPathNameA cannot read path"); + let file_ptr = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!GetFullPathNameA cannot read file_ptr") as u64; + let size = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!GetFullPathNameA cannot read size"); + let buff = emu.maps.read_dword(emu.regs.get_esp()+8).expect("kernel32!GetFullPathNameA cannot read buff"); + let path = emu.maps.read_dword(emu.regs.get_esp()+12).expect("kernel32!GetFullPathNameA cannot read path"); let filename = emu.maps.read_string(file_ptr); println!("{}** {} kernel32!GetFullPathNameA file: {} {}", emu.colors.light_red, emu.pos, filename, emu.colors.nc); for _ in 0..4 { - emu.stack_pop(false); + emu.stack_pop32(false); } - emu.regs.eax = 10; + emu.regs.rax = 10; } fn GetFullPathNameW(emu:&mut emu::Emu) { - let file_ptr = emu.maps.read_dword(emu.regs.esp).expect("kernel32!GetFullPathNameW cannot read file_ptr"); - let size = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!GetFullPathNameW cannot read size"); - let buff = emu.maps.read_dword(emu.regs.esp+8).expect("kernel32!GetFullPathNameW cannot read buff"); - let path = emu.maps.read_dword(emu.regs.esp+12).expect("kernel32!GetFullPathNameW cannot read path"); + let file_ptr = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!GetFullPathNameW cannot read file_ptr") as u64; + let size = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!GetFullPathNameW cannot read size"); + let buff = emu.maps.read_dword(emu.regs.get_esp()+8).expect("kernel32!GetFullPathNameW cannot read buff"); + let path = emu.maps.read_dword(emu.regs.get_esp()+12).expect("kernel32!GetFullPathNameW cannot read path"); let filename = emu.maps.read_wide_string(file_ptr); println!("{}** {} kernel32!GetFullPathNameW file: {} {}", emu.colors.light_red, emu.pos, filename, emu.colors.nc); for _ in 0..4 { - emu.stack_pop(false); + emu.stack_pop32(false); } - emu.regs.eax = 10; + emu.regs.rax = 10; } fn SystemTimeToTzSpecificLocalTime(emu:&mut emu::Emu) { - let tz_ptr = emu.maps.read_dword(emu.regs.esp).expect("kernel32!SystemTimeToTzSpecificLocalTime cannot read tz_ptr"); - let ut_ptr = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!SystemTimeToTzSpecificLocalTime cannot read ut_ptr"); - let lt_ptr = emu.maps.read_dword(emu.regs.esp+8).expect("kernel32!SystemTimeToTzSpecificLocalTime cannot read lt_ptr"); + let tz_ptr = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!SystemTimeToTzSpecificLocalTime cannot read tz_ptr"); + let ut_ptr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!SystemTimeToTzSpecificLocalTime cannot read ut_ptr"); + let lt_ptr = emu.maps.read_dword(emu.regs.get_esp()+8).expect("kernel32!SystemTimeToTzSpecificLocalTime cannot read lt_ptr"); - emu.stack_pop(false); - emu.stack_pop(false); - emu.stack_pop(false); + emu.stack_pop32(false); + emu.stack_pop32(false); + emu.stack_pop32(false); - emu.regs.eax = 1; + emu.regs.rax = 1; } fn GetLogicalDrives(emu:&mut emu::Emu) { println!("{}** {} kernel32!GetLogicalDrives {}", emu.colors.light_red, emu.pos, emu.colors.nc); - emu.regs.eax = 0xc; + emu.regs.rax = 0xc; } fn ExpandEnvironmentStringsA(emu:&mut emu::Emu) { - let src_ptr = emu.maps.read_dword(emu.regs.esp).expect("kernel32!ExpandEnvironmentStringsA cannot read src"); - let dst_ptr = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!ExpandEnvironmentStringsA cannot read dst"); - let size = emu.maps.read_dword(emu.regs.esp+8).expect("kernel32!ExpandEnvironmentStringsA cannot read size"); + let src_ptr = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!ExpandEnvironmentStringsA cannot read src") as u64; + let dst_ptr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!ExpandEnvironmentStringsA cannot read dst") as u64; + let size = emu.maps.read_dword(emu.regs.get_esp()+8).expect("kernel32!ExpandEnvironmentStringsA cannot read size"); let src = emu.maps.read_string(src_ptr); println!("{}** {} kernel32!ExpandEnvironmentStringsA `{}` {}", emu.colors.light_red, emu.pos, src, emu.colors.nc); - emu.stack_pop(false); - emu.stack_pop(false); - emu.stack_pop(false); + emu.stack_pop32(false); + emu.stack_pop32(false); + emu.stack_pop32(false); - emu.regs.eax = 1; + emu.regs.rax = 1; //TODO: implement expand } fn ExpandEnvironmentStringsW(emu:&mut emu::Emu) { - let src_ptr = emu.maps.read_dword(emu.regs.esp).expect("kernel32!ExpandEnvironmentStringsW cannot read src"); - let dst_ptr = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!ExpandEnvironmentStringsW cannot read dst"); - let size = emu.maps.read_dword(emu.regs.esp+8).expect("kernel32!ExpandEnvironmentStringsW cannot read size"); + let src_ptr = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!ExpandEnvironmentStringsW cannot read src") as u64; + let dst_ptr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!ExpandEnvironmentStringsW cannot read dst") as u64; + let size = emu.maps.read_dword(emu.regs.get_esp()+8).expect("kernel32!ExpandEnvironmentStringsW cannot read size"); let src = emu.maps.read_wide_string(src_ptr); @@ -707,260 +707,260 @@ fn ExpandEnvironmentStringsW(emu:&mut emu::Emu) { //TODO: implement expand - emu.stack_pop(false); - emu.stack_pop(false); - emu.stack_pop(false); + emu.stack_pop32(false); + emu.stack_pop32(false); + emu.stack_pop32(false); - emu.regs.eax = 1; + emu.regs.rax = 1; } fn GetFileAttributesA(emu:&mut emu::Emu) { - let filename_ptr = emu.maps.read_dword(emu.regs.esp).expect("kernel32!GetFileAttributesA cannot read filename_ptr"); + let filename_ptr = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!GetFileAttributesA cannot read filename_ptr") as u64; let filename = emu.maps.read_string(filename_ptr); println!("{}** {} kernel32!GetFileAttributesA file: {} {}", emu.colors.light_red, emu.pos, filename, emu.colors.nc); - emu.regs.eax = 0x123; // file attributes + emu.regs.rax = 0x123; // file attributes - emu.stack_pop(false); + emu.stack_pop32(false); } fn GetFileAttributesW(emu:&mut emu::Emu) { - let filename_ptr = emu.maps.read_dword(emu.regs.esp).expect("kernel32!GetFileAttributesW cannot read filename_ptr"); + let filename_ptr = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!GetFileAttributesW cannot read filename_ptr") as u64; let filename = emu.maps.read_wide_string(filename_ptr); println!("{}** {} kernel32!GetFileAttributesW file: {} {}", emu.colors.light_red, emu.pos, filename, emu.colors.nc); - emu.stack_pop(false); + emu.stack_pop32(false); - emu.regs.eax = 0x123; // file attributes + emu.regs.rax = 0x123; // file attributes } fn FileTimeToSystemTime(emu:&mut emu::Emu) { - let file_time = emu.maps.read_dword(emu.regs.esp).expect("kernel32!FileTimeToSystemTime cannot read file_time"); - let sys_time_ptr = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!FileTimeToSystemTime cannot read sys_time_ptr"); + let file_time = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!FileTimeToSystemTime cannot read file_time"); + let sys_time_ptr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!FileTimeToSystemTime cannot read sys_time_ptr"); println!("{}** {} kernel32!FileTimeToSystemTime {} ", emu.colors.light_red, emu.pos, emu.colors.nc); - emu.stack_pop(false); - emu.stack_pop(false); + emu.stack_pop32(false); + emu.stack_pop32(false); - emu.regs.eax = 1; + emu.regs.rax = 1; } fn FindFirstFileA(emu:&mut emu::Emu) { - let file_ptr = emu.maps.read_dword(emu.regs.esp).expect("kernel32!FindFirstFileA cannot read file_ptr"); - let find_data = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!FindFirstFileA cannot read find_data"); + let file_ptr = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!FindFirstFileA cannot read file_ptr") as u64; + let find_data = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!FindFirstFileA cannot read find_data"); let file = emu.maps.read_string(file_ptr); println!("{}** {} kernel32!FindFirstFileA file: {} {}", emu.colors.light_red, emu.pos, file, emu.colors.nc); - emu.stack_pop(false); - emu.stack_pop(false); + emu.stack_pop32(false); + emu.stack_pop32(false); - emu.regs.eax = 1; + emu.regs.rax = 1; } fn FindFirstFileW(emu:&mut emu::Emu) { - let file_ptr = emu.maps.read_dword(emu.regs.esp).expect("kernel32!FindFirstFileW cannot read file_ptr"); - let find_data = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!FindFirstFileW cannot read find_data"); + let file_ptr = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!FindFirstFileW cannot read file_ptr") as u64; + let find_data = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!FindFirstFileW cannot read find_data"); let file = emu.maps.read_wide_string(file_ptr); println!("{}** {} kernel32!FindFirstFileW file: {} {}", emu.colors.light_red, emu.pos, file, emu.colors.nc); - emu.stack_pop(false); - emu.stack_pop(false); + emu.stack_pop32(false); + emu.stack_pop32(false); - emu.regs.eax = helper::handler_create(); + emu.regs.rax = helper::handler_create(); } fn FindNextFileA(emu:&mut emu::Emu) { - let hndl = emu.maps.read_dword(emu.regs.esp).expect("kernel32!FindNextFileA cannot read the handle"); - let find_data = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!FindNextFileA cannot read the find_data"); + let hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!FindNextFileA cannot read the handle"); + let find_data = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!FindNextFileA cannot read the find_data"); println!("{}** {} kernel32!FindNextFileA {}", emu.colors.light_red, emu.pos, emu.colors.nc); - emu.stack_pop(false); - emu.stack_pop(false); + emu.stack_pop32(false); + emu.stack_pop32(false); - emu.regs.eax = constants::ERROR_NO_MORE_FILES; + emu.regs.rax = constants::ERROR_NO_MORE_FILES; } fn FindNextFileW(emu:&mut emu::Emu) { - let hndl = emu.maps.read_dword(emu.regs.esp).expect("kernel32!FindNextFileW cannot read the handle"); - let find_data = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!FindNextFileW cannot read the find_data"); + let hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!FindNextFileW cannot read the handle"); + let find_data = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!FindNextFileW cannot read the find_data"); println!("{}** {} kernel32!FindNextFileW {}", emu.colors.light_red, emu.pos, emu.colors.nc); - emu.stack_pop(false); - emu.stack_pop(false); + emu.stack_pop32(false); + emu.stack_pop32(false); - emu.regs.eax = constants::ERROR_NO_MORE_FILES; + emu.regs.rax = constants::ERROR_NO_MORE_FILES; } fn CopyFileA(emu:&mut emu::Emu) { - let src_ptr = emu.maps.read_dword(emu.regs.esp).expect("kernel32!CopyFileA cannot read src_ptr"); - let dst_ptr = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!CopyFileA cannot read dst_ptr"); - let do_fail = emu.maps.read_dword(emu.regs.esp+8).expect("kernel32!CopyFileA cannot read do_fail"); + let src_ptr = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!CopyFileA cannot read src_ptr") as u64; + let dst_ptr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!CopyFileA cannot read dst_ptr") as u64; + let do_fail = emu.maps.read_dword(emu.regs.get_esp()+8).expect("kernel32!CopyFileA cannot read do_fail"); let src = emu.maps.read_string(src_ptr); let dst = emu.maps.read_string(dst_ptr); println!("{}** {} kernel32!CopyFileA `{}` to `{}` {}", emu.colors.light_red, emu.pos, src, dst, emu.colors.nc); - emu.stack_pop(false); - emu.stack_pop(false); - emu.stack_pop(false); + emu.stack_pop32(false); + emu.stack_pop32(false); + emu.stack_pop32(false); - emu.regs.eax = 1; + emu.regs.rax = 1; } fn CopyFileW(emu:&mut emu::Emu) { - let src_ptr = emu.maps.read_dword(emu.regs.esp).expect("kernel32!CopyFileW cannot read src_ptr"); - let dst_ptr = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!CopyFileW cannot read dst_ptr"); - let do_fail = emu.maps.read_dword(emu.regs.esp+8).expect("kernel32!CopyFileW cannot read do_fail"); + let src_ptr = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!CopyFileW cannot read src_ptr") as u64; + let dst_ptr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!CopyFileW cannot read dst_ptr") as u64; + let do_fail = emu.maps.read_dword(emu.regs.get_esp()+8).expect("kernel32!CopyFileW cannot read do_fail"); let src = emu.maps.read_wide_string(src_ptr); let dst = emu.maps.read_wide_string(dst_ptr); println!("{}** {} kernel32!CopyFileW `{}` to `{}` {}", emu.colors.light_red, emu.pos, src, dst, emu.colors.nc); - emu.stack_pop(false); - emu.stack_pop(false); - emu.stack_pop(false); + emu.stack_pop32(false); + emu.stack_pop32(false); + emu.stack_pop32(false); - emu.regs.eax = 1; + emu.regs.rax = 1; } fn FindClose(emu:&mut emu::Emu) { - let hndl = emu.maps.read_dword(emu.regs.esp).expect("kernel32!FindClose cannot read the handle"); + let hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!FindClose cannot read the handle") as u64; println!("{}** {} kernel32!FindClose {}", emu.colors.light_red, emu.pos, emu.colors.nc); - emu.stack_pop(false); + emu.stack_pop32(false); helper::handler_close(hndl); - emu.regs.eax = 1; + emu.regs.rax = 1; } fn MoveFileA(emu:&mut emu::Emu) { - let src_ptr = emu.maps.read_dword(emu.regs.esp).expect("kernel32!MoveFileA cannot read src_ptr"); - let dst_ptr = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!MoveFileA cannot read dst_ptr"); + let src_ptr = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!MoveFileA cannot read src_ptr") as u64; + let dst_ptr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!MoveFileA cannot read dst_ptr") as u64; let src = emu.maps.read_string(src_ptr); let dst = emu.maps.read_string(dst_ptr); println!("{}** {} kernel32!MoveFileA `{}` to `{}` {}", emu.colors.light_red, emu.pos, src, dst, emu.colors.nc); - emu.stack_pop(false); - emu.stack_pop(false); + emu.stack_pop32(false); + emu.stack_pop32(false); - emu.regs.eax = 1; + emu.regs.rax = 1; } fn MoveFileW(emu:&mut emu::Emu) { - let src_ptr = emu.maps.read_dword(emu.regs.esp).expect("kernel32!MoveFileW cannot read src_ptr"); - let dst_ptr = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!MoveFileW cannot read dst_ptr"); + let src_ptr = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!MoveFileW cannot read src_ptr") as u64; + let dst_ptr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!MoveFileW cannot read dst_ptr") as u64; let src = emu.maps.read_wide_string(src_ptr); let dst = emu.maps.read_wide_string(dst_ptr); println!("{}** {} kernel32!MoveFileW `{}` to `{}` {}", emu.colors.light_red, emu.pos, src, dst, emu.colors.nc); - emu.stack_pop(false); - emu.stack_pop(false); + emu.stack_pop32(false); + emu.stack_pop32(false); - emu.regs.eax = 1; + emu.regs.rax = 1; } fn OpenProcess(emu:&mut emu::Emu) { - let access = emu.maps.read_dword(emu.regs.esp).expect("kernel32!OpenProcess cannot read access"); - let inherit = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!OpenProcess cannot read inherit"); - let pid = emu.maps.read_dword(emu.regs.esp+8).expect("kernel32!OpenProcess cannot read pid"); + let access = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!OpenProcess cannot read access"); + let inherit = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!OpenProcess cannot read inherit"); + let pid = emu.maps.read_dword(emu.regs.get_esp()+8).expect("kernel32!OpenProcess cannot read pid"); println!("{}** {} kernel32!OpenProcess pid: {} {}", emu.colors.light_red, emu.pos, pid, emu.colors.nc); - emu.stack_pop(false); - emu.stack_pop(false); - emu.stack_pop(false); + emu.stack_pop32(false); + emu.stack_pop32(false); + emu.stack_pop32(false); - emu.regs.eax = helper::handler_create(); + emu.regs.rax = helper::handler_create(); } fn GetCurrentProcessId(emu:&mut emu::Emu) { println!("{}** {} kernel32!GetCurrentProcessId {}", emu.colors.light_red, emu.pos, emu.colors.nc); - emu.regs.eax = 0x123; + emu.regs.rax = 0x123; } fn Thread32First(emu:&mut emu::Emu) { - let hndl = emu.maps.read_dword(emu.regs.esp).expect("kernel32!Thread32First cannot read the handle"); - let entry = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!Thread32First cannot read the entry32"); + let hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!Thread32First cannot read the handle"); + let entry = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!Thread32First cannot read the entry32"); println!("{}** {} kernel32!Thread32First {}", emu.colors.light_red, emu.pos, emu.colors.nc); - emu.stack_pop(false); - emu.stack_pop(false); + emu.stack_pop32(false); + emu.stack_pop32(false); - emu.regs.eax = 1; + emu.regs.rax = 1; } fn Thread32Next(emu:&mut emu::Emu) { - let hndl = emu.maps.read_dword(emu.regs.esp).expect("kernel32!Thread32Next cannot read the handle"); - let entry = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!Thread32Next cannot read the entry32"); + let hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!Thread32Next cannot read the handle"); + let entry = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!Thread32Next cannot read the entry32"); println!("{}** {} kernel32!Thread32Next {}", emu.colors.light_red, emu.pos, emu.colors.nc); - emu.stack_pop(false); - emu.stack_pop(false); + emu.stack_pop32(false); + emu.stack_pop32(false); - emu.regs.eax = constants::ERROR_NO_MORE_FILES; + emu.regs.rax = constants::ERROR_NO_MORE_FILES; } fn OpenThread(emu:&mut emu::Emu) { - let access = emu.maps.read_dword(emu.regs.esp).expect("kernel32!OpenThread cannot read acess"); - let inherit = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!OpenThread cannot read inherit"); - let tid = emu.maps.read_dword(emu.regs.esp+8).expect("kernel32!OpenThread cannot read tid"); + let access = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!OpenThread cannot read acess"); + let inherit = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!OpenThread cannot read inherit"); + let tid = emu.maps.read_dword(emu.regs.get_esp()+8).expect("kernel32!OpenThread cannot read tid"); println!("{}** {} kernel32!OpenThread tid: {} {}", emu.colors.light_red, emu.pos, tid, emu.colors.nc); - emu.stack_pop(false); - emu.stack_pop(false); - emu.stack_pop(false); + emu.stack_pop32(false); + emu.stack_pop32(false); + emu.stack_pop32(false); - emu.regs.eax = helper::handler_create(); + emu.regs.rax = helper::handler_create(); } fn CreateToolhelp32Snapshot(emu:&mut emu::Emu) { - let flags = emu.maps.read_dword(emu.regs.esp).expect("kernel32!CreateToolhelp32Snapshot cannot read flags"); - let pid = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!CreateToolhelp32Snapshot cannot read pid"); + let flags = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!CreateToolhelp32Snapshot cannot read flags"); + let pid = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!CreateToolhelp32Snapshot cannot read pid"); println!("{}** {} kernel32!CreateToolhelp32Snapshot pid: {} {}", emu.colors.light_red, emu.pos, pid, emu.colors.nc); - emu.stack_pop(false); - emu.stack_pop(false); + emu.stack_pop32(false); + emu.stack_pop32(false); - emu.regs.eax = helper::handler_create(); + emu.regs.rax = helper::handler_create(); } fn CreateThread(emu:&mut emu::Emu) { - let sec_attr = emu.maps.read_dword(emu.regs.esp).expect("kernel32!CreateThread cannot read sec_attr"); - let stack_sz = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!CreateThread cannot read stack_sz"); - let code = emu.maps.read_dword(emu.regs.esp+8).expect("kernel32!CreateThread cannot read fptr"); - let param = emu.maps.read_dword(emu.regs.esp+12).expect("kernel32!CreateThread cannot read param"); - let flags = emu.maps.read_dword(emu.regs.esp+16).expect("kernel32!CreateThread cannot read flags"); - let tid_ptr = emu.maps.read_dword(emu.regs.esp+20).expect("kernel32!CreateThread cannot read tid_ptr"); + let sec_attr = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!CreateThread cannot read sec_attr"); + let stack_sz = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!CreateThread cannot read stack_sz"); + let code = emu.maps.read_dword(emu.regs.get_esp()+8).expect("kernel32!CreateThread cannot read fptr") as u64; + let param = emu.maps.read_dword(emu.regs.get_esp()+12).expect("kernel32!CreateThread cannot read param"); + let flags = emu.maps.read_dword(emu.regs.get_esp()+16).expect("kernel32!CreateThread cannot read flags") as u64; + let tid_ptr = emu.maps.read_dword(emu.regs.get_esp()+20).expect("kernel32!CreateThread cannot read tid_ptr") as u64; emu.maps.write_dword(tid_ptr, 0x123); println!("{}** {} kernel32!CreateThread code: {} {}", emu.colors.light_red, emu.pos, code, emu.colors.nc); for _ in 0..6 { - emu.stack_pop(false); + emu.stack_pop32(false); } if flags == constants::CREATE_SUSPENDED { @@ -973,8 +973,8 @@ fn CreateThread(emu:&mut emu::Emu) { if line == "y" || line == "yes" { if emu.maps.is_mapped(code) { - emu.regs.eip = code; - emu.regs.eax = 0; + emu.regs.set_eip(code); + emu.regs.rax = 0; // alloc a stack vs reusing stack. return; } else { @@ -982,17 +982,17 @@ fn CreateThread(emu:&mut emu::Emu) { } } - emu.regs.eax = helper::handler_create(); + emu.regs.rax = helper::handler_create(); } fn MapViewOfFile(emu:&mut emu::Emu) { - let hndl = emu.maps.read_dword(emu.regs.esp).expect("kernel32!MapViewOfFile cannot read the handle"); - let access = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!MapViewOfFile cannot read the acess"); - let off_hight = emu.maps.read_dword(emu.regs.esp+8).expect("kernel32!MapViewOfFile cannot read the off_hight"); - let off_low = emu.maps.read_dword(emu.regs.esp+12).expect("kernel32!MapViewOfFile cannot read the off_low"); - let size = emu.maps.read_dword(emu.regs.esp+16).expect("kernel32!MapViewOfFile cannot read the size"); + let hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!MapViewOfFile cannot read the handle"); + let access = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!MapViewOfFile cannot read the acess"); + let off_hight = emu.maps.read_dword(emu.regs.get_esp()+8).expect("kernel32!MapViewOfFile cannot read the off_hight") as u64; + let off_low = emu.maps.read_dword(emu.regs.get_esp()+12).expect("kernel32!MapViewOfFile cannot read the off_low") as u64; + let size = emu.maps.read_dword(emu.regs.get_esp()+16).expect("kernel32!MapViewOfFile cannot read the size") as u64; - let off:u64 = (off_hight as u64) << 32 + off_low; + let off:u64 = (off_hight << 32) + off_low; println!("{}** {} kernel32!MapViewOfFile hndl: {} off: {} sz: {} {}", emu.colors.light_red, emu.pos, hndl, off, size, emu.colors.nc); @@ -1003,104 +1003,104 @@ fn MapViewOfFile(emu:&mut emu::Emu) { //TODO: use mem.load() for _ in 0..5 { - emu.stack_pop(false); + emu.stack_pop32(false); } - emu.regs.eax = addr; + emu.regs.rax = addr; } fn GetSystemTimeAsFileTime(emu:&mut emu::Emu) { - let sys_time_ptr = emu.maps.read_dword(emu.regs.esp).expect("kernel32!GetSystemTimeAsFileTime cannot read sys_time_ptr"); + let sys_time_ptr = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!GetSystemTimeAsFileTime cannot read sys_time_ptr"); println!("{}** {} kernel32!GetSystemTimeAsFileTime {}", emu.colors.light_red, emu.pos, emu.colors.nc); - emu.stack_pop(false); + emu.stack_pop32(false); - emu.regs.eax = 1; + emu.regs.rax = 1; } fn GetCurrentThreadId(emu:&mut emu::Emu) { println!("{}** {} kernel32!GetCurrentThreadId {}", emu.colors.light_red, emu.pos, emu.colors.nc); - emu.regs.eax = 0x111; //TODO: track pids and tids + emu.regs.rax = 0x111; //TODO: track pids and tids } fn GetTickCount(emu:&mut emu::Emu) { println!("{}** {} kernel32!GetTickCount {}", emu.colors.light_red, emu.pos, emu.colors.nc); - emu.regs.eax = 1; + emu.regs.rax = 1; } fn QueryPerformanceCounter(emu:&mut emu::Emu) { - let counter_ptr = emu.maps.read_dword(emu.regs.esp).expect("kernel32!QueryPerformanceCounter cannot read counter_ptr"); + let counter_ptr = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!QueryPerformanceCounter cannot read counter_ptr") as u64; emu.maps.write_dword(counter_ptr, 0x1); println!("{}** {} kernel32!QueryPerformanceCounter {}", emu.colors.light_red, emu.pos, emu.colors.nc); - emu.stack_pop(false); + emu.stack_pop32(false); - emu.regs.eax = 1; + emu.regs.rax = 1; } fn HeapCreate(emu:&mut emu::Emu) { - let opts = emu.maps.read_dword(emu.regs.esp).expect("kernel32!HeapCreate cannot read opts"); - let init_sz = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!HeapCreate cannot read init_sz"); - let max_sz = emu.maps.read_dword(emu.regs.esp+8).expect("kernel32!HeapCreate cannot read max_sz"); + let opts = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!HeapCreate cannot read opts"); + let init_sz = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!HeapCreate cannot read init_sz"); + let max_sz = emu.maps.read_dword(emu.regs.get_esp()+8).expect("kernel32!HeapCreate cannot read max_sz"); println!("{}** {} kernel32!HeapCreate initSz: {} maxSz: {} {}", emu.colors.light_red, emu.pos, init_sz, max_sz, emu.colors.nc); - emu.stack_pop(false); - emu.stack_pop(false); - emu.stack_pop(false); + emu.stack_pop32(false); + emu.stack_pop32(false); + emu.stack_pop32(false); - emu.regs.eax = helper::handler_create(); + emu.regs.rax = helper::handler_create(); } fn GetModuleHandleA(emu:&mut emu::Emu) { - let mod_name_ptr = emu.maps.read_dword(emu.regs.esp).expect("kernel32!GetModuleHandleA cannot read mod_name_ptr"); + let mod_name_ptr = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!GetModuleHandleA cannot read mod_name_ptr") as u64; let mod_name = emu.maps.read_string(mod_name_ptr); println!("{}** {} kernel32!GetModuleHandleA '{}' {}", emu.colors.light_red, emu.pos, mod_name, emu.colors.nc); - emu.stack_pop(false); + emu.stack_pop32(false); - emu.regs.eax = helper::handler_create(); + emu.regs.rax = helper::handler_create(); } fn GetModuleHandleW(emu:&mut emu::Emu) { - let mod_name_ptr = emu.maps.read_dword(emu.regs.esp).expect("kernel32!GetModuleHandleW cannot read mod_name_ptr"); + let mod_name_ptr = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!GetModuleHandleW cannot read mod_name_ptr") as u64; let mod_name = emu.maps.read_wide_string(mod_name_ptr); println!("{}** {} kernel32!GetModuleHandleW '{}' {}", emu.colors.light_red, emu.pos, mod_name, emu.colors.nc); - emu.stack_pop(false); + emu.stack_pop32(false); - emu.regs.eax = helper::handler_create(); + emu.regs.rax = helper::handler_create(); } fn TlsAlloc(emu:&mut emu::Emu) { println!("{}** {} kernel32!TlsAlloc {}", emu.colors.light_red, emu.pos, emu.colors.nc); - emu.regs.eax = 1; + emu.regs.rax = 1; } fn TlsFree(emu:&mut emu::Emu) { - let idx = emu.maps.read_dword(emu.regs.esp).expect("kernel32!TlsFree cannot read idx"); + let idx = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!TlsFree cannot read idx"); println!("{}** {} kernel32!TlsFree idx: {} {}", emu.colors.light_red, emu.pos, idx, emu.colors.nc); - emu.stack_pop(false); - emu.regs.eax = 1; + emu.stack_pop32(false); + emu.regs.rax = 1; } fn TlsSetValue(emu:&mut emu::Emu) { - let idx = emu.maps.read_dword(emu.regs.esp).expect("kernel32!TlsSetValue cannot read idx"); - let val = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!TlsSetValue cannot read val_ptr"); + let idx = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!TlsSetValue cannot read idx"); + let val = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!TlsSetValue cannot read val_ptr"); println!("{}** {} kernel32!TlsSetValue idx: {} val: 0x{:x} {}", emu.colors.light_red, emu.pos, idx, val, emu.colors.nc); @@ -1113,90 +1113,90 @@ fn TlsSetValue(emu:&mut emu::Emu) { emu.tls[idx as usize] = val; } - emu.stack_pop(false); - emu.stack_pop(false); + emu.stack_pop32(false); + emu.stack_pop32(false); - emu.regs.eax = 1; + emu.regs.rax = 1; } fn TlsGetValue(emu:&mut emu::Emu) { - let idx = emu.maps.read_dword(emu.regs.esp).expect("kernel32!TlsGetValue cannot read idx"); + let idx = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!TlsGetValue cannot read idx"); - emu.stack_pop(false); + emu.stack_pop32(false); if idx as usize > emu.tls.len() { - emu.regs.eax = 0; + emu.regs.rax = 0; } else { - emu.regs.eax = emu.tls[idx as usize]; + emu.regs.rax = emu.tls[idx as usize] as u64; } - println!("{}** {} kernel32!TlsGetValue idx: {} =0x{:x} {}", emu.colors.light_red, emu.pos, idx, emu.regs.eax, emu.colors.nc); + println!("{}** {} kernel32!TlsGetValue idx: {} =0x{:x} {}", emu.colors.light_red, emu.pos, idx, emu.regs.get_eax() as u32, emu.colors.nc); } fn EncodePointer(emu:&mut emu::Emu) { - let ptr = emu.maps.read_dword(emu.regs.esp).expect("kernel32!EncodePointer cannot read the pointer"); + let ptr = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!EncodePointer cannot read the pointer") as u64; println!("{}** {} kernel32!EncodePointer ptr: 0x{:x} {}", emu.colors.light_red, emu.pos, ptr, emu.colors.nc); - emu.stack_pop(false); - emu.regs.eax = ptr; + emu.stack_pop32(false); + emu.regs.rax = ptr; } fn DecodePointer(emu:&mut emu::Emu) { - let ptr = emu.maps.read_dword(emu.regs.esp).expect("kernel32!DecodePointer cannot read the pointer"); + let ptr = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!DecodePointer cannot read the pointer") as u64; println!("{}** {} kernel32!DecodePointer ptr: 0x{:x} {}", emu.colors.light_red, emu.pos, ptr, emu.colors.nc); - emu.stack_pop(false); - emu.regs.eax = ptr; + emu.stack_pop32(false); + emu.regs.rax = ptr; } fn Sleep(emu:&mut emu::Emu) { - let millis = emu.maps.read_dword(emu.regs.esp).expect("kernel32!Sleep cannot read millis"); + let millis = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!Sleep cannot read millis"); println!("{}** {} kernel32!Sleep millis: {} {}", emu.colors.light_red, emu.pos, millis, emu.colors.nc); - emu.stack_pop(false); + emu.stack_pop32(false); } fn InitializeCriticalSectionAndSpinCount(emu:&mut emu::Emu) { - let crit_sect = emu.maps.read_dword(emu.regs.esp).expect("kernel32!InitializeCriticalSectionAndSpinCount cannot read crit_sect"); - let spin_count = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!InitializeCriticalSectionAndSpinCount cannot read spin_count"); + let crit_sect = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!InitializeCriticalSectionAndSpinCount cannot read crit_sect"); + let spin_count = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!InitializeCriticalSectionAndSpinCount cannot read spin_count"); println!("{}** {} kernel32!InitializeCriticalSectionAndSpinCount crit_sect: 0x{:x} spin_count: {} {}", emu.colors.light_red, emu.pos, crit_sect, spin_count, emu.colors.nc); - emu.stack_pop(false); - emu.stack_pop(false); + emu.stack_pop32(false); + emu.stack_pop32(false); - emu.regs.eax = 1; + emu.regs.rax = 1; } fn HeapAlloc(emu:&mut emu::Emu) { - let hndl = emu.maps.read_dword(emu.regs.esp).expect("kernel32!HeapAlloc cannot read the handle"); - let flags = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!HeapAlloc cannot read the flags"); - let size = emu.maps.read_dword(emu.regs.esp+8).expect("kernel32!HeapAlloc cannot read the size"); + let hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!HeapAlloc cannot read the handle"); + let flags = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!HeapAlloc cannot read the flags"); + let size = emu.maps.read_dword(emu.regs.get_esp()+8).expect("kernel32!HeapAlloc cannot read the size") as u64; - emu.regs.eax = match emu.maps.alloc(size) { + emu.regs.rax = match emu.maps.alloc(size) { Some(sz) => sz, None => 0, }; - let mem = emu.maps.create_map(format!("alloc_{:x}", emu.regs.eax).as_str()); - mem.set_base(emu.regs.eax); + let mem = emu.maps.create_map(format!("alloc_{:x}", emu.regs.get_eax() as u32).as_str()); + mem.set_base(emu.regs.get_eax()); mem.set_size(size); println!("{}** {} kernel32!HeapAlloc flags: 0x{:x} size: {} =0x{:x} {}", emu.colors.light_red, - emu.pos, flags, size, emu.regs.eax, emu.colors.nc); + emu.pos, flags, size, emu.regs.get_eax() as u32, emu.colors.nc); for _ in 0..3 { - emu.stack_pop(false); + emu.stack_pop32(false); } } fn GetProcessAffinityMask(emu:&mut emu::Emu) { - let hndl = emu.maps.read_dword(emu.regs.esp).expect("kernel32!GetProcessAffinityMask cannot read the handle"); - let proc_affinity_mask_ptr = emu.maps.read_dword(emu.regs.esp+4).expect("kernel32!GetProcessAffinityMask cannot read the proc_affinity_mask_ptr"); - let sys_affinity_mask_ptr = emu.maps.read_dword(emu.regs.esp+8).expect("kernel32!GetProcessAffinityMask cannot read the sys_affinity_mask_ptr"); + let hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!GetProcessAffinityMask cannot read the handle") as u64; + let proc_affinity_mask_ptr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("kernel32!GetProcessAffinityMask cannot read the proc_affinity_mask_ptr") as u64; + let sys_affinity_mask_ptr = emu.maps.read_dword(emu.regs.get_esp()+8).expect("kernel32!GetProcessAffinityMask cannot read the sys_affinity_mask_ptr") as u64; emu.maps.write_dword(proc_affinity_mask_ptr, 0x1337); emu.maps.write_dword(sys_affinity_mask_ptr, 0x1337); @@ -1204,39 +1204,39 @@ fn GetProcessAffinityMask(emu:&mut emu::Emu) { println!("{}** {} kernel32!GetProcessAffinityMask {}", emu.colors.light_red, emu.pos, emu.colors.nc); - emu.regs.eax = 1; + emu.regs.rax = 1; for _ in 0..3 { - emu.stack_pop(false); + emu.stack_pop32(false); } } fn IsDebuggerPresent(emu:&mut emu::Emu) { println!("{}** {} kernel32!IsDebuggerPresent {}", emu.colors.light_red, emu.pos, emu.colors.nc); - emu.regs.eax = 0; // of course :p + emu.regs.rax = 0; // of course :p } fn SetUnhandledExceptionFilter(emu:&mut emu::Emu) { - let callback = emu.maps.read_dword(emu.regs.esp).expect("kernel32!SetUnhandledExceptionFilter cannot read the callback"); + let callback = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!SetUnhandledExceptionFilter cannot read the callback") as u64; println!("{}** {} kernel32!SetUnhandledExceptionFilter callback: 0x{:x} {}", emu.colors.light_red, emu.pos, callback, emu.colors.nc); - emu.regs.eax = emu.seh; + emu.regs.rax = emu.seh; emu.seh = callback; - emu.stack_pop(false); + emu.stack_pop32(false); } fn UnhandledExceptionFilter(emu:&mut emu::Emu) { - let exception_info = emu.maps.read_dword(emu.regs.esp).expect("kernel32!UnhandledExceptionFilter cannot read exception_info"); + let exception_info = emu.maps.read_dword(emu.regs.get_esp()).expect("kernel32!UnhandledExceptionFilter cannot read exception_info"); println!("{}** {} kernel32!UnhandledExceptionFilter exception_info: 0x{:x} {}", emu.colors.light_red, emu.pos, exception_info, emu.colors.nc); - emu.stack_pop(false); - emu.regs.eax = constants::EXCEPTION_EXECUTE_HANDLER; // a debugger would had answered EXCEPTION_CONTINUE_SEARCH + emu.stack_pop32(false); + emu.regs.rax = constants::EXCEPTION_EXECUTE_HANDLER; // a debugger would had answered EXCEPTION_CONTINUE_SEARCH } fn GetCurrentProcess(emu:&mut emu::Emu) { println!("{}** {} kernel32!GetCurrentProcess {}", emu.colors.light_red, emu.pos, emu.colors.nc); - emu.regs.eax = helper::handler_create(); + emu.regs.rax = helper::handler_create(); } diff --git a/src/emu/winapi/ntdll.rs b/src/emu/winapi/ntdll.rs index 05a007d..a2bb4d6 100644 --- a/src/emu/winapi/ntdll.rs +++ b/src/emu/winapi/ntdll.rs @@ -31,12 +31,12 @@ fn NtAllocateVirtualMemory(emu:&mut emu::Emu) { ); */ - let addr_ptr = emu.maps.read_dword(emu.regs.esp+4).expect("bad NtAllocateVirtualMemory address pointer parameter"); - let size_ptr = emu.maps.read_dword(emu.regs.esp+12).expect("bad NtAllocateVirtualMemory size pointer parameter"); - let addr = emu.maps.read_dword(addr_ptr).expect("bad NtAllocateVirtualMemory address parameter"); - let size = emu.maps.read_dword(size_ptr).expect("bad NtAllocateVirtualMemory size parameter"); + let addr_ptr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("bad NtAllocateVirtualMemory address pointer parameter") as u64; + let size_ptr = emu.maps.read_dword(emu.regs.get_esp()+12).expect("bad NtAllocateVirtualMemory size pointer parameter") as u64; + let addr = emu.maps.read_dword(addr_ptr).expect("bad NtAllocateVirtualMemory address parameter") as u64; + let size = emu.maps.read_dword(size_ptr).expect("bad NtAllocateVirtualMemory size parameter") as u64; let do_alloc:bool; - let alloc_addr:u32; + let alloc_addr:u64; if addr == 0 { do_alloc = true; @@ -64,41 +64,41 @@ fn NtAllocateVirtualMemory(emu:&mut emu::Emu) { alloc.set_size(size); //alloc.set_bottom(alloc_addr + size); - if !emu.maps.write_dword(addr_ptr, alloc_addr) { + if !emu.maps.write_dword(addr_ptr, alloc_addr as u32) { panic!("NtAllocateVirtualMemory: cannot write on address pointer"); } - emu.regs.eax = emu::constants::STATUS_SUCCESS; + emu.regs.rax = emu::constants::STATUS_SUCCESS; for _ in 0..6 { - emu.stack_pop(false); + emu.stack_pop32(false); } } fn stricmp(emu:&mut emu::Emu) { - let str1ptr = emu.maps.read_dword(emu.regs.esp).expect("ntdll!stricmp: error reading string1"); - let str2ptr = emu.maps.read_dword(emu.regs.esp+4).expect("ntdll!stricmp: error reading string2"); + let str1ptr = emu.maps.read_dword(emu.regs.get_esp()).expect("ntdll!stricmp: error reading string1") as u64; + let str2ptr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("ntdll!stricmp: error reading string2") as u64; let str1 = emu.maps.read_string(str1ptr); let str2 = emu.maps.read_string(str2ptr); println!("{}** {} ntdll!stricmp '{}'=='{}'? {}", emu.colors.light_red, emu.pos, str1, str2, emu.colors.nc); if str1 == str2 { - emu.regs.eax = 0; + emu.regs.rax = 0; } else { - emu.regs.eax = 1; + emu.regs.rax = 1; } for _ in 0..2 { - emu.stack_pop(false); + emu.stack_pop32(false); } } fn NtQueryVirtualMemory(emu:&mut emu::Emu) { - let handle = emu.maps.read_dword(emu.regs.esp).expect("ntdll!NtQueryVirtualMemory: error reading handle"); - let addr = emu.maps.read_dword(emu.regs.esp+4).expect("ntdll!NtQueryVirtualMemory: error reading address"); + let handle = emu.maps.read_dword(emu.regs.get_esp()).expect("ntdll!NtQueryVirtualMemory: error reading handle") as u64; + let addr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("ntdll!NtQueryVirtualMemory: error reading address") as u64; println!("{}** {} ntdll!NtQueryVirtualMemory addr: 0x{:x} {}", emu.colors.light_red, emu.pos, addr, emu.colors.nc); @@ -110,37 +110,37 @@ fn NtQueryVirtualMemory(emu:&mut emu::Emu) { } } - let out_meminfo_ptr = emu.maps.read_dword(emu.regs.esp+12).expect("ntdll_NtQueryVirtualMemory: error reading out pointer to meminfo"); + let out_meminfo_ptr = emu.maps.read_dword(emu.regs.get_esp()+12).expect("ntdll_NtQueryVirtualMemory: error reading out pointer to meminfo") as u64; if !emu.maps.is_mapped(addr) { println!("/!\\ ntdll!NtQueryVirtualMemory: querying non maped addr: 0x{:x}", addr); for _ in 0..6 { - emu.stack_pop(false); + emu.stack_pop32(false); } - emu.regs.eax = emu::constants::STATUS_INVALID_PARAMETER; + emu.regs.rax = emu::constants::STATUS_INVALID_PARAMETER; } let base = emu.maps.get_addr_base(addr).unwrap_or(0); let mut mem_info = structures::MemoryBasicInformation::load(out_meminfo_ptr, &emu.maps); - mem_info.base_address = base; //addr & 0xfff; - mem_info.allocation_base = base; // addr & 0xfff; + mem_info.base_address = base as u32; //addr & 0xfff; + mem_info.allocation_base = base as u32; // addr & 0xfff; mem_info.allocation_protect = constants::PAGE_EXECUTE | constants::PAGE_READWRITE; mem_info.state = constants::MEM_COMMIT; mem_info.typ = constants::MEM_PRIVATE; mem_info.save(out_meminfo_ptr, &mut emu.maps); for _ in 0..6 { - emu.stack_pop(false); + emu.stack_pop32(false); } - emu.regs.eax = constants::STATUS_SUCCESS; + emu.regs.rax = constants::STATUS_SUCCESS; } fn LdrLoadDll(emu:&mut emu::Emu) { - let libaddr_ptr = emu.maps.read_dword(emu.regs.esp+12).expect("LdrLoadDll: error reading lib ptr"); - let libname_ptr = emu.maps.read_dword(emu.regs.esp+20).expect("LdrLoadDll: error reading lib param"); + let libaddr_ptr = emu.maps.read_dword(emu.regs.get_esp()+12).expect("LdrLoadDll: error reading lib ptr") as u64; + let libname_ptr = emu.maps.read_dword(emu.regs.get_esp()+20).expect("LdrLoadDll: error reading lib param") as u64; let libname = emu.maps.read_wide_string(libname_ptr); println!("{}** {} ntdll!LdrLoadDll lib: {} {}", emu.colors.light_red, emu.pos, libname, emu.colors.nc); @@ -161,28 +161,28 @@ fn LdrLoadDll(emu:&mut emu::Emu) { for _ in 0..4 { - emu.stack_pop(false); + emu.stack_pop32(false); } - emu.regs.eax = emu::constants::STATUS_SUCCESS; + emu.regs.rax = emu::constants::STATUS_SUCCESS; } fn RtlVectoredExceptionHandler(emu:&mut emu::Emu) { - let p1 = emu.maps.read_dword(emu.regs.esp).expect("ntdll_RtlVectoredExceptionHandler: error reading p1"); - let fptr = emu.maps.read_dword(emu.regs.esp+4).expect("ntdll_RtlVectoredExceptionHandler: error reading fptr"); + let p1 = emu.maps.read_dword(emu.regs.get_esp()).expect("ntdll_RtlVectoredExceptionHandler: error reading p1") as u64; + let fptr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("ntdll_RtlVectoredExceptionHandler: error reading fptr") as u64; println!("{}** {} ntdll!RtlVectoredExceptionHandler {} callback: 0x{:x} {}", emu.colors.light_red, emu.pos, p1, fptr, emu.colors.nc); emu.veh = fptr; - emu.regs.eax = 0x2c2878; - emu.stack_pop(false); - emu.stack_pop(false); + emu.regs.rax = 0x2c2878; + emu.stack_pop32(false); + emu.stack_pop32(false); } fn NtGetContextThread(emu:&mut emu::Emu) { - let handle = emu.maps.read_dword(emu.regs.esp).expect("ntdll_NtGetContextThread: error reading stack"); - let ctx_ptr = emu.maps.read_dword(emu.regs.esp+4).expect("ntdll_NtGetContextThread: error reading context pointer"); - let ctx_ptr2 = emu.maps.read_dword(ctx_ptr).expect("ntdll_NtGetContextThread: error reading context ptr"); + let handle = emu.maps.read_dword(emu.regs.get_esp()).expect("ntdll_NtGetContextThread: error reading stack") as u64; + let ctx_ptr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("ntdll_NtGetContextThread: error reading context pointer") as u64; + let ctx_ptr2 = emu.maps.read_dword(ctx_ptr).expect("ntdll_NtGetContextThread: error reading context ptr") as u64; println!("{}** {} ntdll_NtGetContextThread ctx {}", emu.colors.light_red, emu.pos, emu.colors.nc); @@ -207,11 +207,11 @@ fn NtGetContextThread(emu:&mut emu::Emu) { }*/ let ctx = Context32::new(&emu.regs); - ctx.save(ctx_ptr2, &mut emu.maps); + ctx.save(ctx_ptr2 as u32, &mut emu.maps); - emu.regs.eax = 0; - emu.stack_pop(false); - emu.stack_pop(false); + emu.regs.rax = 0; + emu.stack_pop32(false); + emu.stack_pop32(false); } diff --git a/src/emu/winapi/user32.rs b/src/emu/winapi/user32.rs index 36c3c4d..1299f3c 100644 --- a/src/emu/winapi/user32.rs +++ b/src/emu/winapi/user32.rs @@ -10,21 +10,21 @@ pub fn gateway(addr:u32, emu:&mut emu::Emu) { } fn MessageBoxA(emu:&mut emu::Emu) { - let titleptr = emu.maps.read_dword(emu.regs.esp+8).expect("user32_MessageBoxA: error reading title"); - let msgptr = emu.maps.read_dword(emu.regs.esp+4).expect("user32_MessageBoxA: error reading message"); + let titleptr = emu.maps.read_dword(emu.regs.get_esp()+8).expect("user32_MessageBoxA: error reading title") as u64; + let msgptr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("user32_MessageBoxA: error reading message") as u64; let msg = emu.maps.read_string(msgptr); let title = emu.maps.read_string(titleptr); println!("{}** {} user32!MessageBoxA {} {} {}", emu.colors.light_red, emu.pos, title, msg, emu.colors.nc); - emu.regs.eax = 0; + emu.regs.rax = 0; for _ in 0..4 { - emu.stack_pop(false); + emu.stack_pop32(false); } } fn GetDesktopWindow(emu:&mut emu::Emu) { println!("{}** {} user32!GetDesktopWindow {}", emu.colors.light_red, emu.pos, emu.colors.nc); - //emu.regs.eax = 0x11223344; // current window handle - emu.regs.eax = 0; // no windows handler is more stealthy + //emu.regs.rax = 0x11223344; // current window handle + emu.regs.rax = 0; // no windows handler is more stealthy } diff --git a/src/emu/winapi/wininet.rs b/src/emu/winapi/wininet.rs index d908176..70ea531 100644 --- a/src/emu/winapi/wininet.rs +++ b/src/emu/winapi/wininet.rs @@ -30,11 +30,11 @@ lazy_static! { pub fn InternetOpenA(emu:&mut emu::Emu) { - let uagent_ptr = emu.maps.read_dword(emu.regs.esp).expect("wininet!InternetOpenA cannot read uagent_ptr"); - let access = emu.maps.read_dword(emu.regs.esp+4).expect("wininet!InternetOpenA cannot read access"); - let proxy_ptr = emu.maps.read_dword(emu.regs.esp+8).expect("wininet!InternetOpenA cannot read proxy_ptr"); - let proxybypass_ptr = emu.maps.read_dword(emu.regs.esp+12).expect("wininet!InternetOpenA cannot read proxybypass_ptr"); - let flags = emu.maps.read_dword(emu.regs.esp+16).expect("wininet!InternetOpenA cannot read flags"); + let uagent_ptr = emu.maps.read_dword(emu.regs.get_esp()).expect("wininet!InternetOpenA cannot read uagent_ptr") as u64; + let access = emu.maps.read_dword(emu.regs.get_esp()+4).expect("wininet!InternetOpenA cannot read access") as u64; + let proxy_ptr = emu.maps.read_dword(emu.regs.get_esp()+8).expect("wininet!InternetOpenA cannot read proxy_ptr") as u64; + let proxybypass_ptr = emu.maps.read_dword(emu.regs.get_esp()+12).expect("wininet!InternetOpenA cannot read proxybypass_ptr") as u64; + let flags = emu.maps.read_dword(emu.regs.get_esp()+16).expect("wininet!InternetOpenA cannot read flags"); let mut uagent = "".to_string(); let mut proxy = "".to_string(); @@ -54,24 +54,24 @@ pub fn InternetOpenA(emu:&mut emu::Emu) { println!("{}** {} wininet!InternetOpenA uagent: {} proxy: {} {} {}", emu.colors.light_red, emu.pos, uagent, proxy, proxy_bypass, emu.colors.nc); for _ in 0..5 { - emu.stack_pop(false); + emu.stack_pop32(false); } - if emu.cfg.endpoint { + if emu.cfg.endpoint { // endpoint mode if uagent_ptr != 0 && uagent != "" { endpoint::http_set_headers("User-Agent", &uagent); } } - emu.regs.eax = helper::handler_create(); + emu.regs.rax = helper::handler_create(); } pub fn InternetOpenW(emu:&mut emu::Emu) { - let uagent_ptr = emu.maps.read_dword(emu.regs.esp).expect("wininet!InternetOpenW cannot read uagent_ptr"); - let access = emu.maps.read_dword(emu.regs.esp+4).expect("wininet!InternetOpenW cannot read access"); - let proxy_ptr = emu.maps.read_dword(emu.regs.esp+8).expect("wininet!InternetOpenW cannot read proxy_ptr"); - let proxybypass_ptr = emu.maps.read_dword(emu.regs.esp+12).expect("wininet!InternetOpenW cannot read proxybypass_ptr"); - let flags = emu.maps.read_dword(emu.regs.esp+16).expect("wininet!InternetOpenW cannot read flags"); + let uagent_ptr = emu.maps.read_dword(emu.regs.get_esp()).expect("wininet!InternetOpenW cannot read uagent_ptr") as u64; + let access = emu.maps.read_dword(emu.regs.get_esp()+4).expect("wininet!InternetOpenW cannot read access") as u64; + let proxy_ptr = emu.maps.read_dword(emu.regs.get_esp()+8).expect("wininet!InternetOpenW cannot read proxy_ptr") as u64; + let proxybypass_ptr = emu.maps.read_dword(emu.regs.get_esp()+12).expect("wininet!InternetOpenW cannot read proxybypass_ptr") as u64; + let flags = emu.maps.read_dword(emu.regs.get_esp()+16).expect("wininet!InternetOpenW cannot read flags"); let mut uagent = "".to_string(); let mut proxy = "".to_string(); @@ -90,27 +90,27 @@ pub fn InternetOpenW(emu:&mut emu::Emu) { println!("{}** {} wininet!InternetOpenW uagent: {} proxy: {} {} {}", emu.colors.light_red, emu.pos, uagent, proxy, proxy_bypass, emu.colors.nc); for _ in 0..5 { - emu.stack_pop(false); + emu.stack_pop32(false); } - if emu.cfg.endpoint { + if emu.cfg.endpoint { // endpoint mode if uagent_ptr != 0 && uagent != "" { endpoint::http_set_headers("User-Agent", &uagent.replace("\x00","")); } } - emu.regs.eax = helper::handler_create(); // internet handle + emu.regs.rax = helper::handler_create(); // internet handle } pub fn InternetConnectA(emu:&mut emu::Emu) { - let internet_hndl = emu.maps.read_dword(emu.regs.esp).expect("wininet!InternetConnectA cannot read hndl"); - let server_ptr = emu.maps.read_dword(emu.regs.esp+4).expect("wininet!InternetConnectA cannot read server_ptr"); - let port = emu.maps.read_dword(emu.regs.esp+8).expect("wininet!InternetConnectA cannot read port"); - let login_ptr = emu.maps.read_dword(emu.regs.esp+12).expect("wininet!InternetConnectA cannot read login_ptr"); - let passw_ptr = emu.maps.read_dword(emu.regs.esp+16).expect("wininet!InternetConnectA cannot read passw_ptr"); - let service = emu.maps.read_dword(emu.regs.esp+20).expect("wininet!InternetConnectA cannot read service"); - let flags = emu.maps.read_dword(emu.regs.esp+24).expect("wininet!InternetConnectA cannot read flags"); - let ctx = emu.maps.read_dword(emu.regs.esp+28).expect("wininet!InternetConnectA cannot read ctx"); + let internet_hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("wininet!InternetConnectA cannot read hndl") as u64; + let server_ptr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("wininet!InternetConnectA cannot read server_ptr") as u64; + let port = emu.maps.read_dword(emu.regs.get_esp()+8).expect("wininet!InternetConnectA cannot read port"); + let login_ptr = emu.maps.read_dword(emu.regs.get_esp()+12).expect("wininet!InternetConnectA cannot read login_ptr") as u64; + let passw_ptr = emu.maps.read_dword(emu.regs.get_esp()+16).expect("wininet!InternetConnectA cannot read passw_ptr") as u64; + let service = emu.maps.read_dword(emu.regs.get_esp()+20).expect("wininet!InternetConnectA cannot read service"); + let flags = emu.maps.read_dword(emu.regs.get_esp()+24).expect("wininet!InternetConnectA cannot read flags"); + let ctx = emu.maps.read_dword(emu.regs.get_esp()+28).expect("wininet!InternetConnectA cannot read ctx"); let mut server = "".to_string(); let mut login = "".to_string(); @@ -138,21 +138,21 @@ pub fn InternetConnectA(emu:&mut emu::Emu) { } for _ in 0..8 { - emu.stack_pop(false); + emu.stack_pop32(false); } - emu.regs.eax = helper::handler_create(); // connect handle + emu.regs.rax = helper::handler_create(); // connect handle } pub fn InternetConnectW(emu:&mut emu::Emu) { - let internet_hndl = emu.maps.read_dword(emu.regs.esp).expect("wininet!InternetConnectW cannot read hndl"); - let server_ptr = emu.maps.read_dword(emu.regs.esp+4).expect("wininet!InternetConnectW cannot read server_ptr"); - let port = emu.maps.read_dword(emu.regs.esp+8).expect("wininet!InternetConnectW cannot read port"); - let login_ptr = emu.maps.read_dword(emu.regs.esp+12).expect("wininet!InternetConnectW cannot read login_ptr"); - let passw_ptr = emu.maps.read_dword(emu.regs.esp+16).expect("wininet!InternetConnectW cannot read passw_ptr"); - let service = emu.maps.read_dword(emu.regs.esp+20).expect("wininet!InternetConnectW cannot read service"); - let flags = emu.maps.read_dword(emu.regs.esp+24).expect("wininet!InternetConnectW cannot read flags"); - let ctx = emu.maps.read_dword(emu.regs.esp+28).expect("wininet!InternetConnectW cannot read ctx"); + let internet_hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("wininet!InternetConnectW cannot read hndl") as u64; + let server_ptr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("wininet!InternetConnectW cannot read server_ptr") as u64; + let port = emu.maps.read_dword(emu.regs.get_esp()+8).expect("wininet!InternetConnectW cannot read port"); + let login_ptr = emu.maps.read_dword(emu.regs.get_esp()+12).expect("wininet!InternetConnectW cannot read login_ptr") as u64; + let passw_ptr = emu.maps.read_dword(emu.regs.get_esp()+16).expect("wininet!InternetConnectW cannot read passw_ptr") as u64; + let service = emu.maps.read_dword(emu.regs.get_esp()+20).expect("wininet!InternetConnectW cannot read service"); + let flags = emu.maps.read_dword(emu.regs.get_esp()+24).expect("wininet!InternetConnectW cannot read flags"); + let ctx = emu.maps.read_dword(emu.regs.get_esp()+28).expect("wininet!InternetConnectW cannot read ctx"); let mut server = "".to_string(); let mut login = "".to_string(); @@ -180,21 +180,21 @@ pub fn InternetConnectW(emu:&mut emu::Emu) { } for _ in 0..8 { - emu.stack_pop(false); + emu.stack_pop32(false); } - emu.regs.eax = helper::handler_create(); // connect handle + emu.regs.rax = helper::handler_create(); // connect handle } fn HttpOpenRequestA(emu:&mut emu::Emu) { - let conn_hndl = emu.maps.read_dword(emu.regs.esp).expect("wininet!HttpOpenRequestA cannot read hndl"); - let method_ptr = emu.maps.read_dword(emu.regs.esp+4).expect("wininet!HttpOpenRequestA cannot read method_ptr"); - let path_ptr = emu.maps.read_dword(emu.regs.esp+8).expect("wininet!HttpOpenRequestA cannot read path_ptr"); - let version_ptr = emu.maps.read_dword(emu.regs.esp+12).expect("wininet!HttpOpenRequestA cannot read version_ptr"); - let referrer_ptr = emu.maps.read_dword(emu.regs.esp+16).expect("wininet!HttpOpenRequestA cannot read referrer_ptr"); - let access_ptr = emu.maps.read_dword(emu.regs.esp+20).expect("wininet!HttpOpenRequestA cannot read access_ptr"); - let flags = emu.maps.read_dword(emu.regs.esp+24).expect("wininet!HttpOpenRequestA cannot read flags"); - let ctx = emu.maps.read_dword(emu.regs.esp+28).expect("wininet!HttpOpenRequestA cannot read ctx"); + let conn_hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("wininet!HttpOpenRequestA cannot read hndl") as u64; + let method_ptr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("wininet!HttpOpenRequestA cannot read method_ptr") as u64; + let path_ptr = emu.maps.read_dword(emu.regs.get_esp()+8).expect("wininet!HttpOpenRequestA cannot read path_ptr") as u64; + let version_ptr = emu.maps.read_dword(emu.regs.get_esp()+12).expect("wininet!HttpOpenRequestA cannot read version_ptr") as u64; + let referrer_ptr = emu.maps.read_dword(emu.regs.get_esp()+16).expect("wininet!HttpOpenRequestA cannot read referrer_ptr") as u64; + let access_ptr = emu.maps.read_dword(emu.regs.get_esp()+20).expect("wininet!HttpOpenRequestA cannot read access_ptr") as u64; + let flags = emu.maps.read_dword(emu.regs.get_esp()+24).expect("wininet!HttpOpenRequestA cannot read flags") as u64; + let ctx = emu.maps.read_dword(emu.regs.get_esp()+28).expect("wininet!HttpOpenRequestA cannot read ctx"); let mut method = "".to_string(); let mut path = "".to_string(); @@ -246,22 +246,22 @@ fn HttpOpenRequestA(emu:&mut emu::Emu) { } for _ in 0..8 { - emu.stack_pop(false); + emu.stack_pop32(false); } - emu.regs.eax = helper::handler_create(); // request handle + emu.regs.rax = helper::handler_create(); // request handle } fn HttpOpenRequestW(emu:&mut emu::Emu) { - let conn_hndl = emu.maps.read_dword(emu.regs.esp).expect("wininet!HttpOpenRequestW cannot read hndl"); - let method_ptr = emu.maps.read_dword(emu.regs.esp+4).expect("wininet!HttpOpenRequestW cannot read method_ptr"); - let path_ptr = emu.maps.read_dword(emu.regs.esp+8).expect("wininet!HttpOpenRequestW cannot read path_ptr"); - let version_ptr = emu.maps.read_dword(emu.regs.esp+12).expect("wininet!HttpOpenRequestW cannot read version_ptr"); - let referrer_ptr = emu.maps.read_dword(emu.regs.esp+16).expect("wininet!HttpOpenRequestW cannot read referrer_ptr"); - let access_ptr = emu.maps.read_dword(emu.regs.esp+20).expect("wininet!HttpOpenRequestW cannot read access_ptr"); - let flags = emu.maps.read_dword(emu.regs.esp+24).expect("wininet!HttpOpenRequestW cannot read flags"); - let ctx = emu.maps.read_dword(emu.regs.esp+28).expect("wininet!HttpOpenRequestW cannot read ctx"); + let conn_hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("wininet!HttpOpenRequestW cannot read hndl") as u64; + let method_ptr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("wininet!HttpOpenRequestW cannot read method_ptr") as u64; + let path_ptr = emu.maps.read_dword(emu.regs.get_esp()+8).expect("wininet!HttpOpenRequestW cannot read path_ptr") as u64; + let version_ptr = emu.maps.read_dword(emu.regs.get_esp()+12).expect("wininet!HttpOpenRequestW cannot read version_ptr") as u64; + let referrer_ptr = emu.maps.read_dword(emu.regs.get_esp()+16).expect("wininet!HttpOpenRequestW cannot read referrer_ptr") as u64; + let access_ptr = emu.maps.read_dword(emu.regs.get_esp()+20).expect("wininet!HttpOpenRequestW cannot read access_ptr") as u64; + let flags = emu.maps.read_dword(emu.regs.get_esp()+24).expect("wininet!HttpOpenRequestW cannot read flags") as u64; + let ctx = emu.maps.read_dword(emu.regs.get_esp()+28).expect("wininet!HttpOpenRequestW cannot read ctx"); let mut method = "".to_string(); let mut path = "".to_string(); @@ -308,17 +308,17 @@ fn HttpOpenRequestW(emu:&mut emu::Emu) { } for _ in 0..8 { - emu.stack_pop(false); + emu.stack_pop32(false); } - emu.regs.eax = helper::handler_create(); // request handle + emu.regs.rax = helper::handler_create(); // request handle } fn InternetSetOptionA(emu:&mut emu::Emu) { - let inet_hndl = emu.maps.read_dword(emu.regs.esp).expect("wininet!InternetSetOptionA cannot read inet_hndl"); - let option = emu.maps.read_dword(emu.regs.esp+4).expect("wininet!InternetSetOptionA cannot read option"); - let buffer = emu.maps.read_dword(emu.regs.esp+8).expect("wininet!InternetSetOptionA cannot read buffer"); - let len = emu.maps.read_dword(emu.regs.esp+12).expect("wininet!InternetSetOptionA cannot read len"); + let inet_hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("wininet!InternetSetOptionA cannot read inet_hndl") as u64; + let option = emu.maps.read_dword(emu.regs.get_esp()+4).expect("wininet!InternetSetOptionA cannot read option"); + let buffer = emu.maps.read_dword(emu.regs.get_esp()+8).expect("wininet!InternetSetOptionA cannot read buffer") as u64; + let len = emu.maps.read_dword(emu.regs.get_esp()+12).expect("wininet!InternetSetOptionA cannot read len"); let mut buffer_content = "".to_string(); if buffer != 0 { @@ -333,17 +333,17 @@ fn InternetSetOptionA(emu:&mut emu::Emu) { } for _ in 0..4 { - emu.stack_pop(false); + emu.stack_pop32(false); } - emu.regs.eax = 1; // true + emu.regs.rax = 1; // true } fn InternetSetOptionW(emu:&mut emu::Emu) { - let inet_hndl = emu.maps.read_dword(emu.regs.esp).expect("wininet!InternetSetOptionW cannot read inet_hndl"); - let option = emu.maps.read_dword(emu.regs.esp+4).expect("wininet!InternetSetOptionW cannot read option"); - let buffer = emu.maps.read_dword(emu.regs.esp+8).expect("wininet!InternetSetOptionW cannot read buffer"); - let len = emu.maps.read_dword(emu.regs.esp+12).expect("wininet!InternetSetOptionW cannot read len"); + let inet_hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("wininet!InternetSetOptionW cannot read inet_hndl") as u64; + let option = emu.maps.read_dword(emu.regs.get_esp()+4).expect("wininet!InternetSetOptionW cannot read option"); + let buffer = emu.maps.read_dword(emu.regs.get_esp()+8).expect("wininet!InternetSetOptionW cannot read buffer") as u64; + let len = emu.maps.read_dword(emu.regs.get_esp()+12).expect("wininet!InternetSetOptionW cannot read len"); let mut buffer_content = "".to_string(); if buffer != 0 { @@ -358,18 +358,18 @@ fn InternetSetOptionW(emu:&mut emu::Emu) { } for _ in 0..4 { - emu.stack_pop(false); + emu.stack_pop32(false); } - emu.regs.eax = 1; // true + emu.regs.rax = 1; // true } fn HttpSendRequestA(emu:&mut emu::Emu) { - let req_hndl = emu.maps.read_dword(emu.regs.esp).expect("wininet!HttpSendRequestA cannot read req_hndl"); - let hdrs_ptr = emu.maps.read_dword(emu.regs.esp+4).expect("wininet!HttpSendRequestA cannot read hdrs_ptr"); - let hdrs_len = emu.maps.read_dword(emu.regs.esp+8).expect("wininet!HttpSendRequestA cannot read hdrs_len"); - let opt_ptr = emu.maps.read_dword(emu.regs.esp+12).expect("wininet!HttpSendRequestA cannot read opt_ptr"); - let opt_len = emu.maps.read_dword(emu.regs.esp+16).expect("wininet!HttpSendRequestA cannot read opt_len"); + let req_hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("wininet!HttpSendRequestA cannot read req_hndl") as u64; + let hdrs_ptr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("wininet!HttpSendRequestA cannot read hdrs_ptr") as u64; + let hdrs_len = emu.maps.read_dword(emu.regs.get_esp()+8).expect("wininet!HttpSendRequestA cannot read hdrs_len") as u64; + let opt_ptr = emu.maps.read_dword(emu.regs.get_esp()+12).expect("wininet!HttpSendRequestA cannot read opt_ptr") as u64; + let opt_len = emu.maps.read_dword(emu.regs.get_esp()+16).expect("wininet!HttpSendRequestA cannot read opt_len"); let hdrs = emu.maps.read_string(hdrs_ptr); let opt = emu.maps.read_string(opt_ptr); @@ -386,18 +386,18 @@ fn HttpSendRequestA(emu:&mut emu::Emu) { } for _ in 0..5 { - emu.stack_pop(false); + emu.stack_pop32(false); } - emu.regs.eax = 1; // true + emu.regs.rax = 1; // true } fn HttpSendRequestW(emu:&mut emu::Emu) { - let req_hndl = emu.maps.read_dword(emu.regs.esp).expect("wininet!HttpSendRequestW cannot read req_hndl"); - let hdrs_ptr = emu.maps.read_dword(emu.regs.esp+4).expect("wininet!HttpSendRequestW cannot read hdrs_ptr"); - let hdrs_len = emu.maps.read_dword(emu.regs.esp+8).expect("wininet!HttpSendRequestW cannot read hdrs_len"); - let opt_ptr = emu.maps.read_dword(emu.regs.esp+12).expect("wininet!HttpSendRequestW cannot read opt_ptr"); - let opt_len = emu.maps.read_dword(emu.regs.esp+16).expect("wininet!HttpSendRequestW cannot read opt_len"); + let req_hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("wininet!HttpSendRequestW cannot read req_hndl") as u64; + let hdrs_ptr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("wininet!HttpSendRequestW cannot read hdrs_ptr") as u64; + let hdrs_len = emu.maps.read_dword(emu.regs.get_esp()+8).expect("wininet!HttpSendRequestW cannot read hdrs_len"); + let opt_ptr = emu.maps.read_dword(emu.regs.get_esp()+12).expect("wininet!HttpSendRequestW cannot read opt_ptr") as u64; + let opt_len = emu.maps.read_dword(emu.regs.get_esp()+16).expect("wininet!HttpSendRequestW cannot read opt_len"); let hdrs = emu.maps.read_wide_string(hdrs_ptr); let opt = emu.maps.read_wide_string(opt_ptr); @@ -414,28 +414,28 @@ fn HttpSendRequestW(emu:&mut emu::Emu) { } for _ in 0..5 { - emu.stack_pop(false); + emu.stack_pop32(false); } - emu.regs.eax = 1; // true + emu.regs.rax = 1; // true } fn InternetErrorDlg(emu:&mut emu::Emu) { - let err = emu.maps.read_dword(emu.regs.esp+8).expect("wininet!InternetErrorDlg cannot read error"); + let err = emu.maps.read_dword(emu.regs.get_esp()+8).expect("wininet!InternetErrorDlg cannot read error"); println!("{}** {} wininet!InternetErrorDlg err: {} {}", emu.colors.light_red, emu.pos, err, emu.colors.nc); for _ in 0..5 { - emu.stack_pop(false); + emu.stack_pop32(false); } - emu.regs.eax = 0; + emu.regs.rax = 0; } fn InternetReadFile(emu:&mut emu::Emu) { - let file_hndl = emu.maps.read_dword(emu.regs.esp).expect("wininet!InternetReadFile cannot read file_hndl"); - let buff_ptr = emu.maps.read_dword(emu.regs.esp+4).expect("wininet!InternetReadFile cannot read buff_ptr"); - let bytes_to_read = emu.maps.read_dword(emu.regs.esp+8).expect("wininet!InternetReadFile cannot read bytes_to_read"); - let bytes_read_ptr = emu.maps.read_dword(emu.regs.esp+12).expect("wininet!InternetReadFile cannot read bytes_read"); + let file_hndl = emu.maps.read_dword(emu.regs.get_esp()).expect("wininet!InternetReadFile cannot read file_hndl") as u64; + let buff_ptr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("wininet!InternetReadFile cannot read buff_ptr") as u64; + let bytes_to_read = emu.maps.read_dword(emu.regs.get_esp()+8).expect("wininet!InternetReadFile cannot read bytes_to_read") as u64; + let bytes_read_ptr = emu.maps.read_dword(emu.regs.get_esp()+12).expect("wininet!InternetReadFile cannot read bytes_read") as u64; @@ -456,15 +456,15 @@ fn InternetReadFile(emu:&mut emu::Emu) { if *count < 3 { emu.maps.write_spaced_bytes(buff_ptr, "90 90 90 90".to_string()); - emu.maps.write_dword(bytes_read_ptr, bytes_to_read); + emu.maps.write_dword(bytes_read_ptr, bytes_to_read as u32); } else { emu.maps.write_dword(bytes_read_ptr, 0); } } for _ in 0..4 { - emu.stack_pop(false); + emu.stack_pop32(false); } - emu.regs.eax = 1; // true + emu.regs.rax = 1; // true } diff --git a/src/emu/winapi/ws2_32.rs b/src/emu/winapi/ws2_32.rs index d51520b..79f7f36 100644 --- a/src/emu/winapi/ws2_32.rs +++ b/src/emu/winapi/ws2_32.rs @@ -48,72 +48,72 @@ fn WsaStartup(emu:&mut emu::Emu) { println!("{}** {} ws2_32!WsaStartup {}", emu.colors.light_red, emu.pos, emu.colors.nc); for _ in 0..2 { - emu.stack_pop(false); + emu.stack_pop32(false); } - emu.regs.eax = 0; + emu.regs.rax = 0; } fn WsaSocketA(emu:&mut emu::Emu) { println!("{}** {} ws2_32!WsaSocketA {}", emu.colors.light_red, emu.pos, emu.colors.nc); for _ in 0..6 { - emu.stack_pop(false); + emu.stack_pop32(false); } - emu.regs.eax = helper::socket_create(); + emu.regs.rax = helper::socket_create(); } fn socket(emu:&mut emu::Emu) { println!("{}** {} ws2_32!socket {}", emu.colors.light_red, emu.pos, emu.colors.nc); for _ in 0..3 { - emu.stack_pop(false); + emu.stack_pop32(false); } - emu.regs.eax = helper::socket_create(); + emu.regs.rax = helper::socket_create(); } fn WsaHtons(emu:&mut emu::Emu) { - let host_port = emu.maps.read_dword(emu.regs.esp+4).expect("ws2_32!WsaHtons cannot read host_port"); - let out_port = emu.maps.read_dword(emu.regs.esp+8).expect("ws2_32!WsaHtons cannot read out_port"); + let host_port = emu.maps.read_dword(emu.regs.get_esp()+4).expect("ws2_32!WsaHtons cannot read host_port"); + let out_port = emu.maps.read_dword(emu.regs.get_esp()+8).expect("ws2_32!WsaHtons cannot read out_port"); println!("{}** {} ws2_32!WsaHtons {} {}", emu.colors.light_red, emu.pos, host_port, emu.colors.nc); for _ in 0..3 { - emu.stack_pop(false); + emu.stack_pop32(false); } //TODO: implement this - emu.regs.eax = 0; + emu.regs.rax = 0; } fn htons(emu:&mut emu::Emu) { - let port:u16 = match emu.maps.read_word(emu.regs.esp) { + let port:u16 = match emu.maps.read_word(emu.regs.get_esp()) { Some(p) => p, None => 0, }; println!("{}** {} ws2_32!htons port: {} {}", emu.colors.light_red, emu.pos, port, emu.colors.nc); - emu.stack_pop(false); - emu.regs.eax = port.to_be() as u32; + emu.stack_pop32(false); + emu.regs.rax = port.to_be() as u64; } fn inet_addr(emu:&mut emu::Emu) { - let addr = emu.maps.read_dword(emu.regs.esp).expect("ws2_32!inet_addr: error reading addr"); + let addr = emu.maps.read_dword(emu.regs.get_esp()).expect("ws2_32!inet_addr: error reading addr"); println!("{}** {} ws2_32!inet_addr {}", emu.colors.light_red, emu.pos, emu.colors.nc); - emu.stack_pop(false); - emu.regs.eax = 0; + emu.stack_pop32(false); + emu.regs.rax = 0; } fn connect(emu:&mut emu::Emu) { - let sock = emu.maps.read_dword(emu.regs.esp).expect("ws2_32!connect: error reading sock"); - let sockaddr_ptr = emu.maps.read_dword(emu.regs.esp+4).expect("ws2_32!connect: error reading sockaddr ptr"); + let sock = emu.maps.read_dword(emu.regs.get_esp()).expect("ws2_32!connect: error reading sock") as u64; + let sockaddr_ptr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("ws2_32!connect: error reading sockaddr ptr") as u64; //let sockaddr = emu.maps.read_bytes(sockaddr_ptr, 8); let family:u16 = emu.maps.read_word(sockaddr_ptr).expect("ws2_32!connect: error reading family"); let port:u16 = emu.maps.read_word(sockaddr_ptr+2).expect("ws2_32!connect: error reading port").to_be(); @@ -123,7 +123,7 @@ fn connect(emu:&mut emu::Emu) { println!("{}** {} ws2_32!connect family: {} {}:{} {}", emu.colors.light_red, emu.pos, family, sip, port, emu.colors.nc); for _ in 0..3 { - emu.stack_pop(false); + emu.stack_pop32(false); } if emu.cfg.endpoint { @@ -132,33 +132,33 @@ fn connect(emu:&mut emu::Emu) { } else { println!("\tcannot connect. dont use -e"); } - emu.regs.eax = 0; - } else { + emu.regs.rax = 0; + } else { // offline mode if !helper::socket_exist(sock) { println!("\tinvalid socket."); - emu.regs.eax = 1; + emu.regs.rax = 1; } else { - emu.regs.eax = 0; + emu.regs.rax = 0; } } } fn recv(emu:&mut emu::Emu) { - let sock = emu.maps.read_dword(emu.regs.esp).expect("ws2_32!recv: error reading sock"); - let buff = emu.maps.read_dword(emu.regs.esp+4).expect("ws2_32!recv: error reading buff"); - let mut len = emu.maps.read_dword(emu.regs.esp+8).expect("ws2_32!recv: error reading len"); - let flags = emu.maps.read_dword(emu.regs.esp+12).expect("ws2_32!recv: error reading flags"); + let sock = emu.maps.read_dword(emu.regs.get_esp()).expect("ws2_32!recv: error reading sock") as u64; + let buff = emu.maps.read_dword(emu.regs.get_esp()+4).expect("ws2_32!recv: error reading buff") as u64; + let mut len = emu.maps.read_dword(emu.regs.get_esp()+8).expect("ws2_32!recv: error reading len") as u64; + let flags = emu.maps.read_dword(emu.regs.get_esp()+12).expect("ws2_32!recv: error reading flags") as u64; println!("{}** {} ws2_32!recv buff: 0x{:x} sz: {} {}", emu.colors.light_red, emu.pos, buff, len, emu.colors.nc); for _ in 0..4 { - emu.stack_pop(false); + emu.stack_pop32(false); } if !helper::socket_exist(sock) { println!("\tinvalid socket."); - emu.regs.eax = 1; + emu.regs.rax = 1; return; } @@ -170,7 +170,7 @@ fn recv(emu:&mut emu::Emu) { emu.maps.write_buffer(buff, &rbuff); println!("\nreceived {} bytes from the endpoint.", n); - emu.regs.eax = n as u32; + emu.regs.rax = n as u64; } else { let mut count_recv = COUNT_RECV.lock().unwrap(); @@ -187,28 +187,28 @@ fn recv(emu:&mut emu::Emu) { emu.maps.memset(buff, 0x90, len as usize); } - emu.regs.eax = len; + emu.regs.rax = len; } } } fn send(emu:&mut emu::Emu) { - let sock = emu.maps.read_dword(emu.regs.esp).expect("ws2_32!send: error reading sock"); - let buff = emu.maps.read_dword(emu.regs.esp+4).expect("ws2_32!send: error reading buff"); - let mut len = emu.maps.read_dword(emu.regs.esp+8).expect("ws2_32!send: error reading len"); - let flags = emu.maps.read_dword(emu.regs.esp+12).expect("ws2_32!send: error reading flags"); + let sock = emu.maps.read_dword(emu.regs.get_esp()).expect("ws2_32!send: error reading sock") as u64; + let buff = emu.maps.read_dword(emu.regs.get_esp()+4).expect("ws2_32!send: error reading buff") as u64; + let mut len = emu.maps.read_dword(emu.regs.get_esp()+8).expect("ws2_32!send: error reading len") as u64; + let flags = emu.maps.read_dword(emu.regs.get_esp()+12).expect("ws2_32!send: error reading flags") as u64; let bytes = emu.maps.read_string_of_bytes(buff, len as usize); for _ in 0..4 { - emu.stack_pop(false); + emu.stack_pop32(false); } println!("{}** {} ws2_32!send {{{}}} {}", emu.colors.light_red, emu.pos, bytes, emu.colors.nc); if !helper::socket_exist(sock) { println!("\tinvalid socket."); - emu.regs.eax = 0; + emu.regs.rax = 0; return; } @@ -217,7 +217,7 @@ fn send(emu:&mut emu::Emu) { let buffer = emu.maps.read_buffer(buff, len as usize); let n = endpoint::sock_send(&buffer); println!("\tsent {} bytes.", n); - emu.regs.eax = n as u32; + emu.regs.rax = n as u64; } else { let mut count_send = COUNT_SEND.lock().unwrap(); @@ -226,16 +226,16 @@ fn send(emu:&mut emu::Emu) { len = 0; // finish the send loop } - emu.regs.eax = len; + emu.regs.rax = len; } } fn bind(emu:&mut emu::Emu) { - let sock = emu.maps.read_dword(emu.regs.esp).expect("ws2_32!send: error reading sock"); - let saddr = emu.maps.read_dword(emu.regs.esp+4).expect("ws2_32!send: error reading addr"); - let len = emu.maps.read_dword(emu.regs.esp+8).expect("ws2_32!send: error reading len"); + let sock = emu.maps.read_dword(emu.regs.get_esp()).expect("ws2_32!send: error reading sock") as u64; + let saddr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("ws2_32!send: error reading addr") as u64; + let len = emu.maps.read_dword(emu.regs.get_esp()+8).expect("ws2_32!send: error reading len") as u64; let family:u16 = emu.maps.read_word(saddr).expect("ws2_32!connect: error reading family"); let port:u16 = emu.maps.read_word(saddr+2).expect("ws2_32!connect: error reading port"); @@ -246,60 +246,60 @@ fn bind(emu:&mut emu::Emu) { println!("{}** {} ws2_32!bind family: {} {}:{} {}", emu.colors.light_red, emu.pos, family, sip, port.to_be(), emu.colors.nc); for _ in 0..3 { - emu.stack_pop(false); + emu.stack_pop32(false); } if !helper::socket_exist(sock) { println!("\tbad socket."); - emu.regs.eax = 1; + emu.regs.rax = 1; } else { - emu.regs.eax = 0; + emu.regs.rax = 0; } } fn listen(emu:&mut emu::Emu) { - let sock = emu.maps.read_dword(emu.regs.esp).expect("ws2_32!send: error reading sock"); - let connections = emu.maps.read_dword(emu.regs.esp+4).expect("ws2_32!send: error reading num of connections"); + let sock = emu.maps.read_dword(emu.regs.get_esp()).expect("ws2_32!send: error reading sock") as u64; + let connections = emu.maps.read_dword(emu.regs.get_esp()+4).expect("ws2_32!send: error reading num of connections") as u64; println!("{}** {} ws2_32!listen connections: {} {}", emu.colors.light_red, emu.pos, connections, emu.colors.nc); for _ in 0..2 { - emu.stack_pop(false); + emu.stack_pop32(false); } if !helper::socket_exist(sock) { println!("\tinvalid socket."); - emu.regs.eax = 1; + emu.regs.rax = 1; } else { - emu.regs.eax = 0; + emu.regs.rax = 0; } } fn accept(emu:&mut emu::Emu) { - let sock = emu.maps.read_dword(emu.regs.esp).expect("ws2_32!accept: error reading sock"); - let saddr = emu.maps.read_dword(emu.regs.esp+4).expect("ws2_32!accept: error reading sockaddr"); - let len = emu.maps.read_dword(emu.regs.esp+8).expect("ws2_32!seacceptnd: error reading len"); - let flags = emu.maps.read_dword(emu.regs.esp+12).expect("ws2_32!accept: error reading flags"); + let sock = emu.maps.read_dword(emu.regs.get_esp()).expect("ws2_32!accept: error reading sock") as u64; + let saddr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("ws2_32!accept: error reading sockaddr") as u64; + let len = emu.maps.read_dword(emu.regs.get_esp()+8).expect("ws2_32!seacceptnd: error reading len") as u64; + let flags = emu.maps.read_dword(emu.regs.get_esp()+12).expect("ws2_32!accept: error reading flags") as u64; let bytes = emu.maps.read_string_of_bytes(saddr, len as usize); println!("{}** {} ws2_32!accept connections: {} {}", emu.colors.light_red, emu.pos, bytes, emu.colors.nc); for _ in 0..4 { - emu.stack_pop(false); + emu.stack_pop32(false); } if !helper::socket_exist(sock) { println!("\tinvalid socket."); - emu.regs.eax = 1; + emu.regs.rax = 1; } else { - emu.regs.eax = 0; + emu.regs.rax = 0; } } fn closesocket(emu:&mut emu::Emu) { - let sock = emu.maps.read_dword(emu.regs.esp).expect("ws2_32!send: error reading sock"); + let sock = emu.maps.read_dword(emu.regs.get_esp()).expect("ws2_32!send: error reading sock") as u64; println!("{}** {} ws2_32!closesocket {}", emu.colors.light_red, emu.pos, emu.colors.nc); @@ -309,16 +309,16 @@ fn closesocket(emu:&mut emu::Emu) { endpoint::sock_close(); } - emu.stack_pop(false); - emu.regs.eax = 0; + emu.stack_pop32(false); + emu.regs.rax = 0; } fn setsockopt(emu:&mut emu::Emu) { - let sock = emu.maps.read_dword(emu.regs.esp).expect("ws2_32!setsockopt: error reading sock"); - let level = emu.maps.read_dword(emu.regs.esp+4).expect("ws2_32!setsockopt: error reading level"); - let optname = emu.maps.read_dword(emu.regs.esp+8).expect("ws2_32!setsockopt: error reading optname"); - let optval = emu.maps.read_dword(emu.regs.esp+12).expect("ws2_32!setsockopt: error reading optval"); - let optlen = emu.maps.read_dword(emu.regs.esp+16).expect("ws2_32!setsockopt: error reading optlen"); + let sock = emu.maps.read_dword(emu.regs.get_esp()).expect("ws2_32!setsockopt: error reading sock") as u64; + let level = emu.maps.read_dword(emu.regs.get_esp()+4).expect("ws2_32!setsockopt: error reading level") as u64; + let optname = emu.maps.read_dword(emu.regs.get_esp()+8).expect("ws2_32!setsockopt: error reading optname") as u64; + let optval = emu.maps.read_dword(emu.regs.get_esp()+12).expect("ws2_32!setsockopt: error reading optval") as u64; + let optlen = emu.maps.read_dword(emu.regs.get_esp()+16).expect("ws2_32!setsockopt: error reading optlen") as u64; let val = match emu.maps.read_dword(optval) { Some(v) => v, @@ -328,23 +328,23 @@ fn setsockopt(emu:&mut emu::Emu) { println!("{}** {} ws2_32!setsockopt lvl: {} opt: {} val: {} {}", emu.colors.light_red, emu.pos, level, optname, val, emu.colors.nc); for _ in 0..5 { - emu.stack_pop(false); + emu.stack_pop32(false); } if !helper::socket_exist(sock) { println!("\tinvalid socket."); - emu.regs.eax = 1; + emu.regs.rax = 1; } else { - emu.regs.eax = 0; + emu.regs.rax = 0; } } fn getsockopt(emu:&mut emu::Emu) { - let sock = emu.maps.read_dword(emu.regs.esp).expect("ws2_32!getsockopt: error reading sock"); - let level = emu.maps.read_dword(emu.regs.esp+4).expect("ws2_32!getsockopt: error reading level"); - let optname = emu.maps.read_dword(emu.regs.esp+8).expect("ws2_32!getsockopt: error reading optname"); - let optval = emu.maps.read_dword(emu.regs.esp+12).expect("ws2_32!getsockopt: error reading optval"); - let optlen = emu.maps.read_dword(emu.regs.esp+16).expect("ws2_32!getsockopt: error reading optlen"); + let sock = emu.maps.read_dword(emu.regs.get_esp()).expect("ws2_32!getsockopt: error reading sock") as u64; + let level = emu.maps.read_dword(emu.regs.get_esp()+4).expect("ws2_32!getsockopt: error reading level") as u64; + let optname = emu.maps.read_dword(emu.regs.get_esp()+8).expect("ws2_32!getsockopt: error reading optname") as u64; + let optval = emu.maps.read_dword(emu.regs.get_esp()+12).expect("ws2_32!getsockopt: error reading optval") as u64; + let optlen = emu.maps.read_dword(emu.regs.get_esp()+16).expect("ws2_32!getsockopt: error reading optlen") as u64; emu.maps.write_dword(optval, 1); @@ -352,36 +352,36 @@ fn getsockopt(emu:&mut emu::Emu) { println!("{}** {} ws2_32!getsockopt lvl: {} opt: {} {}", emu.colors.light_red, emu.pos, level, optname, emu.colors.nc); for _ in 0..5 { - emu.stack_pop(false); + emu.stack_pop32(false); } if !helper::socket_exist(sock) { println!("\tinvalid socket."); - emu.regs.eax = 1; + emu.regs.rax = 1; } else { - emu.regs.eax = 0; + emu.regs.rax = 0; } } fn WsaAccept(emu:&mut emu::Emu) { - let sock = emu.maps.read_dword(emu.regs.esp).expect("ws2_32!WsaAccept: error reading sock"); - let saddr = emu.maps.read_dword(emu.regs.esp+4).expect("ws2_32!WsaAccept: error reading sockaddr"); - let len = emu.maps.read_dword(emu.regs.esp+8).expect("ws2_32!WsaAccept: error reading len"); - let cond = emu.maps.read_dword(emu.regs.esp+12).expect("ws2_32!WsaAccept: error reading cond"); - let callback = emu.maps.read_dword(emu.regs.esp+16).expect("ws2_32!WsaAccept: error reading callback"); + let sock = emu.maps.read_dword(emu.regs.get_esp()).expect("ws2_32!WsaAccept: error reading sock") as u64; + let saddr = emu.maps.read_dword(emu.regs.get_esp()+4).expect("ws2_32!WsaAccept: error reading sockaddr") as u64; + let len = emu.maps.read_dword(emu.regs.get_esp()+8).expect("ws2_32!WsaAccept: error reading len") as u64; + let cond = emu.maps.read_dword(emu.regs.get_esp()+12).expect("ws2_32!WsaAccept: error reading cond") as u64; + let callback = emu.maps.read_dword(emu.regs.get_esp()+16).expect("ws2_32!WsaAccept: error reading callback") as u64; let bytes = emu.maps.read_string_of_bytes(saddr, len as usize); println!("{}** {} ws2_32!WsaAccept connections: {} callback: {} {}", emu.colors.light_red, emu.pos, bytes, callback, emu.colors.nc); for _ in 0..4 { - emu.stack_pop(false); + emu.stack_pop32(false); } if !helper::socket_exist(sock) { println!("\tinvalid socket."); - emu.regs.eax = 1; + emu.regs.rax = 1; } else { - emu.regs.eax = 0; + emu.regs.rax = 0; } } diff --git a/src/main.rs b/src/main.rs index 5638eeb..55f4611 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,7 +17,7 @@ use clap::{Arg, App}; fn main() { let mut cfg = Config::new(); let matches = App::new("SCEMU 32bits emulator for Shellcodes") - .version("0.2.6") + .version("0.3.0") .author("@sha0coder") .arg(Arg::with_name("filename") .short("f") @@ -140,7 +140,7 @@ fn main() { if matches.is_present("string") { cfg.trace_string = true; - cfg.string_addr = u32::from_str_radix(matches.value_of("string").expect("select the address of the string").trim_start_matches("0x"), 16).expect("invalid address"); + cfg.string_addr = u64::from_str_radix(matches.value_of("string").expect("select the address of the string").trim_start_matches("0x"), 16).expect("invalid address"); } if matches.is_present("inspect") { @@ -149,13 +149,13 @@ fn main() { } if matches.is_present("64bits") { - cfg.is_64 = true; + cfg.is_64bits = true; } if matches.is_present("maps") { cfg.maps_folder = matches.value_of("maps").expect("specify the maps folder").to_string(); - } else { - if cfg.is_64 { + } else { // if maps is not selected, by default ... + if cfg.is_64bits { cfg.maps_folder = "maps64/".to_string(); } else { cfg.maps_folder = "maps32/".to_string(); @@ -168,13 +168,13 @@ fn main() { } if matches.is_present("console_addr") { cfg.console2 = true; - cfg.console_addr = u32::from_str_radix(matches.value_of("console_addr").expect("select the address to spawn console with -C").trim_start_matches("0x"), 16).expect("invalid address"); + cfg.console_addr = u64::from_str_radix(matches.value_of("console_addr").expect("select the address to spawn console with -C").trim_start_matches("0x"), 16).expect("invalid address"); } if matches.is_present("entry_point") { - cfg.entry_point = u32::from_str_radix(matches.value_of("entry_point").expect("select the entry point address -a").trim_start_matches("0x"), 16).expect("invalid address"); + cfg.entry_point = u64::from_str_radix(matches.value_of("entry_point").expect("select the entry point address -a").trim_start_matches("0x"), 16).expect("invalid address"); } if matches.is_present("code_base_address") { - cfg.code_base_addr = u32::from_str_radix(matches.value_of("entry_point").expect("select the code base address -b").trim_start_matches("0x"), 16).expect("invalid address"); + cfg.code_base_addr = u64::from_str_radix(matches.value_of("entry_point").expect("select the code base address -b").trim_start_matches("0x"), 16).expect("invalid address"); if !matches.is_present("entry_point") { eprintln!("if the code base is selected, you have to select the entry point ie -b 0x600000 -a 0x600000"); std::process::exit(1);