Skip to content

Commit

Permalink
Merge pull request #307 from gdt050579/dissasm_view
Browse files Browse the repository at this point in the history
fixed dissasm bugs and other improvements
  • Loading branch information
rzaharia authored Apr 22, 2024
2 parents 46ac1a0 + 8496cff commit 3714d12
Show file tree
Hide file tree
Showing 10 changed files with 111 additions and 85 deletions.
2 changes: 1 addition & 1 deletion AppCUI
19 changes: 14 additions & 5 deletions GViewCore/src/App/Instance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ Instance::Instance()
this->mnuWindow = nullptr;
this->mnuHelp = nullptr;
this->mnuFile = nullptr;
this->lastOpenedFolderLocation = ".";
}
bool Instance::LoadSettings()
{
Expand Down Expand Up @@ -457,18 +458,26 @@ bool Instance::AddBufferWindow(
}
void Instance::OpenFile()
{
auto res = Dialogs::FileDialog::ShowOpenFileWindow("", "", ".");
auto res = Dialogs::FileDialog::ShowOpenFileWindow("", "", this->lastOpenedFolderLocation);
if (res.has_value()) {
if (AddFileWindow(res.value(), OpenMethod::BestMatch, "") == false)
if (!AddFileWindow(res.value(), OpenMethod::BestMatch, "")) {
ShowErrors();
}else {
this->lastOpenedFolderLocation = res.value().parent_path().u8string();
}
}
}
void Instance::OpenFolder()
{
auto res = Dialogs::FileDialog::ShowOpenFileWindow("", "GVIEW:IGNORE-EVERYTHING", ".");
auto res = Dialogs::FileDialog::ShowOpenFileWindow("", "GVIEW:IGNORE-EVERYTHING", this->lastOpenedFolderLocation);
if (res.has_value()) {
if (AddFileWindow(res.value(), OpenMethod::BestMatch, "") == false)
ShowErrors();
{
if (!AddFileWindow(res.value(), OpenMethod::BestMatch, ""))
ShowErrors();
else {
this->lastOpenedFolderLocation = res.value().parent_path().u8string();
}
}
}
}
void Instance::UpdateCommandBar(AppCUI::Application::CommandBar& commandBar)
Expand Down
31 changes: 23 additions & 8 deletions GViewCore/src/View/DissasmViewer/Config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,24 +28,39 @@ constexpr int32 RIGHT_CLICK_CLEAR_SELECTION = 7;
constexpr int32 RIGHT_CLICK_DISSASM_COLLAPSE_ZONE = 8;
constexpr int32 RIGHT_CLICK_DISSASM_EXPAND_ZONE = 9;

static struct {
struct RightClickCommand {
int commandID;
std::string_view text;
// Input::Key shortcutKey = Input::Key::None;
AppCUI::Controls::ItemHandle handle = AppCUI::Controls::InvalidItemHandle;
} RIGHT_CLICK_MENU_COMMANDS[] = {
};

inline RightClickCommand RIGHT_CLICK_MENU_COMMANDS[] = {
/*{ RIGHT_CLICK_MENU_CMD_NEW_STRUCTURE, "New structure" },
{ RIGHT_CLICK_MENU_CMD_EDIT_STRUCTURE, "Edit structure" },
{ RIGHT_CLICK_MENU_CMD_DELETE_STRUCTURE, "Delete structure" },*/
{ RIGHT_CLICK_MENU_CMD_NEW_COLLAPSE_ZONE, "Add collapse zone" },
{ RIGHT_CLICK_DISSASM_REMOVE_COLLAPSE_ZONE, "Remove collapse zone" },
{ RIGHT_CLICK_DISSASM_COLLAPSE_ZONE, "Collapse zone" },
{ RIGHT_CLICK_DISSASM_EXPAND_ZONE, "Expand zone" },
{ RIGHT_CLICK_ADD_COMMENT, "Add comment" },
{ RIGHT_CLICK_REMOVE_COMMENT, "Remove comment" },
{ RIGHT_CLICK_CLEAR_SELECTION, "Clear selections" },
};

struct RightClickSubMenus {
const char* name;
std::vector<RightClickCommand> commands;
AppCUI::Controls::ItemHandle handle;
};

inline RightClickSubMenus RIGHT_CLICK_SUB_MENUS_COMMANDS[] = { { "CollapsibleZone",
{
{ RIGHT_CLICK_MENU_CMD_NEW_COLLAPSE_ZONE, "Add collapse zone" },
{ RIGHT_CLICK_DISSASM_REMOVE_COLLAPSE_ZONE, "Remove collapse zone" },
{ RIGHT_CLICK_DISSASM_COLLAPSE_ZONE, "Collapse zone" },
{ RIGHT_CLICK_DISSASM_EXPAND_ZONE, "Expand zone" },
} },
{ "Comment",
{
{ RIGHT_CLICK_ADD_COMMENT, "Add comment" },
{ RIGHT_CLICK_REMOVE_COMMENT, "Remove comment" },
} } };

namespace GView
{
namespace View
Expand Down
20 changes: 9 additions & 11 deletions GViewCore/src/View/DissasmViewer/DissasmViewer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ namespace View
uint32 GetExpandedSize() const;
};

enum class DissasmParseZoneType : uint8 { StructureParseZone, DissasmCodeParseZone, CollapsibleAndTextZone, JavaBytecodeZone };
enum class DissasmParseZoneType : uint8 { StructureParseZone, DissasmCodeParseZone, CollapsibleAndTextZone };

struct ParseZone {
uint32 startLineIndex;
Expand Down Expand Up @@ -102,13 +102,6 @@ namespace View
CollapsibleAndTextData data;
};

// JClass code
struct JavaBytecodeZone : public ParseZone {
DisassemblyZone zoneDetails;
bool isInit;
std::vector<std::string> bytecodeLines;
};

struct AsmOffsetLine {
uint64 offset;
uint32 line;
Expand Down Expand Up @@ -153,6 +146,7 @@ namespace View
uint8 flags;
uint8 lineArrowToDraw;
const void* mapping;
const DissasmCodeInternalType* parent;

bool shouldAddButton;
bool isZoneCollapsed;
Expand All @@ -177,6 +171,7 @@ namespace View
mapping = other.mapping;
memcpy(bytes, other.bytes, sizeof(bytes));
memcpy(mnemonic, other.mnemonic, CS_MNEMONIC_SIZE);
parent = other.parent;
shouldAddButton = other.shouldAddButton;
isZoneCollapsed = false;
}
Expand All @@ -192,6 +187,7 @@ namespace View
mapping = other.mapping;
memcpy(bytes, other.bytes, sizeof(bytes));
memcpy(mnemonic, other.mnemonic, CS_MNEMONIC_SIZE);
parent = other.parent;
shouldAddButton = other.shouldAddButton;
isZoneCollapsed = false;
}
Expand Down Expand Up @@ -282,8 +278,9 @@ namespace View
index = 0;
}

