diff --git a/RElicAnalysis-0.1.0 b/RElicAnalysis-0.1.0 deleted file mode 100755 index dd2f3b5..0000000 Binary files a/RElicAnalysis-0.1.0 and /dev/null differ diff --git a/RElicAnalysis-0.1.1 b/RElicAnalysis-0.1.1 new file mode 100755 index 0000000..d98b955 Binary files /dev/null and b/RElicAnalysis-0.1.1 differ diff --git a/RElicAnalysis/CMakeLists.txt b/RElicAnalysis/CMakeLists.txt index 6b4d5aa..48dabc8 100644 --- a/RElicAnalysis/CMakeLists.txt +++ b/RElicAnalysis/CMakeLists.txt @@ -72,7 +72,9 @@ if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) elf/mdielfview.cpp elf/mdielfview.h dialogabout.h dialogabout.cpp - dockmenu.h dockmenu.cpp + + + elf/elfsymbolmodel.h elf/elfsymbolmodel.cpp diff --git a/RElicAnalysis/CMakeLists.txt.user b/RElicAnalysis/CMakeLists.txt.user index 1018f3b..c9be3ed 100644 --- a/RElicAnalysis/CMakeLists.txt.user +++ b/RElicAnalysis/CMakeLists.txt.user @@ -1,10 +1,10 @@ - + EnvironmentId - {7576b28b-0509-4f2e-9112-d416507c0bdd} + {c1ad1696-344c-4cbf-8c9b-7903590215f2} ProjectExplorer.Project.ActiveTarget @@ -76,7 +76,7 @@ true true Builtin.DefaultTidyAndClazy - 2 + 4 true @@ -89,10 +89,10 @@ ProjectExplorer.Project.Target.0 Desktop - Desktop - Desktop - {4f4e56a4-b54b-4c8a-9576-1e917c71a3c7} - 0 + Desktop Qt 6.6.2 GCC 64bit + Desktop Qt 6.6.2 GCC 64bit + qt.qt6.662.gcc_64_kit + 1 0 0 @@ -100,16 +100,17 @@ 2 false - -DCMAKE_GENERATOR:STRING=Unix Makefiles + -DCMAKE_GENERATOR:STRING=Ninja -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DQT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable} --DCMAKE_PREFIX_PATH:STRING=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_C_COMPILER:STRING=%{Compiler:Executable:C} --DCMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} -DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} + /home/gbucchino/Documents/GIT/RElicAnalysis/RElicAnalysis 0 - /home/geoffrey/Documents/GIT/cryptoshield/RElicAnalysis/build-RElicAnalysis-Desktop-Debug + /home/gbucchino/Documents/GIT/RElicAnalysis/build-RElicAnalysis-Desktop_Qt_6_6_2_GCC_64bit-Debug @@ -157,15 +158,16 @@ 2 false - -DCMAKE_GENERATOR:STRING=Unix Makefiles + -DCMAKE_GENERATOR:STRING=Ninja -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DQT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable} --DCMAKE_PREFIX_PATH:STRING=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_C_COMPILER:STRING=%{Compiler:Executable:C} --DCMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx} +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} -DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} - /home/geoffrey/Documents/GIT/cryptoshield/RElicAnalysis/build-RElicAnalysis-Desktop-Release + /home/gbucchino/Documents/GIT/RElicAnalysis/RElicAnalysis + /home/gbucchino/Documents/GIT/RElicAnalysis/build-RElicAnalysis-Desktop_Qt_6_6_2_GCC_64bit-Release @@ -175,6 +177,7 @@ false true + Build CMakeProjectManager.MakeStep 1 @@ -191,6 +194,7 @@ false true + Build CMakeProjectManager.MakeStep 1 @@ -206,170 +210,7 @@ Release CMakeProjectManager.CMakeBuildConfiguration - - RelWithDebInfo - 2 - false - - -DCMAKE_GENERATOR:STRING=Unix Makefiles --DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo --DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DQT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable} --DCMAKE_PREFIX_PATH:STRING=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_C_COMPILER:STRING=%{Compiler:Executable:C} --DCMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx} --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} - /home/geoffrey/Documents/GIT/cryptoshield/RElicAnalysis/build-RElicAnalysis-Desktop-RelWithDebInfo - - - - - all - - false - - true - CMakeProjectManager.MakeStep - - 1 - Build - Build - ProjectExplorer.BuildSteps.Build - - - - - - clean - - false - - true - CMakeProjectManager.MakeStep - - 1 - Clean - Clean - ProjectExplorer.BuildSteps.Clean - - 2 - false - - false - - Release with Debug Information - CMakeProjectManager.CMakeBuildConfiguration - - - RelWithDebInfo - 2 - false - - -DCMAKE_GENERATOR:STRING=Unix Makefiles --DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo --DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DQT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable} --DCMAKE_PREFIX_PATH:STRING=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_C_COMPILER:STRING=%{Compiler:Executable:C} --DCMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx} --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} - 0 - /home/geoffrey/Documents/GIT/cryptoshield/RElicAnalysis/build-RElicAnalysis-Desktop-Profile - - - - - all - - false - - true - CMakeProjectManager.MakeStep - - 1 - Build - Build - ProjectExplorer.BuildSteps.Build - - - - - - clean - - false - - true - CMakeProjectManager.MakeStep - - 1 - Clean - Clean - ProjectExplorer.BuildSteps.Clean - - 2 - false - - false - - Profile - CMakeProjectManager.CMakeBuildConfiguration - - - MinSizeRel - 2 - false - - -DCMAKE_GENERATOR:STRING=Unix Makefiles --DCMAKE_BUILD_TYPE:STRING=MinSizeRel --DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DQT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable} --DCMAKE_PREFIX_PATH:STRING=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_C_COMPILER:STRING=%{Compiler:Executable:C} --DCMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx} --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} - /home/geoffrey/Documents/GIT/cryptoshield/RElicAnalysis/build-RElicAnalysis-Desktop-MinSizeRel - - - - - all - - false - - true - CMakeProjectManager.MakeStep - - 1 - Build - Build - ProjectExplorer.BuildSteps.Build - - - - - - clean - - false - - true - CMakeProjectManager.MakeStep - - 1 - Clean - Clean - ProjectExplorer.BuildSteps.Clean - - 2 - false - - false - - Minimum Size Release - CMakeProjectManager.CMakeBuildConfiguration - - 5 + 2 0 @@ -388,17 +229,18 @@ true 0 true - 2 false - - ProjectExplorer.CustomExecutableRunConfiguration - + RElicAnalysis + CMakeProjectManager.CMakeRunConfiguration.RElicAnalysis + RElicAnalysis false true + true true + /home/gbucchino/Documents/GIT/RElicAnalysis/build-RElicAnalysis-Desktop_Qt_6_6_2_GCC_64bit-Release 1 diff --git a/RElicAnalysis/data.h b/RElicAnalysis/data.h index ac0cc18..289b3c5 100644 --- a/RElicAnalysis/data.h +++ b/RElicAnalysis/data.h @@ -97,10 +97,8 @@ struct elfSymbol { unsigned char st_info; unsigned char st_other; QByteArray st_shndx; - char *data; + //char *data; uint64_t size; - int countEntries; - int entry; }; struct elfHash { diff --git a/RElicAnalysis/dataDisas.h b/RElicAnalysis/dataDisas.h index 40596df..dbfd61b 100644 --- a/RElicAnalysis/dataDisas.h +++ b/RElicAnalysis/dataDisas.h @@ -9,7 +9,8 @@ struct object_asm { char cmd[SIZE_OBJECT_CMD]; // Store the command - char *hexCmd; // Store the command in hex + //char *hexCmd; // Store the command in hex + char hexCmd[SIZE_OBJECT_CMD]; size_t octets; size_t addr; // Command start at }; diff --git a/RElicAnalysis/dialogabout.cpp b/RElicAnalysis/dialogabout.cpp index c6cf9f0..6362749 100644 --- a/RElicAnalysis/dialogabout.cpp +++ b/RElicAnalysis/dialogabout.cpp @@ -6,7 +6,7 @@ DialogAbout::DialogAbout(): QDialog() { QVBoxLayout *mainLayout = new QVBoxLayout; - QLabel *labelTitle = new QLabel("RElicAnalysis 0.1.0"); + QLabel *labelTitle = new QLabel("RElicAnalysis 0.1.1"); QFont fontTitle; fontTitle.setPointSize(15); fontTitle.setBold(true); diff --git a/RElicAnalysis/disasasm.cpp b/RElicAnalysis/disasasm.cpp index 173f958..67ac4c6 100644 --- a/RElicAnalysis/disasasm.cpp +++ b/RElicAnalysis/disasasm.cpp @@ -29,7 +29,7 @@ static int dump_asm(void *stream, const char *fmt, ...){ /* * Cf: https://github.com/bpftrace/bpftrace/blob/master/src/bfd-disasm.cpp#L49C1-L55C2 */ -/*static int dump_asm_styled(void *out __attribute__((unused)), enum disassembler_style s __attribute__((unused)), +static int dump_asm_styled(void *out __attribute__((unused)), enum disassembler_style s __attribute__((unused)), const char *fmt __attribute__((unused)), ...) { struct dataDisas *sData = (struct dataDisas*)out; @@ -54,7 +54,7 @@ static int dump_asm(void *stream, const char *fmt, ...){ memcpy(sData->s_object_asm[index].cmd, tmp, strlen(tmp)); return 0; -}*/ +} struct dataDisas *disas_asm(unsigned char *buffer, uint64_t startAddress, size_t length){ struct disassemble_info disasm_info; @@ -94,8 +94,8 @@ static int dump_asm(void *stream, const char *fmt, ...){ * https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/commit/?id=600b7b26c07a070d0153daa76b3806c1e52c9e00 * https://patchwork.yoctoproject.org/project/arm/patch/20220824025819.4888-1-jon.mason@arm.com/#5104 */ - //init_disassemble_info (&disasm_info, sData, dump_asm, dump_asm_styled); - init_disassemble_info (&disasm_info, sData, dump_asm); + init_disassemble_info (&disasm_info, sData, dump_asm, dump_asm_styled); + //init_disassemble_info (&disasm_info, sData, dump_asm); disasm_info.arch = bfd_arch_i386; disasm_info.mach = bfd_mach_x86_64; disasm_info.read_memory_func = buffer_read_memory; @@ -119,6 +119,7 @@ static int dump_asm(void *stream, const char *fmt, ...){ int bufferIndex = 0; while (i < length){ size_t octets = disas(i, &disasm_info); + //qDebug() << octets; sData->s_object_asm[sData->countEntries].octets = octets; sData->s_object_asm[sData->countEntries].addr = nextStart; @@ -127,10 +128,17 @@ static int dump_asm(void *stream, const char *fmt, ...){ * We free in the parsingElf file */ /* hexCmd object will be freed in parsingElf file */ - sData->s_object_asm[sData->countEntries].hexCmd = (char*)malloc(sizeof(char) * octets); + + /*sData->s_object_asm[sData->countEntries].hexCmd = (char*)malloc(sizeof(char) * octets); + if (!sData->s_object_asm[sData->countEntries].hexCmd){ + qDebug() << "Failed "; + return NULL; + }*/ + memcpy(sData->s_object_asm[sData->countEntries].hexCmd, &buffer[bufferIndex], octets); + i += octets; nextStart += octets; bufferIndex += octets; @@ -151,6 +159,5 @@ static int dump_asm(void *stream, const char *fmt, ...){ memset(&sData->s_object_asm[sData->countEntries], 0, sizeof(&sData->s_object_asm)); memset(sData->s_object_asm[sData->countEntries].cmd, 0, SIZE_OBJECT_CMD); }; - return sData; } diff --git a/RElicAnalysis/elf/elfsymbolmodel.cpp b/RElicAnalysis/elf/elfsymbolmodel.cpp new file mode 100644 index 0000000..1365294 --- /dev/null +++ b/RElicAnalysis/elf/elfsymbolmodel.cpp @@ -0,0 +1,34 @@ +#include "elfsymbolmodel.h" +#include + +ElfSymbolModel::ElfSymbolModel() { +} + +void ElfSymbolModel::setSymbol(struct elfSymbol *elf, struct elfObjectDisas *s){ + if(!m_hash[elf]) + m_hash[elf] = new QList(); + m_hash[elf]->append(s); +} + +/* + * This function return the list of all keys, which represent a section in Elf + */ +QList ElfSymbolModel::getKeys(){ + return m_hash.keys(); +} + +/* + * This function return all asm code from the symbol specified in argument + */ +QList *ElfSymbolModel::getASMCode(struct elfSymbol *symbol){ + return m_hash.value(symbol); +} + +ElfSymbolModel::~ElfSymbolModel(){ + if (m_hash.size() > 0){ + for (struct elfSymbol *key : m_hash.keys()){ + if (m_hash[key]) + delete m_hash[key]; + } + } +} diff --git a/RElicAnalysis/elf/elfsymbolmodel.h b/RElicAnalysis/elf/elfsymbolmodel.h new file mode 100644 index 0000000..8b5d8d7 --- /dev/null +++ b/RElicAnalysis/elf/elfsymbolmodel.h @@ -0,0 +1,22 @@ +#ifndef ELFSYMBOLMODEL_H +#define ELFSYMBOLMODEL_H + +#include +#include +#include "../data.h" + +class ElfSymbolModel +{ +public: + ElfSymbolModel(); + ~ElfSymbolModel(); + + void setSymbol(struct elfSymbol *, struct elfObjectDisas *); + QList getKeys(); + QList *getASMCode(struct elfSymbol *); + +private: + QHash *> m_hash; +}; + +#endif // ELFSYMBOLMODEL_H diff --git a/RElicAnalysis/elf/mdielf.cpp b/RElicAnalysis/elf/mdielf.cpp index 71c51dc..1cda81a 100644 --- a/RElicAnalysis/elf/mdielf.cpp +++ b/RElicAnalysis/elf/mdielf.cpp @@ -272,6 +272,7 @@ void MdiElf::_addCaracteristics(ElfData *elfData) { s += "ELF number sections: " + QString::number(hexToInt(sElfHdr->e_shnum.toHex())) + "\n"; s += "ELF sections offset: " + QString::number(hexToInt(sElfHdr->e_shoff.toHex())) + "\n"; s += "String table: " + QString::number(hexToInt(sElfHdr->e_shstrndx.toHex())) + "\n"; + s += "Bss size: " + QString::number(elfData->getBssSectionSize()) + " bytes\n"; m_textEditCaracteristics->setPlainText(s); } diff --git a/RElicAnalysis/elf/mdielfdisassembled.cpp b/RElicAnalysis/elf/mdielfdisassembled.cpp index 645e650..d54bb57 100644 --- a/RElicAnalysis/elf/mdielfdisassembled.cpp +++ b/RElicAnalysis/elf/mdielfdisassembled.cpp @@ -14,49 +14,8 @@ MdiElfDisassembled::MdiElfDisassembled(ProjectElf *projectElf): QMdiSubWindow() // Main layout QHBoxLayout *mainLayout = new QHBoxLayout; - /* - * Explorer part - * Get here all symbols, such as functions - */ - m_modelExplorer = new QStandardItemModel; - - // ListView that contains all symbols - m_viewExplorer = new QListView; - m_viewExplorer->setModel(m_modelExplorer); - m_viewExplorer->setStyleSheet("border: none"); - m_viewExplorer->setMaximumWidth(250); - connect(m_viewExplorer, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(_itemClicked(QModelIndex))); - // ASM code m_modelAnalyse = new QStandardItemModel; - QHash *> disasCode = elfData->getDisasCode(); - - for (const QByteArray &key : disasCode.keys()){ - // Add to the explorer - QStandardItem *itemExplorer = new QStandardItem(key); - m_modelExplorer->appendRow(itemExplorer); - - // Add to the QListView - QStandardItem *item = new QStandardItem(key); - QFont font; - font.setItalic(true); - font.setPointSize(12); - item->setFont(font); - m_modelAnalyse->appendRow(item); - - /* - * Add the modelIndex to the list. - * This list is used when the user has cliked the item - */ - m_listModelExplorer.append(m_modelAnalyse->indexFromItem(item)); - - /* Add the disas code to the QListView */ - for (qsizetype i = 0; i < disasCode[key]->size(); ++i){ - //qDebug() << "Disas: " << key << " " << disasCode[key]->at(i)->hexCmd; - QString s = sanitizeASMCode(disasCode[key]->at(i)); - m_modelAnalyse->appendRow(new QStandardItem(s)); - } - } // ListView that contains the ASM code m_viewAnalyse = new QListView; @@ -64,7 +23,54 @@ MdiElfDisassembled::MdiElfDisassembled(ProjectElf *projectElf): QMdiSubWindow() m_viewAnalyse->setSelectionMode(QAbstractItemView::NoSelection); //m_viewAnalyse->setStyleSheet("border: none"); - mainLayout->addWidget(m_viewExplorer); + // We get all symbols and associate with the section (QTreeWidgetItem) + m_treeWidget = new QTreeWidget; + m_treeWidget->setMaximumWidth(250); + m_treeWidget->setHeaderHidden(true); + + QHash hash = elfData->getAllSections(); + if (hash.size() > 0){ + for (const QByteArray §ion : hash.keys()){ + QTreeWidgetItem *itemSection = new QTreeWidgetItem(m_treeWidget); + itemSection->setText(0, section); + ElfSymbolModel *model = elfData->getSymbolsBySection(section); + + // Add to the QListView (ViewAnalysis) + QStandardItem *itemAnalysisSection = new QStandardItem(section); + QFont font; + font.setItalic(true); + font.setBold(true); + font.setPointSize(12); + itemAnalysisSection->setFont(font); + m_modelAnalyse->appendRow(itemAnalysisSection); + + QList symbols = model->getKeys(); + for (size_t i = 0; i < symbols.size(); i++){ + // Add to the QTreeWidget + QTreeWidgetItem *subItem = new QTreeWidgetItem(itemSection); + struct elfSymbol *symbol = symbols.at(i); + subItem->setText(0, symbol->st_name); + + // Add to the ViewAnalysis (QListView) + QStandardItem *itemSymbol = new QStandardItem(symbol->st_name); + QFont fontSymbol; + font.setItalic(true); + font.setPointSize(12); + itemSymbol->setFont(fontSymbol); + m_modelAnalyse->appendRow(itemSymbol); + + // Dump the asm code + QList *disas = model->getASMCode(symbol); + for (size_t j = 0; j < disas->size(); j++){ + struct elfObjectDisas *obj = disas->at(j); + QStandardItem *itemASM = new QStandardItem(sanitizeASMCode(obj)); + m_modelAnalyse->appendRow(itemASM); + } + } + } + } + + mainLayout->addWidget(m_treeWidget); mainLayout->addWidget(m_viewAnalyse); widget->setLayout(mainLayout); @@ -83,26 +89,16 @@ QString MdiElfDisassembled::sanitizeASMCode(struct elfObjectDisas *obj){ char tabs[maxTab + 1]; /* +1 for the \0 */ memset(tabs, 0, maxTab); size_t t; - //qDebug() << hexCmd << " " << len << " " << maxTab; + for(t = 0; t < maxTab; t++) tabs[t] = ' '; tabs[t] = '\t'; tabs[t + 1] = '\0'; return "\t" + hex + "\t" + hexCmd.toUpper() + tabs + obj->cmd; } -void MdiElfDisassembled::_itemClicked(const QModelIndex &model){ - int row = model.row(); - if (row != -1){ - m_viewAnalyse->clearSelection(); - QModelIndex model = m_listModelExplorer.at(row); - QItemSelectionModel *selection = m_viewAnalyse->selectionModel(); - selection->setCurrentIndex(model, QItemSelectionModel::Select); - } -} MdiElfDisassembled::~MdiElfDisassembled(){ - delete m_modelExplorer; delete m_modelAnalyse; - delete m_viewExplorer; delete m_viewAnalyse; + delete m_treeWidget; } diff --git a/RElicAnalysis/elf/mdielfdisassembled.h b/RElicAnalysis/elf/mdielfdisassembled.h index f7c7f30..c5d7f3b 100644 --- a/RElicAnalysis/elf/mdielfdisassembled.h +++ b/RElicAnalysis/elf/mdielfdisassembled.h @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include "../projectelf.h" /* Used for printing the ASM code */ @@ -21,15 +23,11 @@ public: private: ProjectElf *m_projectElf; - QListView *m_viewExplorer; QListView *m_viewAnalyse; - QStandardItemModel *m_modelExplorer; + QTreeWidget *m_treeWidget; QStandardItemModel *m_modelAnalyse; QList m_listModelExplorer; QString sanitizeASMCode(struct elfObjectDisas *); - -private slots: - void _itemClicked(const QModelIndex &); }; diff --git a/RElicAnalysis/elfdata.cpp b/RElicAnalysis/elfdata.cpp index ba79346..587cc13 100644 --- a/RElicAnalysis/elfdata.cpp +++ b/RElicAnalysis/elfdata.cpp @@ -13,20 +13,24 @@ ElfData::ElfData() { m_listDynSymbols = new QList; } -void ElfData::addToHash(QByteArray b, struct elfObjectDisas *obj){ - /* - * Here, we add the item in the list - * We create a map with the QList, a map contain an entry which contains a pointer to the QList - */ - if (!m_hash.contains(b)){ - m_hash[b] = new QList; - } - - m_hash[b]->append(obj); +void ElfData::newSection(QByteArray b){ + m_hashSections[b] = new ElfSymbolModel; } -QHash *> ElfData::getDisasCode(){ - return m_hash; +void ElfData::setSymbol(QByteArray b, struct elfSymbol *elf, struct elfObjectDisas *disas){ + if (m_hashSections[b]){ + //qDebug() << "New symbol: " << elf->st_name; + m_hashSections[b]->setSymbol(elf, disas); + } +} + +ElfSymbolModel *ElfData::getSymbolsBySection(QByteArray b){ + if (m_hashSections[b]) + return m_hashSections[b]; +} + +QHash ElfData::getAllSections(){ + return m_hashSections; } void ElfData::setArchitecture(int a){ @@ -73,7 +77,7 @@ void ElfData::setProgramHeader(struct elfProgram *p){ void ElfData::setSectionHeader(struct elfSection *s){ m_listSections->append(s); } -void ElfData::setSymbol(struct elfSymbol * s){ +void ElfData::setSymbol(struct elfSymbol *s){ m_listSymbols->append(s); } void ElfData::setDynSymbols(struct elfSymbol *s){ @@ -85,6 +89,9 @@ void ElfData::setHash(struct elfHash *h){ void ElfData::setTextSymbol(struct elfSymbol *sElfS){ m_listTextSymbols->append(sElfS); } +void ElfData::setBssSectionSize(unsigned long s){ + m_bssSectionSize = s; +} struct elfIdent *ElfData::getIdentification(){ return m_sElfId; @@ -110,6 +117,9 @@ QList *ElfData::getTextSymbols() { QList *ElfData::getHashes(){ return m_listHashes; } +unsigned long ElfData::getBssSectionSize(){ + return m_bssSectionSize; +} QString ElfData::mapProgramType(int type){ QString text; switch(type){ @@ -332,8 +342,11 @@ ElfData::~ElfData() { //for (qsizetype i = 0; i < m_listSections->size(); i++) // free(m_listSections->at(i)); - for (qsizetype i = 0; i < m_listSymbols->size(); i++) - free(m_listSymbols->at(i)->data); + for (qsizetype i = 0; i < m_listSymbols->size(); i++){ + //qDebug() << "Freeing: " << m_listSymbols->at(i); + //free(m_listSymbols->at(i)->data); + //free(m_listSymbols->at(i)); + } // Clean from dynamic variables from parsingelf file delete m_listProgs; @@ -343,9 +356,11 @@ ElfData::~ElfData() { delete m_listHashes; delete m_listDynSymbols; - for (const QByteArray &key : m_hash.keys()){ - for (qsizetype i = 0; i < m_hash[key]->size(); i++) - free(m_hash[key]->at(i)); - delete(m_hash[key]); + if(m_hashSections.size() > 0){ + for (const QByteArray &key : m_hashSections.keys()){ + if (m_hashSections[key]){ + delete m_hashSections[key]; // delete ElfSymbolModel object + } + } } } diff --git a/RElicAnalysis/elfdata.h b/RElicAnalysis/elfdata.h index f9aa5fe..113bfe1 100644 --- a/RElicAnalysis/elfdata.h +++ b/RElicAnalysis/elfdata.h @@ -3,6 +3,7 @@ #include #include +#include "elf/elfsymbolmodel.h" #include "data.h" enum Architecture{ @@ -26,6 +27,7 @@ class ElfData { void setSizeofElf_Ehdr(size_t); void setSizeofElf_Phdr(size_t); void setSizeofElf_Shdr(size_t); + void setBssSectionSize(unsigned long); int getArchitecture(); struct elfIdent *getIdentification(); @@ -39,6 +41,7 @@ class ElfData { size_t getSizeofElf_Ehdr(); size_t getSizeofElf_Phdr(); size_t getSizeofElf_Shdr(); + unsigned long getBssSectionSize(); QString mapProgramType(int); QString mapSectionType(int); @@ -49,8 +52,10 @@ class ElfData { QString mapMachineType(int); QString mapSymbolType(int); - void addToHash(QByteArray, struct elfObjectDisas *); - QHash *> getDisasCode(); + void newSection(QByteArray); + void setSymbol(QByteArray, struct elfSymbol *, struct elfObjectDisas *); + ElfSymbolModel *getSymbolsBySection(QByteArray); + QHash getAllSections(); private: int m_architecture; @@ -65,7 +70,8 @@ class ElfData { QList *m_listDynSymbols; QList *m_listTextSymbols; QList *m_listHashes; - QHash *> m_hash; + QHash m_hashSections; + unsigned long m_bssSectionSize; }; #endif // ELFDATA_H diff --git a/RElicAnalysis/fileinfo.cpp b/RElicAnalysis/fileinfo.cpp index e2d67c3..0d9345e 100644 --- a/RElicAnalysis/fileinfo.cpp +++ b/RElicAnalysis/fileinfo.cpp @@ -18,24 +18,6 @@ FileInfo::FileInfo(QFile &file) { m_filename = info.fileName(); QString fullPath = m_path + "/" + m_filename; m_rawData = NULL; - - /* Get signature of the file */ - //QByteArray b = file.readAll(); - //m_rawData = b.data(); - //m_rawData = (char *)malloc(m_sizeFile); - //qDebug() << "FOOO: " << b.size(); - //memcpy(m_rawData, b.data(), b.size()); - //m_rawData = b.constData(); - //m_rawData = b.data(); - //qDebug() << b[0] << b[1] << b[2] << b[3]; - //QByteArray b1 = b + 1; - //qDebug() << b1[0] << b1[1] << b1[2] << b1[3]; - - - /*QDataStream in(&file); - qint64 len = in.readRawData(m_rawData, m_sizeFile); - qDebug() << len;*/ - /* * I need to read the file in the old way, because with Qt functions, my buffer is corrupted * i do not have the full data diff --git a/RElicAnalysis/parsingelf.cpp b/RElicAnalysis/parsingelf.cpp index 2471304..91e5d6a 100644 --- a/RElicAnalysis/parsingelf.cpp +++ b/RElicAnalysis/parsingelf.cpp @@ -149,20 +149,24 @@ void elf32ProgramHdr(int fd, Elf32_Off phoff, off_t phnum){ } bool elf64SectionHdr(const char *buffer, ElfData *elfData, size_t offset, quint16 shstrndx, int shnum){ - size_t lenShdr = sizeof(Elf64_Shdr); bool res = false; + struct elfSymbol *elfSymbols = NULL; + size_t symtabnum = 0; // We malloc the variable and we free it in the elfData destructor struct elfSection *elfS = (struct elfSection *)malloc(shnum * sizeof(struct elfSection)); + ; if (elfS == NULL) return false; Elf64_Shdr *shdr = (Elf64_Shdr*)(buffer + offset); + Elf64_Sym *symtab = NULL; + // Get the string table header Elf64_Shdr *strtab = &shdr[shstrndx]; - Elf64_Shdr *shdrtext = NULL; - Elf64_Shdr *shdrfini = NULL; - Elf64_Shdr *shdrhash = NULL; + //Elf64_Shdr *shdrtext = NULL; + //Elf64_Shdr *shdrfini = NULL; + //Elf64_Shdr *shdrhash = NULL; const char *b = buffer + strtab->sh_offset; int indexStrTab = 0; int indexSymbolTab = 0; @@ -172,6 +176,36 @@ bool elf64SectionHdr(const char *buffer, ElfData *elfData, size_t offset, quint1 int indexHashTab = 0; int indexDynSymTab = 0; + /* + * We need to get the .symtab and .strtab + */ + for (int i = 0; i < shnum; i++){ + const char *shname = b + shdr[i].sh_name; + // .symtab + if (shdr[i].sh_type == 0x02 && strcmp(shname, ".symtab") == 0) + indexSymbolTab = i; + + // .strtab for symbal name + if (shdr[i].sh_type == 0x03 && strcmp(shname, ".strtab") == 0) + indexStrTab = i; + } + + /* Get all symbols and store to the ElfData */ + res = getAllSymbols(buffer, &symtab, &elfSymbols, &symtabnum, elfData, shdr, indexStrTab, indexSymbolTab); + if (!res){ + free(elfS); + return false; + } + + /*for (size_t i = 0; i < symtabnum; i++){ + qDebug() << "Symbol: " << symtab[i].st_value; + }*/ + // We need to get the symbol name + Elf64_Shdr *strTabShdr = &shdr[indexStrTab]; + // Get section for symbol table + Elf64_Shdr *symtabShdr = &shdr[indexSymbolTab]; + + for (int i = 0; i < shnum; i++){ memset(&elfS[i], 0, sizeof(struct elfSection)); @@ -186,7 +220,7 @@ bool elf64SectionHdr(const char *buffer, ElfData *elfData, size_t offset, quint1 elfS[i].sh_info = convertFrom32bits(shdr[i].sh_info); elfS[i].sh_addralign = convertFrom32bits(shdr[i].sh_addralign); elfS[i].sh_entsize = convertFrom32bits(shdr[i].sh_entsize); - qDebug() << elfS[i].sh_name << " " << elfS[i].sh_offset.toHex() << " " << elfS[i].sh_size.toHex(); + //qDebug() << elfS[i].sh_name << " " << elfS[i].sh_offset.toHex() << " " << elfS[i].sh_size.toHex(); elfData->setSectionHeader(&elfS[i]); const char *shname = b + shdr[i].sh_name; @@ -201,17 +235,93 @@ bool elf64SectionHdr(const char *buffer, ElfData *elfData, size_t offset, quint1 if (shdr[i].sh_type == 0x01 && strcmp(shname, ".text") == 0){ indexTextTab = i; + /*bool r = disasSection(buffer, elfData, ".text", shdr[i].sh_offset, shdr[i].sh_size); + if (!r) + return r;*/ + + elfData->newSection(".text"); + + unsigned long textoffset = 0, textend = 0; + textoffset = shdr[i].sh_offset; + // -1 for avoiding the .fini section + textend = shdr[i].sh_offset + shdr[i].sh_size; + + // We get all symbols from .text section + for (size_t i = 0; i < symtabnum; i++){ + unsigned long end = symtab[i].st_value + symtab[i].st_size; + + if (symtab[i].st_value >= textoffset && end <= textend && symtab[i].st_value != textend){ + const char *b2 = buffer + strTabShdr->sh_offset; + struct elfSymbol *sym = getElf64Sym(b2, symtab[i]); + //qDebug() << sym->st_name << " " << sym->st_size.toHex() << " " << sym->st_value.toHex(); + /* Disas the asm code for the symbol and store to the elfData */ + disasSymbol(buffer, ".text", elfData, sym, symtab[i].st_value, symtab[i].st_size); + + //if (sym) + // free(sym); + } + //elfData->setTextSymbol(&(*elfS)[i]); + } } - if (shdr[i].sh_type == 0x01 && strcmp(shname, ".fini") == 0) + if (shdr[i].sh_type == 0x01 && strcmp(shname, ".fini") == 0){ indexFiniTab = i; + /*bool r = disasSection(buffer, elfData, ".fini", shdr[i].sh_offset, shdr[i].sh_size); + if (!r) + return r;*/ + + elfData->newSection(".fini"); + + unsigned long finioffset = shdr[i].sh_offset; + unsigned long finiend = shdr[i].sh_offset + shdr[i].sh_size; + + for (size_t i = 0; i < symtabnum; i++){ + unsigned long end = symtab[i].st_value + symtab[i].st_size; + + /* + * In the following code, we identify if the symbol is located in the .text section + * If yes, we add it to the QList, that can be used for disassemble code + */ + if (symtab[i].st_value >= finioffset && end <= finiend && symtab[i].st_value != finiend){ + const char *b2 = buffer + strTabShdr->sh_offset; + + struct elfSymbol *sym = getElf64Sym(b2, symtab[i]); + + disasSymbol(buffer, ".fini", elfData, sym, symtab[i].st_value, symtab[i].st_size); + /*if (sym) + free(sym);*/ + } + //elfData->setTextSymbol(&(*elfS)[i]); + } + } // .data - if (shdr[i].sh_type == 0x01){ } + if (shdr[i].sh_type == 0x01 && strcmp(shname, ".data") == 0){ + /*bool r = disasSection(buffer, elfData, ".data", shdr[i].sh_offset, shdr[i].sh_size); + if (!r) + return r;*/ + + elfData->newSection(".data"); + } + + // .rodata + if (shdr[i].sh_type == 0x01 && strcmp(shname, ".rodata") == 0){ + /*bool r = disasSection(buffer, elfData, ".rodata", shdr[i].sh_offset, shdr[i].sh_size); + if (!r) + return r;*/ + + elfData->newSection(".rodata"); + } // .hash - if (shdr[i].sh_type == 0x05 && strcmp(shname, ".hash") == 0) + if (shdr[i].sh_type == 0x05 && strcmp(shname, ".hash") == 0) { indexHashTab = i; + /*bool r = disasSection(buffer, elfData, ".hash", shdr[i].sh_offset, shdr[i].sh_size); + if (!r) + return r;*/ + + elfData->newSection(".hash"); + } if (shdr[i].sh_type == 0xb && strcmp(shname, ".dynsym") == 0) indexDynSymTab = i; @@ -220,41 +330,69 @@ bool elf64SectionHdr(const char *buffer, ElfData *elfData, size_t offset, quint1 indexDynStrTab = i; // .bss - if (shdr[i].sh_type == 0x08){ - //qDebug() << b + shdr[i].sh_name; - //char *bss = (char *)malloc(shdr[i].sh_size); - //memcpy(bss, buffer + shdr[i].sh_offset, shdr[i].sh_size); - //free(bss); + if (shdr[i].sh_type == 0x08 && strcmp(shname, ".bss") == 0) { + /* + * Add the .bss section size to ElfData. + * Should be printed into the caracteristics widgets + */ + elfData->setBssSectionSize(shdr[i].sh_size); } - } - // Get all symbols in the .text section - shdrtext = &shdr[indexTextTab]; - shdrfini = &shdr[indexFiniTab]; - - /* - * Not needed to use shdrfini->sh_offset for the range of the .text - * We can add shdrtext->sh_offset + shdrtext->sh_size - */ - /* - * We can try for each symbols, to get the section .text, .data, .rodata - * getTextSections, getRodataSections, getDataSections, etc. and push to a QList - */ - - // Get all symbols - res = getSymbols(buffer, elfData, shdr, indexStrTab, indexSymbolTab, shdrtext->sh_offset, shdrfini->sh_offset); - if (!res) - return false; - // Get dynsym tab - getDynSym(buffer, elfData, shdr, indexDynSymTab, indexDynStrTab, indexHashTab); // Segmentation fault + getDynSym(buffer, elfData, shdr, indexDynSymTab, indexDynStrTab, indexHashTab); // Hash table - shdrhash = &shdr[indexHashTab]; + //shdrhash = &shdr[indexHashTab]; + return true; +} + +/* + * In this function, we get all symbols. A symbol is stored in the struct elfSymbol.\ + * Each of them are stored in the ElfData + * + * Return false if any errors occurs and true if not + */ +bool getAllSymbols(const char *buffer, Elf64_Sym **symtab, struct elfSymbol **elfS, size_t *symtabnum, ElfData *elfData, Elf64_Shdr *shdr, int indexStrTab, int indexSymbolTab){ + // Get section string table + Elf64_Shdr *strTabShdr = &shdr[indexStrTab]; + // Get section for symbol table + Elf64_Shdr *symtabShdr = &shdr[indexSymbolTab]; + + const char *b2 = buffer + strTabShdr->sh_offset; + //Elf64_Sym *symtab = (Elf64_Sym*)(buffer + shdr[indexSymbolTab].sh_offset); + *symtab = (Elf64_Sym*)(buffer + shdr[indexSymbolTab].sh_offset); + *symtabnum = symtabShdr->sh_size / sizeof(Elf64_Sym); + + /* + * Should be clean in the destructor in ElfData class + */ + *elfS = (struct elfSymbol *)malloc(*symtabnum * sizeof(struct elfSymbol)); + if (!*elfS){ + qDebug() << "Failed to allocate memory"; + *elfS = NULL; + return false; + } + + for (size_t i = 0; i < *symtabnum; i++){ + memset(&(*elfS)[i], 0, sizeof(struct elfSymbol)); + + // Get the data block from the buffer with the st_value which indicate the offset and the st_size + (*elfS)[i].st_name = QByteArray(b2 + (*symtab)[i].st_name); + (*elfS)[i].st_info = (*symtab)[i].st_info; + (*elfS)[i].st_other = (*symtab)[i].st_other; + (*elfS)[i].st_size = convertFrom64bits((*symtab)[i].st_size); + (*elfS)[i].st_shndx = convertFrom16bits((*symtab)[i].st_shndx); + (*elfS)[i].st_value = convertFrom64bits((*symtab)[i].st_value); + + elfData->setSymbol(&(*elfS)[i]); + } return true; } +/* + * This function decode the dynamic symbol + */ bool getDynSym(const char *buffer, ElfData *elfData, Elf64_Shdr *shdr, int indexDynSymTab, int indexDynStrTab, int indexHashTab){ Elf64_Shdr *shdrdynsym = &shdr[indexDynSymTab]; Elf64_Shdr *shdrDynStr = &shdr[indexDynStrTab]; @@ -265,19 +403,17 @@ bool getDynSym(const char *buffer, ElfData *elfData, Elf64_Shdr *shdr, int index Elf64_Sym *symtab = (Elf64_Sym*)(buffer + shdrdynsym->sh_offset); size_t symtabnum = shdrdynsym->sh_size / shdrdynsym->sh_entsize; - struct elfSymbol *elfS = (struct elfSymbol*)malloc(symtabnum * sizeof(elfSymbol)); + struct elfSymbol *elfS = (struct elfSymbol*)malloc(symtabnum * sizeof(struct elfSymbol)); if (elfS == NULL){ qDebug() << "Failed to allocate memory"; return false; } - for (size_t i = 0; i < symtabnum; i++){ memset(&elfS[i], 0, sizeof(struct elfSymbol)); // Get the data block from the buffer with the st_value which indicate the offset and the st_size elfS[i].st_name = QByteArray(b2 + symtab[i].st_name); - //qDebug() << elfS[i].st_name ; elfS[i].st_info = symtab[i].st_info; elfS[i].st_other = symtab[i].st_other; elfS[i].st_size = convertFrom64bits(symtab[i].st_size); @@ -288,122 +424,148 @@ bool getDynSym(const char *buffer, ElfData *elfData, Elf64_Shdr *shdr, int index } return true; } -bool getSymbols(const char *buffer, ElfData *elfData, Elf64_Shdr *shdr, int indexStrTab, int indexSymbolTab, int offsetText, int offsetFini){ - // Get section string table - Elf64_Shdr *strTabShdr = &shdr[indexStrTab]; - // Get section for symbol table - Elf64_Shdr *symtabShdr = &shdr[indexSymbolTab]; - const char *b2 = buffer + strTabShdr->sh_offset; - Elf64_Sym *symtab = (Elf64_Sym*)(buffer + shdr[indexSymbolTab].sh_offset); - size_t symtabnum = symtabShdr->sh_size / sizeof(Elf64_Sym); +/* + * In this function, we create the new struct elfSymbol, that contains informations regarding the elf + * the variable "b" contains the name of the symbol. + * The elfS object will be freed in the destructor of ElfSymbolModel + */ +struct elfSymbol *getElf64Sym(const char *b, const Elf64_Sym symtab){ + struct elfSymbol *elfS = (struct elfSymbol *)malloc(sizeof(struct elfSymbol)); + if (!elfS){ + qDebug() << "NULL"; + return NULL; + } + memset(elfS, 0, sizeof(struct elfSymbol)); - struct elfSymbol *elfS = (struct elfSymbol*)malloc(symtabnum * sizeof(elfSymbol)); - if (elfS == NULL){ - qDebug() << "Failed to allocate memory"; + elfS->st_name = b + symtab.st_name; + elfS->st_info = symtab.st_info; + elfS->st_other = symtab.st_other; + elfS->st_size = convertFrom64bits(symtab.st_size); + elfS->st_shndx = convertFrom16bits(symtab.st_shndx); + elfS->st_value = convertFrom64bits(symtab.st_value); + return elfS; +} + +/* + * This function decode the buffer into asm code with the function disas_asm (binutils) + * The asm decoded is the symbol code located at the offset specified in argument of the function + * The result is store in struct elfObjectDisas + */ +bool disasSymbol(const char *buffer, QByteArray b, ElfData *elfData, struct elfSymbol *elfS, unsigned long long offset, unsigned long long size){ + struct dataDisas *sData; + + //size += 1; + + unsigned char *tmp = (unsigned char*)malloc(size); + memcpy(tmp, buffer + offset, size); + sData = disas_asm(tmp, offset, size); + + if (!sData){ + sData = NULL; return false; } - for (size_t i = 0; i < symtabnum; i++){ - memset(&elfS[i], 0, sizeof(struct elfSymbol)); + for (int j = 0; j < sData->countEntries; j++){ + /* + * The following structure is deleted in the destructor of the ElfData + * The object is stored in a QHash objects + */ + struct elfObjectDisas *sElfObjectDisas = new struct elfObjectDisas; - // Get the data block from the buffer with the st_value which indicate the offset and the st_size - elfS[i].st_name = QByteArray(b2 + symtab[i].st_name); - elfS[i].st_info = symtab[i].st_info; - elfS[i].st_other = symtab[i].st_other; - elfS[i].st_size = convertFrom64bits(symtab[i].st_size); - elfS[i].st_shndx = convertFrom16bits(symtab[i].st_shndx); - elfS[i].st_value = convertFrom64bits(symtab[i].st_value); - - //qDebug() << elfS[i].st_name << " " << elfS[i].st_info << " " << symtab[i].st_size; - if (symtab[i].st_size > 0){ - elfS[i].data = (char*)malloc(symtab[i].st_size); - memcpy(elfS[i].data, buffer + symtab[i].st_value, symtab[i].st_size); - elfS[i].size = symtab[i].st_size; - - // We are going to the get Assembly code - struct dataDisas *sData = disas_asm((unsigned char*)elfS[i].data, symtab[i].st_value, elfS[i].size); - - if (sData == NULL){ - qDebug() << "Failed to get the assembly code"; - // I must freeing elfS structures - /*for (size_t i = 0; i < symtabnum; i++) - free(&elfS[i]);*/ - free(elfS); - elfS = NULL; - return false; - } - - /* - * Nous allons decoder les fonctions des symbols - * Pourquoi pas les variables - */ - int type = (elfS[i].st_info) & 0xf; - //qDebug() << elfS[i].st_name << " " << elfS[i].st_info <<" " << type; - - /* - * We will create a new list which will contains a struct elfObjectDisas - * and that structure store all disassembled code - * After, the entry index in struct elfSymbol is in index to the struct elfObjectDisas - */ - elfS[i].countEntries = sData->countEntries; - //QList *list = new QList; - //qDebug() << elfS[i].st_name; - - // Create new entry - for (int j = 0; j < sData->countEntries; j++){ - // Where I freeing the following structure ???? - struct elfObjectDisas *sElfObjectDisas = new struct elfObjectDisas; - - sElfObjectDisas->cmd = QByteArray( - sData->s_object_asm[j].cmd, - strlen(sData->s_object_asm[j].cmd) - ); - - sElfObjectDisas->hexCmd = QByteArray( - sData->s_object_asm[j].hexCmd, - sData->s_object_asm[j].octets - ); - sElfObjectDisas->octets = sData->s_object_asm[j].octets; - sElfObjectDisas->addr = sData->s_object_asm[j].addr; - //qDebug() << sElfObjectDisas->hexCmd; - //list->append(sElfObjectDisas); - if (type == 2){ - elfData->addToHash(elfS[i].st_name, sElfObjectDisas); - } - } - // Store the symbol disassembled code and get the index - //elfS[i].entry = elfData->setSymbolDisassembled(list); - - /* - * We don't need it anymore, we could clean our sData which contains the disas code - */ - free(sData->s_object_asm->hexCmd); + if (sElfObjectDisas == nullptr){ + //free(sData->s_object_asm->hexCmd); free(sData->s_object_asm); free(sData); + sData = NULL; + return false; } - elfData->setSymbol(&elfS[i]); - //qDebug() << b2 + symtab[i].st_name << " " << symtab[i].st_value << " " << offsetText << " " << offsetFini; - //qDebug() << b2 + symtab[i].st_name << " " << symtab[i].st_value << " " << symtab[i].st_size; - // We check if the symbol is in the .text section - if (symtab[i].st_value >= offsetText && symtab[i].st_value <= offsetFini){ - elfData->setTextSymbol(&elfS[i]); - } + memset(sElfObjectDisas, 0, sizeof(struct sElfObjectDisas *)); - /* - * We can push the symbols to the correct list - * For instance, if symtab[i].st_name == .rodata, we push to the QList - * Also, we can check with the size of the symbols - * size_t l = symtab[i].st_value + symtab[i].st_size - */ + sElfObjectDisas->cmd = QByteArray( + sData->s_object_asm[j].cmd, + strlen(sData->s_object_asm[j].cmd) + ); + + sElfObjectDisas->hexCmd = QByteArray( + sData->s_object_asm[j].hexCmd, + sData->s_object_asm[j].octets + ); + sElfObjectDisas->octets = sData->s_object_asm[j].octets; + sElfObjectDisas->addr = sData->s_object_asm[j].addr; + + elfData->setSymbol(b, elfS, sElfObjectDisas); } + //free(sData->s_object_asm->hexCmd); + free(sData->s_object_asm); + free(sData); + sData = NULL; + return true; } -void getSymbolsText(struct elfSection *sElfS, int indexTextTab, int inexFiniTab){ +/* + * This function decode the buffer into asm code with the function disas_asm (binutils) + * The result is store in struct elfObjectDisas + */ +bool disasSection(const char *buffer, ElfData *elfData, const QByteArray b, quint64 offset, quint64 size){ + struct dataDisas *sData; + + unsigned char *tmp = (unsigned char*)malloc(size); + memcpy(tmp, buffer + offset, size); + sData = disas_asm(tmp, offset, size); + + if (!sData){ + sData = NULL; + return false; + } + + for (int j = 0; j < sData->countEntries; j++){ + /* + * The following structure is deleted in the destructor of the ElfData + * The object is stored in a QHash objects + */ + struct elfObjectDisas *sElfObjectDisas = new struct elfObjectDisas; + + if (sElfObjectDisas == nullptr){ + free(sData->s_object_asm->hexCmd); + free(sData->s_object_asm); + free(sData); + sData = NULL; + return false; + } + + memset(sElfObjectDisas, 0, sizeof(struct sElfObjectDisas *)); + + sElfObjectDisas->cmd = QByteArray( + sData->s_object_asm[j].cmd, + strlen(sData->s_object_asm[j].cmd) + ); + + sElfObjectDisas->hexCmd = QByteArray( + sData->s_object_asm[j].hexCmd, + sData->s_object_asm[j].octets + ); + sElfObjectDisas->octets = sData->s_object_asm[j].octets; + sElfObjectDisas->addr = sData->s_object_asm[j].addr; + //qDebug() << sElfObjectDisas->hexCmd.toHex(); + + //QString addr; + //addr.setNum(sElfObjectDisas->addr, 16); + + //elfData->setSection(b, sElfObjectDisas); + } + + //free(sData->s_object_asm->hexCmd); + free(sData->s_object_asm); + free(sData); + sData = NULL; + + return true; } + bool getHashes(const char *buffer, ElfData *elfData){ return true; } diff --git a/RElicAnalysis/parsingelf.h b/RElicAnalysis/parsingelf.h index 982ad3f..b40010a 100644 --- a/RElicAnalysis/parsingelf.h +++ b/RElicAnalysis/parsingelf.h @@ -41,10 +41,12 @@ bool elf64ProgramHdr(const char *, ElfData *, size_t, int); void elf32ProgramHdr(int, Elf32_Off, off_t); bool elf64SectionHdr(const char *, ElfData *, size_t, quint16, int); void elf32SectionHdr(int, Elf32_Off, off_t); -bool getSymbols(const char *, ElfData *, Elf64_Shdr *, int, int, int, int); +bool disasSymbol(const char *, QByteArray, ElfData *, struct elfSymbol *, unsigned long long, unsigned long long); +bool disasSection(const char *, ElfData *, const QByteArray, quint64, quint64); +bool getAllSymbols(const char *, Elf64_Sym **, struct elfSymbol **, size_t *, ElfData *, Elf64_Shdr *, int, int); bool getDynSym(const char *, ElfData *, Elf64_Shdr *, int, int, int); -void getSymbolsText(struct elfSection *, int, int); bool getHashes(const char *, ElfData *); +struct elfSymbol *getElf64Sym(const char *, const Elf64_Sym); QByteArray convertFrom16bits(quint16); QByteArray convertFrom32bits(quint32); QByteArray convertFrom64bits(quint64);