Skip to content
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
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions crates/libmwemu/src/winapi/winapi32/kernel32/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ pub use wide_char_to_multi_byte::*;
pub use win_exec::*;
pub use write_file::*;
pub use write_process_memory::*;
use crate::emu::Emu;

pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String {
let api = guess_api_name(emu, addr);
Expand Down Expand Up @@ -390,6 +391,7 @@ pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String {
"FreeLibrary" => FreeLibrary(emu),
"FreeResource" => FreeResource(emu),
"GetACP" => GetACP(emu),
"GetThreadId" => GetThreadId(emu),
"GetCommandLineA" => GetCommandLineA(emu),
"GetCommandLineW" => GetCommandLineW(emu),
"GetComputerNameA" => GetComputerNameA(emu),
Expand Down Expand Up @@ -545,6 +547,11 @@ pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String {
String::new()
}

fn GetThreadId(emu: &mut Emu) {
emu.stack_pop32(false);
emu.regs_mut().rax = 0x2c2878;
}

lazy_static! {
static ref COUNT_READ: Mutex<u32> = Mutex::new(0);
static ref COUNT_WRITE: Mutex<u32> = Mutex::new(0);
Expand Down
24 changes: 24 additions & 0 deletions crates/libmwemu/src/winapi/winapi32/ntdll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use crate::winapi::winapi32::kernel32;

use crate::maps::mem64::Permission;
use scan_fmt::scan_fmt_some;
use crate::emu::Emu;
use crate::winapi::winapi64::kernel32::InitializeCriticalSection;

const PAGE_NOACCESS: u32 = 0x01;
const PAGE_READONLY: u32 = 0x02;
Expand Down Expand Up @@ -36,6 +38,8 @@ pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String {
"NtQueryPerformanceCounter" => NtQueryPerformanceCounter(emu),
"RtlGetProcessHeaps" => RtlGetProcessHeaps(emu),
"RtlDosPathNameToNtPathName_U" => RtlDosPathNameToNtPathName_U(emu),
"RtlInitializeCriticalSection" => InitializeCriticalSection(emu),
"RtlZeroMemory" => RtlZeroMemory(emu),
"NtCreateFile" => NtCreateFile(emu),
"RtlFreeHeap" => RtlFreeHeap(emu),
"NtQueryInformationFile" => NtQueryInformationFile(emu),
Expand Down Expand Up @@ -80,6 +84,26 @@ pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String {
String::new()
}

fn RtlZeroMemory(emu: &mut Emu) {
let dest = emu
.maps
.read_dword(emu.regs().get_esp() + 4)
.expect("bad RtlZeroMemory address pointer parameter") as u64;
let length = emu
.maps
.read_dword(emu.regs().get_esp() + 8)
.expect("bad RtlZeroMemory address length parameter") as u64;

log_red!(
emu,
"ntdll!RtlZeroMemory dest: 0x{:x} length: {}",
dest,
length
);

emu.maps.memset(dest, 0, length as usize);
}

fn NtAllocateVirtualMemory(emu: &mut emu::Emu) {
/*
__kernel_entry NTSYSCALLAPI NTSTATUS NtAllocateVirtualMemory(
Expand Down
113 changes: 113 additions & 0 deletions crates/libmwemu/src/winapi/winapi32/ws2_32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,119 @@ lazy_static! {
static ref COUNT_RECV: Mutex<u32> = Mutex::new(0);
}

fn getaddrinfo(emu: &mut emu::Emu) {
let node_name_ptr = emu
.maps
.read_dword(emu.regs().get_esp() + 4)
.expect("ws2_32!getaddrinfo cannot read node_name_ptr");
let service_name_ptr = emu
.maps
.read_dword(emu.regs().get_esp() + 8)
.expect("ws2_32!getaddrinfo cannot read service_name_ptr");
let hints_ptr = emu
.maps
.read_dword(emu.regs().get_esp() + 12)
.expect("ws2_32!getaddrinfo cannot read hints_ptr");
let result_ptr_ptr = emu
.maps
.read_dword(emu.regs().get_esp() + 16)
.expect("ws2_32!getaddrinfo cannot read result_ptr_ptr");

let node_name = if node_name_ptr != 0 {
emu.maps.read_string(node_name_ptr as u64)
} else {
"NULL".to_string()
};

let service_name = if service_name_ptr != 0 {
emu.maps.read_string(service_name_ptr as u64)
} else {
"NULL".to_string()
};

log_red!(emu, "ws2_32!getaddrinfo node: `{}` service: `{}`", node_name, service_name);

// Read hints if provided
let mut hints_flags = 0;
let mut hints_family = 0;
let mut hints_socktype = 0;
let mut hints_protocol = 0;

if hints_ptr != 0 {
hints_flags = emu.maps.read_dword(hints_ptr as u64).unwrap_or(0) as i32;
hints_family = emu.maps.read_dword((hints_ptr + 4) as u64).unwrap_or(0) as i32;
hints_socktype = emu.maps.read_dword((hints_ptr + 8) as u64).unwrap_or(0) as i32;
hints_protocol = emu.maps.read_dword((hints_ptr + 12) as u64).unwrap_or(0) as i32;
}

// Create a dummy ADDRINFO structure
let addrinfo_size = 48; // Size of ADDRINFOA structure (approximate)
let sockaddr_in_size = 16; // Size of sockaddr_in structure

// Allocate memory for the result
let heap_management = emu.heap_management.as_mut().unwrap();
let addrinfo_addr = heap_management.allocate((addrinfo_size + sockaddr_in_size + 100) as usize).unwrap();
let sockaddr_addr = addrinfo_addr + addrinfo_size;
let canonname_addr = sockaddr_addr + sockaddr_in_size;

// Create a dummy sockaddr_in (IPv4 address 127.0.0.1, port based on service)
let ip_addr = 0x0100007f; // 127.0.0.1 in network byte order

// Determine port based on service name
let port = if service_name == "http" || service_name == "80" {
80u16
} else if service_name == "https" || service_name == "443" {
443u16
} else if service_name == "ftp" || service_name == "21" {
21u16
} else if service_name == "ssh" || service_name == "22" {
22u16
} else if service_name == "smtp" || service_name == "25" {
25u16
} else if service_name == "dns" || service_name == "53" {
53u16
} else {
service_name.parse().unwrap_or(80u16)
};

// Write sockaddr_in structure
emu.maps.write_word(sockaddr_addr, 2); // AF_INET = 2
emu.maps.write_word(sockaddr_addr + 2, port.to_be()); // Port in network byte order
emu.maps.write_dword(sockaddr_addr + 4, ip_addr); // IP address (127.0.0.1)
emu.maps.memset(sockaddr_addr + 8, 0, 8); // Zero out the rest

// Write ADDRINFO structure
emu.maps.write_dword(addrinfo_addr, hints_flags as u32); // ai_flags
emu.maps.write_dword(addrinfo_addr + 4, if hints_family != 0 { hints_family as u32 } else { 2 }); // ai_family (AF_INET)
emu.maps.write_dword(addrinfo_addr + 8, if hints_socktype != 0 { hints_socktype as u32 } else { 1 }); // ai_socktype (SOCK_STREAM)
emu.maps.write_dword(addrinfo_addr + 12, if hints_protocol != 0 { hints_protocol as u32 } else { 6 }); // ai_protocol (IPPROTO_TCP)
emu.maps.write_qword(addrinfo_addr + 16, sockaddr_in_size as u64); // ai_addrlen
emu.maps.write_qword(addrinfo_addr + 24, canonname_addr); // ai_canonname
emu.maps.write_qword(addrinfo_addr + 32, sockaddr_addr); // ai_addr

// Set ai_canonname to the node name or "localhost"
let canon_name = if node_name == "NULL" || node_name.is_empty() || node_name == "localhost" {
"localhost.localdomain".to_string()
} else if node_name == "127.0.0.1" {
"localhost".to_string()
} else {
format!("{}.localdomain", node_name)
};
emu.maps.write_string(canonname_addr, &canon_name);

// ai_next is NULL (end of list)
emu.maps.write_qword(addrinfo_addr + 40, 0);

// Store the result pointer in the ppResult parameter
emu.maps.write_qword(result_ptr_ptr as u64, addrinfo_addr);

log::info!("\tcreated dummy ADDRINFO for {}:{} at 0x{:x}", node_name, service_name, addrinfo_addr);
log::info!("\tsockaddr at 0x{:x}, canonname at 0x{:x}", sockaddr_addr, canonname_addr);

// Return 0 for success (WSA error code)
emu.regs_mut().rax = 0;
}

fn WsaStartup(emu: &mut emu::Emu) {
log_red!(emu, "ws2_32!WsaStartup");

Expand Down
7 changes: 7 additions & 0 deletions crates/libmwemu/src/winapi/winapi64/kernel32/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::sync::Mutex;

use crate::constants;
use crate::emu;
use crate::emu::Emu;
use crate::peb::peb64;
use crate::serialization;

Expand Down Expand Up @@ -449,6 +450,7 @@ pub fn gateway(addr: u64, emu: &mut emu::Emu) -> String {
"GetStartupInfoA" => GetStartupInfoA(emu),
"GetStartupInfoW" => GetStartupInfoW(emu),
"GetStdHandle" => GetStdHandle(emu),
"GetThreadId" => GetThreadId(emu),
"GetSystemDirectoryA" => GetSystemDirectoryA(emu),
"GetSystemDirectoryW" => GetSystemDirectoryW(emu),
"GetSystemFirmwareTable" => GetSystemFirmwareTable(emu),
Expand Down Expand Up @@ -566,6 +568,11 @@ pub fn gateway(addr: u64, emu: &mut emu::Emu) -> String {
String::new()
}

fn GetThreadId(emu: &mut Emu) {
let hThread = emu.regs().rcx;
emu.regs_mut().rax = 0x2c2878;
}

lazy_static! {
pub static ref COUNT_READ: Mutex<u32> = Mutex::new(0);
pub static ref COUNT_WRITE: Mutex<u32> = Mutex::new(0);
Expand Down
38 changes: 38 additions & 0 deletions crates/libmwemu/src/winapi/winapi64/ntdll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::serialization;
use crate::structures;
use crate::winapi::helper;
use crate::winapi::winapi64::kernel32;
use crate::winapi::winapi64::kernel32::InitializeCriticalSection;

const PAGE_NOACCESS: u32 = 0x01;
const PAGE_READONLY: u32 = 0x02;
Expand Down Expand Up @@ -44,6 +45,7 @@ pub fn gateway(addr: u64, emu: &mut emu::Emu) -> String {
"NtQueryPerformanceCounter" => NtQueryPerformanceCounter(emu),
"RtlGetProcessHeaps" => RtlGetProcessHeaps(emu),
"RtlDosPathNameToNtPathName_U" => RtlDosPathNameToNtPathName_U(emu),
"RtlInitializeCriticalSection" => InitializeCriticalSection(emu),
"NtCreateFile" => NtCreateFile(emu),
"RtlFreeHeap" => RtlFreeHeap(emu),
"NtQueryInformationFile" => NtQueryInformationFile(emu),
Expand All @@ -65,6 +67,8 @@ pub fn gateway(addr: u64, emu: &mut emu::Emu) -> String {
"NtTerminateThread" => NtTerminateThread(emu),
"RtlAddFunctionTable" => RtlAddFunctionTable(emu),
"RtlCaptureContext" => RtlCaptureContext(emu),
"RtlMoveMemory" => RtlMoveMemory(emu),
"RtlZeroMemory" => RtlZeroMemory(emu),
"RtlLookupFunctionEntry" => RtlLookupFunctionEntry(emu),
"strlen" => strlen(emu),
"NtSetInformationThread" => NtSetInformationThread(emu),
Expand All @@ -91,6 +95,40 @@ pub fn gateway(addr: u64, emu: &mut emu::Emu) -> String {

String::new()
}
fn RtlZeroMemory(emu: &mut emu::Emu) {
let dest = emu.regs().rcx;
let length = emu.regs().rdx;

log_red!(
emu,
"ntdll!RtlZeroMemory dest: 0x{:x} length: {}",
dest,
length
);

emu.maps.memset(dest, 0, length as usize);
}


fn RtlMoveMemory(emu: &mut emu::Emu) {
let dst = emu.regs().rcx;
let src = emu.regs().rdx;
let sz = emu.regs().r8 as usize;

let result = emu.maps.memcpy(dst, src, sz);
if result == false {
panic!("RtlMoveMemory failed to copy");
}

log_red!(
emu,
"** {} ntdll!RtlMoveMemory dst = {:x} src = {:x} sz = {}",
emu.pos,
dst,
src,
sz
);
}

fn NtAllocateVirtualMemory(emu: &mut emu::Emu) {
/*
Expand Down
Loading