DissasmAsmPreCacheData() : index(0), maxLineSize(0)
DissasmAsmPreCacheData(size_t initial_size = 128) : index(0), maxLineSize(0)
{
cachedAsmLines.reserve(initial_size);
}
~DissasmAsmPreCacheData()
{
Expand Down Expand Up @@ -380,6 +377,7 @@ namespace View
BufferView lastData;
uint32 lastReachedLine = -1u;

//fields only for dissasmx86/x64
const uint8* asmData;
uint64 asmSize, asmAddress;

Expand Down Expand Up @@ -415,7 +413,7 @@ namespace View
bool TryRenameLine(uint32 line);

bool GetComment(uint32 line, std::string& comment);
bool AddOrUpdateComment(uint32 line, const std::string& comment,bool showErr = true);
bool AddOrUpdateComment(uint32 line, const std::string& comment, bool showErr = true);
bool RemoveComment(uint32 line, bool showErr = true);
DissasmAsmPreCacheLine GetCurrentAsmLine(uint32 currentLine, Reference<GView::Object> obj, DissasmInsnExtractLineParams* params);
};
Expand Down Expand Up @@ -614,9 +612,9 @@ namespace View
bool WriteStructureToScreen(DrawLineInfo& dli, const DissasmStructureType& currentType, uint32 spaces, DissasmParseStructureZone* structureZone);
bool DrawCollapsibleAndTextZone(DrawLineInfo& dli, CollapsibleAndTextZone* zone);
bool DrawStructureZone(DrawLineInfo& dli, DissasmParseStructureZone* structureZone);
bool DrawJavaBytecodeZone(DrawLineInfo& dli, JavaBytecodeZone* zone);
bool DrawDissasmZone(DrawLineInfo& dli, DissasmCodeZone* zone);
bool DrawDissasmX86AndX64CodeZone(DrawLineInfo& dli, DissasmCodeZone* zone);
bool DrawDissasmJavaByteCodeZone(DrawLineInfo& dli, DissasmCodeZone* zone);
bool PrepareDrawLineInfo(DrawLineInfo& dli);

