From 14059a939f1e7cc7ca6cd3008d3dc99fc7a4fe42 Mon Sep 17 00:00:00 2001 From: Casper Date: Tue, 9 Feb 2021 00:31:08 +0100 Subject: [PATCH] Example demonstrate various advanced use cases --- examples/enum_to_string.rs | 63 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 examples/enum_to_string.rs diff --git a/examples/enum_to_string.rs b/examples/enum_to_string.rs new file mode 100644 index 0000000..45a1a4c --- /dev/null +++ b/examples/enum_to_string.rs @@ -0,0 +1,63 @@ +/*! +This example demonstrates various ways to obfuscate the string literals in more complex scenarios. +The example presented here uses an enum because it can be challenging to return a string representation of it. + */ + +use std::fmt; +use obfstr::{obfstr, position}; + +// Let's try to obfuscate the string representation of this enum. +pub enum Example { + Foo, + Bar, + Baz, +} + +impl Example { + // Returns an owned String but this allocates memory. + pub fn to_str1(&self) -> String { + match self { + Example::Foo => String::from(obfstr!("Foo")), + Example::Bar => String::from(obfstr!("Bar")), + Example::Baz => String::from(obfstr!("Baz")), + } + } + + // Use a callback to keep the string slice allocated on the stack but this gets annoying in more complex scenarios. + pub fn to_str2 R>(&self, mut f: F) -> R { + match self { + Example::Foo => f(obfstr!("Foo")), + Example::Bar => f(obfstr!("Bar")), + Example::Baz => f(obfstr!("Baz")) + } + } + + // Use a buffer to hold the deobfuscated string. Panics if the buffer is too small. + pub fn to_str3<'a>(&self, buf: &'a mut [u8; 4]) -> &'a str { + match self { + Example::Foo => obfstr!(buf <- "Foo"), + Example::Bar => obfstr!(buf <- "Bar"), + Example::Baz => obfstr!(buf <- "Baz"), + } + } + + // Allocate the string literals via concatenation. + pub const POOL: &'static str = concat!("Foo", "Bar", "Baz"); + + // Deobfuscate the POOL constant and pass it here as the pool argument. + // This to string implementation will slice the right substring. + pub fn to_str4<'a>(&self, pool: &'a str) -> &'a str { + match self { + Example::Foo => &pool[position!(Example::POOL, "Foo")], + Example::Bar => &pool[position!(Example::POOL, "Bar")], + Example::Baz => &pool[position!(Example::POOL, "Baz")], + } + } +} +impl fmt::Display for Example { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.to_str2(|s| f.write_str(s)) + } +} + +fn main() {}