MCPcopy Create free account
hub / github.com/ReversecLabs/C3 / PerformCreateCommand

Method PerformCreateCommand

Src/Core/Profiler.cpp:675–731  ·  view source on GitHub ↗

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Source from the content-addressed store, hash-verified

673
674////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
675void FSecure::C3::Core::Profiler::Agent::PerformCreateCommand(json const& jCommandElement)
676{
677 auto profiler = m_Owner.lock();
678 if (!profiler)
679 return; // probably shutting down
680
681 auto gateRelay = profiler->m_Gateway->m_Gateway.lock();
682 if (!gateRelay)
683 return; // probably shutting down
684
685 auto route = gateRelay->FindRoute(m_Id);
686 if (!route)
687 throw std::runtime_error("Failed to find route to agent id = " + m_Id.ToString());
688
689 auto commandWithArguments = base64::decode<ByteVector>(jCommandElement["Command"]["ByteForm"].get<std::string>());
690
691 // check if command is a create device command -> then we need to assign deviceId and retreive its hash and repack commandWithArguments
692 // [CommandId{CreateAndAttachDevice}(u16)][NewDeviceId(u16)][NewDeviceTypeHash(HashT)][arguments]
693 auto commandReadView = ByteView{ commandWithArguments };
694 auto commandId = commandReadView.Read<std::uint16_t>();
695 auto const& createCommands = profiler->m_Gateway->m_CreateCommands;
696 auto command = std::find_if(createCommands.cbegin(), createCommands.cend(), [commandId](Gateway::CreateCommand const& cc) { return cc.m_IsDevice && cc.m_Id == commandId; });
697
698 // this function will only suport create commands
699 if (command == createCommands.cend())
700 return;
701
702 // it is a create command
703 DeviceId newDeviceId = ++m_LastDeviceId;
704 ByteVector repacked;
705 repacked.Write(Command::AddDevice, newDeviceId, command->m_IsNegotiableChannel, command->m_Hash);
706 if (auto binder = profiler->GetBinderTo(command->m_Hash); binder && command->m_IsDevice) // peripheral, check if payload is needed.
707 {
708 auto connector = profiler->m_Gateway->m_Gateway.lock()->GetConnector(binder);
709 if (!connector)
710 throw std::runtime_error{ "Connector for requested peripheral is closed" };
711
712 auto updatedArguments = connector->PeripheralCreationCommand(ByteVector::Create(RouteId{ route->m_RouteId.GetAgentId(), newDeviceId }), commandReadView, m_IsX64);
713 repacked.Concat(updatedArguments);
714 }
715 else
716 {
717 repacked.Concat(commandReadView);
718 }
719
720 commandWithArguments = repacked;
721
722 auto outgoingChannel = route->m_Channel.lock();
723 if (!outgoingChannel)
724 throw std::runtime_error("Tried to send command through dead channel"); // TODO maybe try through different route
725
726 // push json with startup arguments to some container, use it if channel is created.
727 AddScheduledDevice(newDeviceId, jCommandElement["Command"]);
728
729 auto query = ProceduresG2X::RunCommandOnAgentQuery::Create(route->m_RouteId, gateRelay->m_Signature, m_EncryptionKey, gateRelay->m_DecryptionKey, commandWithArguments);
730 gateRelay->LockAndSendPacket(query->ComposeQueryPacket(), outgoingChannel);
731}
732

Callers

nothing calls this directly

Calls 15

IsProcess64bitFunction · 0.85
FindRouteMethod · 0.80
GetBinderToMethod · 0.80
LockAndSendPacketMethod · 0.80
GetDidMethod · 0.80
TurnOnConnectorMethod · 0.80
lockMethod · 0.45
ToStringMethod · 0.45
cbeginMethod · 0.45
cendMethod · 0.45
WriteMethod · 0.45
GetConnectorMethod · 0.45

Tested by

no test coverage detected