diff --git a/data/layout.ini b/data/layout.ini deleted file mode 100644 index ed8595c..0000000 --- a/data/layout.ini +++ /dev/null @@ -1,65 +0,0 @@ -[Window][Conquest] -Pos=0,0 -Size=1908,999 -Collapsed=0 - -[Window][Dear ImGui Demo] -Pos=0,518 -Size=954,481 -Collapsed=0 -DockId=0x00000006,0 - -[Window][Debug##Default] -Pos=60,60 -Size=400,400 -Collapsed=0 - -[Window][Example: Documents] -Pos=0,33 -Size=1050,966 -Collapsed=0 -DockId=0x00000005,0 - -[Window][Dear ImGui Style Editor] -Pos=1346,33 -Size=562,966 -Collapsed=0 -DockId=0x00000004,0 - -[Window][Example: Assets Browser] -Pos=60,60 -Size=800,480 -Collapsed=0 - -[Window][Example: Long text display] -Pos=60,60 -Size=520,600 -Collapsed=0 - -[Window][Dear ImGui Demo/ResizableChild_478B81A3] -IsChild=1 -Size=1857,115 - -[Window][Dear ImGui Demo/Red_BEEF922B] -IsChild=1 -Size=200,100 - -[Window][Info Window] -Pos=956,33 -Size=952,966 -Collapsed=0 -DockId=0x00000002,0 - -[Table][0xB6880529,2] -RefScale=27 -Column 0 Sort=0v - -[Docking][Data] -DockSpace ID=0x3674675E Window=0x538FB738 Pos=0,33 Size=1908,966 Split=X Selected=0x5E5F7166 - DockNode ID=0x00000003 Parent=0x3674675E SizeRef=0,0 Split=X Selected=0x5E5F7166 - DockNode ID=0x00000001 Parent=0x00000003 SizeRef=954,966 Split=Y Selected=0x5E5F7166 - DockNode ID=0x00000005 Parent=0x00000001 SizeRef=954,483 CentralNode=1 - DockNode ID=0x00000006 Parent=0x00000001 SizeRef=954,481 Selected=0x5E5F7166 - DockNode ID=0x00000002 Parent=0x00000003 SizeRef=952,966 Selected=0x7DB93FD0 - DockNode ID=0x00000004 Parent=0x3674675E SizeRef=562,966 Selected=0x3EEA4247 - diff --git a/src/client/layout.ini b/src/client/layout.ini new file mode 100644 index 0000000..5447df3 --- /dev/null +++ b/src/client/layout.ini @@ -0,0 +1,124 @@ +[Window][Conquest] +Size=2868,1695 +Collapsed=0 + +[Window][Dear ImGui Demo] +Pos=956,43 +Size=942,946 +Collapsed=0 +DockId=0x00000002,0 + +[Window][Debug##Default] +Pos=1005,292 +Size=383,470 +Collapsed=0 + +[Window][Example: Documents] +Pos=0,33 +Size=1050,966 +Collapsed=0 +DockId=0x00000003,0 + +[Window][Dear ImGui Style Editor] +Pos=1346,33 +Size=562,966 +Collapsed=0 +DockId=0x00000004,0 + +[Window][Example: Assets Browser] +Pos=956,43 +Size=942,460 +Collapsed=0 +DockId=0x00000009,0 + +[Window][Example: Long text display] +Pos=60,60 +Size=520,600 +Collapsed=0 + +[Window][Dear ImGui Demo/ResizableChild_478B81A3] +IsChild=1 +Size=1857,115 + +[Window][Dear ImGui Demo/Red_BEEF922B] +IsChild=1 +Size=200,100 + +[Window][Info Window] +Pos=953,33 +Size=955,410 +Collapsed=0 +DockId=0x00000005,0 + +[Window][INFORMATION] +Pos=953,34 +Size=1914,403 +Collapsed=0 +DockId=0x00000007,0 + +[Window][Dockspace] +Pos=0,0 +Size=1908,999 +Collapsed=0 + +[Window][Dear ImGui Demo/##Basket_87771727] +IsChild=1 +Size=878,540 + +[Window][Dear ImGui Demo/##Basket_529977C1] +IsChild=1 +Size=878,540 + +[Window][Dear ImGui Demo/##Basket_8B4CCC3E] +IsChild=1 +Size=878,540 + +[Window][Dear ImGui Demo/0_E1BADA21] +IsChild=1 +Size=414,540 + +[Window][Dear ImGui Demo/##Basket_956142B6] +IsChild=1 +Size=878,540 + +[Window][Agents [Table View]] +Pos=10,43 +Size=944,946 +Collapsed=0 +DockId=0x00000001,0 + +[Window][Example: Console] +Pos=1019,231 +Size=520,600 +Collapsed=0 + +[Window][Example: Custom rendering] +Pos=862,167 +Size=623,582 +Collapsed=0 + +[Window][Agents [Graph View]] +Pos=10,43 +Size=944,946 +Collapsed=0 +DockId=0x00000001,0 + +[Table][0xB6880529,2] +RefScale=27 +Column 0 Sort=0v + +[Docking][Data] +DockSpace ID=0x1A591E13 Pos=1,34 Size=2866,1660 Split=Y + DockNode ID=0x00000005 Parent=0x1A591E13 SizeRef=955,410 Selected=0x7DB93FD0 + DockNode ID=0x00000006 Parent=0x1A591E13 SizeRef=955,554 CentralNode=1 Selected=0x5E5F7166 +DockSpace ID=0x3674675E Pos=0,33 Size=2868,1662 Split=X Selected=0x5E5F7166 + DockNode ID=0x00000003 Parent=0x3674675E SizeRef=0,0 CentralNode=1 Selected=0x5E5F7166 + DockNode ID=0x00000004 Parent=0x3674675E SizeRef=562,966 Selected=0x3EEA4247 +DockSpace ID=0x85940918 Window=0x260A4489 Pos=10,43 Size=1888,946 Split=Y + DockNode ID=0x00000009 Parent=0x85940918 SizeRef=1868,460 Selected=0xB38EC866 + DockNode ID=0x0000000A Parent=0x85940918 SizeRef=1868,464 Split=Y + DockNode ID=0x00000007 Parent=0x0000000A SizeRef=954,403 Selected=0x526650BD + DockNode ID=0x00000008 Parent=0x0000000A SizeRef=954,559 Split=X Selected=0xB38EC866 + DockNode ID=0x00000001 Parent=0x00000008 SizeRef=944,484 CentralNode=1 Selected=0xB38EC866 + DockNode ID=0x00000002 Parent=0x00000008 SizeRef=942,484 Selected=0x5E5F7166 + diff --git a/src/client/main.nim b/src/client/main.nim index 73d9e73..4483424 100644 --- a/src/client/main.nim +++ b/src/client/main.nim @@ -1,10 +1,19 @@ +import tables import ./utils/appImGui +import ./views/[dockspace, agents] proc main() = var app = createApp(1024, 800, imnodes = true, title = "Conquest", docking = true) defer: app.destroyApp() - var showConquest = true + var + views: Table[string, ptr bool] + showConquest = true + showAgentsTable = true + showAgentsGraph = false + + views["Agents [Table View]"] = addr showAgentsTable + views["Agents [Graph View]"] = addr showAgentsGraph let io = igGetIO() @@ -12,62 +21,23 @@ proc main() = while not app.handle.windowShouldClose: pollEvents() + # Reduce rendering activity when window is minimized if app.isIconifySleep(): continue newFrame() - # Create fullscreen dockspace as the base where all other windows are placed in - block: - var - windowClass = ImGuiWindowClass_ImGuiWindowClass() - dockspaceFlags: ImGuiDockNodeFlags = ImGuiDockNodeFlags_None.int32 - windowFlags: ImGuiWindow_Flags = ImGuiWindowFlags_MenuBar.int32 or ImGuiWindowFlags_NoDocking.int32 - - var vp = igGetMainViewport() - igSetNextWindowPos(vp.WorkPos, ImGui_Cond_None.int32, vec2(0.0f, 0.0f)) - igSetNextWindowSize(vp.WorkSize, 0) - igSetNextWindowViewport(vp.ID) - igPushStyleVar_Float(ImGuiStyleVar_WindowRounding.int32, 0.0f) - igPushStyleVar_Float(ImGuiStyleVar_WindowBorderSize.int32, 0.0f) - windowFlags = windowFlags or ( - ImGuiWindowFlags_NoTitleBar.int32 or - ImGuiWindowFlags_NoCollapse.int32 or - ImGuiWindowFlags_NoResize.int32 or - ImGuiWindowFlags_NoMove.int32 or - ImGuiWindowFlags_NoBringToFrontOnFocus.int32 or - ImGuiWindowFlags_NoNavFocus.int32 - ) + # UI components + Dockspace().draw(addr showConquest, views) + + if showAgentsTable: + AgentsTable("Agents [Table View]").draw(addr showAgentsTable) - # Add padding - igPushStyleVar_Vec2(ImGuiStyleVar_WindowPadding.int32, vec2(0.0f, 0.0f)) - - igBegin("Conquest", addr showConquest, windowFlags) - defer: igEnd() - - igPopStyleVar(3) - - # Create dockspace - igDockSpace(igGetID_Str("Conquest-Dockspace"), vec2(0.0f, 0.0f), dockspaceFlags, windowClass) - - # Create Dockspace menu bar - if igBeginMenuBar(): - if igBeginMenu("Options", true): - - if igMenuItem("Exit", nil, false, (addr showConquest) != nil): - showConquest = false - igEndMenu() - igEndMenuBar() + if showAgentsGraph: + AgentsTable("Agents [Graph View]").draw(addr showAgentsGraph) - # Components and widgets igShowDemoWindow(nil) - block: - igBegin("Info Window", nil, 0) - defer: igEnd() - - igText(cstring(ICON_FA_USER_SHIELD & " " & getFrontendVersionString())) - # render app.render() diff --git a/src/client/utils/appImGui.nim b/src/client/utils/appImGui.nim index dc240b4..eccbc12 100644 --- a/src/client/utils/appImGui.nim +++ b/src/client/utils/appImGui.nim @@ -35,21 +35,6 @@ type # Forward definitions proc setTheme*(this: var Window, theme: Theme): string -# Sections -const - scWindow = "Window" - startupPosX = "startupPosX" - startupPosY = "startupPosY" - viewportWidth = "viewportWidth" - viewportHeight = "viewportHeigth" - colBGx = "colBGx" - colBGy = "colBGy" - colBGz = "colBGz" - colBGw = "colBGw" - theme = "theme" - scImage = "Image" - imageSaveFormatIndex = "imageSaveFormatIndex" - # Main setup function proc createApp*(w: cint = 1024, h: cint = 900, imnodes: bool = false, implot: bool = false, implot3d = false, title: string = "ImGui window", docking: bool = true): Window = doAssert glfwInit() @@ -153,7 +138,7 @@ proc createApp*(w: cint = 1024, h: cint = 900, imnodes: bool = false, implot: bo result.handle = glfwWin var pio = igGetIO() - pio.IniFileName = fmt"{CONQUEST_ROOT}/data/layout.ini" + pio.IniFileName = fmt"{CONQUEST_ROOT}/src/client/layout.ini".cstring setTheme(Dark) discard setupFonts() result.showWindowDelay = 2 diff --git a/src/client/views/agents.nim b/src/client/views/agents.nim new file mode 100644 index 0000000..7dd6d44 --- /dev/null +++ b/src/client/views/agents.nim @@ -0,0 +1,58 @@ +import times +import imguin/[cimgui, glfw_opengl, simple] +import ../utils/appImGui +import ../../common/[types] + +type + AgentsTableComponent = ref object of RootObj + title: string + agents: seq[Agent] + + +let exampleAgents: seq[Agent] = @[ + Agent( + agentId: "DEADBEEF", + listenerId: "L1234567", + username: "alice", + hostname: "DESKTOP-01", + domain: "CORP", + ip: "192.168.1.10", + os: "Windows 10", + process: "explorer.exe", + pid: 2340, + elevated: true, + sleep: 60, + tasks: @[], + firstCheckin: now() - initDuration(hours = 2), + latestCheckin: now(), + sessionKey: [byte 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31] + ), + Agent( + agentId: "FACEDEAD", + listenerId: "L7654321", + username: "bob", + hostname: "LAPTOP-02", + domain: "SALES", + ip: "10.0.0.5", + os: "Windows 11", + process: "cmd.exe", + pid: 4567, + elevated: false, + sleep: 120, + tasks: @[], + firstCheckin: now() - initDuration(hours = 1, minutes = 30), + latestCheckin: now() - initDuration(minutes = 5), + sessionKey: [byte 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] + ) +] + +proc AgentsTable*(title: string): AgentsTableComponent = + result = new AgentsTableComponent + result.title = title + result.agents = exampleAgents + +proc draw*(component: AgentsTableComponent, showComponent: ptr bool) = + igBegin(component.title, showComponent, 0) + defer: igEnd() + + igText("asd") diff --git a/src/client/views/dockspace.nim b/src/client/views/dockspace.nim new file mode 100644 index 0000000..5510d59 --- /dev/null +++ b/src/client/views/dockspace.nim @@ -0,0 +1,59 @@ +import tables +import imguin/[cimgui, glfw_opengl, simple] +import ../utils/appImGui + +type + DockspaceComponent* = ref object of RootObj + windowClass: ptr ImGuiWindowClass + dockspaceFlags: ImGuiDockNodeFlags + windowFlags: ImGuiWindow_Flags + +proc Dockspace*(): DockspaceComponent = + result = new DockspaceComponent + result.windowClass = ImGuiWindowClass_ImGuiWindowClass() + result.dockspaceFlags = ImGuiDockNodeFlags_None.int32 + result.windowFlags = ImGuiWindowFlags_MenuBar.int32 or ImGuiWindowFlags_NoDocking.int32 + +proc draw*(component: DockspaceComponent, showComponent: ptr bool, views: Table[string, ptr bool]) = + + var vp = igGetMainViewport() + igSetNextWindowPos(vp.WorkPos, ImGui_Cond_None.int32, vec2(0.0f, 0.0f)) + igSetNextWindowSize(vp.WorkSize, 0) + igSetNextWindowViewport(vp.ID) + igPushStyleVar_Float(ImGuiStyleVar_WindowRounding.int32, 0.0f) + igPushStyleVar_Float(ImGuiStyleVar_WindowBorderSize.int32, 0.0f) + component.windowFlags = component.windowFlags or ( + ImGuiWindowFlags_NoTitleBar.int32 or + ImGuiWindowFlags_NoCollapse.int32 or + ImGuiWindowFlags_NoResize.int32 or + ImGuiWindowFlags_NoMove.int32 or + ImGuiWindowFlags_NoBringToFrontOnFocus.int32 or + ImGuiWindowFlags_NoNavFocus.int32 + ) + + # Add padding + igPushStyleVar_Vec2(ImGuiStyleVar_WindowPadding.int32, vec2(10.0f, 10.0f)) + + igBegin("Dockspace", showComponent, component.windowFlags) + defer: igEnd() + + igPopStyleVar(3) + + # Create dockspace + igDockSpace(igGetID_Str("Dockspace"), vec2(0.0f, 0.0f), component.dockspaceFlags, component.windowClass) + + # Create menu bar + if igBeginMenuBar(): + if igBeginMenu("Options", true): + if igMenuItem("Exit", nil, false, (addr showComponent) != nil): + showComponent[] = false + igEndMenu() + + if igBeginMenu("Views", true): + # Create a menu item to toggle each of the main views of the application + for view, showView in views: + if igMenuItem(view, nil, showView[], showView != nil): + showView[] = not showView[] + igEndMenu() + + igEndMenuBar() \ No newline at end of file