diff options
Diffstat (limited to 'obfuscator')
-rw-r--r-- | obfuscator/README.md | 18 | ||||
-rw-r--r-- | obfuscator/obfuscator.cpp | 117 |
2 files changed, 129 insertions, 6 deletions
diff --git a/obfuscator/README.md b/obfuscator/README.md new file mode 100644 index 0000000..585c054 --- /dev/null +++ b/obfuscator/README.md @@ -0,0 +1,18 @@ +# obfuscator + +obfuscator is a C/C++ source-code obfuscation tool.<br/> + +## Status +obfuscator is not feature-complete yet. Below you can find a list of the implemented features and the ones that will be implemented.<br/> +If you have suggestions or recommendations for features to add please make an issue with the `obfuscator` label.<br/> + +### Implemented Features +* Identifier Obfuscation: Swaps the name of all identifiers with their hash. <br/> + +### Future Features +* Obfuscation Exclusion List: obfuscator will accept a list of idenftifiers and their namespace and will not obfuscate those. This feature is added so the user can refrain from obfuscating the standard library.<br/> +* Whitespace Deletion: Pretty much kills all whitespace where it doesn't change the syntax.<br/> +* Comment Deletion: Deletes all comments.<br/> + +## Notes +* Currently the hash function that is being used is `std::hash<>`. The GCC implementation will be probably the default option since the digest is shorter than 32 characters long. The decision was made since quite a few embedded C/C++ compilers can't correctly handle identifiers longer than 32 characters(implementation limitations).<br/> diff --git a/obfuscator/obfuscator.cpp b/obfuscator/obfuscator.cpp index 5d1171b..f987fc8 100644 --- a/obfuscator/obfuscator.cpp +++ b/obfuscator/obfuscator.cpp @@ -29,6 +29,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.* #include <iostream> #include <cassert> #include <vector> +#include <fstream> +#include <regex> /*LLVM headers*/ #include "clang/AST/AST.h" #include "clang/AST/ASTConsumer.h" @@ -162,11 +164,19 @@ public: #ifdef DBG std::cout << "Var name: " << varname << " Hash: " << hash << " New ID: " << newname << "\n"; #endif - SourceLocation SL = VD->getLocation(); - SourceLocation SLE = VD->getLocEnd(); + SourceLocation SLE; + const clang::Expr* EXP = nullptr; + + if (MR.Nodes.getNodeAs<clang::Expr>("expr") !=nullptr) { + EXP = MR.Nodes.getNodeAs<clang::Expr>("expr"); + SLE = EXP->getExprLoc(); + } else { + SLE = VD->getLocEnd(); + } - Rewrite.ReplaceText(SourceRange(SL, SLE), StringRef(newname)); + //@devi-FIXME-cluncky + Rewrite.ReplaceText(SourceRange(SL, SL.getLocWithOffset(VD->getIdentifier()->getLength() - 1)), StringRef(newname)); } } @@ -245,7 +255,7 @@ class MyASTConsumer : public ASTConsumer { public: MyASTConsumer(Rewriter &R) : funcDeclHandler(R), HandlerForVar(R), HandlerForClass(R), HandlerForCalledFunc(R), HandlerForCalledVar(R) { Matcher.addMatcher(functionDecl().bind("funcdecl"), &funcDeclHandler); - Matcher.addMatcher(varDecl().bind("vardecl"), &HandlerForVar); + Matcher.addMatcher(varDecl(anyOf(unless(hasDescendant(expr(anything()))), hasDescendant(expr(anything()).bind("expr")))).bind("vardecl"), &HandlerForVar); Matcher.addMatcher(recordDecl(isClass()).bind("classdecl"), &HandlerForClass); //Matcher.addMatcher(callExpr().bind("calledfunc"), &HandlerForCalledFunc); Matcher.addMatcher(declRefExpr().bind("calledvar"), &HandlerForCalledVar); @@ -267,9 +277,16 @@ private: class ObfFrontendAction : public ASTFrontendAction { public: ObfFrontendAction() {} - ~ObfFrontendAction() {delete BDCProto;} + ~ObfFrontendAction() { + delete BDCProto; + delete tee; + } void EndSourceFileAction() override { + std::error_code EC; + std::string OutputFilename = "./obfuscator-tee"; TheRewriter.getEditBuffer(TheRewriter.getSourceMgr().getMainFileID()).write(llvm::outs()); + tee = new raw_fd_ostream(StringRef(OutputFilename), EC, sys::fs::F_None); + TheRewriter.getEditBuffer(TheRewriter.getSourceMgr().getMainFileID()).write(*tee); } std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, StringRef file) override { @@ -283,13 +300,101 @@ public: private: BlankDiagConsumer* BDCProto = new BlankDiagConsumer; Rewriter TheRewriter; + raw_ostream *tee = &llvm::outs(); +}; +/**********************************************************************************************************************/ +class CommentWiper { + public: + CommentWiper(std::vector<std::string> SourceList) : sourcelist(SourceList) {} + + int run(void) { + for (auto &filepath : sourcelist) { + //std::regex comment1("//.+"); + //std::regex comment2("/\\*.+\\*/"); + //std::regex comment2("/\\*[^]+\\*/"); + //std::regex multibegin("/\\*.+(?!\\*/)"); + //std::regex multiend("(?<!/\\*).+\\*/"); + //std::smatch result; + //bool multiline; + bool slash, backslash, quote, star, multiline; + unsigned int ch_prv; + + std::ifstream sourcefile; + sourcefile.open("../test/bruisertest/obfuscator-tee"); + std::ofstream dupe; + dupe.open("./dupe.cpp"); + std::string line; + while (std::getline(sourcefile, line)) { + line += "\n"; + for (unsigned int ch = 0; ch < line.length(); ++ch) { + if (line[ch] == atoi("/")) slash = true; + if (line[ch] == atoi("\\")) backslash = true; + if (line[ch] == atoi("\"")) quote = true; + if (line[ch] == atoi("*")) star = true; + ch_prv = ch; + } + //if (std::regex_search(line, result, comment1)) {std::cout << "11111" << result.str() << "\n";} + //if (std::regex_search(line, result, comment2)) {std::cout << "22222" << result.str() << "\n";} + //if (std::regex_search(line, result, multibegin)) {std::cout << "33333" << result.str() << "\n";} + //if (std::regex_search(line, result, multiend)) {std::cout << "44444" << result.str() << "\n";} + dupe << line << "\n"; + } + sourcefile.close(); + dupe.close(); + } + return 0; + } + + private: + std::vector<std::string> sourcelist; +}; +/**********************************************************************************************************************/ +class WhitespaceWarper { + public: + WhitespaceWarper(std::vector<std::string> SourceList) : sourcelist(SourceList) {} + + int run(void) { + for (auto &filepath : sourcelist) { + std::ifstream sourcefile; + sourcefile.open("../test/bruisertest/obfuscator-tee"); + std::ofstream dupe; + dupe.open("./dupe.cpp"); + std::string line; + while (std::getline(sourcefile, line)) { + for (auto &character : line) { + if (std::to_string(character) == "\t") { + dupe << "\t"; + } + else if (std::to_string(character) == "\n") { + } + else if (std::to_string(character) == " ") { + dupe << " "; + } + else { + dupe << character; + } + } + } + dupe.close(); + } + return 0; + } + + private: + std::vector<std::string> sourcelist; }; /**********************************************************************************************************************/ /*Main*/ int main(int argc, const char **argv) { CommonOptionsParser op(argc, argv, MatcherSampleCategory); + const std::vector<std::string> &SourcePathList = op.getSourcePathList(); ClangTool Tool(op.getCompilations(), op.getSourcePathList()); - return Tool.run(newFrontendActionFactory<ObfFrontendAction>().get()); + int ret = Tool.run(newFrontendActionFactory<ObfFrontendAction>().get()); + WhitespaceWarper WW(SourcePathList); + //WW.run(); + CommentWiper CW(SourcePathList); + CW.run(); + return ret; } /**********************************************************************************************************************/ /*last line intentionally left blank.*/ |