encrypting with preprocessor

G

Gernot Frisch

Hi,

I want to build a encryption macro set, that can crypt:

char secret[] = CRYPT("KungFu");

to anything unreadable, and then have a function:
char* DECRYPT(char* str)
{
...
}

I think it would be suffictient to encrypt a maximum of 16 characters.
Simple XOR would suffice, too. Any ideas of how that can be done?



--
-Gernot
int main(int argc, char** argv) {printf
("%silto%c%cf%cgl%ssic%ccom%c", "ma", 58, 'g', 64, "ba", 46, 10);}

________________________________________
Looking for a good game? Do it yourself!
GLBasic - you can do
www.GLBasic.com
 
L

Laurent Deniau

Gernot said:
Hi,

I want to build a encryption macro set, that can crypt:

char secret[] = CRYPT("KungFu");

to anything unreadable, and then have a function:
char* DECRYPT(char* str)
{
...
}

I think it would be suffictient to encrypt a maximum of 16 characters.
Simple XOR would suffice, too. Any ideas of how that can be done?

Yes, but it is a bit long to explain and needs a lot of macros (about
200-400 macros) to do it as far as you accept to write:

char secret[] = CRYPT(K,u,n,g,F,u);

instead of a string as a parameters, then CRYPT could output a crypted
string of octal codes for example.

I know this is not an answer, but doing this with macros really require
a "package" of macros to manipulate list of token (e.g. map, cat, merge,
etc...) plus a set of arithmetic and logic operations. I have a such
package so I can provide it on request but it hasn't any documentation.

a+, ld.
 
G

Gernot Frisch

Laurent Deniau said:
Gernot said:
Hi,

I want to build a encryption macro set, that can crypt:

char secret[] = CRYPT("KungFu");

to anything unreadable, and then have a function:
char* DECRYPT(char* str)
{
...
}

I think it would be suffictient to encrypt a maximum of 16
characters. Simple XOR would suffice, too. Any ideas of how that
can be done?

Yes, but it is a bit long to explain and needs a lot of macros
(about 200-400 macros) to do it as far as you accept to write:

char secret[] = CRYPT(K,u,n,g,F,u);

instead of a string as a parameters, then CRYPT could output a
crypted string of octal codes for example.

I know this is not an answer, but doing this with macros really
require a "package" of macros to manipulate list of token (e.g. map,
cat, merge, etc...) plus a set of arithmetic and logic operations. I
have a such package so I can provide it on request but it hasn't any
documentation.

can you give a grief explaination on how to make it?
 
R

Richard Heathfield

Gernot Frisch said:
Hi,

I want to build a encryption macro set, that can crypt:

char secret[] = CRYPT("KungFu");

to anything unreadable, and then have a function:
char* DECRYPT(char* str)
{
...
}

I think it would be suffictient to encrypt a maximum of 16 characters.
Simple XOR would suffice, too. Any ideas of how that can be done?

#define CRYPT(x) my_encryption_routine(x)

I don't think you can do this without calling a function, although I would
be very interested in seeing a counter-example.

My reasoning is as follows: you'd need to do this in a single expression
that doesn't involve a compound statement (because compound statements are
not mere expressions, so they don't yield a value, which wouldn't be so bad
if they played nice with comma operators - but they don't). A function gets
around these problems nicely, but I don't see any other way to do it. In
C99 you could use an inline function, I suppose.

<OT>
If you happen to be using gcc, I think you can use a GNU extension which
allows compound statements in macros to yield results. A gcc newsgroup
would be a good place to ask about this.
</OT>
 
L

Laurent Deniau

Gernot said:
Gernot said:
Hi,

I want to build a encryption macro set, that can crypt:

char secret[] = CRYPT("KungFu");

to anything unreadable, and then have a function:
char* DECRYPT(char* str)
{
...
}

I think it would be suffictient to encrypt a maximum of 16
characters. Simple XOR would suffice, too. Any ideas of how that
can be done?

