Skip to content

Commit e8ef519

Browse files
committed
added unfinished unloading of the plugin
1 parent c156f8a commit e8ef519

File tree

4 files changed

+129
-60
lines changed

4 files changed

+129
-60
lines changed

src/client/hooks.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use super::graphics::{
3939
};
4040
use crate::shared::{
4141
memory::{MemoryManager, MEMORY_MANAGER},
42-
windows::{WI_CONSOLE, WI_MODIFIERS, WI_REMAP},
42+
windows::{unload_self_dll, WI_CONSOLE, WI_DETACH, WI_MODIFIERS, WI_REMAP},
4343
};
4444

4545
lazy_static! {
@@ -48,6 +48,7 @@ lazy_static! {
4848
}
4949

5050
pub unsafe extern "system" fn start_thread(lparam: *mut c_void) -> u32 {
51+
open_client_console();
5152
hook_wndproc(lparam as u64);
5253
hook_wgl_swap_buffers();
5354
0
@@ -192,6 +193,11 @@ unsafe extern "system" fn hooked_wndproc(
192193

193194
return LRESULT(0);
194195
}
196+
WI_DETACH => {
197+
println!("unloading\r\n");
198+
//unload_self_dll();
199+
return LRESULT(0);
200+
}
195201
WM_KEYDOWN => {
196202
let mut modifiers = KEYBOARD_MODIFIERS.lock().unwrap();
197203
let (shift, ctrl, alt) = &mut *modifiers;

src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::os::raw::c_char;
33
use std::sync::Mutex;
44

55
use shared::windows::{get_jagrenderview, inject, is_input_enabled, open_console, toggle_input};
6-
use simba::target::{SimbaTarget, TARGET};
6+
use simba::target::TARGET;
77

88
mod client;
99
mod shared;
@@ -59,7 +59,8 @@ pub extern "C" fn Inject(path: *const c_char, pid: u32) -> bool {
5959
};
6060

6161
let mut target = TARGET.lock().unwrap();
62-
*target = SimbaTarget { pid, hwnd };
62+
target.pid = pid;
63+
target.hwnd = hwnd;
6364

6465
unsafe { inject(module_path, pid, hwnd) }
6566
}

src/shared/windows.rs

Lines changed: 84 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,29 @@
11
use std::{
22
cell::RefCell,
3-
ffi::{c_char, c_int, c_void},
3+
ffi::{c_char, c_int, c_void, OsStr},
44
mem::transmute,
5+
os::windows::ffi::OsStrExt,
56
ptr::null_mut,
67
slice::from_raw_parts,
8+
sync::OnceLock,
79
thread::sleep,
810
time::Duration,
911
};
1012

1113
use windows::{
12-
core::{s, BOOL, PCSTR},
14+
core::{s, BOOL, PCSTR, PCWSTR},
1315
Win32::{
1416
Foundation::{
15-
CloseHandle, FALSE, HINSTANCE, HMODULE, HWND, LPARAM, POINT, TRUE, WAIT_OBJECT_0,
16-
WAIT_TIMEOUT, WPARAM,
17+
CloseHandle, FreeLibrary, FALSE, HINSTANCE, HMODULE, HWND, LPARAM, POINT, TRUE,
18+
WAIT_OBJECT_0, WAIT_TIMEOUT, WPARAM,
1719
},
1820
Graphics::Gdi::ScreenToClient,
1921
System::{
2022
Diagnostics::Debug::WriteProcessMemory,
21-
LibraryLoader::{DisableThreadLibraryCalls, GetModuleHandleA, GetProcAddress},
23+
LibraryLoader::{
24+
DisableThreadLibraryCalls, GetModuleFileNameW, GetModuleHandleA, GetModuleHandleW,
25+
GetProcAddress,
26+
},
2227
Memory::{
2328
VirtualAllocEx, VirtualFreeEx, MEM_COMMIT, MEM_RELEASE, MEM_RESERVE, PAGE_READWRITE,
2429
},
@@ -40,40 +45,36 @@ use windows::{
4045
},
4146
};
4247

43-
use crate::client::hooks::{start_thread, unhook_wgl_swap_buffers, unhook_wndproc};
48+
use crate::{
49+
client::hooks::{start_thread, unhook_wgl_swap_buffers, unhook_wndproc},
50+
simba::target::TARGET,
51+
};
4452

4553
use super::memory::{MemoryManager, MEMORY_MANAGER};
4654

4755
pub const WI_CONSOLE: u32 = WM_USER + 1;
4856
pub const WI_REMAP: u32 = WM_USER + 2;
4957
pub const WI_MODIFIERS: u32 = WM_USER + 3;
58+
pub const WI_DETACH: u32 = WM_USER + 4;
5059

5160
#[no_mangle]
5261
pub static mut MODULE: HMODULE = HMODULE(null_mut());
5362

54-
#[no_mangle]
55-
pub extern "system" fn DllMain(
56-
hinst_dll: HINSTANCE,
57-
fdw_reason: u32,
58-
_lpv_reserved: *mut c_void,
59-
) -> BOOL {
60-
unsafe { MODULE = HMODULE(hinst_dll.0) };
61-
62-
let pid = unsafe { GetCurrentProcessId() };
63-
let hwnd = match get_jagrenderview(pid) {
64-
Some(hwnd) => hwnd,
65-
None => return TRUE,
66-
};
67-
68-
match fdw_reason {
63+
fn client_main(hinst_dll: HINSTANCE, pid: u32, hwnd: HWND, reason: u32) -> BOOL {
64+
match reason {
6965
1 => unsafe {
7066
let _ = DisableThreadLibraryCalls(hinst_dll.into());
67+
let mut buffer = [0u16; 260]; // MAX_PATH
68+
let len = GetModuleFileNameW(Some(HMODULE::from(hinst_dll)), &mut buffer);
7169

72-
let mem_manager = MEMORY_MANAGER.lock().unwrap();
70+
if len > 0 {
71+
let path = String::from_utf16_lossy(&buffer[..len as usize]);
72+
let _ = DLL_NAME.set(path);
73+
}
7374

75+
let mem_manager = MEMORY_MANAGER.lock().unwrap();
7476
if mem_manager.is_mapped() {
7577
println!("[WaspInput]: Console attached. PID: {:?}\r\n", pid);
76-
7778
let _ = CreateThread(
7879
Some(null_mut()),
7980
0,
@@ -82,7 +83,9 @@ pub extern "system" fn DllMain(
8283
THREAD_CREATION_FLAGS(0),
8384
Some(null_mut()),
8485
);
86+
return TRUE;
8587
}
88+
FALSE
8689
},
8790
0 => {
8891
println!("[WaspInput]: Detached.\r\n");
@@ -94,11 +97,67 @@ pub extern "system" fn DllMain(
9497
mem_manager.close_map();
9598
}
9699
};
100+
TRUE
101+
}
102+
_ => FALSE,
103+
}
104+
}
105+
106+
pub static DLL_NAME: OnceLock<String> = OnceLock::new();
107+
108+
fn simba_main(hinst_dll: HINSTANCE, reason: u32) -> BOOL {
109+
match reason {
110+
1 => {
111+
let _ = unsafe { DisableThreadLibraryCalls(hinst_dll.into()) };
112+
TRUE
113+
}
114+
0 => {
115+
let target = TARGET.lock().unwrap();
116+
let hwnd = HWND(target.hwnd as *mut c_void);
117+
let _ = unsafe { PostMessageW(Some(hwnd), WI_DETACH, WPARAM(0), LPARAM(0)) };
118+
TRUE
97119
}
98-
_ => (),
120+
_ => FALSE,
99121
}
122+
}
100123

101-
TRUE
124+
#[no_mangle]
125+
pub extern "system" fn DllMain(
126+
hinst_dll: HINSTANCE,
127+
fdw_reason: u32,
128+
_lpv_reserved: *mut c_void,
129+
) -> BOOL {
130+
unsafe { MODULE = HMODULE(hinst_dll.0) };
131+
132+
let pid = unsafe { GetCurrentProcessId() };
133+
match get_jagrenderview(pid) {
134+
Some(hwnd) => client_main(hinst_dll, pid, hwnd, fdw_reason),
135+
None => simba_main(hinst_dll, fdw_reason),
136+
}
137+
}
138+
139+
fn get_hmodule_from_path(path: &str) -> Option<HMODULE> {
140+
let wide: Vec<u16> = OsStr::new(path)
141+
.encode_wide()
142+
.chain(std::iter::once(0)) // null-terminate
143+
.collect();
144+
145+
unsafe { GetModuleHandleW(PCWSTR::from_raw(wide.as_ptr())).ok() }
146+
}
147+
148+
pub fn unload_self_dll() -> bool {
149+
if let Some(path) = DLL_NAME.get() {
150+
if let Some(hmodule) = get_hmodule_from_path(path) {
151+
let _ = unsafe { FreeLibrary(hmodule) };
152+
true
153+
} else {
154+
eprintln!("Could not get HMODULE for path: {path}");
155+
false
156+
}
157+
} else {
158+
eprintln!("DLL path not initialized.");
159+
false
160+
}
102161
}
103162

104163
pub unsafe fn get_proc_address(name: *const c_char) -> *mut c_void {

src/simba/target.rs

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,17 @@ use super::plugin::PLUGIN_SIMBA_METHODS;
2323
pub struct SimbaTarget {
2424
pub pid: u32,
2525
pub hwnd: u64,
26+
pub keyboard: [bool; 255],
27+
pub mouse: [bool; 3],
2628
}
2729

2830
lazy_static! {
29-
pub static ref TARGET: Mutex<SimbaTarget> = Mutex::new(SimbaTarget { pid: 0, hwnd: 0 });
30-
pub static ref MOUSE_POSITION: Mutex<POINT> = Mutex::new(POINT { x: -1, y: -1 });
31-
static ref KEYBOARD_STATE: Mutex<[bool; 255]> = Mutex::new([false; 255]);
32-
static ref MOUSE_STATE: Mutex<[bool; 3]> = Mutex::new([false; 3]);
31+
pub static ref TARGET: Mutex<SimbaTarget> = Mutex::new(SimbaTarget {
32+
pid: 0,
33+
hwnd: 0,
34+
keyboard: [false; 255],
35+
mouse: [false; 3],
36+
});
3337
}
3438

3539
pub fn get_mouse_pos(hwnd: u64) -> POINT {
@@ -69,7 +73,8 @@ pub extern "C" fn SimbaPluginTarget_Request(args: *const c_char) -> *mut SimbaTa
6973
return &mut *target as *mut SimbaTarget;
7074
}
7175

72-
*target = SimbaTarget { pid, hwnd };
76+
target.pid = pid;
77+
target.hwnd = hwnd;
7378

7479
return &mut *target as *mut SimbaTarget;
7580
}
@@ -121,7 +126,12 @@ pub extern "C" fn SimbaPluginTarget_Release(target: *mut SimbaTarget) {
121126
);
122127

123128
let mut target = TARGET.lock().unwrap();
124-
*target = SimbaTarget { pid: 0, hwnd: 0 };
129+
*target = SimbaTarget {
130+
pid: 0,
131+
hwnd: 0,
132+
keyboard: [false; 255],
133+
mouse: [false; 3],
134+
};
125135
}
126136

127137
#[no_mangle]
@@ -190,11 +200,11 @@ pub extern "C" fn SimbaPluginTarget_MousePressed(
190200
return false;
191201
}
192202

193-
let state = MOUSE_STATE.lock().unwrap();
203+
let target = TARGET.lock().unwrap();
194204
match mouse_button {
195-
1 => state[0],
196-
2 | 4 | 5 => state[1],
197-
3 => state[2],
205+
1 => target.keyboard[0],
206+
2 | 4 | 5 => target.keyboard[1],
207+
3 => target.keyboard[2],
198208
_ => {
199209
println!("[WaspInput]: Unknown mouse button: {}\r\n", mouse_button);
200210
false
@@ -231,8 +241,6 @@ pub extern "C" fn SimbaPluginTarget_MouseTeleport(target: *mut SimbaTarget, x: c
231241

232242
let target = TARGET.lock().unwrap();
233243
mouse_move(target.hwnd, x, y);
234-
let mut lock = MOUSE_POSITION.lock().unwrap();
235-
*lock = POINT { x: x, y: y };
236244
}
237245

238246
#[no_mangle]
@@ -242,22 +250,21 @@ pub extern "C" fn SimbaPluginTarget_MouseUp(target: *mut SimbaTarget, mouse_butt
242250
return;
243251
}
244252

245-
let target = TARGET.lock().unwrap();
253+
let mut target = TARGET.lock().unwrap();
246254

247255
let pt = get_mouse_pos(target.hwnd);
248-
let mut state = MOUSE_STATE.lock().unwrap();
249256
match mouse_button {
250257
1 => {
251258
lbutton(target.hwnd, false, pt.x, pt.y);
252-
state[0] = false;
259+
target.mouse[0] = false;
253260
}
254261
2 | 4 | 5 => {
255262
mbutton(target.hwnd, false, pt.x, pt.y);
256-
state[1] = false;
263+
target.mouse[1] = false;
257264
}
258265
3 => {
259266
rbutton(target.hwnd, false, pt.x, pt.y);
260-
state[2] = false;
267+
target.mouse[2] = false;
261268
}
262269
_ => {
263270
println!("[WaspInput]: Unknown mouse button: {}\r\n", mouse_button);
@@ -273,22 +280,21 @@ pub extern "C" fn SimbaPluginTarget_MouseDown(target: *mut SimbaTarget, mouse_bu
273280
return;
274281
}
275282

276-
let target = TARGET.lock().unwrap();
277-
283+
let mut target = TARGET.lock().unwrap();
278284
let pt = get_mouse_pos(target.hwnd);
279-
let mut state = MOUSE_STATE.lock().unwrap();
285+
280286
match mouse_button {
281287
1 => {
282288
lbutton(target.hwnd, true, pt.x, pt.y);
283-
state[0] = true;
289+
target.mouse[0] = true;
284290
}
285291
2 | 4 | 5 => {
286292
mbutton(target.hwnd, true, pt.x, pt.y);
287-
state[1] = true;
293+
target.mouse[1] = true;
288294
}
289295
3 => {
290296
rbutton(target.hwnd, true, pt.x, pt.y);
291-
state[2] = true;
297+
target.mouse[2] = true;
292298
}
293299
_ => {
294300
println!("[WaspInput]: Unknown mouse button: {}\r\n", mouse_button);
@@ -317,11 +323,9 @@ pub extern "C" fn SimbaPluginTarget_KeyDown(target: *mut SimbaTarget, key: c_int
317323
return;
318324
}
319325

320-
let target = TARGET.lock().unwrap();
326+
let mut target = TARGET.lock().unwrap();
321327
key_down(target.hwnd, key);
322-
323-
let mut state = KEYBOARD_STATE.lock().unwrap();
324-
state[key as usize] = true;
328+
target.keyboard[key as usize] = true;
325329
}
326330

327331
#[no_mangle]
@@ -331,10 +335,9 @@ pub extern "C" fn SimbaPluginTarget_KeyUp(target: *mut SimbaTarget, key: c_int)
331335
return;
332336
}
333337

334-
let target = TARGET.lock().unwrap();
338+
let mut target = TARGET.lock().unwrap();
335339
key_up(target.hwnd, key);
336-
let mut state = KEYBOARD_STATE.lock().unwrap();
337-
state[key as usize] = false;
340+
target.keyboard[key as usize] = false;
338341
}
339342

340343
#[no_mangle]
@@ -365,6 +368,6 @@ pub extern "C" fn SimbaPluginTarget_KeySend(
365368

366369
#[no_mangle]
367370
pub extern "C" fn SimbaPluginTarget_KeyPressed(_target: *mut SimbaTarget, key: c_int) -> bool {
368-
let state = KEYBOARD_STATE.lock().unwrap();
369-
state[key as usize]
371+
let target = TARGET.lock().unwrap();
372+
target.keyboard[key as usize]
370373
}

0 commit comments

Comments
 (0)