Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fxrstor #61

Merged
merged 21 commits into from
Dec 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ x
test/
.venv/
emu.bin
emu.bin*
19 changes: 19 additions & 0 deletions libmwemu/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ pub const STATUS_ACCESS_VIOLATION: u64 = 0xC0000005;
pub const STATUS_INVALID_PARAMETER: u64 = 0xC000000D;

pub const ERROR_SUCCESS: u64 = 0;
pub const ERROR_INVALID_PARAMETER: u64 = 0x57;
pub const ERROR_INSUFFICIENT_BUFFER: u64 = 122;

pub const CP_UTF7: u64 = 65000;
pub const CP_UTF8: u64 = 65001;

pub const NUM_BYTES_TRACE: usize = 16;
pub const VERSION: u64 = 0x1db10106;
Expand Down Expand Up @@ -732,6 +737,20 @@ pub const ARCH_SET_FS: u64 = 0x1002;
pub const ARCH_GET_FS: u64 = 0x1003;
pub const ARCH_GET_GS: u64 = 0x1004;

pub const LOCALE_USER_DEFAULT: u64 = 0x400;
pub const LOCALE_SABBREVMONTHNAME1 : u64 = 68;
pub const LOCALE_SABBREVMONTHNAME2 : u64 = 69;
pub const LOCALE_SABBREVMONTHNAME3 : u64 = 70;
pub const LOCALE_SABBREVMONTHNAME4 : u64 = 71;
pub const LOCALE_SABBREVMONTHNAME5 : u64 = 72;
pub const LOCALE_SABBREVMONTHNAME6 : u64 = 73;
pub const LOCALE_SABBREVMONTHNAME7 : u64 = 74;
pub const LOCALE_SABBREVMONTHNAME8 : u64 = 75;
pub const LOCALE_SABBREVMONTHNAME9 : u64 = 76;
pub const LOCALE_SABBREVMONTHNAME10: u64 = 77;
pub const LOCALE_SABBREVMONTHNAME11: u64 = 78;
pub const LOCALE_SABBREVMONTHNAME12: u64 = 79;

