Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add patchAPI #46

Merged
merged 1 commit into from
Jan 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
46 changes: 46 additions & 0 deletions patchAPI/CFGMaker.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include "CFG.h"
#include "CFGMaker.h"
#include "PatchCFG.h"

#include <iostream>

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<pa::PatchFunction*> all_funcs;
obj->funcs(back_inserter(all_funcs));

// suppress compiler warning
(void)all_funcs;
}
39 changes: 39 additions & 0 deletions patchAPI/CFGTraversal.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include "CFG.h"
#include "CodeObject.h"
#include "PatchCFG.h"

#include <iostream>
#include <vector>

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<pa::PatchFunction*> 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';
}
}
29 changes: 29 additions & 0 deletions patchAPI/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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)
62 changes: 62 additions & 0 deletions patchAPI/PatchModifier.cpp
Original file line number Diff line number Diff line change
@@ -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 <iostream>
#include <vector>

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<pa::PatchFunction*> 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<pa::PatchFunction*> 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);
}
53 changes: 53 additions & 0 deletions patchAPI/PointMaker.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include "CFG.h"
#include "CFGMaker.h"
#include "PatchCFG.h"
#include "PatchMgr.h"
#include "PatchCommon.h"

#include <iostream>

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<pa::PatchFunction*> functions;
patch_object->funcs(std::back_inserter(functions));

for(auto* f : functions) {
std::vector<pa::Point*> entryPoints;
patch_manager->findPoints(pa::Scope(f), pa::Point::FuncEntry, std::back_inserter(entryPoints));
}
}
21 changes: 21 additions & 0 deletions patchAPI/addressSpace.cpp
Original file line number Diff line number Diff line change
@@ -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; }
};
42 changes: 42 additions & 0 deletions patchAPI/findingPoints.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include "AddrSpace.h"
#include "CFG.h"
#include "CodeObject.h"
#include "PatchCFG.h"
#include "PatchMgr.h"
#include "PatchObject.h"

#include <iostream>
#include <vector>

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<pa::PatchFunction*> functions;
patch_object->funcs(std::back_inserter(functions));

for(auto* f : functions) {
std::vector<pa::Point*> 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";
}
}
67 changes: 67 additions & 0 deletions patchAPI/nopPatching.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#include "AddrSpace.h"
#include "CFG.h"
#include "CodeObject.h"
#include "PatchCFG.h"
#include "PatchMgr.h"
#include "PatchObject.h"

#include <iostream>
#include <vector>

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<pa::PatchFunction*> functions;
patch_object->funcs(std::back_inserter(functions));

for(auto* f : functions) {
std::cout << "Instrumenting " << f->name() << '\n';

std::vector<pa::Point*> 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();
}