0

I'm working on a project and have a problem that I believe can be solved with macros, but given the nature of the issue I don't have the experience to write one myself.

Here's what I would expect as input and output of the #define macro:

Inputting code such as this

printf(foobar(Hello World.));

Should result in the preprocessor producing code that reads:

printf((char *)(std::string("")+'H'+'e'+'l'+'l'+'o'+' '+'W'+'o'+'r'+'l'+'d'+'.').c_str());

I'm assuming something this complicated is possible, and I hope one of you guys can help me out.

I NEED IT TO BE A MACRO, I DO NOT want a string constant anywhere.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Nowayz
  • 1,882
  • 4
  • 21
  • 34
  • That basically is a "string constant" except for the terminating zero (although you have one for the ""). What is it you're trying to achieve, why do you want to avoid string constants ? – Nico Oct 24 '11 at 08:12
  • 2
    I am scared to ask in what context this might make sense... (what is your actual request, having it produce that particular output or not having literals before the preprocessor runs?) – David Rodríguez - dribeas Oct 24 '11 at 08:12
  • FYI `std::string()` is better than `std::string("")`. And why on earth would you cast to `char*`? I am surprised with all the clever things people have done, there is no way to do any string manipulation in macros. But really, sorry if you don't want to hear this but macros are better avoided. – tenfour Oct 24 '11 at 08:13
  • 1
    You can not, you are putting an arbitrary string into a MACRO. Did you think maybe programmer use `hi:-)` instead of `Hello World.`, how about right parenthesis in `hi:-)`? – masoud Oct 24 '11 at 08:14
  • The preprocessor is not as powerful as you think it is. You could use a separate program to convert your `Hello World.` to the format you want, though. – wormsparty Oct 24 '11 at 08:15
  • I remember having a similar problem. It was coming from the CUDA compiler handling C-strings really, really badly. Using an array of chars, where each character was typed separately solved the problem. – CygnusX1 Oct 24 '11 at 08:17
  • I'm guessing this a "security by obscurity" and you are trying to prevent hackers from searching your program for string constants? If so then I think you'd be much better off encrypting the contents of the string. – GrahamS Oct 24 '11 at 08:28
  • @GrahamS imagine how upset he will be when he finds a way to do this, then realizes the compiler optimizes it into a string literal :D – tenfour Oct 24 '11 at 08:30
  • @tenfour: yeah I did wonder what a suitably clever compiler would do with the construct in his question. – GrahamS Oct 24 '11 at 08:31
  • @tenfour It doesn't optimze, and if It did I could just turn that off.(using VC++ 2010) – Nowayz Oct 24 '11 at 08:32
  • @GrahamS You're on the right track but no. I'm trying to avoid having the same memory signature each time. All opcodes are virtualized and 100% each compile so technically using my method is more secure in this case than string encryption. (Although an additional encryption is my next step) – Nowayz Oct 24 '11 at 08:36
  • When it comes right down to it obscurity is really all we've got for distributed binaries anyway. Encryption is just another layer of obscurity IMO. Good reverse engineers often still are able to do their jobs. – Nowayz Oct 24 '11 at 08:39
  • You could not only XOR your string with something but also permute characters in it making it nearly invisible for the naked eye and then unpermute and unXOR it back when the program starts up. Of course, you'd need a separate script or program to permute and XOR the original string. – Alexey Frunze Oct 24 '11 at 08:56
  • How about xoring it with something to produce a valid assembly code which would never actually run? That could actually really confuse people :) – CygnusX1 Oct 24 '11 at 17:19

5 Answers5

2

Uh, I fear it is impossible (unless I don't know something). I believe there is no macro to split a given input token (e.g. Hello) into characters building it (H e l l o)

There were some attempts to do such thing, but I fear it is not exactly what you need:

C++: Can a macro expand "abc" into 'a', 'b', 'c'?


"More powerful precompiler" ?

Try this topic: Replacements for the C preprocessor

Community
  • 1
  • 1
CygnusX1
  • 20,968
  • 5
  • 65
  • 109
2

The only solution I can think of is to run your code through a suitable script (probably just some light awk), that does the substitution before your code reaches the pre-compiler.

Depending on your environment you could do this as a "Pre-Build Event" in Visual Studio, or just add a step directly into your makefile.

GrahamS
  • 9,980
  • 9
  • 49
  • 63
  • This is actually what I'm working on right now since it doesn't look like the pre-compiler is able to do what I need. – Nowayz Oct 24 '11 at 08:42
1

Macros are basically substitution or addition of strings. You could do this with a pre-processor of your own, but the standard pre-processor won't split strings into component parts.

How about this: Put all these (assuming there is more than one) 'macros' in a separate file. Write a program that translates them into the expansion you require and then include THAT file in your c program? You could then make the expansion program part of your make file so it's always up to date. Using a separate file makes the expansion program much easier than parsing a c/c++ file.

Neil
  • 11,059
  • 3
  • 31
  • 56
  • I still need it to be able to work on the fly without having to modify or build another function entirely for one string. – Nowayz Oct 24 '11 at 08:28
1

Since you're looking for a narrow, direct answer to your question and without suggestions, here goes:

This is impossible. You must find a different solution to whatever it is you're trying to achieve.

tenfour
  • 36,141
  • 15
  • 83
  • 142
0

Have you tried:

#define toString(x) #x

You can use it after like this:

printf("%s", toString(hello world));

Don't try to use printf directly with the string because you can have format specifier in the string.

printf(toString(hello world)); //wrong, you can have for example %d in the string
Mircea Ispas
  • 20,260
  • 32
  • 123
  • 211
  • This creates a string constant, which he is explicitly trying to avoid ...for whatever reason – Nico Oct 24 '11 at 08:22
  • Without sounding too vague.. If there aren't any string constants, you can't find any string constants. This isn't just some normal production code and I realize the question is odd. – Nowayz Oct 24 '11 at 08:23
  • 1
    If all you're trying to do is conceal some strings, you could simply store a char[] with the values XORed with some interesting value – Nico Oct 24 '11 at 08:30
  • That's actually a good idea but really not what i'm shooting for here. – Nowayz Oct 24 '11 at 08:42