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#[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}