How to write proc macro that obfuscate all string literal in its scope

Note: Simplifed version of this question: Is it possible to evaluate inner macro before outer macro in proc macro?

I use the bitflags crate.
One problem of this crate, is that it unconditionally put the flag name inside executable.

For example,

use bitflags::bitflags;

bitflags! {
    pub struct Flags: u32 {
        const A = 0b00000001;
        const B = 0b00000010;
        const C = 0b00000100;
    }
}

macro expands to

impl ::bitflags::Flags for Flags {
    const FLAGS: &'static [::bitflags::Flag<Flags>] = &[
        {
            #[allow(deprecated, non_upper_case_globals)]
            ::bitflags::Flag::new("A", Flags::A)
        },
        {
            #[allow(deprecated, non_upper_case_globals)]
            ::bitflags::Flag::new("B", Flags::B)
        },
        {
            #[allow(deprecated, non_upper_case_globals)]
            ::bitflags::Flag::new("C", Flags::C)
        },
    ];
}

with the name of bit flags inside executable. ("A", "B", "C")

I do not want these string inside the executable,
which make it easy for reverse engineering.

I know I can make a locally hosted bitflags,
or just make a feature request to bitflags

But I prefer to have a better universally proc macro that does string obfuscate
that transform all string literal to some not meanful string literal

For example,

#[Obfuscate]
bitflags! {

    pub struct Flags: u32 {
        const A = 0b00000001;
        const B = 0b00000010;
        const C = 0b00000100;
    }
}

which transforms to

impl ::bitflags::Flags for Flags {
    const FLAGS: &'static [::bitflags::Flag<Flags>] = &[
        {
            #[allow(deprecated, non_upper_case_globals)]
            ::bitflags::Flag::new("foo", Flags::A)
        },
        {
            #[allow(deprecated, non_upper_case_globals)]
            ::bitflags::Flag::new("bar", Flags::B)
        },
        {
            #[allow(deprecated, non_upper_case_globals)]
            ::bitflags::Flag::new("zzz", Flags::C)
        },
    ];
}

Any idea how to implement this Obfuscate proc macro,
or is it really possible?
or any existing crate on crates.io?

  1. The macro should work for any code, not just limited to bitflags
  2. The exact pattern how the string to transformed to obfuscate form, is not relavent in this qeustion

Please include any cross-posted links, like this one: Attribute or feature flag to remove flag name in the generated code · Issue #413 · bitflags/bitflags (github.com)

not an answer to your question, but may be a solution to your problem: the enumset crate doesn't do this, do my knowledge.

1 Like

Here's what I came up with: Rust Playground

enumset is much simpler, however.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.