pub const UTSNAME: [u8; 390] = [
0x4c, 0x69, 0x6e, 0x75, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Expand Down
4 changes: 2 additions & 2 deletions libmwemu/src/emu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,7 @@ impl Emu {
winapi32::kernel32::load_library(self, "iphlpapi.dll");
winapi32::kernel32::load_library(self, "ws2_32.dll");
winapi32::kernel32::load_library(self, "advapi32.dll");
//winapi32::kernel32::load_library(self, "comctl64.dll");
//winapi32::kernel32::load_library(self, "comctl32.dll");
winapi32::kernel32::load_library(self, "winhttp.dll");
winapi32::kernel32::load_library(self, "wininet.dll");
//winapi32::kernel32::load_library(self, "dnsapi.dll");
Expand Down Expand Up @@ -610,7 +610,7 @@ impl Emu {
winapi64::kernel32::load_library(self, "iphlpapi.dll");
winapi64::kernel32::load_library(self, "ws2_32.dll");
winapi64::kernel32::load_library(self, "advapi32.dll");
winapi64::kernel32::load_library(self, "comctl64.dll");
winapi64::kernel32::load_library(self, "comctl32.dll");
winapi64::kernel32::load_library(self, "winhttp.dll");
winapi64::kernel32::load_library(self, "wininet.dll");
winapi64::kernel32::load_library(self, "dnsapi.dll");
Expand Down
14 changes: 14 additions & 0 deletions libmwemu/src/engine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ pub mod logic;

use iced_x86::{Instruction, Mnemonic, Register};
use crate::emu::Emu;
use crate::fpu::FPUState;
use crate::regs64;
use crate::exception;
use crate::inline;
Expand Down Expand Up @@ -4585,6 +4586,19 @@ pub fn emulate_instruction(
state.save(addr, emu);
}

Mnemonic::Fxrstor => {
emu.show_instruction(&emu.colors.green, ins);

let addr = match emu.get_operand_value(ins, 0, false) {
Some(v) => v,
None => return false,
};

let state = FPUState::load(addr, emu);

emu.fpu.fxrstor(state);
}

Mnemonic::Fistp => {
emu.show_instruction(&emu.colors.green, ins);

Expand Down
31 changes: 31 additions & 0 deletions libmwemu/src/fpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,19 @@ impl FPUState {
}
}

pub fn load(addr: u64, emu: &mut emu::Emu) -> FPUState {
let mut state = FPUState::new();
state.fpu_control_word = emu.maps.read_word(addr).unwrap();
state.fpu_status_word = emu.maps.read_word(addr + 2).unwrap();
state.fpu_tag_word = emu.maps.read_word(addr + 4).unwrap();
state.fpu_opcode = emu.maps.read_word(addr + 6).unwrap();
state.rip = emu.maps.read_qword(addr + 8).unwrap();
state.rdp = emu.maps.read_qword(addr + 16).unwrap();
state.mxcsr = emu.maps.read_dword(addr + 24).unwrap();
state.mxcsr_mask = emu.maps.read_dword(addr + 28).unwrap();
state
}

pub fn save(&self, addr: u64, emu: &mut emu::Emu) {
emu.maps.write_word(addr, self.fpu_control_word); // FCW (offset 0)
emu.maps.write_word(addr + 2, self.fpu_status_word); // FSW (offset 2)
Expand Down Expand Up @@ -328,4 +341,22 @@ impl FPU {
state.xmm = self.xmm.clone();
return state;
}

pub fn fxrstor(&mut self, state: FPUState) {
self.fpu_control_word = state.fpu_control_word;
self.stat = state.fpu_status_word;
self.tag = state.fpu_tag_word;
self.opcode = state.fpu_opcode;
self.ip = state.rip;
self.operand_ptr = state.rdp;
self.mxcsr = state.mxcsr;

// Convert the packed 128-bit ST registers back to f64 values
for i in 0..8 {
let low_bits = (state.st[i] & 0xFFFFFFFFFFFFFFFF) as u64;
self.st[i] = f64::from_bits(low_bits);
}

self.xmm = state.xmm;
}
}
12 changes: 12 additions & 0 deletions libmwemu/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,15 @@ macro_rules! to32 {
};
}

#[macro_export]
macro_rules! log_red {
($emu:expr, $($arg:tt)*) => {
log::info!(
"{}{}{}",
$emu.colors.light_red,
format!($($arg)*),
$emu.colors.nc
);
};
}

2 changes: 1 addition & 1 deletion libmwemu/src/winapi32/advapi32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String {

unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api);
}
log::warn!("calling unimplemented API 0x{:x} {}", addr, api);
log::warn!("calling unimplemented API 0x{:x} {} at 0x{:x}", addr, api, emu.regs.rip);
return api;
}
}
Expand Down
2 changes: 1 addition & 1 deletion libmwemu/src/winapi32/crypt32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String {

unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api);
}
log::warn!("calling unimplemented API 0x{:x} {}", addr, api);
log::warn!("calling unimplemented API 0x{:x} {} at 0x{:x}", addr, api, emu.regs.rip);
return api;
}
}
Expand Down
2 changes: 1 addition & 1 deletion libmwemu/src/winapi32/dnsapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String {

unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api);
}
log::warn!("calling unimplemented API 0x{:x} {}", addr, api);
log::warn!("calling unimplemented API 0x{:x} {} at 0x{:x}", addr, api, emu.regs.rip);
return api;
}
}
Expand Down
2 changes: 1 addition & 1 deletion libmwemu/src/winapi32/iphlpapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String {

unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api);
}
log::warn!("calling unimplemented API 0x{:x} {}", addr, api);
log::warn!("calling unimplemented API 0x{:x} {} at 0x{:x}", addr, api, emu.regs.rip);
return api;
}
}
Expand Down
26 changes: 3 additions & 23 deletions libmwemu/src/winapi32/kernel32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,6 @@ use crate::winapi32::helper;
use lazy_static::lazy_static;
use std::sync::Mutex;

