Skip to content

Commit cf18e62

Browse files
authored
Merge pull request #50 from brandonros/main
tls functioins in winapi64
2 parents 6e768e2 + 2033ed3 commit cf18e62

File tree

5 files changed

+210
-49
lines changed

5 files changed

+210
-49
lines changed

libmwemu/src/emu/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,8 @@ pub struct Emu {
125125
force_break: bool,
126126
force_reload: bool,
127127
pub tls_callbacks: Vec<u64>,
128-
pub tls: Vec<u32>,
128+
pub tls32: Vec<u32>,
129+
pub tls64: Vec<u64>,
129130
pub fls: Vec<u32>,
130131
pub out: String,
131132
pub instruction: Option<Instruction>,
@@ -186,7 +187,8 @@ impl Emu {
186187
force_break: false,
187188
force_reload: false,
188189
tls_callbacks: Vec::new(),
189-
tls: Vec::new(),
190+
tls32: Vec::new(),
191+
tls64: Vec::new(),
190192
fls: Vec::new(),
191193
out: String::new(),
192194
main_thread_cont: 0,

libmwemu/src/emu/winapi32/kernel32.rs

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,17 @@ use crate::emu::winapi32::helper;
99
use lazy_static::lazy_static;
1010
use std::sync::Mutex;
1111

12+
macro_rules! log_red {
13+
($emu:expr, $($arg:tt)*) => {
14+
log::info!(
15+
"{}{}{}",
16+
$emu.colors.light_red,
17+
format!($($arg)*),
18+
$emu.colors.nc
19+
);
20+
};
21+
}
22+
1223
pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String {
1324
let api = guess_api_name(emu, addr);
1425
match api.as_str() {
@@ -179,8 +190,7 @@ pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String {
179190
"RegOpenKeyA" => RegOpenKeyA(emu),
180191
"RegOpenKeyW" => RegOpenKeyW(emu),
181192
_ => {
182-
log::info!("calling unimplemented kernel32 API 0x{:x} {}", addr, api);
183-
return api;
193+
unimplemented!("calling unimplemented kernel32 API 0x{:x} {}", addr, api);
184194
}
185195
}
186196

@@ -2298,7 +2308,8 @@ fn TlsAlloc(emu: &mut emu::Emu) {
22982308
emu.colors.nc
22992309
);
23002310

2301-
emu.regs.rax = 1;
2311+
emu.tls32.push(0);
2312+
emu.regs.set_eax(emu.tls32.len() as u64);
23022313
}
23032314

23042315
fn TlsFree(emu: &mut emu::Emu) {
@@ -2316,7 +2327,7 @@ fn TlsFree(emu: &mut emu::Emu) {
23162327
);
23172328

23182329
emu.stack_pop32(false);
2319-
emu.regs.rax = 1;
2330+
emu.regs.set_eax(1);
23202331
}
23212332

23222333
fn TlsSetValue(emu: &mut emu::Emu) {
@@ -2338,19 +2349,18 @@ fn TlsSetValue(emu: &mut emu::Emu) {
23382349
emu.colors.nc
23392350
);
23402351

2341-
if emu.tls.len() > idx as usize {
2342-
emu.tls[idx as usize] = val;
2352+
if emu.tls32.len() > idx as usize {
2353+
emu.tls32[idx as usize] = val;
23432354
} else {
23442355
for _ in 0..=idx {
2345-
emu.tls.push(0);
2356+
emu.tls32.push(0);
23462357
}
2347-
emu.tls[idx as usize] = val;
2358+
emu.tls32[idx as usize] = val;
23482359
}
23492360

23502361
emu.stack_pop32(false);
23512362
emu.stack_pop32(false);
2352-
2353-
emu.regs.rax = 1;
2363+
emu.regs.set_eax(1);
23542364
}
23552365

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

23622372
emu.stack_pop32(false);
23632373

2364-
if idx as usize > emu.tls.len() {
2365-
emu.regs.rax = 0;
2374+
if idx as usize > emu.tls32.len() {
2375+
emu.regs.set_eax(0);
23662376
} else {
2367-
emu.regs.rax = emu.tls[idx as usize] as u64;
2377+
emu.regs.set_eax(emu.tls32[idx as usize] as u64);
23682378
}
23692379

2370-
log::info!(
2371-
"{}** {} kernel32!TlsGetValue idx: {} =0x{:x} {}",
2372-
emu.colors.light_red,
2380+
log_red!(emu, "** {} kernel32!TlsGetValue idx: {} =0x{:x}",
23732381
emu.pos,
23742382
idx,
2375-
emu.regs.get_eax() as u32,
2376-
emu.colors.nc
2383+
emu.regs.get_eax() as u32
23772384
);
23782385
}
23792386

libmwemu/src/emu/winapi64/kernel32.rs

Lines changed: 140 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,17 @@ use crate::emu::context64;
1010
use lazy_static::lazy_static;
1111
use std::sync::Mutex;
1212

13+
macro_rules! log_red {
14+
($emu:expr, $($arg:tt)*) => {
15+
log::info!(
16+
"{}{}{}",
17+
$emu.colors.light_red,
18+
format!($($arg)*),
19+
$emu.colors.nc
20+
);
21+
};
22+
}
23+
1324
// a in RCX, b in RDX, c in R8, d in R9, then e pushed on stack
1425

1526
pub fn gateway(addr: u64, emu: &mut emu::Emu) -> String {
@@ -137,14 +148,19 @@ pub fn gateway(addr: u64, emu: &mut emu::Emu) -> String {
137148
"lstrcpy" => lstrcpy(emu),
138149
"GetModuleHandleA" => GetModuleHandleA(emu),
139150
"GetModuleHandleW" => GetModuleHandleW(emu),
151+
"TlsAlloc" => TlsAlloc(emu),
152+
"TlsSetValue" => TlsSetValue(emu),
153+
"TlsGetValue" => TlsGetValue(emu),
154+
"TlsFree" => TlsFree(emu),
155+
"GetACP" => GetACP(emu),
156+
"GetStdHandle" => GetStdHandle(emu),
140157

141158
_ => {
142-
log::info!(
159+
unimplemented!(
143160
"calling unimplemented kernel32 64bits API 0x{:x} {}",
144161
addr,
145162
api
146163
);
147-
return api;
148164
}
149165
}
150166

@@ -2832,3 +2848,125 @@ fn GetModuleHandleW(emu: &mut emu::Emu) {
28322848
emu.colors.nc
28332849
);
28342850
}
2851+
2852+
/*
2853+
DWORD TlsAlloc();
2854+
*/
2855+
fn TlsAlloc(emu: &mut emu::Emu) {
2856+
log::info!(
2857+
"{}** {} kernel32!TlsAlloc {}",
2858+
emu.colors.light_red,
2859+
emu.pos,
2860+
emu.colors.nc
2861+
);
2862+
2863+
emu.tls64.push(0);
2864+
emu.regs.rax = (emu.tls64.len() - 1) as u64; // Return index of newly allocated slot
2865+
}
2866+
2867+
/*
2868+
BOOL TlsFree(
2869+
[in] DWORD dwTlsIndex
2870+
);
2871+
*/
2872+
fn TlsFree(emu: &mut emu::Emu) {
2873+
let idx = emu.regs.rcx as usize; // First parameter passed in RCX in x64
2874+
2875+
log::info!(
2876+
"{}** {} kernel32!TlsFree idx: {} {}",
2877+
emu.colors.light_red,
2878+
emu.pos,
2879+
idx,
2880+
emu.colors.nc
2881+
);
2882+
2883+
if idx < emu.tls64.len() {
2884+
emu.tls64[idx] = 0; // Clear the slot
2885+
emu.regs.rax = 1; // Return TRUE
2886+
} else {
2887+
emu.regs.rax = 0; // Return FALSE if invalid index
2888+
}
2889+
}
2890+
2891+
/*
2892+
BOOL TlsSetValue(
2893+
[in] DWORD dwTlsIndex,
2894+
[in, optional] LPVOID lpTlsValue
2895+
);
2896+
*/
2897+
fn TlsSetValue(emu: &mut emu::Emu) {
2898+
let idx = emu.regs.rcx as usize; // First parameter in RCX
2899+
let val = emu.regs.rdx; // Second parameter in RDX
2900+
2901+
log::info!(
2902+
"{}** {} kernel32!TlsSetValue idx: {} val: 0x{:x} {}",
2903+
emu.colors.light_red,
2904+
emu.pos,
2905+
idx,
2906+
val,
2907+
emu.colors.nc
2908+
);
2909+
2910+
if idx < emu.tls64.len() {
2911+
emu.tls64[idx] = val;
2912+
} else {
2913+
// Expand TLS array if needed
2914+
while emu.tls64.len() <= idx {
2915+
emu.tls64.push(0);
2916+
}
2917+
emu.tls64[idx] = val;
2918+
}
2919+
2920+
emu.regs.rax = 1; // Return TRUE
2921+
}
2922+
2923+
/*
2924+
DWORD TlsGetValue(
2925+
[in] DWORD dwTlsIndex
2926+
);
2927+
*/
2928+
fn TlsGetValue(emu: &mut emu::Emu) {
2929+
let idx = emu.regs.rcx as usize; // Parameter passed in RCX in x64
2930+
2931+
let val = if idx < emu.tls64.len() {
2932+
emu.tls64[idx]
2933+
} else {
2934+
0
2935+
};
2936+
2937+
emu.regs.rax = val;
2938+
2939+
log_red!(emu, "** {} kernel32!TlsGetValue idx: {} =0x{:x}",
2940+
emu.pos,
2941+
idx,
2942+
val
2943+
);
2944+
}
2945+
2946+
/*
2947+
UINT GetACP();
2948+
*/
2949+
// TODO: there is GetAcp and GetACP?
2950+
fn GetACP(emu: &mut emu::Emu) {
2951+
log::info!(
2952+
"{}** {} kernel32!GetACP {}",
2953+
emu.colors.light_red,
2954+
emu.pos,
2955+
emu.colors.nc
2956+
);
2957+
emu.regs.rax = 0x00000409;
2958+
}
2959+
2960+
/*
2961+
HANDLE GetStdHandle(
2962+
[in] DWORD nStdHandle
2963+
);
2964+
*/
2965+
fn GetStdHandle(emu: &mut emu::Emu) {
2966+
let nstd = emu.regs.rcx as usize; // Parameter passed in RCX in x64
2967+
log_red!(emu, "** {} kernel32!GetStdHandle nstd: {}",
2968+
emu.pos,
2969+
nstd
2970+
);
2971+
emu.regs.rax = nstd as u64;
2972+
}

scripts/enigma-protector.py

Lines changed: 0 additions & 27 deletions
This file was deleted.

scripts/enigma-protector.sh

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/bin/bash
2+
3+
set -x
4+
5+
export RUST_BACKTRACE=1
6+
export RUST_LOG=info
7+
8+
# Set target architecture based on OS
9+
if [[ "$OSTYPE" == "msys"* ]] || [[ "$OSTYPE" == "cygwin"* ]]; then
10+
TARGET=x86_64-pc-windows-msvc
11+
else
12+
TARGET=x86_64-apple-darwin
13+
fi
14+
15+
cargo run -p mwemu --release \
16+
--target $TARGET \
17+
-- \
18+
--filename ~/Desktop/enigma/surprise.dll \
19+
--maps ./maps64/ \
20+
--64bits \
21+
--mxcsr 0x1FC00001FA0 \
22+
--stack_address 0x32C6FE000 \
23+
--base 0x7FFBFA260000 \
24+
--entry 0x7FFBFB295FF0 \
25+
--rax 0x7FFBFB295FF0 \
26+
--rbx 0x7FFE0385 \
27+
--rcx 0x7FFBFA260000 \
28+
--rdx 0x1 \
29+
--rsp 0x32C6FE378 \
30+
--rbp 0x32C6FE6B8 \
31+
--rsi 0x1 \
32+
--rdi 0x7FFE0384 \
33+
--r8 0x0 \
34+
--r9 0x0 \
35+
--r10 0xA440AE23305F3A70 \
36+
--r11 0x32C6FE3E8 \
37+
--r12 0x7FFBFB295FF0 \
38+
--r13 0x120136C63F0 \
39+
--r14 0x7FFBFA260000 \
40+
--r15 0x0 \
41+
--rflags 0x344

0 commit comments

Comments
 (0)