mirror of https://github.com/infosecn1nja/C3.git
Move logic implementation
parent
5d237e0f9b
commit
ef445129ef
|
@ -1,99 +1,89 @@
|
||||||
#include "StdAfx.h"
|
#include "stdafx.h"
|
||||||
|
#include "ChannelLinter.h"
|
||||||
|
|
||||||
#include "Core/Profiler.h"
|
#include "Core/Profiler.h"
|
||||||
|
|
||||||
namespace MWR::C3::Linter
|
namespace MWR::C3::Linter
|
||||||
{
|
{
|
||||||
/// @throws std::runtime_error if channel with given name was not registered
|
namespace
|
||||||
auto const& GetChannelInfo(std::string_view channelName)
|
|
||||||
{
|
{
|
||||||
return InterfaceFactory::Instance().Find<AbstractChannel>(channelName)->second;
|
/// @throws std::runtime_error if channel with given name was not registered
|
||||||
}
|
auto const& GetChannelInfo(std::string_view channelName)
|
||||||
|
|
||||||
/// template to avoid typing the whole name
|
|
||||||
template<class T>
|
|
||||||
auto GetChannelCapability(T const& channelInfo)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
auto ret = json::parse(channelInfo.m_Capability);
|
return InterfaceFactory::Instance().Find<AbstractChannel>(channelName)->second;
|
||||||
C3::Core::Profiler::Gateway::EnsureCreateExists(ret);
|
|
||||||
C3::Core::Profiler::Gateway::AddBuildInCommands(ret, true);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
catch (json::parse_error& e)
|
|
||||||
|
/// template to avoid typing the whole name
|
||||||
|
template<class T>
|
||||||
|
auto GetChannelCapability(T const& channelInfo)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Failed to parse channel's capability json. "s + e.what());
|
try
|
||||||
|
{
|
||||||
|
auto ret = json::parse(channelInfo.m_Capability);
|
||||||
|
C3::Core::Profiler::Gateway::EnsureCreateExists(ret);
|
||||||
|
C3::Core::Profiler::Gateway::AddBuildInCommands(ret, true);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
catch (json::parse_error & e)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to parse channel's capability json. "s + e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// template to avoid typing the whole name
|
||||||
|
template<class T>
|
||||||
|
auto MakeDevice(MWR::json const& createParams, const T& chInfo)
|
||||||
|
{
|
||||||
|
auto blob = MWR::C3::Core::Profiler::TranslateArguments(createParams);
|
||||||
|
auto channelBridge = std::make_shared<C3::Linter::MockDeviceBridge>(chInfo.m_Builder(blob));
|
||||||
|
channelBridge->OnAttach();
|
||||||
|
return channelBridge;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// template to avoid typing the whole name
|
void ChannelLinter::Process()
|
||||||
template<class T>
|
|
||||||
auto MakeDevice(MWR::json const& createParams, const T& chInfo)
|
|
||||||
{
|
{
|
||||||
auto blob = MWR::C3::Core::Profiler::TranslateArguments(createParams);
|
// select channel
|
||||||
auto channelBridge = std::make_shared<C3::Linter::MockDeviceBridge>(chInfo.m_Builder(blob));
|
auto const& chInfo = C3::Linter::GetChannelInfo(m_Config.m_ChannelName);
|
||||||
channelBridge->OnAttach();
|
|
||||||
return channelBridge;
|
// read create and prompt for arguments
|
||||||
|
auto capability = C3::Linter::GetChannelCapability(chInfo);
|
||||||
|
|
||||||
|
std::cout << "Create channel 1" << std::endl;
|
||||||
|
C3::Linter::Form form(capability.at("/create/arguments"_json_pointer));
|
||||||
|
auto createParams = form.FillForm(m_Config.m_ChannelArguments);
|
||||||
|
auto channel = C3::Linter::MakeDevice(createParams, chInfo);
|
||||||
|
|
||||||
|
if (m_Config.m_TestChannelIO)
|
||||||
|
{
|
||||||
|
std::cout << "Create channel 2" << std::endl;
|
||||||
|
auto const& ch2Args = m_Config.m_ComplementaryChannelArguments ? *m_Config.m_ComplementaryChannelArguments : form.GetComplementaryArgs(m_Config.m_ChannelArguments);
|
||||||
|
json createParams2 = form.FillForm(ch2Args);
|
||||||
|
auto ch2 = C3::Linter::MakeDevice(createParams2, chInfo);
|
||||||
|
|
||||||
|
// test write and read
|
||||||
|
auto data = ByteVector(ByteView(MWR::Utils::GenerateRandomString(64)));
|
||||||
|
channel->GetDevice()->OnSendToChannelInternal(data);
|
||||||
|
auto rcv = std::static_pointer_cast<C3::AbstractChannel>(ch2->GetDevice())->OnReceiveFromChannelInternal();
|
||||||
|
if (data != rcv.at(0))
|
||||||
|
throw std::exception("data sent and received mismatch");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_Config.m_Command)
|
||||||
|
{
|
||||||
|
auto& commandParams = *m_Config.m_Command;
|
||||||
|
auto commandIdL = std::stoi(commandParams.at(0));
|
||||||
|
auto commandId = static_cast<uint16_t>(commandIdL);
|
||||||
|
|
||||||
|
auto& commands = capability.at("commands");
|
||||||
|
auto commandIt = std::find_if(begin(commands), end(commands), [commandId](auto const& c) { return c.contains("id") && c["id"].get<uint16_t>() == commandId; });
|
||||||
|
if (commandIt == end(commands))
|
||||||
|
throw std::runtime_error("Failed to find a command with id: " + std::to_string(commandId));
|
||||||
|
|
||||||
|
C3::Linter::Form commandForm(commandIt->at("arguments"));
|
||||||
|
auto args = commandForm.FillForm({ begin(commandParams) + 1, end(commandParams) }); // +1 to omit command ID
|
||||||
|
auto x = ByteVector{}.Concat(commandId, C3::Core::Profiler::TranslateArguments(args));
|
||||||
|
channel->RunCommand(x);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Entry point of the application.
|
|
||||||
/// @param argc number of program arguments.
|
|
||||||
/// @param argv vector of program arguments.
|
|
||||||
int main(DWORD argc, char* argv[])
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using namespace MWR;
|
|
||||||
|
|
||||||
std::cout << "Custom Command and Control - Channel linter. BUILD: " << C3_BUILD_VERSION << std::endl;
|
|
||||||
C3::Linter::AppConfig context(argc, argv);
|
|
||||||
auto const& config = context.GetConfig();
|
|
||||||
|
|
||||||
// select channel
|
|
||||||
auto const& chInfo = C3::Linter::GetChannelInfo(config.m_ChannelName);
|
|
||||||
|
|
||||||
// read create and prompt for arguments
|
|
||||||
auto capability = C3::Linter::GetChannelCapability(chInfo);
|
|
||||||
|
|
||||||
std::cout << "Create channel 1" << std::endl;
|
|
||||||
C3::Linter::Form form(capability.at("/create/arguments"_json_pointer));
|
|
||||||
auto createParams = form.FillForm(config.m_ChannelArguments);
|
|
||||||
auto channel = C3::Linter::MakeDevice(createParams, chInfo);
|
|
||||||
|
|
||||||
if (config.m_TestChannelIO)
|
|
||||||
{
|
|
||||||
std::cout << "Create channel 2" << std::endl;
|
|
||||||
auto const& ch2Args = config.m_ComplementaryChannelArguments ? *config.m_ComplementaryChannelArguments : form.GetComplementaryArgs(config.m_ChannelArguments);
|
|
||||||
json createParams2 = form.FillForm(ch2Args);
|
|
||||||
auto ch2 = C3::Linter::MakeDevice(createParams2, chInfo);
|
|
||||||
|
|
||||||
// test write and read
|
|
||||||
auto data = ByteVector(ByteView(MWR::Utils::GenerateRandomString(64)));
|
|
||||||
channel->GetDevice()->OnSendToChannelInternal(data);
|
|
||||||
auto rcv = std::static_pointer_cast<C3::AbstractChannel>(ch2->GetDevice())->OnReceiveFromChannelInternal();
|
|
||||||
if (data != rcv.at(0))
|
|
||||||
throw std::exception("data sent and received mismatch");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.m_Command)
|
|
||||||
{
|
|
||||||
auto& commandParams = *config.m_Command;
|
|
||||||
auto commandIdL = std::stoi(commandParams.at(0));
|
|
||||||
auto commandId = static_cast<uint16_t>(commandIdL);
|
|
||||||
|
|
||||||
auto& commands = capability.at("commands");
|
|
||||||
auto commandIt = std::find_if(begin(commands), end(commands), [commandId](auto const& c) { return c.contains("id") && c["id"].get<uint16_t>() == commandId;});
|
|
||||||
if (commandIt == end(commands))
|
|
||||||
throw std::runtime_error("Failed to find a command with id: " + std::to_string(commandId));
|
|
||||||
|
|
||||||
C3::Linter::Form commandForm(commandIt->at("arguments"));
|
|
||||||
auto args = commandForm.FillForm({begin(commandParams) + 1, end(commandParams) }); // +1 to omit command ID
|
|
||||||
auto x = ByteVector{}.Concat(commandId, C3::Core::Profiler::TranslateArguments(args));
|
|
||||||
channel->RunCommand(x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (std::exception & e)
|
|
||||||
{
|
|
||||||
std::cerr << e.what() << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace MWR::C3::Linter
|
||||||
|
{
|
||||||
|
class ChannelLinter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ChannelLinter(AppConfig::Config const& config) : m_Config(config) {}
|
||||||
|
void Process();
|
||||||
|
|
||||||
|
private:
|
||||||
|
AppConfig::Config const& m_Config;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -296,6 +296,7 @@
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="ChannelLinter.h" />
|
||||||
<ClInclude Include="Form.h" />
|
<ClInclude Include="Form.h" />
|
||||||
<ClInclude Include="FormElement.hpp" />
|
<ClInclude Include="FormElement.hpp" />
|
||||||
<ClInclude Include="AppConfig.h" />
|
<ClInclude Include="AppConfig.h" />
|
||||||
|
@ -305,6 +306,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="ChannelLinter.cpp" />
|
<ClCompile Include="ChannelLinter.cpp" />
|
||||||
|
<ClCompile Include="ChannelLinterMain.cpp" />
|
||||||
<ClCompile Include="Form.cpp" />
|
<ClCompile Include="Form.cpp" />
|
||||||
<ClCompile Include="AppConfig.cpp" />
|
<ClCompile Include="AppConfig.cpp" />
|
||||||
<ClCompile Include="InputVector.cpp" />
|
<ClCompile Include="InputVector.cpp" />
|
||||||
|
|
|
@ -4,12 +4,13 @@
|
||||||
<Manifest Include="..\Common\MWR\WinTools\OsVersion.manifest" />
|
<Manifest Include="..\Common\MWR\WinTools\OsVersion.manifest" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="ChannelLinter.cpp" />
|
|
||||||
<ClCompile Include="Form.cpp" />
|
<ClCompile Include="Form.cpp" />
|
||||||
<ClCompile Include="InputVector.cpp" />
|
<ClCompile Include="InputVector.cpp" />
|
||||||
<ClCompile Include="StdAfx.cpp" />
|
<ClCompile Include="StdAfx.cpp" />
|
||||||
<ClCompile Include="MockDeviceBridge.cpp" />
|
<ClCompile Include="MockDeviceBridge.cpp" />
|
||||||
<ClCompile Include="AppConfig.cpp" />
|
<ClCompile Include="AppConfig.cpp" />
|
||||||
|
<ClCompile Include="ChannelLinterMain.cpp" />
|
||||||
|
<ClCompile Include="ChannelLinter.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Form.h" />
|
<ClInclude Include="Form.h" />
|
||||||
|
@ -18,5 +19,6 @@
|
||||||
<ClInclude Include="StdAfx.h" />
|
<ClInclude Include="StdAfx.h" />
|
||||||
<ClInclude Include="MockDeviceBridge.h" />
|
<ClInclude Include="MockDeviceBridge.h" />
|
||||||
<ClInclude Include="AppConfig.h" />
|
<ClInclude Include="AppConfig.h" />
|
||||||
|
<ClInclude Include="ChannelLinter.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -0,0 +1,21 @@
|
||||||
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
|
||||||
|
/// Entry point of the application.
|
||||||
|
/// @param argc number of program arguments.
|
||||||
|
/// @param argv vector of program arguments.
|
||||||
|
int main(DWORD argc, char* argv[])
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using namespace MWR;
|
||||||
|
|
||||||
|
std::cout << "Custom Command and Control - Channel linter. BUILD: " << C3_BUILD_VERSION << std::endl;
|
||||||
|
C3::Linter::AppConfig context(argc, argv);
|
||||||
|
auto const& config = context.GetConfig();
|
||||||
|
C3::Linter::ChannelLinter(config).Process();
|
||||||
|
}
|
||||||
|
catch (std::exception & e)
|
||||||
|
{
|
||||||
|
std::cerr << e.what() << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
|
@ -23,3 +23,4 @@ using json = nlohmann::json;
|
||||||
#include "FormElement.hpp"
|
#include "FormElement.hpp"
|
||||||
#include "Form.h"
|
#include "Form.h"
|
||||||
#include "MockDeviceBridge.h"
|
#include "MockDeviceBridge.h"
|
||||||
|
#include "ChannelLinter.h"
|
||||||
|
|
Loading…
Reference in New Issue