macro_rules! log_red {
($emu:expr, $($arg:tt)*) => {
log::info!(
"{}{}{}",
$emu.colors.light_red,
format!($($arg)*),
$emu.colors.nc
);
};
}

pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String {
let api = guess_api_name(emu, addr);
match api.as_str() {
Expand Down Expand Up @@ -198,7 +187,7 @@ pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String {

unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api);
}
log::warn!("calling unimplemented API 0x{:x} {}", addr, api);
log::warn!("calling unimplemented API 0x{:x} {} at 0x{:x}", addr, api, emu.regs.rip);
return api;
}
}
Expand Down Expand Up @@ -421,9 +410,7 @@ fn GetProcAddress(emu: &mut emu::Emu) {
}
}
emu.regs.rax = 0;
if emu.cfg.verbose >= 1 {
log::info!("kernel32!GetProcAddress error searching {}", func);
}
log::warn!("kernel32!GetProcAddress error searching {}", func);
}

pub fn load_library(emu: &mut emu::Emu, libname: &str) -> u64 {
Expand Down Expand Up @@ -476,14 +463,7 @@ fn LoadLibraryA(emu: &mut emu::Emu) {

emu.regs.rax = load_library(emu, &dll);

log::info!(
"{}** {} kernel32!LoadLibraryA '{}' =0x{:x} {}",
emu.colors.light_red,
emu.pos,
&dll,
emu.regs.get_eax() as u32,
emu.colors.nc
);
log_red!(emu, "** {} kernel32!LoadLibraryA '{}' =0x{:x} rip: 0x{:x}", emu.pos, &dll, emu.regs.get_eax() as u32, emu.regs.rip);

emu.stack_pop32(false);

Expand Down
2 changes: 1 addition & 1 deletion libmwemu/src/winapi32/kernelbase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String {

unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api);
}
log::warn!("calling unimplemented API 0x{:x} {}", addr, api);
log::warn!("calling unimplemented API 0x{:x} {} at 0x{:x}", addr, api, emu.regs.rip);
return api;
}
}
Expand Down
2 changes: 1 addition & 1 deletion libmwemu/src/winapi32/libgcc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String {

unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api);
}
log::warn!("calling unimplemented API 0x{:x} {}", addr, api);
log::warn!("calling unimplemented API 0x{:x} {} at 0x{:x}", addr, api, emu.regs.rip);
return api;
}
}
Expand Down
2 changes: 1 addition & 1 deletion libmwemu/src/winapi32/mscoree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String {

unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api);
}
log::warn!("calling unimplemented API 0x{:x} {}", addr, api);
log::warn!("calling unimplemented API 0x{:x} {} at 0x{:x}", addr, api, emu.regs.rip);
return api;
}
}
Expand Down
2 changes: 1 addition & 1 deletion libmwemu/src/winapi32/msvcrt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String {

unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api);
}
log::warn!("calling unimplemented API 0x{:x} {}", addr, api);
log::warn!("calling unimplemented API 0x{:x} {} at 0x{:x}", addr, api, emu.regs.rip);
return api;
}
}
Expand Down
2 changes: 1 addition & 1 deletion libmwemu/src/winapi32/ntdll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String {

unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api);
}
log::warn!("calling unimplemented API 0x{:x} {}", addr, api);
log::warn!("calling unimplemented API 0x{:x} {} at 0x{:x}", addr, api, emu.regs.rip);
return api;
}
}
Expand Down
2 changes: 1 addition & 1 deletion libmwemu/src/winapi32/oleaut32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String {

unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api);
}
log::warn!("calling unimplemented API 0x{:x} {}", addr, api);
log::warn!("calling unimplemented API 0x{:x} {} at 0x{:x}", addr, api, emu.regs.rip);
return api;
}
}
Expand Down
2 changes: 1 addition & 1 deletion libmwemu/src/winapi32/shlwapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String {

unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api);
}
log::warn!("calling unimplemented API 0x{:x} {}", addr, api);
log::warn!("calling unimplemented API 0x{:x} {} at 0x{:x}", addr, api, emu.regs.rip);
return api;
}
}
Expand Down
2 changes: 1 addition & 1 deletion libmwemu/src/winapi32/user32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String {

unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api);
}
log::warn!("calling unimplemented API 0x{:x} {}", addr, api);
log::warn!("calling unimplemented API 0x{:x} {} at 0x{:x}", addr, api, emu.regs.rip);
return api;
}
}
Expand Down
2 changes: 1 addition & 1 deletion libmwemu/src/winapi32/wincrt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String {

unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api);
}
log::warn!("calling unimplemented API 0x{:x} {}", addr, api);
log::warn!("calling unimplemented API 0x{:x} {} at 0x{:x}", addr, api, emu.regs.rip);
return api;
}
}
Expand Down
2 changes: 1 addition & 1 deletion libmwemu/src/winapi32/wininet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String {

unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api);
}
log::warn!("calling unimplemented API 0x{:x} {}", addr, api);
log::warn!("calling unimplemented API 0x{:x} {} at 0x{:x}", addr, api, emu.regs.rip);
return api;
}
}
Expand Down
2 changes: 1 addition & 1 deletion libmwemu/src/winapi32/ws2_32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String {

unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api);
}
log::warn!("calling unimplemented API 0x{:x} {}", addr, api);
log::warn!("calling unimplemented API 0x{:x} {} at 0x{:x}", addr, api, emu.regs.rip);
return api;
}
}
Expand Down
2 changes: 1 addition & 1 deletion libmwemu/src/winapi64/advapi32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub fn gateway(addr: u64, emu: &mut emu::Emu) -> String {

unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api);
}
log::warn!("calling unimplemented API 0x{:x} {}", addr, api);
log::warn!("calling unimplemented API 0x{:x} {} at 0x{:x}", addr, api, emu.regs.rip);
return api;
}
}
Expand Down
20 changes: 20 additions & 0 deletions libmwemu/src/winapi64/comctl32.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use crate::emu;
use crate::serialization;
use crate::winapi64;

