2019-12-21 18:36:40 +00:00
|
|
|
#include "ELFSectionView.h"
|
|
|
|
#include "string_format.h"
|
|
|
|
#include "lexical_cast_ex.h"
|
|
|
|
|
|
|
|
#include <QLabel>
|
|
|
|
#include <QAction>
|
|
|
|
#include <QInputDialog>
|
|
|
|
#include <QMenu>
|
|
|
|
#include <QMessageBox>
|
|
|
|
#include <QHeaderView>
|
|
|
|
#include <QFontDatabase>
|
|
|
|
#include <QFontMetrics>
|
|
|
|
|
|
|
|
CELFSectionView::CELFSectionView(QMdiSubWindow* parent, QLayout* groupBoxLayout)
|
2019-12-21 18:48:44 +00:00
|
|
|
: QWidget(parent)
|
2019-12-21 18:36:40 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
std::vector<std::string> labelsStr = {"Type:", "Flags:", "Address:", "File Offset:", "Size:", "Section Link:", "Info:", "Alignment:", "Entry Size:"};
|
|
|
|
m_layout = new QVBoxLayout(this);
|
|
|
|
|
|
|
|
auto label = new QLabel(this);
|
|
|
|
QFontMetrics metric(label->font());
|
|
|
|
delete label;
|
|
|
|
auto labelWidth = metric.horizontalAdvance(labelsStr.back().c_str()) + 10;
|
|
|
|
|
|
|
|
for(auto labelStr : labelsStr)
|
|
|
|
{
|
2019-12-21 23:34:38 +00:00
|
|
|
auto horizontalLayout = new QHBoxLayout();
|
2019-12-21 18:36:40 +00:00
|
|
|
auto label = new QLabel(this);
|
|
|
|
label->setText(labelStr.c_str());
|
|
|
|
label->setFixedWidth(labelWidth);
|
|
|
|
|
|
|
|
horizontalLayout->addWidget(label);
|
|
|
|
|
|
|
|
auto lineEdit = new QLineEdit(this);
|
|
|
|
lineEdit->setReadOnly(true);
|
|
|
|
m_editFields.push_back(lineEdit);
|
|
|
|
|
|
|
|
horizontalLayout->addWidget(lineEdit);
|
|
|
|
m_layout->addLayout(horizontalLayout);
|
|
|
|
}
|
|
|
|
|
2020-01-05 22:46:47 +00:00
|
|
|
m_memView = new CMemoryViewTable(this);
|
2019-12-21 23:34:38 +00:00
|
|
|
auto verticalLayout = new QHBoxLayout();
|
2019-12-21 18:36:40 +00:00
|
|
|
verticalLayout->addWidget(m_memView);
|
|
|
|
|
|
|
|
m_dynSecTableWidget = new QTableWidget(this);
|
|
|
|
m_dynSecTableWidget->setRowCount(0);
|
|
|
|
m_dynSecTableWidget->setColumnCount(2);
|
|
|
|
m_dynSecTableWidget->setHorizontalHeaderLabels({"Type", "Value"});
|
|
|
|
m_dynSecTableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
|
|
|
|
|
|
|
|
verticalLayout->addWidget(m_dynSecTableWidget);
|
|
|
|
|
|
|
|
m_layout->addLayout(verticalLayout);
|
|
|
|
|
|
|
|
groupBoxLayout->addWidget(this);
|
|
|
|
hide();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CELFSectionView::SetSection(int section)
|
|
|
|
{
|
|
|
|
FillInformation(section);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CELFSectionView::Reset()
|
|
|
|
{
|
|
|
|
for(auto editField : m_editFields)
|
|
|
|
{
|
|
|
|
editField->clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CELFSectionView::showEvent(QShowEvent* evt)
|
|
|
|
{
|
|
|
|
QWidget::showEvent(evt);
|
2020-01-05 22:46:47 +00:00
|
|
|
m_memView->ShowEvent();
|
2019-12-21 18:36:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CELFSectionView::ResizeEvent()
|
|
|
|
{
|
2020-01-05 22:46:47 +00:00
|
|
|
m_memView->ResizeEvent();
|
2019-12-21 18:36:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CELFSectionView::SetBytesPerLine(int bytesForLine)
|
|
|
|
{
|
2020-01-05 22:46:47 +00:00
|
|
|
m_memView->SetBytesPerLine(bytesForLine);
|
2019-12-21 18:36:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CELFSectionView::SetELF(CELF* pELF)
|
|
|
|
{
|
|
|
|
m_pELF = pELF;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CELFSectionView::FillInformation(int section)
|
|
|
|
{
|
|
|
|
int i = 0;
|
|
|
|
std::string sTemp;
|
2022-03-15 08:13:44 -04:00
|
|
|
auto pH = m_pELF->GetSection(section);
|
2019-12-21 18:36:40 +00:00
|
|
|
|
|
|
|
switch(pH->nType)
|
|
|
|
{
|
|
|
|
case CELF::SHT_NULL:
|
|
|
|
sTemp = "SHT_NULL";
|
|
|
|
break;
|
|
|
|
case CELF::SHT_PROGBITS:
|
|
|
|
sTemp = "SHT_PROGBITS";
|
|
|
|
break;
|
|
|
|
case CELF::SHT_SYMTAB:
|
|
|
|
sTemp = "SHT_SYMTAB";
|
|
|
|
break;
|
|
|
|
case CELF::SHT_STRTAB:
|
|
|
|
sTemp = "SHT_STRTAB";
|
|
|
|
break;
|
|
|
|
case CELF::SHT_HASH:
|
|
|
|
sTemp = "SHT_HASH";
|
|
|
|
break;
|
|
|
|
case CELF::SHT_DYNAMIC:
|
|
|
|
sTemp = "SHT_DYNAMIC";
|
|
|
|
break;
|
|
|
|
case CELF::SHT_NOTE:
|
|
|
|
sTemp = "SHT_NOTE";
|
|
|
|
break;
|
|
|
|
case CELF::SHT_NOBITS:
|
|
|
|
sTemp = "SHT_NOBITS";
|
|
|
|
break;
|
|
|
|
case CELF::SHT_REL:
|
|
|
|
sTemp = "SHT_REL";
|
|
|
|
break;
|
|
|
|
case CELF::SHT_DYNSYM:
|
|
|
|
sTemp = "SHT_DYNSYM";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
sTemp = string_format("Unknown (0x%08X)", pH->nType);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
m_editFields[i++]->setText(sTemp.c_str());
|
|
|
|
|
|
|
|
sTemp = string_format("0x%08X", pH->nFlags);
|
|
|
|
if(pH->nFlags & 0x7)
|
|
|
|
{
|
|
|
|
sTemp += " (";
|
2022-02-28 16:40:29 -05:00
|
|
|
if(pH->nFlags & CELF::SHF_WRITE)
|
2019-12-21 18:36:40 +00:00
|
|
|
{
|
|
|
|
sTemp += "SHF_WRITE";
|
2022-02-28 16:40:29 -05:00
|
|
|
if(pH->nFlags & 0x06)
|
2019-12-21 18:36:40 +00:00
|
|
|
{
|
|
|
|
sTemp += " | ";
|
|
|
|
}
|
|
|
|
}
|
2022-02-28 16:40:29 -05:00
|
|
|
if(pH->nFlags & CELF::SHF_ALLOC)
|
2019-12-21 18:36:40 +00:00
|
|
|
{
|
|
|
|
sTemp += "SHF_ALLOC";
|
|
|
|
if(pH->nFlags & 0x04)
|
|
|
|
{
|
|
|
|
sTemp += " | ";
|
|
|
|
}
|
|
|
|
}
|
2022-02-28 16:40:29 -05:00
|
|
|
if(pH->nFlags & CELF::SHF_EXECINSTR)
|
2019-12-21 18:36:40 +00:00
|
|
|
{
|
|
|
|
sTemp += "SHF_EXECINSTR";
|
|
|
|
}
|
|
|
|
sTemp += ")";
|
|
|
|
}
|
|
|
|
m_editFields[i++]->setText(sTemp.c_str());
|
|
|
|
|
|
|
|
sTemp = string_format("0x%08X", pH->nStart);
|
|
|
|
m_editFields[i++]->setText(sTemp.c_str());
|
|
|
|
|
|
|
|
sTemp = string_format("0x%08X", pH->nOffset);
|
|
|
|
m_editFields[i++]->setText(sTemp.c_str());
|
|
|
|
|
|
|
|
sTemp = string_format("0x%08X", pH->nSize);
|
|
|
|
m_editFields[i++]->setText(sTemp.c_str());
|
|
|
|
|
|
|
|
sTemp = string_format("%i", pH->nIndex);
|
|
|
|
m_editFields[i++]->setText(sTemp.c_str());
|
|
|
|
|
|
|
|
sTemp = string_format("%i", pH->nInfo);
|
|
|
|
m_editFields[i++]->setText(sTemp.c_str());
|
|
|
|
|
|
|
|
sTemp = string_format("0x%08X", pH->nAlignment);
|
|
|
|
m_editFields[i++]->setText(sTemp.c_str());
|
|
|
|
|
|
|
|
sTemp = string_format("0x%08X", pH->nOther);
|
|
|
|
m_editFields[i++]->setText(sTemp.c_str());
|
|
|
|
|
|
|
|
if(pH->nType == CELF::SHT_DYNAMIC)
|
|
|
|
{
|
|
|
|
FillDynamicSectionListView(section);
|
|
|
|
m_dynSecTableWidget->show();
|
2020-01-05 22:46:47 +00:00
|
|
|
m_memView->SetData(nullptr, 0);
|
2019-12-21 18:36:40 +00:00
|
|
|
m_memView->hide();
|
|
|
|
}
|
|
|
|
else if(pH->nType != CELF::SHT_NOBITS)
|
|
|
|
{
|
2019-12-21 18:48:44 +00:00
|
|
|
uint8* data = (uint8*)m_pELF->GetSectionData(section);
|
|
|
|
auto getByte = [data](uint32 offset) {
|
2019-12-21 18:36:40 +00:00
|
|
|
return data[offset];
|
|
|
|
};
|
2020-01-05 22:46:47 +00:00
|
|
|
m_memView->SetData(getByte, pH->nSize);
|
2019-12-21 18:36:40 +00:00
|
|
|
m_memView->show();
|
|
|
|
m_dynSecTableWidget->hide();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-01-05 22:46:47 +00:00
|
|
|
m_memView->SetData(nullptr, 0);
|
2019-12-21 18:36:40 +00:00
|
|
|
m_memView->show();
|
|
|
|
m_dynSecTableWidget->hide();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CELFSectionView::FillDynamicSectionListView(int section)
|
|
|
|
{
|
|
|
|
m_dynSecTableWidget->setRowCount(0);
|
|
|
|
|
2022-03-15 08:13:44 -04:00
|
|
|
auto pH = m_pELF->GetSection(section);
|
2019-12-21 18:36:40 +00:00
|
|
|
const uint32* dynamicData = reinterpret_cast<const uint32*>(m_pELF->GetSectionData(section));
|
|
|
|
const char* stringTable = (pH->nOther != -1) ? reinterpret_cast<const char*>(m_pELF->GetSectionData(pH->nIndex)) : NULL;
|
|
|
|
|
|
|
|
for(unsigned int i = 0; i < pH->nSize; i += 8, dynamicData += 2)
|
|
|
|
{
|
|
|
|
uint32 tag = *(dynamicData + 0);
|
|
|
|
uint32 value = *(dynamicData + 1);
|
|
|
|
|
|
|
|
if(tag == 0) break;
|
|
|
|
|
|
|
|
std::string tempTag;
|
|
|
|
std::string tempVal;
|
|
|
|
|
|
|
|
switch(tag)
|
|
|
|
{
|
|
|
|
case CELF::DT_NEEDED:
|
|
|
|
tempTag = "DT_NEEDED";
|
|
|
|
tempVal = stringTable + value;
|
|
|
|
break;
|
|
|
|
case CELF::DT_PLTRELSZ:
|
|
|
|
tempTag = "DT_PLTRELSZ";
|
|
|
|
tempVal = string_format("0x%08X", value);
|
|
|
|
break;
|
|
|
|
case CELF::DT_PLTGOT:
|
|
|
|
tempTag = "DT_PLTGOT";
|
|
|
|
tempVal = string_format("0x%08X", value);
|
|
|
|
break;
|
|
|
|
case CELF::DT_HASH:
|
|
|
|
tempTag = "DT_HASH";
|
|
|
|
tempVal = string_format("0x%08X", value);
|
|
|
|
break;
|
|
|
|
case CELF::DT_STRTAB:
|
|
|
|
tempTag = "DT_STRTAB";
|
|
|
|
tempVal = string_format("0x%08X", value);
|
|
|
|
break;
|
|
|
|
case CELF::DT_SYMTAB:
|
|
|
|
tempTag = "DT_SYMTAB";
|
|
|
|
tempVal = string_format("0x%08X", value);
|
|
|
|
break;
|
|
|
|
case CELF::DT_SONAME:
|
|
|
|
tempTag = "DT_SONAME";
|
|
|
|
tempVal = stringTable + value;
|
|
|
|
break;
|
|
|
|
case CELF::DT_SYMBOLIC:
|
|
|
|
tempTag = "DT_SYMBOLIC";
|
|
|
|
tempVal = "";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
tempTag = string_format("Unknown (0x%08X)", tag);
|
|
|
|
tempVal = string_format("0x%08X", value);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_dynSecTableWidget->setRowCount((i / 8) + 1);
|
|
|
|
m_dynSecTableWidget->setItem((i / 8), 0, new QTableWidgetItem(tempTag.c_str()));
|
|
|
|
m_dynSecTableWidget->setItem((i / 8), 1, new QTableWidgetItem(tempVal.c_str()));
|
|
|
|
}
|
|
|
|
}
|