Yes, but it is a bit long to explain and needs a lot of macros
(about 200-400 macros) to do it as far as you accept to write:

char secret[] = CRYPT(K,u,n,g,F,u);

instead of a string as a parameters, then CRYPT could output a
crypted string of octal codes for example.

I know this is not an answer, but doing this with macros really
require a "package" of macros to manipulate list of token (e.g. map,
cat, merge, etc...) plus a set of arithmetic and logic operations. I
have a such package so I can provide it on request but it hasn't any
documentation.


can you give a grief explaination on how to make it?

- convert K,u,n,g,F,u to the list (6,(K,u,n,g,F,u))
- create a list of macros, say CODE_, ending with the letters (26*2 + 1
macros) which expand to value/code
- apply concat(CODE_,tok) to the list
- optionally apply some transformation/crypt algo to the list elements
- apply a convertion from value to octal code
- concat the element of the list into a single token
- stringify the result.

As I said, doing this requires somehow 200-300 stupid and repetitive
macros to handle set of values and about 20 smart macros to transform
the list.

a+, ld.
 
C

Chris Dollin

Richard said:
Gernot Frisch said:
Hi,

I want to build a encryption macro set, that can crypt:

char secret[] = CRYPT("KungFu");

(fx:snip)
#define CRYPT(x) my_encryption_routine(x)

I don't think you can do this without calling a function, although I would
be very interested in seeing a counter-example.

Doesn't that not-work in the OPs example? Possible uses of `sizeof (secret)`
may preclude transforming it to `char *secret = CRYPT("KungFu");`.
 
R

Richard Heathfield

Chris Dollin said:
Richard said:
Gernot Frisch said:
Hi,

I want to build a encryption macro set, that can crypt:

char secret[] = CRYPT("KungFu");
(fx:snip)

#define CRYPT(x) my_encryption_routine(x)

I don't think you can do this without calling a function, although I
would be very interested in seeing a counter-example.

Doesn't that not-work in the OPs example?

Oh yes, of course you're right. And in any case, it now transpires that his
reason for wanting the macro is that he doesn't want the string literal to
appear in the binary. I wish he'd said so at the outset.

Now that I know this, I suggest he simply pre-computes the encryption via a
separate program that he does not release. Let the output of the separate
program be, for example:

{
0x34, 0x29, 0xF3, 0xA2, 0x77, 0x21
};

(or whatever), and be saved as secret1.enc. He can then do this:

char secret[] =
#include "secret1.enc"

Problem solved, without any gerharsterly macros.
 
C

Chris Dollin

Richard said:
Chris Dollin said:
Richard said:
Gernot Frisch said:

Hi,

I want to build a encryption macro set, that can crypt:

char secret[] = CRYPT("KungFu");
(fx:snip)

#define CRYPT(x) my_encryption_routine(x)

I don't think you can do this without calling a function, although I
would be very interested in seeing a counter-example.

Doesn't that not-work in the OPs example?

Oh yes, of course you're right. And in any case, it now transpires that his
reason for wanting the macro is that he doesn't want the string literal to
appear in the binary. I wish he'd said so at the outset.

Now that I know this, I suggest he simply pre-computes the encryption via a
separate program that he does not release. Let the output of the separate
program be, for example:

{
0x34, 0x29, 0xF3, 0xA2, 0x77, 0x21
};

(or whatever), and be saved as secret1.enc. He can then do this:

char secret[] =
#include "secret1.enc"

Problem solved, without any gerharsterly macros.

A similar approach would be to write

char secret[] = CRYPTOF_KungFu;

where CRYPTOF_KungFu is a macro which gets #defined somehow: in a single
#included "cryptic.h" file or even as -D options to his compiler commands
if his implementation has such.

Of course suitable conventions and seddery and such allow the extraction
of any number of such CRYPTOF uses in the code, so long as the crypted
things can appear in macro names.
 
L