pub fn gateway(addr: u64, emu: &mut emu::Emu) -> String {
let api = winapi64::kernel32::guess_api_name(emu, addr);
match api.as_str() {
_ => {
if emu.cfg.skip_unimplemented == false {
if emu.cfg.dump_on_exit && emu.cfg.dump_filename.is_some() {
serialization::Serialization::dump_to_file(&emu, emu.cfg.dump_filename.as_ref().unwrap());
}

unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api);
}
log::warn!("calling unimplemented API 0x{:x} {} at 0x{:x}", addr, api, emu.regs.rip);
return api;
}
}
}
11 changes: 7 additions & 4 deletions libmwemu/src/winapi64/comctl64.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use crate::emu;
use crate::serialization;
use crate::winapi64;
use crate::winapi64::kernel32;
//use crate::winapi32::helper;

pub fn gateway(addr: u64, emu: &mut emu::Emu) -> String {
let api = winapi64::kernel32::guess_api_name(emu, addr);
let api = kernel32::guess_api_name(emu, addr);
match api.as_str() {
_ => {
if emu.cfg.skip_unimplemented == false {
Expand All @@ -13,8 +14,10 @@ pub fn gateway(addr: u64, emu: &mut emu::Emu) -> String {

unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api);
}
log::warn!("calling unimplemented API 0x{:x} {}", addr, api);
log::warn!("calling unimplemented API 0x{:x} {} at 0x{:x}", addr, api, emu.regs.rip);
return api;
}
}
}

String::new()
}
2 changes: 1 addition & 1 deletion libmwemu/src/winapi64/dnsapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub fn gateway(addr: u64, emu: &mut emu::Emu) -> String {

unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api);
}
log::warn!("calling unimplemented API 0x{:x} {}", addr, api);
log::warn!("calling unimplemented API 0x{:x} {} at 0x{:x}", addr, api, emu.regs.rip);
return api;
}
}
Expand Down
Loading
Loading