void RegisterStructureCollapseButton(uint32 screenLine, SpecialChars c, ParseZone* zone, bool isBullet = false);
Expand Down
61 changes: 19 additions & 42 deletions GViewCore/src/View/DissasmViewer/Instance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ Instance::Instance(Reference<GView::Object> obj, Settings* _settings)

this->codePage = CodePageID::DOS_437;

for (auto& submenu : RIGHT_CLICK_SUB_MENUS_COMMANDS) {
submenu.handle = rightClickMenu.AddSubMenu(submenu.name);
auto subMenu = rightClickMenu.GetSubMenu(submenu.handle);
for (auto& command : submenu.commands) {
command.handle = subMenu->AddCommandItem(command.text, command.commandID);
}
}

for (auto& menu_command : RIGHT_CLICK_MENU_COMMANDS) {
menu_command.handle = rightClickMenu.AddCommandItem(menu_command.text, menu_command.commandID);
}
Expand Down Expand Up @@ -264,11 +272,11 @@ void Instance::AddComment()
}

uint32 startingLine = zonesFound[0].startingLine;
if (startingLine == 0 || startingLine == 1) {
if (startingLine == 0 || startingLine == 1 || Cursor.startViewLine >= startingLine && Cursor.lineInView == 0) {
Dialogs::MessageBox::ShowNotification("Warning", "Please add comment inside the region, not on the title!");
return;
}
startingLine--;
startingLine -= 2;

const auto convertedZone = static_cast<DissasmCodeZone*>(zone.get());

Expand Down Expand Up @@ -306,7 +314,7 @@ void Instance::RemoveComment()
Dialogs::MessageBox::ShowNotification("Warning", "Please remove comment inside the region, not on the title!");
return;
}
startingLine--;
startingLine -= 2;

