obfacros - a set of macros written in C++14 with g++5, that can be used to obfuscate your c/c++ code, to make it harder for reverse-engineering.
I use this to generate the CTF challenge of "Obfuscating Macros I/II" in DDCTF / *ctf 2019.
Please find the demo.cpp. To compile, just g++ demo.cpp -std=c++14 -o demo.out.
- easy to use: header-only, just include the provided
obfacros.hppand write your code in a way similar to plain c/c++, then compile with g++. - easy to disable: to disable the obfuscation, you just need to replace the macros by normal code like:
#define FOR(init, cond, end, ...) for(init; cond; end) { __VA_ARGS__; }. Checkdemo_obfacros_disabled.cppand the sectionA way to disable the obfuscationin the document. - much harder for reverse-engineering: by flattening the control flow and using dynamic JUMPs
If necessary, the macros may be modified into another form which do not require any features of C++14 or g++.
#include "obfacros.hpp"- write your code using the macros rather than the
for/if/whilec/c++ keywords - compile and enjoy!
- Using all macros(like
FOR/IF/RETURN...) ONLY IN theobfacros scope(betweenFUNCTION_START(var_to_accept_return_value)andFUNCTION_END;) DO NOT declare variablesinside the scope. Please declare all the variables outside in advance.- Avoid using
{}in the obfacros scope. If you want to use{}anyway, please do not use any obfacros inside the{}(before the bracket is closed).
Write this before using any other obfacros to create a scope of obfacros (or we call it obfacros scope or the scope).
retVal specifies the variable to be assigned when RETURN. If you do not use RETURN, just fill in a random variable.
just like for (init; cond; end) { ... } in c/c++
just like while (expr) { ... } in c/c++
just like if (expr) { ... } in c/c++, but with a difference that:
if (expr) { code; } should be written in the form of IF(expr, code);
if (expr) { code; } else { code2; } should be written in the form of IF_ELSE(expr, code) ELSE (code2);
In a word, before you use any ELIF or ELSE, please check the previous macro is with the suffix _ELSE. Likewise, we also have ELIF and ELIF_ELSE.
Jump to next line of FUNCTION_END(jump out of the scope of obfacros) and assign the val to retVal that specified in FUNCTION_START.
If you use any of advanced features, you may not easily disable the obfuscation because there is no corresponding features in the language of c/c++.
For demo, please visit the source code of one of my CTF reverse challenge: https://github.com/garzon/my_ctf_challenges_source_code/tree/master/starctf_2019/obfuscating_macros_II
Manually create a code block. Just like { code }; in c/c++.
Create a code block with a name. Just like if (false) { name: code }; in c/c++.
"include" a previously defined named block(by MAKE_BLOCK_WITH_NAME). Like a function call in c/c++ with variables shared.
- Comment out
#include "obfacros.hpp" - Using the code below to replace the obfacros:
#define FUNCTION_START(...)
#define FUNCTION_END
#define BLOCK(...) { __VA_ARGS__; }
#define IF(expr, ...) if (expr) { __VA_ARGS__; } else {}
#define FOR(init, cond, end, ...) for(init; cond; end) { __VA_ARGS__; }
#define WHILE(expr, ...) while(expr) { __VA_ARGS__; }
#define IF_ELSE(expr, ...) if (expr) { __VA_ARGS__; }
#define ELSE(...) else { __VA_ARGS__; }
#define ELIF(expr, ...) else { if (expr) { __VA_ARGS__; } }
#define ELIF_ELSE(expr, ...) else if (expr) { __VA_ARGS__; }
#define RETURN(...) return (__VA_ARGS__)