#include "GUI.h" #include #include #include #include #include #include #include #include #include #include "Userspace.h" void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) { if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { glfwSetWindowShouldClose(window, true); return; } } GUI::GUI(Userspace& user) :m_Userspace(user) { if(!glfwInit()) exit(1); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); CreateWindow(); } void GUI::CreateWindow() { m_Window = glfwCreateWindow(1200, 800, "CPUSecX86", NULL, NULL); if(!m_Window) { glfwTerminate(); return; } glfwMakeContextCurrent(m_Window); glfwSetKeyCallback(m_Window, key_callback); ImGui::CreateContext(); int version = gladLoadGL(); std::cout << "OpenGL Version: " << std::dec << version << std::endl; ImGui_ImplGlfw_InitForOpenGL(m_Window, true); ImGui_ImplOpenGL3_Init("#version 460"); ImGuiIO& io = ImGui::GetIO(); io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; io.FontGlobalScale = 1.5f; } void GUI::Run() { while (!glfwWindowShouldClose(m_Window)) { glfwPollEvents(); ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); DockingSetup(); ControlGUI(); DebugInfoGUI(); static MemoryEditor process_mem; size_t data_size = 0x10000; process_mem.DrawWindow("Process Memory", m_Userspace.RetrieveMemory(), data_size); if(m_Userspace.GetSystemStatus() == SystemStatus::EXCEPTION) ErrorGUI(); glClear(GL_COLOR_BUFFER_BIT); ImGui::Render(); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); glfwSwapBuffers(m_Window); } ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplGlfw_Shutdown(); ImGui::DestroyContext(); } void GUI::Terminate() { glfwDestroyWindow(m_Window); glfwTerminate(); } void GUI::DockingSetup() { ImGuiID dockspace_id = ImGui::GetID("Dockspace"); ImGuiViewport *viewport = ImGui::GetMainViewport(); if (ImGui::DockBuilderGetNode(dockspace_id) == nullptr) { ImGui::DockBuilderAddNode(dockspace_id, ImGuiDockNodeFlags_DockSpace); ImGui::DockBuilderSetNodeSize(dockspace_id, viewport->Size); ImGuiID dock_id_left = 0; ImGuiID dock_id_main = dockspace_id; ImGui::DockBuilderSplitNode(dock_id_main, ImGuiDir_Left, 0.40f, &dock_id_left, &dock_id_main); ImGuiID dock_id_right = 0; ImGui::DockBuilderSplitNode(dock_id_main, ImGuiDir_Right, 0.40f, &dock_id_right, &dock_id_main); // ImGuiID dock_id_left_top = 0; // ImGuiID dock_id_left_bottom = 0; // ImGui::DockBuilderSplitNode(dock_id_left, ImGuiDir_Up, 0.50f, &dock_id_left_top, &dock_id_left_bottom); ImGui::DockBuilderDockWindow("Process Memory", dock_id_main); ImGui::DockBuilderDockWindow("Debug Information", dock_id_left); ImGui::DockBuilderDockWindow("Emulator Control", dock_id_right); ImGui::DockBuilderFinish(dockspace_id); } ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_NoTabBar; dockspace_flags |= ImGuiDockNodeFlags_PassthruCentralNode; ImGui::DockSpaceOverViewport(dockspace_id, viewport, dockspace_flags); } void GUI::ControlGUI() { ImGui::Begin("Emulator Control"); static std::string state = "STOPPED"; if (m_Userspace.GetSystemStatus() == SystemStatus::STOPPED) state = "STOPPED"; else if (m_Userspace.GetSystemStatus() == SystemStatus::RUNNING) state = "RUNNING"; else if (m_Userspace.GetSystemStatus() == SystemStatus::EXCEPTION) state = "EXCEPTION"; ImGui::Text("Current State: %s", state.c_str()); if(ImGui::Button("Start")) m_Userspace.Start(); ImGui::SameLine(); if(ImGui::Button("Stop")) m_Userspace.Stop(); ImGui::SameLine(); if (ImGui::Button("Reset")) m_Userspace.Reset(); if(ImGui::Button("Step")) m_Userspace.Step(); ImGui::End(); } void GUI::ErrorGUI() { ImGui::PushStyleColor(ImGuiCol_TitleBg, ImVec4(1.0f, 0.0f, 0.0f, 1.0f)); ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(1.0f, 0.0f, 0.0f, 1.0f)); ImGui::PushStyleColor(ImGuiCol_TitleBgActive, ImVec4(1.0f, 0.0f, 0.0f, 1.0f)); ImGui::PushStyleColor(ImGuiCol_ResizeGrip, ImVec4(1.0f, 0.0f, 0.0f, 1.0f)); ImGui::Begin("Exception"); ImGui::Text("An exception was detected! Trace:"); auto& e = m_Userspace.GetException(); for (auto i : e) ImGui::Text("Err: %s", i.c_str()); ImGui::End(); ImGui::PopStyleColor(4); } void GUI::DebugInfoGUI() { ImGuiInputTextFlags flags = ImGuiInputTextFlags_CharsHexadecimal; if (m_Userspace.GetSystemStatus() == SystemStatus::RUNNING) flags |= ImGuiInputTextFlags_ReadOnly; CPUStatus status = m_Userspace.GetCPUStatus(); ImGui::Begin("Debug Information"); ImGui::Text("GP Registers"); ImGui::InputScalar("EAX", ImGuiDataType_U32, &status.m_Registers[0], NULL, NULL, "%08X", flags); ImGui::InputScalar("ECX", ImGuiDataType_U32, &status.m_Registers[1], NULL, NULL, "%08X", flags); ImGui::InputScalar("EDX", ImGuiDataType_U32, &status.m_Registers[2], NULL, NULL, "%08X", flags); ImGui::InputScalar("EBX", ImGuiDataType_U32, &status.m_Registers[3], NULL, NULL, "%08X", flags); ImGui::InputScalar("ESP", ImGuiDataType_U32, &status.m_Registers[4], NULL, NULL, "%08X", flags); ImGui::InputScalar("EBP", ImGuiDataType_U32, &status.m_Registers[5], NULL, NULL, "%08X", flags); ImGui::InputScalar("ESI", ImGuiDataType_U32, &status.m_Registers[6], NULL, NULL, "%08X", flags); ImGui::InputScalar("EDI", ImGuiDataType_U32, &status.m_Registers[7], NULL, NULL, "%08X", flags); ImGui::Separator(); ImGui::Text("Other Registers"); ImGui::InputScalar("IP", ImGuiDataType_U32, &status.m_IP, NULL, NULL, "%08X", flags); ImGui::Separator(); ImGui::Text("Instruction Information"); ImGui::Text("Instruction Length: %d", status.m_Instruction.m_Length); ImGui::Text("Opcode: %s", Opcode2Str(status.m_Instruction.m_Opcode).c_str()); ImGui::Text("Operand1: %x", status.m_Instruction.m_Operand1); ImGui::Text("Operand2: %x", status.m_Instruction.m_Operand2); ImGui::Text("ModRM R/M: %d", status.m_Instruction.m_ModRM.m_Rm); ImGui::Text("ModRM R: %d", status.m_Instruction.m_ModRM.m_Reg); ImGui::Text("ModRM Status: %d", status.m_Instruction.m_ModRM.m_State); ImGui::Text("SIB Scale: %x", status.m_Instruction.m_SIB.m_Scale); ImGui::Text("SIB Index: %x", status.m_Instruction.m_SIB.m_Index); ImGui::Text("SIB Base: %x", status.m_Instruction.m_SIB.m_Base); ImGui::End(); } GUI::~GUI() { Terminate(); }