From e09015638ece23f06f34a553d8615c86b3be0712 Mon Sep 17 00:00:00 2001 From: bloodstalker Date: Sun, 12 Nov 2017 01:16:20 +0330 Subject: added obfuscator, some minor changes made to load.py so it would be easier to call python scripts from lua, general changes for a new project --- README.md | 12 ++- bfd/load.py | 9 +- bruiser/bruiser.cpp | 2 +- makefile | 9 +- obfuscator/compile_commands.json | 7 ++ obfuscator/makefile | 27 ++++++ obfuscator/obfuscator.cpp | 200 +++++++++++++++++++++++++++++++++++++++ 7 files changed, 257 insertions(+), 9 deletions(-) create mode 100644 obfuscator/compile_commands.json create mode 100644 obfuscator/makefile create mode 100644 obfuscator/obfuscator.cpp diff --git a/README.md b/README.md index 94a42a3..7a568ee 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,7 @@ Safercpp runs the automatic refactoring sets on your source code, automatically mutator-lvl1 is an experimental tool that builds your code as a shared object library and keep it in the memory, later to be used by bruiser to dynamically link against or even run.
bruiser is an interactive shell-like tool used to mutate the source code plus run the mutants. You can read about the idea in bruiser's directory.
mutatord, the mutator server and the client are also provided as optional features.
+obfuscator is a C/C++ source code obfuscator.
#### What is SaferCpp? SaferCPlusPlus is essentially a collection of safe data types that are compatible with, and can substitute for, common unsafe native C++ types. You can read more [here](https://github.com/duneroadrunner/SaferCPlusPlus).
@@ -72,6 +73,12 @@ Mutation levels have nothing to do with the order of mutants.
## How to get project mutator +Before you run make, make sure you have all the dependencies:
+* You need LLVM 4.0<.
+* For `safercpp` you will need to have LLVM rtti also.
+* For `bruiser` you will need the python 3.5< dev package.
+* The other libraries used are either submodules or copied inside.
+ Assuming you already have the LLVM/Clang libraries, just run : ```bash @@ -161,6 +168,7 @@ Here Are the build options:
* `WIN_BUILD` will later be used to support Windows builds. It assumes there is a llvm-config and it's in windows path.
* `GNU_MODE` will build the executable with no source code coverage instrumentation for `g++`. Can only be used to build with `g++`.
* The `LLVM_CONF` option is used to tell the compiler which `llvm-config` to use. The default value is `llvm-config`.
+* The `PY_CONF` option tells make which `python-config` to use. The default is `python3-config`.
So for example if you want to build the code with `clang++` without any coverage, and you only want to build the Misra-C rule checker, you should run:

@@ -172,7 +180,7 @@ Note: if you are building the llvm and clang libraries from source, then the llv
Also do note that building the llvm libraries from source in Debug mode will require big space on your harddrive and will need more than 4GB of RAM. Release mode is less resource-greedy, of course.
Finally if you are having problems with the build, you could take a look at `.travis.yml` or under `CITPreBuildDep.sh` under `extra-tools` for some hints or help apart from asking for help, of course.
-As a general rule, if you have Clang and LLVM libraries 3.9 or up on your platform, you can build `mutator`. If there are any problems with builds on platforms other than the ones in `.travis.yml` let me know.
+As a general rule, if you have Clang and LLVM libraries 4.0 or up on your platform, you can build `mutator`. If there are any problems with builds on platforms other than the ones in `.travis.yml` let me know.
After building the executables, you need to run:
@@ -189,7 +197,7 @@ Let me know if you decide to try this and/or have any problems with it.
### Running -To run any of the tree executables, just give a filename or a whitespace-separated list of files. The executables will print out the results to stdout.
+To run any of the executables, just give a filename or a whitespace-separated list of files. The executables will print out the results to stdout.
To run the executables with the mutator UI, you can use `mutator.sh`. For a list of available options, you can type `./mutator.sh -h`.
* `-h, --help` prints out the help.
diff --git a/bfd/load.py b/bfd/load.py index b04db5d..4c681c3 100755 --- a/bfd/load.py +++ b/bfd/load.py @@ -163,6 +163,7 @@ class ELF(object): self.size = int() self.string_tb_e = [] self.string_tb_e_dyn = [] + self.symbols = [] def init(self, size): self.size = size @@ -423,11 +424,11 @@ def main(): so = openSO_r(sys.argv[1]) elf = ELF(so) elf.init(64) - elf.dump_header() - elf.dump_symbol_tb() + #elf.dump_header() + #elf.dump_symbol_tb() #elf.dump_phdrs() - #elf.dump_shdrs() - elf.dump_symbol_idx() + elf.dump_shdrs() + #elf.dump_symbol_idx() #elf.dump_objs() ''' so.close() diff --git a/bruiser/bruiser.cpp b/bruiser/bruiser.cpp index 309e41d..dfd12f6 100644 --- a/bruiser/bruiser.cpp +++ b/bruiser/bruiser.cpp @@ -231,7 +231,7 @@ class PyExec { pArgs = nullptr; std::cout << BLUE << "calling python function..." << NORMAL << "\n"; pValue = PyObject_CallObject(pFunc, pArgs); - std::cout << BLUE << "i made it here" << NORMAL << "\n"; + //std::cout << BLUE << "i made it here" << NORMAL << "\n"; //Py_DECREF(pArgs); if (pValue != nullptr) { std::cout << GREEN << "call finished successfully." << NORMAL << "\n"; diff --git a/makefile b/makefile index f25f25a..3fd1d63 100644 --- a/makefile +++ b/makefile @@ -14,13 +14,14 @@ TARGETD=mutatord TARGETS=mutatorserver SFCPP01=safercpp-arr BRUISER=bruiser +OBSC=obfuscator ######################################RULES#################################### .DEFAULT: all -.PHONY:all clean install help $(TARGET0) $(TARGET1) $(TARGET2) TAGS $(SFCPP01) $(BRUISER) +.PHONY:all clean install help $(TARGET0) $(TARGET1) $(TARGET2) TAGS $(SFCPP01) $(BRUISER) $(OBSC) -all: $(TARGET0) $(TARGET1) $(TARGET2) $(TARGETC) $(TARGETD) $(TARGETS) $(SFCPP01) $(BRUISER) +all: $(TARGET0) $(TARGET1) $(TARGET2) $(TARGETC) $(TARGETD) $(TARGETS) $(SFCPP01) $(BRUISER) $(OBSC) .cpp.o: $(CXX) $(CXX_FLAGS) -c $< -o $@ @@ -42,6 +43,9 @@ $(SFCPP01): $(BRUISER): $(MAKE) -C bruiser CXX=$(CXX) LLVM_CONF=$(LLVM_CONF) BUILD_MODE=$(BUILD_MODE) +$(OBSC): + $(MAKE) -C obfuscator CXX=$(CXX) LLVM_CONF=$(LLVM_CONF) BUILD_MODE=$(BUILD_MODE) + $(TARGETC): $(MAKE) -C daemon mutatorclient @@ -61,6 +65,7 @@ clean: $(MAKE) -C daemon clean $(MAKE) -C safercpp clean $(MAKE) -C bruiser clean + $(MAKE) -C obfuscator clean install: chmod +x ./mutator.sh diff --git a/obfuscator/compile_commands.json b/obfuscator/compile_commands.json new file mode 100644 index 0000000..5b4729c --- /dev/null +++ b/obfuscator/compile_commands.json @@ -0,0 +1,7 @@ +[ + { + "command": "c++ -c -I/home/bloodstalker/extra/llvm-clang-4/llvm/include -I/home/bloodstalker/extra/llvm-clang-4/build/include -fPIC -fvisibility-inlines-hidden -Werror=date-time -std=c++11 -Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wno-maybe-uninitialized -Wdelete-non-virtual-dtor -Wno-comment -ffunction-sections -fdata-sections -O2 -fno-exceptions -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/bloodstalker/extra/llvm-clang-4/llvm/tools/clang/include -I/home/bloodstalker/extra/llvm-clang-4/build/tools/clang/include -std=c++1z -stdlib=libstdc++ -UNDEBUG -fexceptions -o obfuscator.o obfuscator.cpp", + "directory": "/home/bloodstalker/devi/hell2/obfuscator", + "file": "/home/bloodstalker/devi/hell2/obfuscator/obfuscator.cpp" + } +] \ No newline at end of file diff --git a/obfuscator/makefile b/obfuscator/makefile new file mode 100644 index 0000000..dee61e2 --- /dev/null +++ b/obfuscator/makefile @@ -0,0 +1,27 @@ + +######################################INCLUDES################################# +include ../macros.mk + +#######################################VARS#################################### +OBSC=obfuscator +######################################RULES#################################### +.DEFAULT: all + +.PHONY: all clean help $(OBSC) + +all: $(OBSC) + +.cpp.o: + $(CXX) $(CXX_FLAGS) -c $< -o $@ + +$(OBSC): $(OBSC).o ../mutator_aux.o + $(CXX) $^ $(LD_FLAGS) -o $@ + +clean: + rm -f *.o *~ $(OBSC) + +help: + @echo 'There is help.' + @echo 'All is the defualt target.' + @echo 'Clean runs clean.' + @echo 'For a more complete and detaild list of BUILD_MODE and other things look at the main makefiles help under project root.' diff --git a/obfuscator/obfuscator.cpp b/obfuscator/obfuscator.cpp new file mode 100644 index 0000000..ae8e9e7 --- /dev/null +++ b/obfuscator/obfuscator.cpp @@ -0,0 +1,200 @@ + +/***************************************************Project Mutator****************************************************/ +//-*-c++-*- +/*first line intentionally left blank.*/ +/*Copyright (C) 2017 Farzad Sadeghi + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*/ +/*code structure inspired by Eli Bendersky's tutorial on Rewriters.*/ +/**********************************************************************************************************************/ +/*FIXME-all classes should use replacements.*/ +/**********************************************************************************************************************/ +/*included modules*/ +/*project headers*/ +#include "../mutator_aux.h" +/*standard headers*/ +#include +#include +#include +/*LLVM headers*/ +#include "clang/AST/AST.h" +#include "clang/AST/ASTConsumer.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Basic/LLVM.h" +#include "clang/CodeGen/CodeGenAction.h" +#include "clang/CodeGen/BackendUtil.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/FrontendActions.h" +#include "clang/Lex/Lexer.h" +#include "clang/Tooling/CommonOptionsParser.h" +#include "clang/Tooling/Tooling.h" +#include "clang/Rewrite/Core/Rewriter.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Function.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Linker/Linker.h" +/**********************************************************************************************************************/ +/*used namespaces*/ +using namespace llvm; +using namespace clang; +using namespace clang::ast_matchers; +using namespace clang::driver; +using namespace clang::tooling; +/**********************************************************************************************************************/ +/*global vars*/ + +static llvm::cl::OptionCategory MatcherSampleCategory("Matcher Sample"); +/**********************************************************************************************************************/ +class FuncDecl : public MatchFinder::MatchCallback +{ +public: + FuncDecl (Rewriter &Rewrite) : Rewrite (Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("funcdecl") != nullptr) { + const FunctionDecl* FD = MR.Nodes.getNodeAs("funcdecl"); + std::string funcname = FD->getNameInfo().getAsString(); + std::size_t hash = std::hash{}(funcname); + std::string newname = "ID" + std::to_string(hash); + std::cout << "Function name: " << funcname << " Hash: " << hash << " New ID: " << newname << "\n"; + + SourceRange SR = FD->getSourceRange(); + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class VDecl : public MatchFinder::MatchCallback +{ +public: + VDecl (Rewriter &Rewrite) : Rewrite (Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) + { + if (MR.Nodes.getNodeAs("vardecl") != nullptr) { + const VarDecl* VD = MR.Nodes.getNodeAs("vardecl"); + std::string varname = VD->getIdentifier()->getName().str(); + std::size_t hash = std::hash{}(varname); + std::string newname = "ID" + std::to_string(hash); + std::cout << "Var name: " << varname << " Hash: " << hash << " New ID: " << newname << "\n"; + + SourceRange SR = VD->getSourceRange(); + } + } + +private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class ClassDecl : public MatchFinder::MatchCallback { + public: + ClassDecl (Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) { + if (MR.Nodes.getNodeAs("classdecl") != nullptr) { + const RecordDecl* RD = MR.Nodes.getNodeAs("classdecl"); + } + } + + private: + Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class PPInclusion : public PPCallbacks +{ +public: + explicit PPInclusion (SourceManager *SM) : SM(*SM) {} + + virtual void MacroDefined(const Token &MacroNameTok, const MacroDirective *MD) { + const MacroInfo* MI = MD->getMacroInfo(); + + SourceLocation SL = MacroNameTok.getLocation(); + CheckSLValidity(SL); + std::string macroname = MacroNameTok.getIdentifierInfo()->getName().str(); + std::size_t hash = std::hash{}(macroname); + std::string newname = "ID" + std::to_string(hash); + std::cout << "Macro name: " << macroname << " Hash: " << hash << " New ID: " << newname << "\n"; + } + +private: + const SourceManager &SM; +}; +/**********************************************************************************************************************/ +class BlankDiagConsumer : public clang::DiagnosticConsumer +{ + public: + BlankDiagConsumer() = default; + virtual ~BlankDiagConsumer() {} + virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) override {} +}; +/**********************************************************************************************************************/ +class MyASTConsumer : public ASTConsumer { +public: + MyASTConsumer(Rewriter &R) : funcDeclHandler(R), HandlerForVar(R), HandlerForClass(R) { + Matcher.addMatcher(functionDecl().bind("funcdecl"), &funcDeclHandler); + Matcher.addMatcher(varDecl().bind("vardecl"), &HandlerForVar); + Matcher.addMatcher(recordDecl(isClass()).bind("classdecl"), &HandlerForClass); + } + + void HandleTranslationUnit(ASTContext &Context) override { + Matcher.matchAST(Context); + } + +private: + FuncDecl funcDeclHandler; + VDecl HandlerForVar; + ClassDecl HandlerForClass; + MatchFinder Matcher; +}; +/**********************************************************************************************************************/ +class ObfFrontendAction : public ASTFrontendAction { +public: + ObfFrontendAction() {} + ~ObfFrontendAction() {} + void EndSourceFileAction() override { + //TheRewriter.getEditBuffer(TheRewriter.getSourceMgr().getMainFileID()).write(llvm::outs()); + } + + std::unique_ptr CreateASTConsumer(CompilerInstance &CI, StringRef file) override { + CI.getPreprocessor().addPPCallbacks(llvm::make_unique(&CI.getSourceManager())); + DiagnosticsEngine &DE = CI.getPreprocessor().getDiagnostics(); + DE.setClient(BDCProto, false); + TheRewriter.setSourceMgr(CI.getSourceManager(), CI.getLangOpts()); + return llvm::make_unique(TheRewriter); + } + +private: + BlankDiagConsumer* BDCProto = new BlankDiagConsumer; + Rewriter TheRewriter; +}; +/**********************************************************************************************************************/ +/*Main*/ +int main(int argc, const char **argv) { + CommonOptionsParser op(argc, argv, MatcherSampleCategory); + ClangTool Tool(op.getCompilations(), op.getSourcePathList()); + return Tool.run(newFrontendActionFactory().get()); +} +/**********************************************************************************************************************/ +/*last line intentionally left blank.*/ + -- cgit v1.2.3