🧑‍💻 埋点分析

#206
This commit is contained in:
BTMuli
2026-01-17 15:24:00 +08:00
parent 75b6ba40e9
commit f8933c7ca1
2 changed files with 64 additions and 28 deletions

View File

@@ -1,5 +1,5 @@
// 主模块,用于启动应用
// @since Beta v0.9.1
// @since Beta v0.9.2
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
@@ -25,7 +25,12 @@ fn main() {
},
));
#[cfg(target_os = "windows")]
enable_dpi_v2();
{
enable_dpi_v2();
unsafe {
std::env::set_var("RUST_BACKTRACE", "1");
}
}
#[cfg(target_os = "linux")]
unsafe {
// Not unsafe if you don't use edition 2024

View File

@@ -3,6 +3,8 @@
#![cfg(target_os = "windows")]
use std::ptr;
use std::thread::sleep;
use std::time::Duration;
use widestring::U16CString;
use windows_sys::Win32::Foundation::{
CloseHandle, ERROR_BAD_LENGTH, ERROR_SUCCESS, FreeLibrary, GetLastError, HANDLE,
@@ -12,6 +14,7 @@ use windows_sys::Win32::Storage::FileSystem::PIPE_ACCESS_DUPLEX;
use windows_sys::Win32::System::Diagnostics::Debug::WriteProcessMemory;
use windows_sys::Win32::System::Diagnostics::ToolHelp::{
CreateToolhelp32Snapshot, MODULEENTRY32W, Module32FirstW, Module32NextW, TH32CS_SNAPMODULE,
TH32CS_SNAPMODULE32,
};
use windows_sys::Win32::System::LibraryLoader::{
DONT_RESOLVE_DLL_REFERENCES, GetModuleHandleA, GetProcAddress, LoadLibraryExW,
@@ -135,48 +138,76 @@ pub fn inject_dll(pi: &PROCESS_INFORMATION, dll_path: &str) {
}
}
fn create_snapshot(pid: u32) -> Option<HANDLE> {
unsafe {
loop {
SetLastError(ERROR_SUCCESS);
let snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
let error = GetLastError();
if error == ERROR_SUCCESS && snapshot != INVALID_HANDLE_VALUE {
return Some(snapshot);
}
if error != ERROR_BAD_LENGTH {
return None;
struct Snapshot(HANDLE);
impl Drop for Snapshot {
fn drop(&mut self) {
unsafe {
if self.0 != INVALID_HANDLE_VALUE {
CloseHandle(self.0);
}
}
}
}
/// 枚举模块,找到 DLL 基址
fn create_snapshot(pid: u32) -> Option<Snapshot> {
loop {
unsafe {
SetLastError(ERROR_SUCCESS);
// 加上 SNAPMODULE32 提高兼容性
let snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, pid);
let error = GetLastError();
if error == ERROR_SUCCESS && snapshot != INVALID_HANDLE_VALUE {
return Some(Snapshot(snapshot));
}
// 如果不是 BAD_LENGTH直接返回错误
if error != ERROR_BAD_LENGTH {
eprintln!("CreateToolhelp32Snapshot failed: GetLastError = {}", error);
return None;
}
// 如果是 ERROR_BAD_LENGTH继续重试
}
}
}
pub fn find_module_base(pid: u32, dll_name: &str) -> Option<usize> {
unsafe {
let snapshot = match create_snapshot(pid) {
Some(h) => h,
Some(s) => s,
None => return None,
};
let mut me32 =
MODULEENTRY32W { dwSize: std::mem::size_of::<MODULEENTRY32W>() as u32, ..Default::default() };
if Module32FirstW(snapshot, &mut me32) != 0 {
loop {
let name = String::from_utf16_lossy(
&me32.szModule
[..me32.szModule.iter().position(|&c| c == 0).unwrap_or(me32.szModule.len())],
);
if name.eq_ignore_ascii_case(dll_name) {
CloseHandle(snapshot);
return Some(me32.modBaseAddr as usize);
}
if Module32NextW(snapshot, &mut me32) == 0 {
break;
// 尝试多次枚举以应对时序问题
for _attempt in 0..5 {
if Module32FirstW(snapshot.0, &mut me32) != 0 {
loop {
let len = me32.szModule.iter().position(|&c| c == 0).unwrap_or(me32.szModule.len());
let name = String::from_utf16_lossy(&me32.szModule[..len]);
eprintln!("Enumerated module: {}", name);
// 精确文件名比较或后缀比较(大小写不敏感)
if name.eq_ignore_ascii_case(dll_name)
|| name.to_lowercase().ends_with(&dll_name.to_lowercase())
{
return Some(me32.modBaseAddr as usize);
}
if Module32NextW(snapshot.0, &mut me32) == 0 {
break;
}
}
} else {
let err = GetLastError();
eprintln!("Module32FirstW failed: GetLastError = {}", err);
}
// 等待再重试
sleep(Duration::from_millis(100));
}
CloseHandle(snapshot);
None
}
}