Laurent Deniau

Richard said:
Gernot Frisch said:

Hi,

I want to build a encryption macro set, that can crypt:

char secret[] = CRYPT("KungFu");

to anything unreadable, and then have a function:
char* DECRYPT(char* str)
{
...
}

I think it would be suffictient to encrypt a maximum of 16 characters.
Simple XOR would suffice, too. Any ideas of how that can be done?


#define CRYPT(x) my_encryption_routine(x)

I don't think you can do this without calling a function, although I would
be very interested in seeing a counter-example.

My reasoning is as follows: you'd need to do this in a single expression
that doesn't involve a compound statement (because compound statements are
not mere expressions, so they don't yield a value, which wouldn't be so bad
if they played nice with comma operators - but they don't). A function gets
around these problems nicely, but I don't see any other way to do it. In
C99 you could use an inline function, I suppose.

Here is a macro which compute the FNV hash function of the first 32
characters of a litteral string at compile time. The original litteral
string 'str' does not appear in the binary. I let you adapt this macro
to do encryption instead of computing hash code. I have another version
which stops when the tailing '\0' is encountered in the litteral string,
but the compile time is much much longer since the generated AST is
completely evaluated before reductions start (at least in gcc, but I
think in most compilers because it is in a separate compilation phase).

a+, ld.

#define ooc_staticHashStr32(str, initVal) \
OOC_STATICHASHSTR32_(str \
"\000\000\000\000\000\000\000\000" \
"\000\000\000\000\000\000\000\000" \
"\000\000\000\000\000\000\000\000" \
"\000\000\000\000\000\000\000\000", \
(initVal))

#define OOC_STATICHASHSTR32_(str, initVal) \
(((((((((((((((((((((((((((((((( \
(unsigned long)(initVal) \
*16777619ul+(unsigned char)(str)[ 0]) \
*16777619ul+(unsigned char)(str)[ 1]) \
*16777619ul+(unsigned char)(str)[ 2]) \
*16777619ul+(unsigned char)(str)[ 3]) \
*16777619ul+(unsigned char)(str)[ 4]) \
*16777619ul+(unsigned char)(str)[ 5]) \
*16777619ul+(unsigned char)(str)[ 6]) \
*16777619ul+(unsigned char)(str)[ 7]) \
*16777619ul+(unsigned char)(str)[ 8]) \
*16777619ul+(unsigned char)(str)[ 9]) \
*16777619ul+(unsigned char)(str)[10]) \
*16777619ul+(unsigned char)(str)[11]) \
*16777619ul+(unsigned char)(str)[12]) \
*16777619ul+(unsigned char)(str)[13]) \
*16777619ul+(unsigned char)(str)[14]) \
*16777619ul+(unsigned char)(str)[15]) \
*16777619ul+(unsigned char)(str)[16]) \
*16777619ul+(unsigned char)(str)[17]) \
*16777619ul+(unsigned char)(str)[18]) \
*16777619ul+(unsigned char)(str)[19]) \
*16777619ul+(unsigned char)(str)[20]) \
*16777619ul+(unsigned char)(str)[21]) \
*16777619ul+(unsigned char)(str)[22]) \
*16777619ul+(unsigned char)(str)[23]) \
*16777619ul+(unsigned char)(str)[24]) \
*16777619ul+(unsigned char)(str)[25]) \
*16777619ul+(unsigned char)(str)[26]) \
*16777619ul+(unsigned char)(str)[27]) \
*16777619ul+(unsigned char)(str)[28]) \
*16777619ul+(unsigned char)(str)[29]) \
*16777619ul+(unsigned char)(str)[30]) \
*16777619ul+(unsigned char)(str)[31])
 
G

Gernot Frisch

Now that I know this, I suggest he simply pre-computes the
encryption via a
separate program that he does not release. Let the output of the
separate
program be, for example:

{
0x34, 0x29, 0xF3, 0xA2, 0x77, 0x21
};

