diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d621f2..f9e9a44 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,7 @@ add_subdirectory(interceptOutput) add_subdirectory(maxMallocSize) add_subdirectory(memoryAccessCounter) add_subdirectory(parseAPI) +add_subdirectory(patchAPI) add_subdirectory(proccontrol) add_subdirectory(readGlobalVariables) add_subdirectory(stackwalker) diff --git a/patchAPI/CFGMaker.cpp b/patchAPI/CFGMaker.cpp new file mode 100644 index 0000000..d384c8b --- /dev/null +++ b/patchAPI/CFGMaker.cpp @@ -0,0 +1,46 @@ +#include "CFG.h" +#include "CFGMaker.h" +#include "PatchCFG.h" + +#include + +namespace dp = Dyninst::ParseAPI; +namespace pa = Dyninst::PatchAPI; + +/* + * A custom function CFG generator + * + */ + +struct FunctionTracer : pa::PatchFunction { + FunctionTracer(dp::Function *f, pa::PatchObject* o) : pa::PatchFunction(f, o) { + std::cout << "Making function " << f->name() << '\n'; + } +}; + +class CFGTracer : public pa::CFGMaker { + public: + pa::PatchFunction* makeFunction(dp::Function *f, pa::PatchObject* o) override { + return new FunctionTracer(f, o); + } +}; + +int main(int argc, char* argv[]) { + if(argc < 2 || argc > 3) { + std::cerr << "Usage: " << argv[0] << " file\n"; + return -1; + } + + auto* sts = new dp::SymtabCodeSource(argv[1]); + auto* co = new dp::CodeObject(sts); + + constexpr Dyninst::Address base_address{0UL}; + CFGTracer tracer; + auto* obj = pa::PatchObject::create(co, base_address, &tracer); + + std::vector all_funcs; + obj->funcs(back_inserter(all_funcs)); + + // suppress compiler warning + (void)all_funcs; +} diff --git a/patchAPI/CFGTraversal.cpp b/patchAPI/CFGTraversal.cpp new file mode 100644 index 0000000..20defac --- /dev/null +++ b/patchAPI/CFGTraversal.cpp @@ -0,0 +1,39 @@ +#include "CFG.h" +#include "CodeObject.h" +#include "PatchCFG.h" + +#include +#include + +namespace dp = Dyninst::ParseAPI; +namespace pa = Dyninst::PatchAPI; + +/* + * Traverse the CFG using PatchAPI + */ + +int main(int argc, char* argv[]) { + if(argc < 2 || argc > 3) { + std::cerr << "Usage: " << argv[0] << " file\n"; + return -1; + } + + auto* sts = new dp::SymtabCodeSource(argv[1]); + auto* co = new dp::CodeObject(sts); + + constexpr Dyninst::Address base_address{0UL}; + auto* obj = pa::PatchObject::create(co, base_address); + + std::vector all_funcs; + obj->funcs(back_inserter(all_funcs)); + + for(auto* f : all_funcs) { + std::cout << "Function: " << f->name() << '\n'; + + for(auto* b : f->blocks()) { + std::cout << " Block :" << b->format() << '\n'; + } + + std::cout << '\n'; + } +} diff --git a/patchAPI/CMakeLists.txt b/patchAPI/CMakeLists.txt new file mode 100644 index 0000000..9e79e40 --- /dev/null +++ b/patchAPI/CMakeLists.txt @@ -0,0 +1,29 @@ +project(patchAPI LANGUAGES CXX) + +add_executable(CFGTraversal CFGTraversal.cpp) +target_compile_options(CFGTraversal PRIVATE ${EXAMPLES_WARNING_FLAGS}) +target_link_libraries(CFGTraversal PRIVATE Dyninst::patchAPI) + +add_executable(findingPoints findingPoints.cpp) +target_compile_options(findingPoints PRIVATE ${EXAMPLES_WARNING_FLAGS}) +target_link_libraries(findingPoints PRIVATE Dyninst::patchAPI) + +add_executable(nopPatching nopPatching.cpp) +target_compile_options(nopPatching PRIVATE ${EXAMPLES_WARNING_FLAGS}) +target_link_libraries(nopPatching PRIVATE Dyninst::patchAPI) + +add_library(addressSpace SHARED addressSpace.cpp) +target_compile_options(addressSpace PRIVATE ${EXAMPLES_WARNING_FLAGS}) +target_link_libraries(addressSpace PRIVATE Dyninst::patchAPI) + +add_executable(CFGMaker CFGMaker.cpp) +target_compile_options(CFGMaker PRIVATE ${EXAMPLES_WARNING_FLAGS}) +target_link_libraries(CFGMaker PRIVATE Dyninst::patchAPI) + +add_executable(PointMaker PointMaker.cpp) +target_compile_options(PointMaker PRIVATE ${EXAMPLES_WARNING_FLAGS}) +target_link_libraries(PointMaker PRIVATE Dyninst::patchAPI) + +add_executable(PatchModifier PatchModifier.cpp) +target_compile_options(PatchModifier PRIVATE ${EXAMPLES_WARNING_FLAGS}) +target_link_libraries(PatchModifier PRIVATE Dyninst::patchAPI) diff --git a/patchAPI/PatchModifier.cpp b/patchAPI/PatchModifier.cpp new file mode 100644 index 0000000..bab7075 --- /dev/null +++ b/patchAPI/PatchModifier.cpp @@ -0,0 +1,62 @@ +#include "AddrSpace.h" +#include "CFG.h" +#include "CodeObject.h" +#include "PatchCFG.h" +#include "PatchMgr.h" +#include "PatchObject.h" +#include "PatchModifier.h" + +#include +#include + +namespace dp = Dyninst::ParseAPI; +namespace pa = Dyninst::PatchAPI; + +/* + * Insert an x86 nop slide in every function + */ + +int main(int argc, char* argv[]) { + if(argc < 2 || argc > 3) { + std::cerr << "Usage: " << argv[0] << " file\n"; + return -1; + } + + auto* sts = new dp::SymtabCodeSource(argv[1]); + auto* co = new dp::CodeObject(sts); + + constexpr Dyninst::Address base_address{0UL}; + auto* patch_object = pa::PatchObject::create(co, base_address); + + auto* address_space = pa::AddrSpace::create(patch_object); + auto patch_manager = pa::PatchMgr::create(address_space); + + pa::Patcher patcher(patch_manager); + + std::vector functions; + patch_object->funcs(std::back_inserter(functions)); + + auto const* func_to_remove = "InterestingProcedure"; + auto found = std::find_if(functions.begin(), functions.end(), + [func_to_remove](pa::PatchFunction* p) { return p->name() == func_to_remove;}); + + if(found == functions.end()) { + std::cerr << "Couldn't find '" << func_to_remove << "'\n"; + return -1; + } + + auto print_functions = [](std::vector const& funcs) { + for(auto* f : funcs) { + std::cout << f->name() << '\n'; + } + }; + + print_functions(functions); + + pa::PatchModifier::remove(*found); + + functions.clear(); + patch_object->funcs(std::back_inserter(functions)); + + print_functions(functions); +} diff --git a/patchAPI/PointMaker.cpp b/patchAPI/PointMaker.cpp new file mode 100644 index 0000000..235c751 --- /dev/null +++ b/patchAPI/PointMaker.cpp @@ -0,0 +1,53 @@ +#include "CFG.h" +#include "CFGMaker.h" +#include "PatchCFG.h" +#include "PatchMgr.h" +#include "PatchCommon.h" + +#include + +namespace dp = Dyninst::ParseAPI; +namespace pa = Dyninst::PatchAPI; + +/* + * A custom point generator + * + */ + +struct PointTracer : pa::Point { + PointTracer(pa::Point::Type t, pa::PatchMgrPtr m, pa::PatchFunction* f) : pa::Point(t, m, f) { + std::cout << "Making point for " << f->name() << '\n'; + } +}; + +class PointMakerTracer : public pa::PointMaker { + public: + pa::Point* mkFuncPoint(pa::Point::Type t, pa::PatchMgrPtr m, pa::PatchFunction *f) override { + return new PointTracer(t, m, f); + } +}; + +int main(int argc, char* argv[]) { + if(argc < 2 || argc > 3) { + std::cerr << "Usage: " << argv[0] << " file\n"; + return -1; + } + + auto* sts = new dp::SymtabCodeSource(argv[1]); + auto* co = new dp::CodeObject(sts); + + constexpr Dyninst::Address base_address{0UL}; + auto* patch_object = pa::PatchObject::create(co, base_address); + + auto* address_space = pa::AddrSpace::create(patch_object); + PointMakerTracer point_tracer{}; + auto patch_manager = pa::PatchMgr::create(address_space, nullptr, &point_tracer); + + std::vector functions; + patch_object->funcs(std::back_inserter(functions)); + + for(auto* f : functions) { + std::vector entryPoints; + patch_manager->findPoints(pa::Scope(f), pa::Point::FuncEntry, std::back_inserter(entryPoints)); + } +} diff --git a/patchAPI/addressSpace.cpp b/patchAPI/addressSpace.cpp new file mode 100644 index 0000000..025eedf --- /dev/null +++ b/patchAPI/addressSpace.cpp @@ -0,0 +1,21 @@ +#include "AddrSpace.h" +#include "PatchObject.h" + +namespace pa = Dyninst::PatchAPI; + +struct MyAddrSpace : pa::AddrSpace { + + Dyninst::Address malloc(pa::PatchObject*, size_t , Dyninst::Address ) override { + // do memory allocation here + return 0; + } + + bool write(pa::PatchObject* , Dyninst::Address , Dyninst::Address , size_t ) override { + // copy data from the address from_addr to the address to_addr + return true; + } + + bool realloc(pa::PatchObject* , Dyninst::Address , size_t ) override { return true; } + + bool free(pa::PatchObject* , Dyninst::Address ) override { return true; } +}; diff --git a/patchAPI/findingPoints.cpp b/patchAPI/findingPoints.cpp new file mode 100644 index 0000000..443c62e --- /dev/null +++ b/patchAPI/findingPoints.cpp @@ -0,0 +1,42 @@ +#include "AddrSpace.h" +#include "CFG.h" +#include "CodeObject.h" +#include "PatchCFG.h" +#include "PatchMgr.h" +#include "PatchObject.h" + +#include +#include + +namespace dp = Dyninst::ParseAPI; +namespace pa = Dyninst::PatchAPI; + +/* + * Find entry points for every function + */ + +int main(int argc, char* argv[]) { + if(argc < 2 || argc > 3) { + std::cerr << "Usage: " << argv[0] << " file\n"; + return -1; + } + + auto* sts = new dp::SymtabCodeSource(argv[1]); + auto* co = new dp::CodeObject(sts); + + constexpr Dyninst::Address base_address{0UL}; + auto* patch_object = pa::PatchObject::create(co, base_address); + + auto* address_space = pa::AddrSpace::create(patch_object); + auto patch_manager = pa::PatchMgr::create(address_space); + + std::vector functions; + patch_object->funcs(std::back_inserter(functions)); + + for(auto* f : functions) { + std::vector entryPoints; + patch_manager->findPoints(pa::Scope(f), pa::Point::FuncEntry, std::back_inserter(entryPoints)); + + std::cout << f->name() << " has " << entryPoints.size() << " entry point(s)\n"; + } +} diff --git a/patchAPI/nopPatching.cpp b/patchAPI/nopPatching.cpp new file mode 100644 index 0000000..78c52ee --- /dev/null +++ b/patchAPI/nopPatching.cpp @@ -0,0 +1,67 @@ +#include "AddrSpace.h" +#include "CFG.h" +#include "CodeObject.h" +#include "PatchCFG.h" +#include "PatchMgr.h" +#include "PatchObject.h" + +#include +#include + +namespace dp = Dyninst::ParseAPI; +namespace pa = Dyninst::PatchAPI; + +/* + * Insert an x86 nop slide in every function + */ + +class NopSlide : public pa::Snippet { + int count{4}; + +public: + NopSlide(int num_nops) : count{num_nops} {} + + bool generate(pa::Point*, Dyninst::Buffer& buffer) override { + uint8_t byte = 0x90; + for(int i = 0; i < count; i++) { + buffer.push_back(byte); + } + return true; + } +}; + +int main(int argc, char* argv[]) { + if(argc < 2 || argc > 3) { + std::cerr << "Usage: " << argv[0] << " file\n"; + return -1; + } + + auto* sts = new dp::SymtabCodeSource(argv[1]); + auto* co = new dp::CodeObject(sts); + + constexpr Dyninst::Address base_address{0UL}; + auto* patch_object = pa::PatchObject::create(co, base_address); + + auto* address_space = pa::AddrSpace::create(patch_object); + auto patch_manager = pa::PatchMgr::create(address_space); + + pa::Patcher patcher(patch_manager); + auto snippet = pa::Snippet::create(new NopSlide(10)); + + std::vector functions; + patch_object->funcs(std::back_inserter(functions)); + + for(auto* f : functions) { + std::cout << "Instrumenting " << f->name() << '\n'; + + std::vector entryPoints; + patch_manager->findPoints(pa::Scope(f), pa::Point::FuncEntry, std::back_inserter(entryPoints)); + + for(auto* point : entryPoints) { + std::cout << " point at " << point->addr() << '\n'; + patcher.add(pa::PushBackCommand::create(point, snippet)); + } + } + + patcher.commit(); +}