Improved module selection in payload generation modal with tooltips from the module manager.

This commit is contained in:
Jakob Friedl
2025-09-27 12:36:59 +02:00
parent 9de4ac4838
commit 933a72f920
13 changed files with 55 additions and 25 deletions

View File

@@ -32,14 +32,16 @@ proc draw*(component: ListenersTableComponent, showComponent: ptr bool, ws: WebS
if igButton("Start Listener", vec2(0.0f, 0.0f)):
igOpenPopup_str("Start Listener", ImGui_PopupFlags_None.int32)
igSameLine(0.0f, textSpacing)
# Payload generation modal
# Payload generation modal (only enabled when at least one listener is active)
igBeginDisabled(component.listeners.len() <= 0)
if igButton("Generate Payload", vec2(0.0f, 0.0f)):
igOpenPopup_str("Generate Payload", ImGui_PopupFlags_None.int32)
igEndDisabled()
let listener = component.startListenerModal.draw()
if listener != nil:
ws.sendStartListener(listener)
component.listeners.add(listener)
component.generatePayloadModal.draw(component.listeners)

View File

@@ -2,6 +2,7 @@ import strutils, sequtils
import imguin/[cimgui, glfw_opengl, simple]
import ../../utils/[appImGui, colors]
import ../../../common/[types, profile, utils]
import ../../../modules/manager
import ../widgets/dualListSelection
type
@@ -11,7 +12,7 @@ type
sleepMask: int32
spoofStack: bool
sleepMaskTechniques: seq[string]
moduleSelection: DualListSelectionComponent[ModuleType]
moduleSelection: DualListSelectionComponent[Module]
proc AgentModal*(): AgentModalComponent =
result = new AgentModalComponent
@@ -23,14 +24,17 @@ proc AgentModal*(): AgentModalComponent =
for technique in SleepObfuscationTechnique.low .. SleepObfuscationTechnique.high:
result.sleepMaskTechniques.add($technique)
var modules: seq[ModuleType]
for module in ModuleType:
modules.add(module)
let modules = getModules()
proc moduleName(module: Module): string =
return module.name
proc moduleDesc(module: Module): string =
result = module.description & "\nModule commands:\n"
for cmd in module.commands:
result &= " - " & cmd.name & "\n"
proc compareModules(x, y: Module): int =
return cmp(x.name, y.name)
proc moduleName(module: ModuleType): string =
return ($module).split("_")[1..^1].mapIt(it.toLowerAscii().capitalizeAscii()).join("")
result.moduleSelection = DualListSelection(modules, moduleName)
result.moduleSelection = DualListSelection(modules, moduleName, compareModules, moduleDesc)
proc resetModalValues(component: AgentModalComponent) =
component.listener = 0
@@ -119,7 +123,7 @@ proc draw*(component: AgentModalComponent, listeners: seq[UIListener]) =
# Iterate over modules
var module: uint32 = 0
for m in component.moduleSelection.items[1]:
module = module or uint32(m)
module = module or uint32(m.moduleType)
echo module
component.resetModalValues()

View File

@@ -1,6 +1,6 @@
import strutils, sequtils, algorithm
import imguin/[cimgui, glfw_opengl, simple]
import ../../utils/[appImGui, colors]
import ../../utils/[appImGui, colors, utils]
import ../../../common/[types, utils]
type
@@ -8,36 +8,40 @@ type
items*: array[2, seq[T]]
selection: array[2, ptr ImGuiSelectionBasicStorage]
display: proc(item: T): string
compare: proc(x, y: T): int
tooltip: proc(item: T): string
proc defaultDisplay[T](item: T): string =
return $item
proc DualListSelection*[T](items: seq[T], display: proc(item: T): string = defaultDisplay): DualListSelectionComponent[T] =
proc DualListSelection*[T](items: seq[T], display: proc(item: T): string = defaultDisplay, compare: proc(x, y: T): int, tooltip: proc(item: T): string = nil): DualListSelectionComponent[T] =
result = new DualListSelectionComponent[T]
result.items[0] = items
result.items[1] = @[]
result.selection[0] = ImGuiSelectionBasicStorage_ImGuiSelectionBasicStorage()
result.selection[1] = ImGuiSelectionBasicStorage_ImGuiSelectionBasicStorage()
result.display = display
result.compare = compare
result.tooltip = tooltip
proc moveAll[T](component: DualListSelectionComponent[T], src, dst: int) =
for m in component.items[src]:
component.items[dst].add(m)
component.items[dst].sort()
component.items[dst].sort(component.compare)
component.items[src].setLen(0)
ImGuiSelectionBasicStorage_Swap(component.selection[src], component.selection[dst])
ImGuiSelectionBasicStorage_Clear(component.selection[src])
proc moveSelection[T](component: DualListSelectionComponent[T], src, dst: int) =
var keep: seq[ModuleType]
var keep: seq[T]
for i in 0 ..< component.items[src].len():
let item = component.items[src][i]
if not component.selection[src].ImGuiSelectionBasicStorage_Contains(cast[ImGuiID](i)):
keep.add(item)
continue
component.items[dst].add(item)
component.items[dst].sort()
component.items[dst].sort(component.compare)
component.items[src] = keep
ImGuiSelectionBasicStorage_Swap(component.selection[src], component.selection[dst])
@@ -83,6 +87,9 @@ proc draw*[T](component: DualListSelectionComponent[T]) =
var isSelected = ImGuiSelectionBasicStorage_Contains(selection, cast[ImGuiID](row))
igSetNextItemSelectionUserData(row)
discard igSelectable_Bool(component.display(modules[row]), isSelected, ImGuiSelectableFlags_AllowDoubleClick.int32, vec2(0.0f, 0.0f))
if not component.tooltip.isNil():
setTooltip(component.tooltip(modules[row]))
# Move on Enter and double-click
if igIsItemFocused():
@@ -134,6 +141,9 @@ proc draw*[T](component: DualListSelectionComponent[T]) =
igSetNextItemSelectionUserData(row)
discard igSelectable_Bool(component.display(modules[row]), isSelected, ImGuiSelectableFlags_AllowDoubleClick.int32, vec2(0.0f, 0.0f))
if not component.tooltip.isNil():
setTooltip(component.tooltip(modules[row]))
# Move on Enter and double-click
if igIsItemFocused():
if igIsKeyPressed_Bool(ImGuiKey_Enter, false) or igIsKeyPressed_Bool(ImGuiKey_KeypadEnter, false):