diff --git a/.gitignore b/.gitignore index 4469528..8826a2f 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ **/build +**/.cache diff --git a/instrument/CMakeLists.txt b/instrument/CMakeLists.txt new file mode 100644 index 0000000..3001a0b --- /dev/null +++ b/instrument/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.5) +project(interceptor) + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +add_subdirectory(target) +add_subdirectory(instrument) +add_subdirectory(app) diff --git a/instrument/app/CMakeLists.txt b/instrument/app/CMakeLists.txt new file mode 100644 index 0000000..cdb5065 --- /dev/null +++ b/instrument/app/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.5) +project(app) + +file(GLOB SOURCES "src/*.cpp") +add_executable(${PROJECT_NAME} ${SOURCES}) +target_link_libraries(${PROJECT_NAME} PRIVATE target) diff --git a/instrument/app/src/main.cpp b/instrument/app/src/main.cpp new file mode 100644 index 0000000..7d04d52 --- /dev/null +++ b/instrument/app/src/main.cpp @@ -0,0 +1,7 @@ +#include "A.h" + +int main(int argc, const char *argp[], const char *envp[]) { + A a; + a.method("test"); + return 0; +} diff --git a/instrument/compile_commands.json b/instrument/compile_commands.json new file mode 120000 index 0000000..25eb4b2 --- /dev/null +++ b/instrument/compile_commands.json @@ -0,0 +1 @@ +build/compile_commands.json \ No newline at end of file diff --git a/instrument/instrument/CMakeLists.txt b/instrument/instrument/CMakeLists.txt new file mode 100644 index 0000000..a003663 --- /dev/null +++ b/instrument/instrument/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.5) +project(instrument) + +file(GLOB SOURCES "src/*.cpp") +add_library(${PROJECT_NAME} SHARED ${SOURCES}) +add_dependencies(${PROJECT_NAME} target) +target_link_libraries(${PROJECT_NAME} + PRIVATE + dl +) diff --git a/instrument/instrument/src/intercept.cpp b/instrument/instrument/src/intercept.cpp new file mode 100644 index 0000000..bcd2833 --- /dev/null +++ b/instrument/instrument/src/intercept.cpp @@ -0,0 +1,31 @@ +#include +#include +#include +using std::cout; +using std::endl; + +class A; + +// Function pointer to store the original method +typedef void (*MethodType)(A *, const std::string &); +MethodType original_method = nullptr; + +extern "C" void _ZN1A6methodERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE(A *obj, const std::string &msg) { + cout << "Intercepted A::method with message: " << msg << endl; + + // Call the original method if it was found + if (original_method) { + original_method(obj, msg); + } +} + +// Initialization function +extern "C" void __attribute__((constructor)) init() { + cout << "Shared library has been preloaded." << endl; + + // Get the original A::method using dlsym and RTLD_NEXT + original_method = (MethodType)dlsym(RTLD_NEXT, "_ZN1A6methodERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE"); + if (!original_method) { + cout << "Error: unable to find original A::method" << endl; + } +} diff --git a/instrument/target/CMakeLists.txt b/instrument/target/CMakeLists.txt new file mode 100644 index 0000000..acc5f5e --- /dev/null +++ b/instrument/target/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.5) +project(target) + +file(GLOB SOURCES "src/*.cpp") +add_library(${PROJECT_NAME} SHARED ${SOURCES}) +target_include_directories(${PROJECT_NAME} + PUBLIC + include) diff --git a/instrument/target/include/A.h b/instrument/target/include/A.h new file mode 100644 index 0000000..73d6c0b --- /dev/null +++ b/instrument/target/include/A.h @@ -0,0 +1,7 @@ +#pragma once +#include + +class A { +public: + void method(const std::string& msg); +}; diff --git a/instrument/target/src/A.cpp b/instrument/target/src/A.cpp new file mode 100644 index 0000000..26d2b7d --- /dev/null +++ b/instrument/target/src/A.cpp @@ -0,0 +1,8 @@ +#include "A.h" +#include +using std::cout; +using std::endl; + +void A::method(const std::string &msg) { + cout << "original: " << msg << endl; +}