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
6 changes: 4 additions & 2 deletions libmwemu/src/emu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ pub struct Emu {
force_break: bool,
force_reload: bool,
pub tls_callbacks: Vec<u64>,
pub tls: Vec<u32>,
pub tls32: Vec<u32>,
pub tls64: Vec<u64>,
pub fls: Vec<u32>,
pub out: String,
pub instruction: Option<Instruction>,
Expand Down Expand Up @@ -186,7 +187,8 @@ impl Emu {
force_break: false,
force_reload: false,
tls_callbacks: Vec::new(),
tls: Vec::new(),
tls32: Vec::new(),
tls64: Vec::new(),
fls: Vec::new(),
out: String::new(),
main_thread_cont: 0,
Expand Down
43 changes: 25 additions & 18 deletions libmwemu/src/emu/winapi32/kernel32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@ use crate::emu::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 @@ -179,8 +190,7 @@ pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String {
"RegOpenKeyA" => RegOpenKeyA(emu),
"RegOpenKeyW" => RegOpenKeyW(emu),
_ => {
log::info!("calling unimplemented kernel32 API 0x{:x} {}", addr, api);
return api;
unimplemented!("calling unimplemented kernel32 API 0x{:x} {}", addr, api);
}
}

Expand Down Expand Up @@ -2298,7 +2308,8 @@ fn TlsAlloc(emu: &mut emu::Emu) {
emu.colors.nc
);

emu.regs.rax = 1;
emu.tls32.push(0);
emu.regs.set_eax(emu.tls32.len() as u64);
}

fn TlsFree(emu: &mut emu::Emu) {
Expand All @@ -2316,7 +2327,7 @@ fn TlsFree(emu: &mut emu::Emu) {
);

emu.stack_pop32(false);
emu.regs.rax = 1;
emu.regs.set_eax(1);
}

fn TlsSetValue(emu: &mut emu::Emu) {
Expand All @@ -2338,19 +2349,18 @@ fn TlsSetValue(emu: &mut emu::Emu) {
emu.colors.nc
);

if emu.tls.len() > idx as usize {
emu.tls[idx as usize] = val;
if emu.tls32.len() > idx as usize {
emu.tls32[idx as usize] = val;
} else {
for _ in 0..=idx {
emu.tls.push(0);
emu.tls32.push(0);
}
emu.tls[idx as usize] = val;
emu.tls32[idx as usize] = val;
}

emu.stack_pop32(false);
emu.stack_pop32(false);

emu.regs.rax = 1;
emu.regs.set_eax(1);
}

fn TlsGetValue(emu: &mut emu::Emu) {
Expand All @@ -2361,19 +2371,16 @@ fn TlsGetValue(emu: &mut emu::Emu) {

emu.stack_pop32(false);

if idx as usize > emu.tls.len() {
emu.regs.rax = 0;
if idx as usize > emu.tls32.len() {
emu.regs.set_eax(0);
} else {
emu.regs.rax = emu.tls[idx as usize] as u64;
emu.regs.set_eax(emu.tls32[idx as usize] as u64);
}

log::info!(
"{}** {} kernel32!TlsGetValue idx: {} =0x{:x} {}",
emu.colors.light_red,
log_red!(emu, "** {} kernel32!TlsGetValue idx: {} =0x{:x}",
emu.pos,
idx,
emu.regs.get_eax() as u32,
emu.colors.nc
emu.regs.get_eax() as u32
);
}

Expand Down
142 changes: 140 additions & 2 deletions libmwemu/src/emu/winapi64/kernel32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@ use crate::emu::context64;
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
);
};
}

// a in RCX, b in RDX, c in R8, d in R9, then e pushed on stack

pub fn gateway(addr: u64, emu: &mut emu::Emu) -> String {
Expand Down Expand Up @@ -137,14 +148,19 @@ pub fn gateway(addr: u64, emu: &mut emu::Emu) -> String {
"lstrcpy" => lstrcpy(emu),
"GetModuleHandleA" => GetModuleHandleA(emu),
"GetModuleHandleW" => GetModuleHandleW(emu),
"TlsAlloc" => TlsAlloc(emu),
"TlsSetValue" => TlsSetValue(emu),
"TlsGetValue" => TlsGetValue(emu),
"TlsFree" => TlsFree(emu),
"GetACP" => GetACP(emu),
"GetStdHandle" => GetStdHandle(emu),

_ => {
log::info!(
unimplemented!(
"calling unimplemented kernel32 64bits API 0x{:x} {}",
addr,
api
);
return api;
}
}

Expand Down Expand Up @@ -2832,3 +2848,125 @@ fn GetModuleHandleW(emu: &mut emu::Emu) {
emu.colors.nc
);
}

/*
DWORD TlsAlloc();
*/
fn TlsAlloc(emu: &mut emu::Emu) {
log::info!(
"{}** {} kernel32!TlsAlloc {}",
emu.colors.light_red,
emu.pos,
emu.colors.nc
);

emu.tls64.push(0);
emu.regs.rax = (emu.tls64.len() - 1) as u64; // Return index of newly allocated slot
}

/*
BOOL TlsFree(
[in] DWORD dwTlsIndex
);
*/
fn TlsFree(emu: &mut emu::Emu) {
let idx = emu.regs.rcx as usize; // First parameter passed in RCX in x64

log::info!(
"{}** {} kernel32!TlsFree idx: {} {}",
emu.colors.light_red,
emu.pos,
idx,
emu.colors.nc
);

if idx < emu.tls64.len() {
emu.tls64[idx] = 0; // Clear the slot
emu.regs.rax = 1; // Return TRUE
} else {
emu.regs.rax = 0; // Return FALSE if invalid index
}
}

/*
BOOL TlsSetValue(
[in] DWORD dwTlsIndex,
[in, optional] LPVOID lpTlsValue
);
*/
fn TlsSetValue(emu: &mut emu::Emu) {
let idx = emu.regs.rcx as usize; // First parameter in RCX
let val = emu.regs.rdx; // Second parameter in RDX

log::info!(
"{}** {} kernel32!TlsSetValue idx: {} val: 0x{:x} {}",
emu.colors.light_red,
emu.pos,
idx,
val,
emu.colors.nc
);

if idx < emu.tls64.len() {
emu.tls64[idx] = val;
} else {
// Expand TLS array if needed
while emu.tls64.len() <= idx {
emu.tls64.push(0);
}
emu.tls64[idx] = val;
}

emu.regs.rax = 1; // Return TRUE
}

/*
DWORD TlsGetValue(
[in] DWORD dwTlsIndex
);
*/
fn TlsGetValue(emu: &mut emu::Emu) {
let idx = emu.regs.rcx as usize; // Parameter passed in RCX in x64

let val = if idx < emu.tls64.len() {
emu.tls64[idx]
} else {
0
};

emu.regs.rax = val;

log_red!(emu, "** {} kernel32!TlsGetValue idx: {} =0x{:x}",
emu.pos,
idx,
val
);
}

/*
UINT GetACP();
*/
// TODO: there is GetAcp and GetACP?
fn GetACP(emu: &mut emu::Emu) {
log::info!(
"{}** {} kernel32!GetACP {}",
emu.colors.light_red,
emu.pos,
emu.colors.nc
);
emu.regs.rax = 0x00000409;
}

/*
HANDLE GetStdHandle(
[in] DWORD nStdHandle
);
*/
fn GetStdHandle(emu: &mut emu::Emu) {
let nstd = emu.regs.rcx as usize; // Parameter passed in RCX in x64
log_red!(emu, "** {} kernel32!GetStdHandle nstd: {}",
emu.pos,
nstd
);
emu.regs.rax = nstd as u64;
}
27 changes: 0 additions & 27 deletions scripts/enigma-protector.py

This file was deleted.

41 changes: 41 additions & 0 deletions scripts/enigma-protector.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/bin/bash

set -x

export RUST_BACKTRACE=1
export RUST_LOG=info

# Set target architecture based on OS
if [[ "$OSTYPE" == "msys"* ]] || [[ "$OSTYPE" == "cygwin"* ]]; then
TARGET=x86_64-pc-windows-msvc
else
TARGET=x86_64-apple-darwin
fi

cargo run -p mwemu --release \
--target $TARGET \
-- \
--filename ~/Desktop/enigma/surprise.dll \
--maps ./maps64/ \
--64bits \
--mxcsr 0x1FC00001FA0 \
--stack_address 0x32C6FE000 \
--base 0x7FFBFA260000 \
--entry 0x7FFBFB295FF0 \
--rax 0x7FFBFB295FF0 \
--rbx 0x7FFE0385 \
--rcx 0x7FFBFA260000 \
--rdx 0x1 \
--rsp 0x32C6FE378 \
--rbp 0x32C6FE6B8 \
--rsi 0x1 \
--rdi 0x7FFE0384 \
--r8 0x0 \
--r9 0x0 \
--r10 0xA440AE23305F3A70 \
--r11 0x32C6FE3E8 \
--r12 0x7FFBFB295FF0 \
--r13 0x120136C63F0 \
--r14 0x7FFBFA260000 \
--r15 0x0 \
--rflags 0x344
Loading