(or whatever), and be saved as secret1.enc. He can then do this:

char secret[] =
#include "secret1.enc"

Problem solved, without any gerharsterly macros.

A similar approach would be to write

char secret[] = CRYPTOF_KungFu;

where CRYPTOF_KungFu is a macro which gets #defined somehow: in a
single
#included "cryptic.h" file or even as -D options to his compiler
commands
if his implementation has such.

Of course suitable conventions and seddery and such allow the
extraction
of any number of such CRYPTOF uses in the code, so long as the
crypted
things can appear in macro names.

That's exaclty what I don't want - using an external program. I just
want to write my source code and have the precompiler mess with it.
 
G

Gernot Frisch

I don't quite get it.
How would I left-trim a string by 3 characters using the precompiler?

Like:

#define TRIM3(str) t__TRIM3(str "\0\0\0")
#define t_TRIM3(str) ((str)+3)

(which does not work)
 
K

Kenneth Brody

Gernot Frisch wrote:
[...]
can you give a grief explaination on how to make it?

I think that any explanation would give you plenty of grief. :)

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
G

Gordon Burditt

Of course suitable conventions and seddery and such allow the
That's exaclty what I don't want - using an external program. I just
want to write my source code and have the precompiler mess with it.

The preprocessor cannot access memory. If you represent the string
to be crypted as a quoted string, it's not possible to get at individual
characters to manipulate them at preprocessor time.

You can do things like:

char cryptedtext[] = {'T' ^ 0x55, 'e' ^ 0x55, 'x' ^ 0x55, 't' ^ 0x55};

but it's *NOT* encrypted in the preprocessed source code.

Gordon L. Burditt
 
L

Laurent Deniau

Gernot said:
I don't quite get it.
How would I left-trim a string by 3 characters using the precompiler?

Like:

#define TRIM3(str) t__TRIM3(str "\0\0\0")
#define t_TRIM3(str) ((str)+3)

(which does not work)

It does not work because the orignal string still appears in the binary,
it is what you mean by "does not work"?

#define TRIM3(str) { t__TRIM3(str "\0\0\0") }
#define t_TRIM3(str) (str)[3],(str)[4],(str)[5]

a+, ld.
 
G

Gernot Frisch

[...]
can you give a grief explaination on how to make it?

I think that any explanation would give you plenty of grief. :)

Doh! "brief" - I mean: short in length. Oh dear. My brain decay is
proceeding much faster than I thought ;)
 
R

Rod Pemberton

Gernot Frisch said:
Hi,

I want to build a encryption macro set, that can crypt:

char secret[] = CRYPT("KungFu");

to anything unreadable, and then have a function:
char* DECRYPT(char* str)
{
...
}

I think it would be suffictient to encrypt a maximum of 16 characters.
Simple XOR would suffice, too. Any ideas of how that can be done?

I don't believe that using the preprocessor is the best solution, but here
is a simple solution:

#define _S(x) #x
#define _T(a,b,c,d,e,f) _S(a ## b ## c ## d ## e ## f)
#define CRYPT(a,b,c,d,e,f) _T(a,b,c,d,e,f)

/* define aliases for each letter, limited to _A-Za-z0-9 */
/* or you can use specific char's, say '!', directly in txt1 */
#define _CK A
#define _Cu z
#define _Cn y
#define _Cg q
#define _CF p

int main(void)
{

char txt1[]=CRYPT(_CK,_Cu,_Cn,_Cg,_CF,_Cu);
char *secret=txt1;

}

That is probably about as much "encryption" as you would ever want to do
with the preprocessor. Anything further will be a nightmare to implement
properly.

A better solution is to write a small program to open your binary, search
for a specific string, and replace it with the encrypted string. That is
what I would do.


Rod Pemberton
 
L

Laurent Deniau

Rod said:
Hi,

I want to build a encryption macro set, that can crypt:

char secret[] = CRYPT("KungFu");