const auto convertedZone = static_cast<DissasmCodeZone*>(zone.get());
convertedZone->RemoveComment(startingLine);
Expand Down Expand Up @@ -378,8 +386,6 @@ bool Instance::PrepareDrawLineInfo(DrawLineInfo& dli)
return DrawDissasmZone(dli, (DissasmCodeZone*) zones[i].get());
case DissasmParseZoneType::CollapsibleAndTextZone:
return DrawCollapsibleAndTextZone(dli, (CollapsibleAndTextZone*) zones[i].get());
case DissasmParseZoneType::JavaBytecodeZone:
return DrawJavaBytecodeZone(dli, (JavaBytecodeZone*) zones[i].get());
default:
return false;
}
Expand Down Expand Up @@ -726,14 +732,17 @@ bool Instance::DrawCollapsibleAndTextZone(DrawLineInfo& dli, CollapsibleAndTextZ

bool Instance::DrawDissasmZone(DrawLineInfo& dli, DissasmCodeZone* zone)
{
// TODO: extend java bytecode struct to be drawn here!!
if (zone->zoneDetails.language != DisassemblyLanguage::x86 && zone->zoneDetails.language != DisassemblyLanguage::x64) {
switch (zone->zoneDetails.language) {
case DisassemblyLanguage::x86:
case DisassemblyLanguage::x64:
return DrawDissasmX86AndX64CodeZone(dli, zone);
case DisassemblyLanguage::JavaByteCode:
return DrawDissasmJavaByteCodeZone(dli, zone);
default:
dli.WriteErrorToScreen("Not yet supported language!");
AdjustZoneExtendedSize(zone, 1);
return true;
}

return DrawDissasmX86AndX64CodeZone(dli, zone);
}

void Instance::RegisterStructureCollapseButton(uint32 screenLine, SpecialChars c, ParseZone* zone, bool isBullet)
Expand Down Expand Up @@ -843,21 +852,7 @@ void Instance::RecomputeDissasmZones()
mappingData[OffsetToLinePosition(mapping.first).line].push_back({ &mapping.second, DissasmParseZoneType::StructureParseZone });
}
for (auto& dissasmZone : settings->disassemblyZones) {
// TODO: improve this
DissasmParseZoneType zoneType;
switch (dissasmZone.second.language) {
case DisassemblyLanguage::x86:
case DisassemblyLanguage::x64:
zoneType = DissasmParseZoneType::DissasmCodeParseZone;
break;
case DisassemblyLanguage::JavaByteCode:
zoneType = DissasmParseZoneType::JavaBytecodeZone;
break;
default:
// unimplemented
abort();
}
mappingData[OffsetToLinePosition(dissasmZone.first).line].push_back({ &dissasmZone.second, zoneType });
mappingData[OffsetToLinePosition(dissasmZone.first).line].push_back({ &dissasmZone.second, DissasmParseZoneType::DissasmCodeParseZone });
}
for (auto& zone : settings->collapsibleAndTextZones) {
mappingData[OffsetToLinePosition(zone.first).line].push_back({ &zone.second, DissasmParseZoneType::CollapsibleAndTextZone });
Expand Down Expand Up @@ -968,24 +963,6 @@ void Instance::RecomputeDissasmZones()
lastZoneEndingIndex = collapsibleZone->endingLineIndex;
settings->parseZones.push_back(std::move(collapsibleZone));
} break;
case DissasmParseZoneType::JavaBytecodeZone: {
const auto convertedData = static_cast<DisassemblyZone*>(entry.data);
auto javaByteCodeZone = std::make_unique<JavaBytecodeZone>();
javaByteCodeZone->zoneDetails = *convertedData;
javaByteCodeZone->startLineIndex = zoneStartingLine;
javaByteCodeZone->isCollapsed = Layout.structuresInitialCollapsedState;
javaByteCodeZone->endingLineIndex = javaByteCodeZone->startLineIndex + 1;
javaByteCodeZone->zoneID = currentIndex++;
javaByteCodeZone->zoneType = DissasmParseZoneType::JavaBytecodeZone;
javaByteCodeZone->extendedSize = DISSASM_INITIAL_EXTENDED_SIZE;

if (!javaByteCodeZone->isCollapsed)
javaByteCodeZone->endingLineIndex += javaByteCodeZone->extendedSize;

// lastEndMinusLastOffset = collapsibleZone->endingLineIndex + collapsibleZone->textLinesOffset;
lastZoneEndingIndex = javaByteCodeZone->endingLineIndex;
settings->parseZones.push_back(std::move(javaByteCodeZone));
} break;
}
}
}
Expand Down
7 changes: 5 additions & 2 deletions GViewCore/src/View/DissasmViewer/Settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@ Settings::Settings()

void Settings::SetDefaultDisassemblyLanguage(DisassemblyLanguage lang)
{
if (lang == DisassemblyLanguage::Default || lang == DisassemblyLanguage::Count)
lang = DisassemblyLanguage::x86;
INTERNAL_SETTINGS->defaultLanguage = lang;
}

