use crate::emu;
use crate::serialization;
use crate::winapi::winapi64;
pub fn gateway(addr: u64, emu: &mut emu::Emu) -> String {
let api = winapi64::kernel32::guess_api_name(emu, addr);
let api = api.split("!").last().unwrap_or(&api);
match api {
"RealShellExecuteA" => RealShellExecuteA(emu),
"SHGetFolderPathW" => SHGetFolderPathW(emu),
"ShellExecuteA" => ShellExecuteA(emu),
"ShellExecuteW" => ShellExecuteW(emu),
_ => {
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.to_ascii_lowercase();
}
}
String::new()
}
fn ShellExecuteA(emu: &mut emu::Emu) {
let hwnd = emu.regs().rcx;
let lp_operation = emu.regs().rdx;
let lp_file = emu.regs().r8;
let lp_parameters = emu.regs().r9;
let lp_directory = emu
.maps
.read_qword(emu.regs().rsp + 0x20)
.expect("shell32!ShellExecuteA error reading lp_directory");
let n_show_cmd = emu
.maps
.read_qword(emu.regs().rsp + 0x28)
.expect("shell32!ShellExecuteA error reading n_show_cmd");
let operation = if lp_operation != 0 {
emu.maps.read_string(lp_operation)
} else {
"open".to_string()
};
let file = emu.maps.read_string(lp_file);
let params = if lp_parameters != 0 {
emu.maps.read_string(lp_parameters)
} else {
"".to_string()
};
log_red!(
emu,
"shell32!ShellExecuteA op: {} file: {} params: {}",
operation,
file,
params
);
emu.regs_mut().rax = 42; }
fn ShellExecuteW(emu: &mut emu::Emu) {
let hwnd = emu.regs().rcx;
let lp_operation = emu.regs().rdx;
let lp_file = emu.regs().r8;
let lp_parameters = emu.regs().r9;
let lp_directory = emu
.maps
.read_qword(emu.regs().rsp + 0x20)
.expect("shell32!ShellExecuteW error reading lp_directory");
let n_show_cmd = emu
.maps
.read_qword(emu.regs().rsp + 0x28)
.expect("shell32!ShellExecuteW error reading n_show_cmd");
let operation = if lp_operation != 0 {
emu.maps.read_wide_string(lp_operation)
} else {
"open".to_string()
};
let file = emu.maps.read_wide_string(lp_file);
let params = if lp_parameters != 0 {
emu.maps.read_wide_string(lp_parameters)
} else {
"".to_string()
};
log_red!(
emu,
"shell32!ShellExecuteW op: {} file: {} params: {}",
operation,
file,
params
);
emu.regs_mut().rax = 42; }
fn RealShellExecuteA(emu: &mut emu::Emu) {
let handle = emu.regs().rcx;
let operation = emu.regs().rdx;
let file_ptr = emu.regs().r8;
let params_ptr = emu.regs().r9;
let dir = emu
.maps
.read_qword(emu.regs().rsp + 0x20)
.expect("cannot read parameter");
let bShowWindow = emu
.maps
.read_qword(emu.regs().rsp + 0x28)
.expect("cannot read parameter");
let file = emu.maps.read_string(file_ptr);
let params = emu.maps.read_string(params_ptr);
log_red!(emu, "shell32!RealShellExecuteA {} {}", file, params);
emu.regs_mut().rax = 34;
}
fn SHGetFolderPathW(emu: &mut emu::Emu) {
let hwnd = emu.regs().rcx;
let csidl = emu.regs().rdx as i32;
let h_token = emu.regs().r8;
let dw_flags = emu.regs().r9 as u32;
let psz_path = emu
.maps
.read_qword(emu.regs().rsp + 0x20)
.expect("shell32!SHGetFolderPathW error reading pszPath");
log_red!(
emu,
"shell32!SHGetFolderPathW hwnd: 0x{:x} csidl: 0x{:x} token: 0x{:x} flags: 0x{:x} path: 0x{:x}",
hwnd,
csidl,
h_token,
dw_flags,
psz_path
);
let folder_path = match csidl & 0xFFFF {
0x0005 => "C:\\Users\\User\\Documents", 0x001a => "C:\\Users\\User\\AppData\\Roaming", 0x001c => "C:\\Users\\User\\AppData\\Local", 0x0020 => "C:\\Users\\User\\AppData\\Local\\Microsoft\\Windows\\INetCache", 0x0021 => "C:\\Users\\User\\AppData\\Local\\Microsoft\\Windows\\INetCookies", 0x0022 => "C:\\Users\\User\\AppData\\Local\\Microsoft\\Windows\\History", 0x0023 => "C:\\ProgramData", 0x0024 => "C:\\Windows", 0x0025 => "C:\\Windows\\System32", 0x0026 => "C:\\Program Files", 0x0027 => "C:\\Users\\User\\Pictures", 0x0028 => "C:\\Users\\User", 0x0029 => "C:\\Windows\\SysWOW64", 0x002a => "C:\\Program Files (x86)", 0x002b => "C:\\Program Files\\Common Files", 0x002c => "C:\\Program Files (x86)\\Common Files", 0x002d => "C:\\ProgramData\\Microsoft\\Windows\\Templates", 0x002e => "C:\\Users\\Public\\Documents", 0x002f => "C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Administrative Tools", 0x0030 => "C:\\Users\\User\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Administrative Tools", 0x0031 => "C:\\Users\\User\\AppData\\Roaming\\Microsoft\\Windows\\Network Shortcuts", 0x0035 => "C:\\Users\\Public\\Music", 0x0036 => "C:\\Users\\Public\\Pictures", 0x0037 => "C:\\Users\\Public\\Videos", 0x0038 => "C:\\Windows\\Resources", _ => panic!("Unimplemented CSIDL value: 0x{:x} at {}", csidl, emu.pos),
};
if psz_path != 0 {
emu.maps.write_wide_string(psz_path, folder_path);
}
emu.regs_mut().rax = 0;
}