Skip to content

Commit 4236183

Browse files
committed
64-bit is not stdcall
1 parent a811c06 commit 4236183

File tree

1 file changed

+44
-37
lines changed

1 file changed

+44
-37
lines changed

libmwemu/src/emu/winapi64/kernel32.rs

Lines changed: 44 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2836,6 +2836,9 @@ fn GetModuleHandleW(emu: &mut emu::Emu) {
28362836
);
28372837
}
28382838

2839+
/*
2840+
DWORD TlsAlloc();
2841+
*/
28392842
fn TlsAlloc(emu: &mut emu::Emu) {
28402843
log::info!(
28412844
"{}** {} kernel32!TlsAlloc {}",
@@ -2845,16 +2848,16 @@ fn TlsAlloc(emu: &mut emu::Emu) {
28452848
);
28462849

28472850
emu.tls64.push(0);
2848-
let tls_index = emu.tls64.len() as u64;
2849-
log::info!("kernel32!TlsAlloc tls_index: {}", tls_index);
2850-
emu.regs.rax = tls_index;
2851+
emu.regs.rax = (emu.tls64.len() - 1) as u64; // Return index of newly allocated slot
28512852
}
28522853

2854+
/*
2855+
BOOL TlsFree(
2856+
[in] DWORD dwTlsIndex
2857+
);
2858+
*/
28532859
fn TlsFree(emu: &mut emu::Emu) {
2854-
let idx = emu
2855-
.maps
2856-
.read_dword(emu.regs.get_esp())
2857-
.expect("kernel32!TlsFree cannot read idx");
2860+
let idx = emu.regs.rcx as usize; // First parameter passed in RCX in x64
28582861

28592862
log::info!(
28602863
"{}** {} kernel32!TlsFree idx: {} {}",
@@ -2864,19 +2867,23 @@ fn TlsFree(emu: &mut emu::Emu) {
28642867
emu.colors.nc
28652868
);
28662869

2867-
emu.stack_pop64(false);
2868-
emu.regs.rax = 1;
2870+
if idx < emu.tls64.len() {
2871+
emu.tls64[idx] = 0; // Clear the slot
2872+
emu.regs.rax = 1; // Return TRUE
2873+
} else {
2874+
emu.regs.rax = 0; // Return FALSE if invalid index
2875+
}
28692876
}
28702877

2878+
/*
2879+
BOOL TlsSetValue(
2880+
[in] DWORD dwTlsIndex,
2881+
[in, optional] LPVOID lpTlsValue
2882+
);
2883+
*/
28712884
fn TlsSetValue(emu: &mut emu::Emu) {
2872-
let idx = emu
2873-
.maps
2874-
.read_dword(emu.regs.get_esp()) // dword, not qword despite x64?
2875-
.expect("kernel32!TlsSetValue cannot read idx");
2876-
let val = emu
2877-
.maps
2878-
.read_qword(emu.regs.get_esp() + 4)
2879-
.expect("kernel32!TlsSetValue cannot read val_ptr");
2885+
let idx = emu.regs.rcx as usize; // First parameter in RCX
2886+
let val = emu.regs.rdx; // Second parameter in RDX
28802887

28812888
log::info!(
28822889
"{}** {} kernel32!TlsSetValue idx: {} val: 0x{:x} {}",
@@ -2887,41 +2894,41 @@ fn TlsSetValue(emu: &mut emu::Emu) {
28872894
emu.colors.nc
28882895
);
28892896

2890-
if emu.tls64.len() > idx as usize {
2891-
emu.tls64[idx as usize] = val;
2897+
if idx < emu.tls64.len() {
2898+
emu.tls64[idx] = val;
28922899
} else {
2893-
for _ in 0..=idx {
2900+
// Expand TLS array if needed
2901+
while emu.tls64.len() <= idx {
28942902
emu.tls64.push(0);
28952903
}
2896-
emu.tls64[idx as usize] = val;
2904+
emu.tls64[idx] = val;
28972905
}
28982906

2899-
emu.stack_pop32(false);
2900-
emu.stack_pop64(false);
2901-
2902-
emu.regs.rax = 1;
2907+
emu.regs.rax = 1; // Return TRUE
29032908
}
29042909

2910+
/*
2911+
DWORD TlsGetValue(
2912+
[in] DWORD dwTlsIndex
2913+
);
2914+
*/
29052915
fn TlsGetValue(emu: &mut emu::Emu) {
2906-
let idx = emu
2907-
.maps
2908-
.read_dword(emu.regs.get_esp()) // dword, not qword despite x64?
2909-
.expect("kernel32!TlsGetValue cannot read idx");
2910-
2911-
emu.stack_pop32(false); // dword, not qword despite x64?
2916+
let idx = emu.regs.rcx as usize; // Parameter passed in RCX in x64
29122917

2913-
if idx as usize > emu.tls64.len() {
2914-
emu.regs.rax = 0;
2918+
let val = if idx < emu.tls64.len() {
2919+
emu.tls64[idx]
29152920
} else {
2916-
emu.regs.rax = emu.tls64[idx as usize];
2917-
}
2921+
0
2922+
};
2923+
2924+
emu.regs.rax = val;
29182925

29192926
log::info!(
29202927
"{}** {} kernel32!TlsGetValue idx: {} =0x{:x} {}",
29212928
emu.colors.light_red,
29222929
emu.pos,
29232930
idx,
2924-
emu.regs.rax,
2931+
val,
29252932
emu.colors.nc
29262933
);
2927-
}
2934+
}

0 commit comments

Comments
 (0)