void Settings::AddDisassemblyZone(uint64 zoneStart, uint64 zoneSize, uint64 zoneDissasmStartPoint, DisassemblyLanguage lang)
{
if (lang == DisassemblyLanguage::Default || lang == DisassemblyLanguage::Count)
lang = INTERNAL_SETTINGS->defaultLanguage;
INTERNAL_SETTINGS->disassemblyZones[zoneStart] = { zoneStart, zoneSize, zoneDissasmStartPoint, lang };
}

Expand Down Expand Up @@ -47,8 +51,7 @@ void Settings::AddBidimensionalArray(uint64 offset, std::string_view name, Varia
void Settings::AddVariable(uint64 offset, std::string_view name, TypeID type)
{
auto res = INTERNAL_SETTINGS->userDesignedTypes.find(type);
if (res == INTERNAL_SETTINGS->userDesignedTypes.end())
{
if (res == INTERNAL_SETTINGS->userDesignedTypes.end()) {
// err;
return;
}
Expand Down
26 changes: 18 additions & 8 deletions GViewCore/src/View/DissasmViewer/jclass/DissasmJClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@
using namespace GView::View::DissasmViewer;
using namespace GView::View::DissasmViewer::JClass;

bool Instance::DrawJavaBytecodeZone(DrawLineInfo& dli, JavaBytecodeZone* zone)
inline void PopulateZoneTextToDissasmAsmPreCacheLine(DissasmCodeZone* zone, const char* text, uint32 len)
{
DissasmAsmPreCacheLine line = {};
line.op_str = strdup(text);
line.op_str_size = len;
zone->asmPreCacheData.cachedAsmLines.push_back(std::move(line));
}

bool Instance::DrawDissasmJavaByteCodeZone(DrawLineInfo& dli, DissasmCodeZone* zone)
{
if (!zone->isInit) {
const auto buffer = this->obj->GetData().GetEntireFile();
Expand All @@ -19,21 +27,22 @@ bool Instance::DrawJavaBytecodeZone(DrawLineInfo& dli, JavaBytecodeZone* zone)

auto clazz = creator.create();
if (clazz) {
zone->bytecodeLines.emplace_back("Constant data:");
PopulateZoneTextToDissasmAsmPreCacheLine(zone, "Constant data:", strlen("Constant data:"));
if (parser.constant_data.empty()) {
zone->bytecodeLines.emplace_back("No constant data!");
PopulateZoneTextToDissasmAsmPreCacheLine(zone, "No constant data!", strlen("No constant data!"));
}

LocalString<64> line;
for (auto& constantData : parser.constant_data) {
line.SetFormat(" %s", ConstantKindNames[static_cast<uint32>(constantData.kind)]);
zone->bytecodeLines.emplace_back(line.GetText());
PopulateZoneTextToDissasmAsmPreCacheLine(zone, line.GetText(), line.Len());
}
}else {
zone->bytecodeLines.emplace_back("Failed to parse class file, there are still some features in progress!");
} else {
const char* msg = "Failed to parse class file, there are still some features in progress!";
PopulateZoneTextToDissasmAsmPreCacheLine(zone, msg, strlen(msg));
}

AdjustZoneExtendedSize(zone, zone->bytecodeLines.size());
AdjustZoneExtendedSize(zone, zone->asmPreCacheData.cachedAsmLines.size());

zone->isInit = true;
}
Expand Down Expand Up @@ -62,7 +71,8 @@ bool Instance::DrawJavaBytecodeZone(DrawLineInfo& dli, JavaBytecodeZone* zone)

const uint32 currentLine = dli.textLineToDraw - 1u;

chars.Add(zone->bytecodeLines[currentLine].c_str(), ColorMan.Colors.AsmJumpInstruction);
const char* lineText = zone->asmPreCacheData.cachedAsmLines[currentLine].op_str;
chars.Add(lineText, ColorMan.Colors.AsmJumpInstruction);

const auto bufferToDraw = CharacterView{ chars.GetBuffer(), chars.Len() };
HighlightSelectionAndDrawCursorText(dli, static_cast<uint32>(bufferToDraw.length()), static_cast<uint32>(bufferToDraw.length()));
Expand Down
Loading

0 comments on commit 3714d12

Please sign in to comment.