to anything unreadable, and then have a function:
char* DECRYPT(char* str)
{
...
}

I think it would be suffictient to encrypt a maximum of 16 characters.
Simple XOR would suffice, too. Any ideas of how that can be done?


I don't believe that using the preprocessor is the best solution, but here
is a simple solution:

#define _S(x) #x
#define _T(a,b,c,d,e,f) _S(a ## b ## c ## d ## e ## f)
#define CRYPT(a,b,c,d,e,f) _T(a,b,c,d,e,f)

/* define aliases for each letter, limited to _A-Za-z0-9 */
/* or you can use specific char's, say '!', directly in txt1 */
#define _CK A
#define _Cu z
#define _Cn y
#define _Cg q
#define _CF p

int main(void)
{

char txt1[]=CRYPT(_CK,_Cu,_Cn,_Cg,_CF,_Cu);

Why don't you concatenate the _C prefix in the CRYPT macro?

#define CRYPT(a,b,c,d,e,f) _T(_C##a,_C##b,_C##c,_C##d,_C##e,_C##f)

Then you can directly write:

char txt1[]=CRYPT(K,u,n,g,F,u);
char *secret=txt1;

}

That is probably about as much "encryption" as you would ever want to do
with the preprocessor. Anything further will be a nightmare to implement
properly.
Why?

A better solution is to write a small program to open your binary, search
for a specific string, and replace it with the encrypted string. That is
what I would do.

I prefer the CPP way as the OP. By the way, the final result need not be
a valid C litteral string, but only an array of bytes (e.g no '\0' at
the end and the length coded at the beginning) to avoid strings to catch it.

a+, ld.
 
G

Gernot Frisch

Laurent Deniau said:
Gernot said:
I don't quite get it.
How would I left-trim a string by 3 characters using the
precompiler?

Like:

#define TRIM3(str) t__TRIM3(str "\0\0\0")
#define t_TRIM3(str) ((str)+3)

(which does not work)

It does not work because the orignal string still appears in the
binary, it is what you mean by "does not work"?

#define TRIM3(str) { t__TRIM3(str "\0\0\0") }
#define t_TRIM3(str) (str)[3],(str)[4],(str)[5]


I want it that way:
const char str[] = TRIM3("KungFu");

resulting in str[] == "ngFu";

That's impossible, right?
 
L

Laurent Deniau

Gernot said:
Gernot said:
I don't quite get it.
How would I left-trim a string by 3 characters using the
precompiler?

Like:

#define TRIM3(str) t__TRIM3(str "\0\0\0")
#define t_TRIM3(str) ((str)+3)

(which does not work)

It does not work because the orignal string still appears in the
binary, it is what you mean by "does not work"?

#define TRIM3(str) { t__TRIM3(str "\0\0\0") }
#define t_TRIM3(str) (str)[3],(str)[4],(str)[5]



I want it that way:
const char str[] = TRIM3("KungFu");

resulting in str[] == "ngFu";

So here you want a trim of 2, not 3
That's impossible, right?

Why? The code above is a start but from there, you get it in 1min of
work (I thought my example on the hash code to be explicit). Assuming
that you deal with a string length of 8 characters max (can be extended
easily) and you want to apply a trim of 2 (like above):
> cat tmp.c
#include <stdio.h>

#define CRYPT8(str) { CRYPT8_(str "\0\0\0\0\0\0\0\0") }
#define CRYPT8_(str) \
(str)[2],(str)[3],(str)[4],(str)[5],(str)[6],(str)[7],'\0'

int main(void)
{
const char str[] = CRYPT8("KungFu");
puts(strcmp(str,"ngFu") ? "KO" : "OK");
}
> gcc tmp.c -o tmp
> ./tmp OK
> strings ./tmp | grep "KungFu" | wc -l
0

the string "KungFu" is *not* in the binary. Impossible?

a+, ld.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,821
Latest member
AleidaSchi

Latest Threads

Top