Skip to content

Commit

Permalink
Add backing parameter logging
Browse files Browse the repository at this point in the history
  • Loading branch information
Manuel Bischof committed Jul 24, 2023
1 parent 19cae96 commit 7e74ae6
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 4 deletions.
7 changes: 7 additions & 0 deletions plugins/apitracing/src/lib/ApiTracing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ namespace ApiTracing
throw std::runtime_error("Unknown operating system.");
}
}

// Hook process if it's already running
auto runningProcesses = pluginInterface->getRunningProcesses();
for (const auto& processInformation : *runningProcesses)
{
tracer->traceProcess(processInformation);
}
}

void ApiTracing::unload()
Expand Down
13 changes: 13 additions & 0 deletions plugins/apitracing/src/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,20 @@ set_property(TARGET yaml-cpp PROPERTY POSITION_INDEPENDENT_CODE TRUE)
target_compile_definitions(apitracing-obj PUBLIC YAML_CPP_SUPPORT)
target_link_libraries(apitracing-obj PUBLIC yaml-cpp)

# Setup json-cpp

FetchContent_Declare(
jsoncpp
GIT_REPOSITORY https://github.com/open-source-parsers/jsoncpp.git
GIT_TAG 1.9.5
)
FetchContent_MakeAvailable(jsoncpp)
set_property(TARGET jsoncpp_static PROPERTY POSITION_INDEPENDENT_CODE TRUE)
target_link_libraries(apitracing-obj PUBLIC jsoncpp_static)

# Add public vmicore headers

add_subdirectory("${VMICORE_DIRECTORY_ROOT}/src/include" "${CMAKE_CURRENT_BINARY_DIR}/vmicore-public-headers")
target_link_libraries(apitracing-obj PUBLIC vmicore-public-headers)


48 changes: 44 additions & 4 deletions plugins/apitracing/src/lib/FunctionHook.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "FunctionHook.h"
#include "Filenames.h"
#include "json/writer.h"
#include <algorithm>
#include <fmt/core.h>
#include <utility>
Expand Down Expand Up @@ -56,24 +57,63 @@ namespace ApiTracing
}

auto extractedParameters = extractor->extractParameters(event, parameterInformation);
logParameterList(extractedParameters);

Json::Value root;
Json::FastWriter fast;
root["functionName"] = functionName;
auto json = getParameterListAsJson(extractedParameters, root);
std::string unformattedTraces = fast.write(json);

logger->info(
"Monitored function parameters",
{{"ProcessDtb", event.getCr3()}, {"ThreadID", event.getGs()}, {"Traces", unformattedTraces}});
}
return BpResponse::Continue;
}

Json::Value
FunctionHook::getParameterListAsJson(const std::vector<ExtractedParameterInformation>& extractedParameters,
Json::Value root)
{
for (const auto& extractedParameter : extractedParameters)
{
Json::Value parameter;
std::visit(
[&parameter = parameter, &extractedParameter = extractedParameter](auto&& arg)
{
parameter["name"] = extractedParameter.name;
parameter["value"] = std::forward<std::remove_reference_t<decltype(arg)>>(arg);
},
extractedParameter.data);

if (!extractedParameter.backingParameters.empty())
{
auto backingParameters = getParameterListAsJson(extractedParameter.backingParameters, parameter);
parameter["backingParameters"] = backingParameters;
}
// push_back here
root["parameters"].append(parameter);
}
return root;
}

void FunctionHook::logParameterList(const std::vector<ExtractedParameterInformation>& extractedParameters)
{
for (const auto& extractedParameter : extractedParameters)
{
std::visit(
[&extractedParameter = extractedParameter, &logger = logger](auto&& arg)
[&functionName = functionName, &extractedParameter = extractedParameter, &logger = logger](auto&& arg)
{
logger->info("Parameter",
{{"Name", extractedParameter.name},
{{"Function", functionName},
{"Name", extractedParameter.name},
{"Value", std::forward<std::remove_reference_t<decltype(arg)>>(arg)}});
},
extractedParameter.data);
// TODO: Log backing parameters
if (!extractedParameter.backingParameters.empty())
{
logParameterList(extractedParameter.backingParameters);
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions plugins/apitracing/src/lib/FunctionHook.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "ConstantDefinitions.h"
#include "config/FunctionDefinitions.h"
#include "os/Extractor.h"
#include "json/value.h"
#include <vmicore/io/ILogger.h>
#include <vmicore/plugins/PluginInterface.h>
#include <vmicore/vmi/IBreakpoint.h>
Expand Down Expand Up @@ -37,6 +38,9 @@ namespace ApiTracing
VmiCore::Plugin::PluginInterface* pluginInterface;
std::unique_ptr<VmiCore::ILogger> logger;

Json::Value getParameterListAsJson(const std::vector<ExtractedParameterInformation>& extractedParameters,
Json::Value root);

void logParameterList(const std::vector<ExtractedParameterInformation>& extractedParameters);
};
}
Expand Down
20 changes: 20 additions & 0 deletions plugins/apitracing/test/FunctionHook_UnitTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ namespace ApiTracing
std::shared_ptr<MockIntrospectionAPI> introspectionAPI = std::make_shared<NiceMock<MockIntrospectionAPI>>();
std::shared_ptr<MockExtractor> extractor = std::make_shared<NiceMock<MockExtractor>>();
std::shared_ptr<MockInterruptEvent> interruptEvent = std::make_shared<NiceMock<MockInterruptEvent>>();
std::vector<ExtractedParameterInformation> extractedParameterInformation{
{.name = "TestInt0", .data = 0},
{.name = "TestInt1",
.data = 3,
.backingParameters = {{.name = "TestInt2", .data = 4}, {.name = "TestString1", .data = "A"}}}};

static constexpr VmiCore::addr_t testModuleBase = 0x420;
static constexpr VmiCore::addr_t testDtb = 0x1337;
Expand Down Expand Up @@ -72,8 +77,23 @@ namespace ApiTracing
std::make_shared<std::vector<ParameterInformation>>(
std::vector<ParameterInformation>{{.name = "TestParameter"}}),
pluginInterface.get()};
functionHook.hookFunction(testModuleBase, testDtb);
EXPECT_CALL(*extractor, extractParameters).Times(1);

functionHook.hookCallback(*interruptEvent);
}

TEST_F(FunctionHookTestFixture, hookCallBack_functionHookWithParameters_logsParameters)
{
FunctionHook functionHook{"TestModule",
"TestFunction",
extractor,
introspectionAPI,
std::make_shared<std::vector<ParameterInformation>>(
std::vector<ParameterInformation>{{.name = "TestParameter"}}),
pluginInterface.get()};
functionHook.hookFunction(testModuleBase, testDtb);
ON_CALL(*extractor, extractParameters).WillByDefault(Return(extractedParameterInformation));
EXPECT_CALL(*extractor, extractParameters).Times(1);

functionHook.hookCallback(*interruptEvent);
Expand Down

0 comments on commit 7e74ae6

Please sign in to comment.