commit b11cbe2d194da99f2d615b7dbc301b1b15b7a9df Author: geoffrey Date: Fri May 1 15:19:10 2026 +0200 First commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dd07bff --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build-* diff --git a/README.md b/README.md new file mode 100644 index 0000000..70e8347 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# RElicAnalysis +RElicAnalysis, for Reverse Engineering, relicAnalysis, it's an opensource application based on [Qt](https://www.qt.io/) for analysis binary such ELF file. diff --git a/RElicAnalysis-0.1.0 b/RElicAnalysis-0.1.0 new file mode 100755 index 0000000..dd2f3b5 Binary files /dev/null and b/RElicAnalysis-0.1.0 differ diff --git a/RElicAnalysis/CMakeLists.txt b/RElicAnalysis/CMakeLists.txt new file mode 100644 index 0000000..6b4d5aa --- /dev/null +++ b/RElicAnalysis/CMakeLists.txt @@ -0,0 +1,130 @@ +cmake_minimum_required(VERSION 3.5) + +project(RElicAnalysis VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets LinguistTools) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets LinguistTools) + +#link_directories(/usr/lib/x86_64-linux-gnu/) +find_package (opcodes) +#find_library(libopcodes ONLY_CMAKE_FIND_ROOT_PATH) +#add_library (libopcodes) +#add_library( libopcodes STATIC IMPORTED ) +#add_executable( libopcodes ) +#set_target_properties(libopcodes PROPERTIES +# IMPORTED_LOCATION "/usr/lib/x86_64-linux-gnu/libopcodes.so" +#) +# target_link_libraries( ${BFD_LIBRARY} ) + +set(TS_FILES RElicAnalysis_en_GB.ts) + +set(PROJECT_SOURCES + main.cpp + menubar.h + menubar.cpp + mainwindow.cpp + mainwindow.h +) + +if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) + qt_add_executable(RElicAnalysis + MANUAL_FINALIZATION + ${PROJECT_SOURCES} + + centralwidget.h centralwidget.cpp + parsingelf.h parsingelf.cpp + + + data.h + stylesheet.h + elfdata.h elfdata.cpp + project.h project.cpp + projectelf.h projectelf.cpp + handleproject.h handleproject.cpp + + fileinfo.h fileinfo.cpp + modelwidgetelf.h modelwidgetelf.cpp + + elf/dialogelfident.h elf/dialogelfident.cpp + elf/dialogelfheader.h elf/dialogelfheader.cpp + functions.h + functions.cpp + elf/dialogelfprogram.h elf/dialogelfprogram.cpp + elf/dialogelfsection.h elf/dialogelfsection.cpp + elf/dialogelfsymbol.h elf/dialogelfsymbol.cpp + + disasasm.h disasasm.cpp + dataDisas.h + + elf/mdielfhandler.h elf/mdielfhandler.cpp + elf/mdielf.h elf/mdielf.cpp + + + + elf/mdielfdisassembled.h elf/mdielfdisassembled.cpp + elf/mdielfview.cpp + elf/mdielfview.h + dialogabout.h dialogabout.cpp + dockmenu.h dockmenu.cpp + + + + + + + ) +# Define target properties for Android with Qt 6 as: +# set_property(TARGET RElicAnalysis APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR +# ${CMAKE_CURRENT_SOURCE_DIR}/android) +# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation + + qt_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES}) +else() + if(ANDROID) + add_library(RElicAnalysis SHARED + ${PROJECT_SOURCES} + ) +# Define properties for Android with Qt 5 after find_package() calls as: +# set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android") + else() + add_executable(RElicAnalysis + ${PROJECT_SOURCES} + ) + endif() + + qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES}) +endif() + +target_link_libraries(RElicAnalysis PRIVATE Qt${QT_VERSION_MAJOR}::Widgets opcodes) + +# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. +# If you are developing for iOS or macOS you should consider setting an +# explicit, fixed bundle identifier manually though. +if(${QT_VERSION} VERSION_LESS 6.1.0) + set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER com.example.RElicAnalysis) +endif() +set_target_properties(RElicAnalysis PROPERTIES + ${BUNDLE_ID_OPTION} + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +include(GNUInstallDirs) +install(TARGETS RElicAnalysis + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) + +if(QT_VERSION_MAJOR EQUAL 6) + qt_finalize_executable(RElicAnalysis) +endif() diff --git a/RElicAnalysis/CMakeLists.txt.user b/RElicAnalysis/CMakeLists.txt.user new file mode 100644 index 0000000..1018f3b --- /dev/null +++ b/RElicAnalysis/CMakeLists.txt.user @@ -0,0 +1,418 @@ + + + + + + EnvironmentId + {7576b28b-0509-4f2e-9112-d416507c0bdd} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + 0 + false + true + false + 0 + true + true + 0 + 8 + true + false + 1 + true + true + true + *.md, *.MD, Makefile + false + true + true + + + + ProjectExplorer.Project.PluginSettings + + + true + false + true + true + true + true + + + 0 + true + + true + true + Builtin.DefaultTidyAndClazy + 2 + true + + + + true + + + + + ProjectExplorer.Project.Target.0 + + Desktop + Desktop + Desktop + {4f4e56a4-b54b-4c8a-9576-1e917c71a3c7} + 0 + 0 + 0 + + Debug + 2 + false + + -DCMAKE_GENERATOR:STRING=Unix Makefiles +-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} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} + 0 + /home/geoffrey/Documents/GIT/cryptoshield/RElicAnalysis/build-RElicAnalysis-Desktop-Debug + + + + + all + + false + + true + Build + CMakeProjectManager.MakeStep + + 1 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + + clean + + false + + true + Build + CMakeProjectManager.MakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Debug + CMakeProjectManager.CMakeBuildConfiguration + + + Release + 2 + false + + -DCMAKE_GENERATOR:STRING=Unix Makefiles +-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} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} + /home/geoffrey/Documents/GIT/cryptoshield/RElicAnalysis/build-RElicAnalysis-Desktop-Release + + + + + 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 + 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 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ProjectExplorer.DefaultDeployConfiguration + + 1 + + true + true + 0 + true + + + 2 + + false + + ProjectExplorer.CustomExecutableRunConfiguration + + false + true + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/RElicAnalysis/centralwidget.cpp b/RElicAnalysis/centralwidget.cpp new file mode 100644 index 0000000..ca05668 --- /dev/null +++ b/RElicAnalysis/centralwidget.cpp @@ -0,0 +1,40 @@ +#include "centralwidget.h" + + +CentralWidget::CentralWidget(MainWindow *mainWindow): QMdiArea() { + m_mainWindow = mainWindow; + setViewMode(QMdiArea::TabbedView); + setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); + setAttribute(Qt::WA_Resized); + //setTabPosition(QTabWidget::West); + + /*setStyleSheet("QTabWidget::pane {" + "border: 1px solid lightgray; " + "top:-1px; " + "color: #FFF;" + "background-color: #656565;} " + "QTabBar::tab {padding:15px;background-color: #656565;}" + "QTabBar::tab::hover {background-color: #aaa;}" + "QTabBar::tab::selected {background-color: #353535;border-left:3px solid #000;color:#aaa;font-weight:bold;}"); + */ + //this->_addWelcomeTab(); +} +void CentralWidget::closeCurrentProject(){ + +} +void CentralWidget::_addWelcomeTab(){ + QMdiSubWindow *window = new QMdiSubWindow; + window->setWindowTitle("Welcome"); + window->resize(this->width(), this->height()); + window->setWindowFlags(Qt::FramelessWindowHint); + + QWidget *mainWidget = new QWidget; + QVBoxLayout *layout = new QVBoxLayout; + + + mainWidget->setLayout(layout); + window->setWidget(mainWidget); + + addSubWindow(window)->show(); +} +CentralWidget::~CentralWidget(){} diff --git a/RElicAnalysis/centralwidget.h b/RElicAnalysis/centralwidget.h new file mode 100644 index 0000000..725fbc8 --- /dev/null +++ b/RElicAnalysis/centralwidget.h @@ -0,0 +1,25 @@ +#ifndef CENTRALWIDGET_H +#define CENTRALWIDGET_H + +#include +#include +#include +#include +#include "elf/mdielfhandler.h" + + +class MainWindow; +class CentralWidget: public QMdiArea { + Q_OBJECT + public: + CentralWidget(MainWindow *); + ~CentralWidget(); + void closeCurrentProject(); + + private: + MainWindow *m_mainWindow; + + void _addWelcomeTab(); +}; + +#endif // CENTRALWIDGET_H diff --git a/RElicAnalysis/data.h b/RElicAnalysis/data.h new file mode 100644 index 0000000..ac0cc18 --- /dev/null +++ b/RElicAnalysis/data.h @@ -0,0 +1,110 @@ +#ifndef DATA_H +#define DATA_H + +#include + +/* Signature file */ +#define SIGNATURE_UNKNOWN 0 +#define SIGNATURE_ELF 1 +#define SIGNATURE_PE 2 +#define SIGNATURE_PNG 3 + +/*** ELF ***/ +// quint16 -> unsigned short -> 16bits -> 2 bytes +// quint32 -> unsigned int -> 32bits -> 4 bytes +// quint64 -> unsigned long long int -> 64bits -> 8 bytes + +struct elfIdent{ + QByteArray signature[4]; + QByteArray arch; + QByteArray endianess; // LSB = 1; MSB = 2 + QByteArray version; + QByteArray abi; + QByteArray vers_abi; + QByteArray padding[7]; +}; + +struct elfHdr{ + QByteArray e_type; + QByteArray e_machine; + QByteArray e_version; + QByteArray e_entry; + QByteArray e_phoff; + QByteArray e_shoff; + QByteArray e_flags; + QByteArray e_ehsize; + QByteArray e_phentsize; + QByteArray e_phnum; + QByteArray e_shentsize; + QByteArray e_shnum; + QByteArray e_shstrndx; +}; +struct elf32Hdr{ + /* + * For type + * https://github.com/torvalds/linux/blob/master/include/uapi/linux/elf.h + */ + quint16 e_type; + quint16 e_machine; + quint32 e_version; + quint32 e_entry; + quint32 e_phoff; + quint32 e_shoff; + quint32 e_flags; + quint16 e_ehsize; + quint16 e_phentsize; + quint16 e_phnum; + quint16 e_shentsize; + quint16 e_shnum; + quint16 e_shstrndx; +}; +struct elfProgram { + QByteArray p_type; + QByteArray p_flags; + QByteArray p_offset; + QByteArray p_vaddr; + QByteArray p_paddr; + QByteArray p_filesz; + QByteArray p_memsz; + QByteArray p_align; +}; +struct elfSection { + QByteArray sh_name; + QByteArray sh_type; + QByteArray sh_flags; + QByteArray sh_addr; + QByteArray sh_offset; + QByteArray sh_size; + QByteArray sh_link; + QByteArray sh_info; + QByteArray sh_addralign; + QByteArray sh_entsize; +}; + +struct elfObjectDisas { + QByteArray cmd; // Store the command + //char *hexCmd; // Store the command in hex + QByteArray hexCmd; + //char *hexCmd2; + size_t octets; + size_t addr; // Command start at +}; + +struct elfSymbol { + QByteArray st_name; + QByteArray st_value; + QByteArray st_size; + unsigned char st_info; + unsigned char st_other; + QByteArray st_shndx; + char *data; + uint64_t size; + int countEntries; + int entry; +}; + +struct elfHash { + +}; + +#endif // DATA_H diff --git a/RElicAnalysis/dataDisas.h b/RElicAnalysis/dataDisas.h new file mode 100644 index 0000000..40596df --- /dev/null +++ b/RElicAnalysis/dataDisas.h @@ -0,0 +1,22 @@ +#ifndef DATADISAS_H +#define DATADISAS_H + +#include + + +#define NUMBER_STRUCT_ENTRIES 128 +#define SIZE_OBJECT_CMD 64 + +struct object_asm { + char cmd[SIZE_OBJECT_CMD]; // Store the command + char *hexCmd; // Store the command in hex + size_t octets; + size_t addr; // Command start at +}; + +struct dataDisas { + struct object_asm *s_object_asm; + int countEntries; +}; + +#endif // DATADISAS_H diff --git a/RElicAnalysis/dialogabout.cpp b/RElicAnalysis/dialogabout.cpp new file mode 100644 index 0000000..c6cf9f0 --- /dev/null +++ b/RElicAnalysis/dialogabout.cpp @@ -0,0 +1,81 @@ +#include "dialogabout.h" + +DialogAbout::DialogAbout(): QDialog() { + setWindowTitle("About RElicAnalysis"); + //setStyleSheet("QDialog::border: 1px solid #afafaf;"); + + QVBoxLayout *mainLayout = new QVBoxLayout; + + QLabel *labelTitle = new QLabel("RElicAnalysis 0.1.0"); + QFont fontTitle; + fontTitle.setPointSize(15); + fontTitle.setBold(true); + labelTitle->setFont(fontTitle); + mainLayout->addWidget(labelTitle); + + QString basedOn = "Based on Qt " + QByteArray(QT_VERSION_STR); + QLabel *labelBasedOn = new QLabel(basedOn); + mainLayout->addWidget(labelBasedOn); + + QLabel *labelAuthor = new QLabel("Author: Bucchino Geoffrey"); + mainLayout->addWidget(labelAuthor); + + QLabel *labelLicense = new QLabel("Under the licence GPL"); + mainLayout->addWidget(labelLicense); + + QLabel *labelWebsite = new QLabel("Visit https://cryptoshield.bucchino.org/ for more information"); + mainLayout->addWidget(labelWebsite); + + QHBoxLayout *layoutButtons = new QHBoxLayout; + QPushButton *buttonQuit = new QPushButton("Close"); + buttonQuit->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + connect(buttonQuit, SIGNAL(clicked()), this, SLOT(close())); + layoutButtons->addStretch(1); + layoutButtons->addWidget(buttonQuit, 0, Qt::AlignRight); + + mainLayout->addLayout(layoutButtons); + mainLayout->addStretch(); + setLayout(mainLayout); +} + +/*DialogAbout::DialogAbout() : QDialog() { + QVBoxLayout *layout = new QVBoxLayout; + + // Informations + QGridLayout *layoutAbout = new QGridLayout; + QLabel *labelLeftName = new QLabel("Nom du programme"); + QLabel *labelRightName = new QLabel("Editeur LaTex"); + QLabel *labelLeftVersion = new QLabel("Version"); + QLabel *labelRightVersion = new QLabel("1.0"); + QLabel *labelLeftLicence = new QLabel("Licence"); + QLabel *labelRightLicence = new QLabel("GPL"); + QLabel *labelLeftAuthor= new QLabel("Auteur"); + QLabel *labelRightAuthor = new QLabel("BUCCHINO Geoffrey"); + QLabel *labelLeftURL = new QLabel("Adresse Internet"); + QLabel *labelRightURL = new QLabel("www.geoffreybucchino.com"); + + layoutAbout->addWidget(labelLeftName, 0,0); + layoutAbout->addWidget(labelRightName, 0,1); + layoutAbout->addWidget(labelLeftVersion,1,0); + layoutAbout->addWidget(labelRightVersion,1,1); + layoutAbout->addWidget(labelLeftLicence,2,0); + layoutAbout->addWidget(labelRightLicence,2,1); + layoutAbout->addWidget(labelLeftAuthor,3,0); + layoutAbout->addWidget(labelRightAuthor, 3,1); + layoutAbout->addWidget(labelLeftURL,4,0); + layoutAbout->addWidget(labelRightURL,4,1); + + // Button + QHBoxLayout *layoutButton = new QHBoxLayout; + layoutButton->setAlignment(Qt::AlignRight); + QPushButton *buttonOk = new QPushButton("Ok"); + connect(buttonOk, SIGNAL(clicked()), this, SLOT(close())); + + layoutButton->addWidget(buttonOk); + + layout->addLayout(layoutAbout); + layout->addLayout(layoutButton); + + setLayout(layout); +}*/ + diff --git a/RElicAnalysis/dialogabout.h b/RElicAnalysis/dialogabout.h new file mode 100644 index 0000000..68604fd --- /dev/null +++ b/RElicAnalysis/dialogabout.h @@ -0,0 +1,19 @@ +#ifndef DIALOGABOUT_H +#define DIALOGABOUT_H + +#include +#include +#include +#include +#include +#include + +class DialogAbout : public QDialog +{ +public: + DialogAbout(); + + +}; + +#endif // DIALOGABOUT_H diff --git a/RElicAnalysis/disasasm.cpp b/RElicAnalysis/disasasm.cpp new file mode 100644 index 0000000..173f958 --- /dev/null +++ b/RElicAnalysis/disasasm.cpp @@ -0,0 +1,156 @@ +#include "disasasm.h" +#include + + +static int dump_asm(void *stream, const char *fmt, ...){ + struct dataDisas *sData = (struct dataDisas*)stream; + size_t index = sData->countEntries; + + va_list args; + va_start(args, fmt); + char str[SIZE_OBJECT_CMD]; + vsprintf(str, fmt, args); + + va_end(args); + + char tmp[SIZE_OBJECT_CMD]; + memset(tmp, 0, SIZE_OBJECT_CMD); + if (strlen(sData->s_object_asm[index].cmd) > 0){ + memcpy(tmp, sData->s_object_asm[index].cmd, strlen(sData->s_object_asm[index].cmd)); + //strlcat(tmp, str, strlen(str)); + strcat(tmp, str); + } + else + memcpy(tmp, str, strlen(str)); + + memcpy(sData->s_object_asm[index].cmd, tmp, strlen(tmp)); + return 0; +} +/* + * 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)), + const char *fmt __attribute__((unused)), ...) +{ + struct dataDisas *sData = (struct dataDisas*)out; + size_t index = sData->countEntries; + + va_list args; + va_start(args, fmt); + char str[SIZE_OBJECT_CMD]; + vsprintf(str, fmt, args); + + va_end(args); + + char tmp[SIZE_OBJECT_CMD]; + memset(tmp, 0, SIZE_OBJECT_CMD); + if (strlen(sData->s_object_asm[index].cmd) > 0){ + memcpy(tmp, sData->s_object_asm[index].cmd, strlen(sData->s_object_asm[index].cmd)); + //strlcat(tmp, str, strlen(str)); + strcat(tmp, str); + } + else + memcpy(tmp, str, strlen(str)); + + 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; + + /* + * We are going to allocate our struct dataDisas which will contains our assembly code + * We are unallocated in parsing Elf file + */ + struct dataDisas *sData = (struct dataDisas*)malloc(sizeof(struct dataDisas)); + if (sData == NULL){ + qDebug() << "Failed to allocate"; + return NULL; + } + + sData->s_object_asm = (struct object_asm*)malloc(sizeof(struct object_asm) * NUMBER_STRUCT_ENTRIES); + if (sData->s_object_asm == NULL){ + qDebug() << "Failed to allocate"; + free(sData); + return NULL; + } + memset(sData->s_object_asm, 0, sizeof(&sData->s_object_asm)); + for (int i = 0; i < NUMBER_STRUCT_ENTRIES; i++) + memset(sData->s_object_asm[i].cmd, 0, SIZE_OBJECT_CMD); + + sData->countEntries = 0; + + /* + * Init out disassemble_info struct and provide our sData structure as a stream + * Find in the file dis-asm.h: + * Defined in https://github.com/redox-os/binutils-gdb/blob/master/include/dis-asm.h + * For the architecture: https://ftp.gnu.org/old-gnu/Manuals/bfd-2.9.1/html_node/bfd_29.html + */ + // TODO: Need to identify the version of the libbinutils, for old system, it's with three arguments + //qDebug() << BFD_VERSION; + //qDebug() << bfd_version_string(); + + /* + * 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); + disasm_info.arch = bfd_arch_i386; + disasm_info.mach = bfd_mach_x86_64; + disasm_info.read_memory_func = buffer_read_memory; + disasm_info.buffer = buffer; + disasm_info.buffer_vma = 0; + disasm_info.buffer_length = length; + disassemble_init_for_target(&disasm_info); + + disassembler_ftype disas; + disas = disassembler(bfd_arch_i386, false, bfd_mach_x86_64, NULL); + + if (!disas){ + qDebug() << "Cannot be disassembled"; + return NULL; + } + + size_t i = 0; + int count = 0; + int relocating = 1; + int nextStart = startAddress; + int bufferIndex = 0; + while (i < length){ + size_t octets = disas(i, &disasm_info); + sData->s_object_asm[sData->countEntries].octets = octets; + sData->s_object_asm[sData->countEntries].addr = nextStart; + + /* + * hexCmd will contain the command in hex + * 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); + memcpy(sData->s_object_asm[sData->countEntries].hexCmd, + &buffer[bufferIndex], + octets); + i += octets; + nextStart += octets; + bufferIndex += octets; + + sData->countEntries++; + count++; + + // If we have an out of memory, we extend the buffer + if (count == NUMBER_STRUCT_ENTRIES){ + relocating++; + sData->s_object_asm = (struct object_asm *)realloc(sData->s_object_asm, sizeof(struct object_asm) * (NUMBER_STRUCT_ENTRIES * relocating)); + + // Reinit ? + + count = 0; + } + // Init the next structure + 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/disasasm.h b/RElicAnalysis/disasasm.h new file mode 100644 index 0000000..7c2b6bc --- /dev/null +++ b/RElicAnalysis/disasasm.h @@ -0,0 +1,28 @@ +#ifndef DISASASM_H +#define DISASASM_H + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "bfd.h" +#include "dataDisas.h" + +/* + * References + * - https://dwarfstd.org/doc/Debugging%20using%20DWARF-2012.pdf + * - https://ftp.gnu.org/old-gnu/Manuals/bfd-2.9.1/html_chapter/bfd_1.html + */ + +// +static bfd_boolean disassemble; + +static int dump_asm(void *, const char *,...); + struct dataDisas *disas_asm(unsigned char *, uint64_t, size_t); + +#endif // DISASASM_H diff --git a/RElicAnalysis/dockmenu.cpp b/RElicAnalysis/dockmenu.cpp new file mode 100644 index 0000000..f4174dc --- /dev/null +++ b/RElicAnalysis/dockmenu.cpp @@ -0,0 +1,56 @@ +#include "dockmenu.h" + +QDockMenu::QDockMenu() { + // Sidebar widget + QWidget *sidebar = new QWidget; + QVBoxLayout *layout = new QVBoxLayout(sidebar); + layout->setSpacing(10); + layout->setContentsMargins(5, 5, 5, 5); + + // Create buttons + QToolButton *btnWelcome = new QToolButton; + btnWelcome->setIcon(QIcon(":/icons/welcome.png")); // your icon + btnWelcome->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + btnWelcome->setText("Welcome"); + + QToolButton *btnEdit = new QToolButton; + btnEdit->setIcon(QIcon(":/icons/edit.png")); + btnEdit->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + btnEdit->setText("Edit"); + + QToolButton *btnDesign = new QToolButton; + btnDesign->setIcon(QIcon(":/icons/design.png")); + btnDesign->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + btnDesign->setText("Design"); + + QToolButton *btnDebug = new QToolButton; + btnDebug->setIcon(QIcon(":/icons/debug.png")); + btnDebug->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + btnDebug->setText("Debug"); + + QToolButton *btnProjects = new QToolButton; + btnProjects->setIcon(QIcon(":/icons/projects.png")); + btnProjects->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + btnProjects->setText("Projects"); + + QToolButton *btnHelp = new QToolButton; + btnHelp->setIcon(QIcon(":/icons/help.png")); + btnHelp->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + btnHelp->setText("Help"); + + // Add buttons to layout + layout->addWidget(btnWelcome); + layout->addWidget(btnEdit); + layout->addWidget(btnDesign); + layout->addWidget(btnDebug); + layout->addWidget(btnProjects); + layout->addWidget(btnHelp); + layout->addStretch(); // push buttons to top + + // Set sidebar as dock widget or fixed widget + //window.setCentralWidget(new QWidget); // placeholder for main area + //window.addDockWidget(Qt::LeftDockWidgetArea, new QDockWidget("Sidebar", &window)); + //window.findChild()->setWidget(sidebar); + //window.findChild()->setFeatures(QDockWidget::NoDockWidgetFeatures); // fix it + +} diff --git a/RElicAnalysis/dockmenu.h b/RElicAnalysis/dockmenu.h new file mode 100644 index 0000000..271b237 --- /dev/null +++ b/RElicAnalysis/dockmenu.h @@ -0,0 +1,15 @@ +#ifndef DOCKMENU_H +#define DOCKMENU_H + +#include +#include +#include +#include + +class QDockMenu +{ +public: + QDockMenu(); +}; + +#endif // DOCKMENU_H diff --git a/RElicAnalysis/elf.cpp b/RElicAnalysis/elf.cpp new file mode 100644 index 0000000..957618d --- /dev/null +++ b/RElicAnalysis/elf.cpp @@ -0,0 +1,233 @@ +#include +#include +#include +#include +#include +#include +#include + +struct elf_ident{ + unsigned char arch; + unsigned char endianess; + unsigned char version; + unsigned char abi; + unsigned char vers_abi; + unsigned char padding[7]; + unsigned char len; +} __attribute__((packed)); + +static int getSignature(int); +static void elf32(int, off_t, Elf32_Ehdr*); +static void elf64(int, off_t, Elf64_Ehdr*); +static void elf64ProgramHdr(int, Elf64_Off, off_t); +static void elf32ProgramHdr(int, Elf32_Off, off_t); +static void elf64SectionHdr(int, Elf64_Off, off_t); +static void elf32SectionHdr(int, Elf32_Off, off_t); +int main(int argc, char *argv[]){ + struct stat st; + struct elf_ident *sElfIdent = NULL; + char buffer_ident[12] = {0}; + int fd_r; + size_t length; + int res; + if (argc < 2){ + printf("Please, specify the ELF file\n"); + exit(-1); + } + + /* Get stat information */ + stat(argv[1], &st); + + if ((fd_r = open(argv[1], O_RDONLY)) == -1){ + printf("Failed to read the file %s\n", argv[1]); + exit(-1); + } + /* Get th 4 first bytes to get the signature */ + res = getSignature(fd_r); + if (res == -1 || res == 0){ + printf("Failed to get the signature of the file\n"); + exit(-1); + } + + /* Now, we get the 12 first bytes for the ELF identification */ + length = read(fd_r, buffer_ident, 12); + + sElfIdent = (struct elf_ident*)buffer_ident; + + printf("ELF header information:\n"); + printf("Arch:\t\t%d\n", sElfIdent->arch); + printf("Endianess:\t%d\n", sElfIdent->endianess); + printf("Version:\t%d\n", sElfIdent->version); + printf("ABI:\t\t%d\n", sElfIdent->abi); + printf("Version ABI:\t%d\n", sElfIdent->vers_abi); + /*printf("Padding: "); + for(int i = 0; i < 7; i++) + printf("%d ", sElfIdent->padding[i]); + printf("\n");*/ + printf("Length:\t\t%d\n", sElfIdent->len); + + // Now, get all the Elf header + lseek(fd_r, 0, SEEK_SET); + + if (sElfIdent->arch == 1) { // Arch x82 + char buffer[sizeof(Elf32_Ehdr)]; // 52 bytes + length = read(fd_r, buffer, 52); + elf32(fd_r, st.st_size, (Elf32_Ehdr*)buffer); + + }else if(sElfIdent->arch == 2) { // Arch x64 + char buffer[sizeof(Elf64_Ehdr)]; // 64 bytes + length = read(fd_r, buffer, 64); + elf64(fd_r, st.st_size, (Elf64_Ehdr*)buffer); + } + + + close(fd_r); +} +/* + * This function get the signature to be sure if the file is a ELF + */ +static int getSignature(int fd) { + char buffer[4]; + size_t length = read(fd, buffer, 4); + + if (length == -1) + return -1; + + /*if (strcmp(buffer, "\x7f\x45\x4c\x46") == 0){ + printf("ELF\n"); + }*/ + if (buffer[0] == 0x7f && buffer[1] == 0x45 && buffer[2] == 0x4c && buffer[3] == 0x46) + return 1; + return 0; +} +static void elf64(int fd, off_t fileLen, Elf64_Ehdr *ehdr){ + size_t len = fileLen - sizeof(Elf64_Ehdr); + char buffer[len]; + + printf("Type: %d\n", ehdr->e_type); + printf("Machine: %d\n", ehdr->e_machine); + printf("Version: %d\n", ehdr->e_version); + printf("entry: %d\n", ehdr->e_entry); + printf("Phoff: %d\n", ehdr->e_phoff); + printf("Shoff: %d\n", ehdr->e_shoff); + printf("Flags: %d\n", ehdr->e_flags); + printf("Ehsize: %d\n", ehdr->e_ehsize); + printf("Phentsize: %d\n", ehdr->e_phentsize); + printf("Phnum: %d\n", ehdr->e_phnum); + printf("ShEntSize: %d\n", ehdr->e_shentsize); + printf("ShNum: %d\n", ehdr->e_shnum); + printf("Shstrndx: %d\n", ehdr->e_shstrndx); + + // Read the rest of the file + //printf("%d\n", len); + //read(fd, buffer, len); + /*for (int i = 0; i < len; i++) + printf("%02x ", buffer[i]);*/ + + // Get program headers + elf64ProgramHdr(fd, ehdr->e_phoff, ehdr->e_phnum); + + // Get section headers + elf64SectionHdr(fd, ehdr->e_shoff, ehdr->e_phnum); +} +static void elf32(int fd, off_t fileLen, Elf32_Ehdr *ehdr){ + size_t len = fileLen - sizeof(Elf32_Ehdr); + char buffer[len]; + + printf("Type: %d\n", ehdr->e_type); + printf("Machine: %d\n", ehdr->e_machine); + printf("Version: %d\n", ehdr->e_version); + printf("entry: %d\n", ehdr->e_entry); + printf("Phoff: %d\n", ehdr->e_phoff); + printf("Shoff: %d\n", ehdr->e_shoff); + printf("Flags: %d\n", ehdr->e_flags); + printf("Ehsize: %d\n", ehdr->e_ehsize); + printf("Phentsize: %d\n", ehdr->e_phentsize); + printf("Phnum: %d\n", ehdr->e_phnum); + printf("ShEntSize: %d\n", ehdr->e_shentsize); + printf("ShNum: %d\n", ehdr->e_shnum); + printf("Shstrndx: %d\n", ehdr->e_shstrndx); + + // Get program headers + elf32ProgramHdr(fd, ehdr->e_phoff, ehdr->e_phnum); +} +static void elf64ProgramHdr(int fd, Elf64_Off phoff, off_t phnum){ + printf("%ld\n", sizeof(Elf64_Phdr)); // 56 bytes + + size_t len = sizeof(Elf64_Phdr); + char buf[len]; + + // Go to the program header part + lseek(fd, phoff, SEEK_SET); + + for (int i = 0; i < phnum; i++){ + read(fd, buf, len); + Elf64_Phdr *phdr = (Elf64_Phdr*)buf; + printf("\nProgram header\n"); + printf("Type: %d\n", phdr->p_type); + printf("Offset: %d\n", phdr->p_offset); + printf("Vaddr: %d\n", phdr->p_vaddr); + printf("Paddr: %d\n", phdr->p_paddr); + printf("File size: %d\n", phdr->p_filesz); + printf("Mem size: %d\n", phdr->p_memsz); + printf("Flags: %d\n", phdr->p_flags); + printf("Align: %d\n", phdr->p_align); + + memset(buf, 0, len); + } +} +static void elf32ProgramHdr(int fd, Elf32_Off phoff, off_t phnum){ + size_t len = sizeof(Elf32_Phdr); + char buf[len]; + + // Go to the program header part + lseek(fd, phoff, SEEK_SET); + + for (int i = 0; i < phnum; i++){ + read(fd, buf, len); + Elf32_Phdr *phdr = (Elf32_Phdr*)buf; + printf("\nProgram header\n"); + printf("Type: %d\n", phdr->p_type); + printf("Offset: %d\n", phdr->p_offset); + printf("Vaddr: %d\n", phdr->p_vaddr); + printf("Paddr: %d\n", phdr->p_paddr); + printf("File size: %d\n", phdr->p_filesz); + printf("Mem size: %d\n", phdr->p_memsz); + printf("Flags: %d\n", phdr->p_flags); + printf("Align: %d\n", phdr->p_align); + + memset(buf, 0, len); + } +} +static void elf64SectionHdr(int fd, Elf64_Off phoff, off_t shnum){ + size_t len = sizeof(Elf64_Shdr); + char buf[len]; + + // Go to the program header part + lseek(fd, phoff, SEEK_SET); + + for (int i = 0; i < shnum; i++){ + read(fd, buf, len); + Elf64_Shdr *shdr = (Elf64_Shdr*)buf; + printf("\nSection header\n"); + printf("Name: %d\n", shdr->sh_name); + printf("Type: %d\n", shdr->sh_type); + + memset(buf, 0, len); + } +} +static void elf32SectionHdr(int fd, Elf32_Off phoff, off_t shnum){ + size_t len = sizeof(Elf32_Shdr); + char buf[len]; + + // Go to the program header part + lseek(fd, phoff, SEEK_SET); + + for (int i = 0; i < shnum; i++){ + read(fd, buf, len); + Elf32_Shdr *shdr = (Elf32_Shdr*)buf; + printf("\nSection header\n"); + + memset(buf, 0, len); + } +} diff --git a/RElicAnalysis/elf/dialogelfheader.cpp b/RElicAnalysis/elf/dialogelfheader.cpp new file mode 100644 index 0000000..4e98495 --- /dev/null +++ b/RElicAnalysis/elf/dialogelfheader.cpp @@ -0,0 +1,84 @@ +#include "dialogelfheader.h" + +DialogElfHeader::DialogElfHeader(ElfData *elfData): QDialog() { + struct elfHdr *sElfHdr = elfData->getHeader(); + setWindowTitle("ELF Header"); + setFixedSize(350, 250); + + QVBoxLayout *mainLayout = new QVBoxLayout; + + QGridLayout *layoutData = new QGridLayout; + layoutData->setSpacing(0); + layoutData->setContentsMargins(0, 0, 0, 0); + QLabel *labelType = new QLabel("Type: "); + QLabel *labelTypeHex = new QLabel( + elfData->mapTypeElf(hexToInt(sElfHdr->e_type.toHex())) + + " (" + printHex(sElfHdr->e_type.toHex()) + ")" + ); + QLabel *labelMachine = new QLabel("Machine: "); + QLabel *labelMachineHex = new QLabel( + elfData->mapMachineType(hexToInt(sElfHdr->e_machine.toHex())) + + " (" + printHex(sElfHdr->e_machine.toHex()) + ")" + ); + QLabel *labelVersion = new QLabel("Version: "); + QLabel *labelVersionHex = new QLabel(printHex(sElfHdr->e_version.toHex())); + QLabel *labelEntryAddres = new QLabel("Entry address: "); + QLabel *labelEntryAddressHex = new QLabel(printHex(sElfHdr->e_entry.toHex())); + QLabel *labelProgHdrOff = new QLabel("Program Header offset: "); + QLabel *labelProgHdrOffHex = new QLabel(printHex(sElfHdr->e_phoff.toHex())); + QLabel *labelSectionHdrOff = new QLabel("Section Header Offset: "); + QLabel *labelSectionHdrOffHex = new QLabel(printHex(sElfHdr->e_shoff.toHex())); + QLabel *labelFlags = new QLabel("Flags: "); + QLabel *labelFlagsHex = new QLabel(printHex(sElfHdr->e_flags.toHex())); + QLabel *labelElfHdrSize = new QLabel("ELF Header size: "); + QLabel *labelElfHdrSizeHex = new QLabel(printHex(sElfHdr->e_ehsize.toHex())); + QLabel *labelProgEntrySize = new QLabel("Program entry size: "); + QLabel *labelProgEntrySizeHex = new QLabel(printHex(sElfHdr->e_phentsize.toHex())); + QLabel *labelProgNum = new QLabel("Number of program entry: "); + QLabel *labelProgNumHex = new QLabel(printHex(sElfHdr->e_phnum.toHex())); + QLabel *labelSectionHdrSize = new QLabel("Section Header size: "); + QLabel *labelSectionHdrSizeHex = new QLabel(printHex(sElfHdr->e_shentsize.toHex())); + QLabel *labelSectionNum = new QLabel("Number of section entry: "); + QLabel *labelSectionNumHex = new QLabel(printHex(sElfHdr->e_shnum.toHex())); + QLabel *labelSectionStrIndex = new QLabel("Section string index: "); + QLabel *labelSectionStrIndexHex = new QLabel(printHex(sElfHdr->e_shentsize.toHex())); + + layoutData->addWidget(labelType, 0, 0); + layoutData->addWidget(labelTypeHex, 0, 1); + layoutData->addWidget(labelMachine, 1, 0); + layoutData->addWidget(labelMachineHex, 1, 1); + layoutData->addWidget(labelVersion, 2, 0); + layoutData->addWidget(labelVersionHex, 2, 1); + layoutData->addWidget(labelEntryAddres, 3, 0); + layoutData->addWidget(labelEntryAddressHex, 3, 1); + layoutData->addWidget(labelProgHdrOff, 4, 0); + layoutData->addWidget(labelProgHdrOffHex, 4, 1); + layoutData->addWidget(labelSectionHdrOff, 5, 0); + layoutData->addWidget(labelSectionHdrOffHex, 5, 1); + layoutData->addWidget(labelFlags, 6, 0); + layoutData->addWidget(labelFlagsHex, 6, 1); + layoutData->addWidget(labelElfHdrSize, 7, 0); + layoutData->addWidget(labelElfHdrSizeHex, 7, 1); + layoutData->addWidget(labelProgEntrySize, 8, 0); + layoutData->addWidget(labelProgEntrySizeHex, 8, 1); + layoutData->addWidget(labelProgNum, 9, 0); + layoutData->addWidget(labelProgNumHex, 9, 1); + layoutData->addWidget(labelSectionHdrSize, 10, 0); + layoutData->addWidget(labelSectionHdrSizeHex, 10, 1); + layoutData->addWidget(labelSectionNum, 11, 0); + layoutData->addWidget(labelSectionNumHex, 11, 1); + layoutData->addWidget(labelSectionStrIndex, 12, 0); + layoutData->addWidget(labelSectionStrIndexHex, 12, 1); + + QHBoxLayout *layoutButton = new QHBoxLayout; + layoutButton->setAlignment(Qt::AlignRight); + QPushButton *buttonClose = new QPushButton("Close"); + connect(buttonClose, SIGNAL(clicked()), this, SLOT(close())); + + layoutButton->addWidget(buttonClose); + + mainLayout->addLayout(layoutData); + mainLayout->addLayout(layoutButton); + + setLayout(mainLayout); +} diff --git a/RElicAnalysis/elf/dialogelfheader.h b/RElicAnalysis/elf/dialogelfheader.h new file mode 100644 index 0000000..a653ac8 --- /dev/null +++ b/RElicAnalysis/elf/dialogelfheader.h @@ -0,0 +1,20 @@ +#ifndef DIALOGELFHEADER_H +#define DIALOGELFHEADER_H + +#include +#include +#include +#include +#include +#include +#include "../data.h" +#include "../elfdata.h" +#include "../functions.h" + + +class DialogElfHeader: public QDialog { + public: + DialogElfHeader(ElfData *); +}; + +#endif // DIALOGELFHEADER_H diff --git a/RElicAnalysis/elf/dialogelfident.cpp b/RElicAnalysis/elf/dialogelfident.cpp new file mode 100644 index 0000000..b11c9b4 --- /dev/null +++ b/RElicAnalysis/elf/dialogelfident.cpp @@ -0,0 +1,62 @@ +#include "dialogelfident.h" + +DialogElfIdent::DialogElfIdent(ElfData *elfData): QDialog() { + struct elfIdent *sElfIdent = elfData->getIdentification(); + + setWindowTitle("ELF Identification"); + setFixedSize(300, 150); + QVBoxLayout *mainLayout = new QVBoxLayout; + + QGridLayout *layoutData = new QGridLayout; + layoutData->setSpacing(0); + layoutData->setContentsMargins(0, 0, 0, 0); + QLabel *labelSignature = new QLabel("Signature: "); + QLabel *labelSignatureHex = new QLabel(sElfIdent->signature[0] + + sElfIdent->signature[1] + + sElfIdent->signature[2] + + sElfIdent->signature[3]); + QLabel *labelArchitecture = new QLabel("Architecture: "); + QLabel *labelArchitectureHex = new QLabel( + elfData->mapArchitecture(hexToInt(sElfIdent->arch.toHex())) + + " (" + printHex(sElfIdent->arch.toHex()) + ")" + ); + QLabel *labelEndianness = new QLabel("Endianness: "); + QLabel *labelEndiannessHex = new QLabel( + elfData->mapEndianess(hexToInt(sElfIdent->endianess.toHex())) + + " (" + printHex(sElfIdent->endianess.toHex()) + ")" + ); + QLabel *labelVersion = new QLabel("Version: "); + QLabel *labelVersionHex = new QLabel(sElfIdent->version.toHex()); + QLabel *labelABI = new QLabel("ABI: "); + QLabel *labelABIHex = new QLabel( + elfData->mapABI(hexToInt(sElfIdent->abi.toHex())) + + " (" + printHex(sElfIdent->abi.toHex()) + ")" + ); + QLabel *labelVersABI = new QLabel("Version ABI: "); + QLabel *labelVersABIHex = new QLabel(sElfIdent->vers_abi.toHex()); + + layoutData->addWidget(labelSignature, 0, 0); + layoutData->addWidget(labelSignatureHex, 0, 1); + layoutData->addWidget(labelArchitecture, 1, 0); + layoutData->addWidget(labelArchitectureHex, 1, 1); + layoutData->addWidget(labelEndianness, 2, 0); + layoutData->addWidget(labelEndiannessHex, 2, 1); + layoutData->addWidget(labelVersion, 3, 0); + layoutData->addWidget(labelVersionHex, 3, 1); + layoutData->addWidget(labelABI, 4, 0); + layoutData->addWidget(labelABIHex, 4, 1); + layoutData->addWidget(labelVersABI, 5, 0); + layoutData->addWidget(labelVersABIHex, 5, 1); + + QHBoxLayout *layoutButton = new QHBoxLayout; + layoutButton->setAlignment(Qt::AlignRight); + QPushButton *buttonClose = new QPushButton("Close"); + connect(buttonClose, SIGNAL(clicked()), this, SLOT(close())); + + layoutButton->addWidget(buttonClose); + + mainLayout->addLayout(layoutData); + mainLayout->addLayout(layoutButton); + + setLayout(mainLayout); +} diff --git a/RElicAnalysis/elf/dialogelfident.h b/RElicAnalysis/elf/dialogelfident.h new file mode 100644 index 0000000..1f381b6 --- /dev/null +++ b/RElicAnalysis/elf/dialogelfident.h @@ -0,0 +1,20 @@ +#ifndef DIALOGELFIDENT_H +#define DIALOGELFIDENT_H + +#include +#include +#include +#include +#include +#include +#include "../data.h" +#include "../elfdata.h" +#include "../functions.h" + + +class DialogElfIdent: public QDialog { + public: + DialogElfIdent(ElfData *); +}; + +#endif // DIALOGELFIDENT_H diff --git a/RElicAnalysis/elf/dialogelfprogram.cpp b/RElicAnalysis/elf/dialogelfprogram.cpp new file mode 100644 index 0000000..d1e1c84 --- /dev/null +++ b/RElicAnalysis/elf/dialogelfprogram.cpp @@ -0,0 +1,82 @@ +#include "dialogelfprogram.h" + +DialogElfProgram::DialogElfProgram(): QDialog() { + setWindowTitle("ELF Program"); + setFixedSize(350, 250); + + QVBoxLayout *mainLayout = new QVBoxLayout; + + QGridLayout *layoutData = new QGridLayout; + QLabel *labelProgramType = new QLabel("Program type: "); + m_labelProgramType = new QLabel; + QLabel *labelProgFlags = new QLabel("Flags: "); + m_labelProgFlags = new QLabel; + QLabel *labelOffset = new QLabel("Offset: "); + m_labelOffset = new QLabel; + QLabel *labelVA = new QLabel("Virtual Address: "); + m_labelVA = new QLabel; + QLabel *labelPA = new QLabel("Physical Address: "); + m_labelPA = new QLabel; + QLabel *labelProgramSize = new QLabel("Program size: "); + m_labelProgramSize = new QLabel; + QLabel *labelMemSize = new QLabel("Memory size: "); + m_labelMemSize = new QLabel; + QLabel *labelAlign = new QLabel("Align: "); + m_labelAlign = new QLabel; + + layoutData->addWidget(labelProgramType, 0, 0); + layoutData->addWidget(m_labelProgramType, 0, 1); + layoutData->addWidget(labelProgFlags, 1, 0); + layoutData->addWidget(m_labelProgFlags, 1, 1); + layoutData->addWidget(labelOffset, 2, 0); + layoutData->addWidget(m_labelOffset, 2, 1); + layoutData->addWidget(labelVA, 3, 0); + layoutData->addWidget(m_labelVA, 3, 1); + layoutData->addWidget(labelPA, 4, 0); + layoutData->addWidget(m_labelPA, 4, 1); + layoutData->addWidget(labelProgramSize, 5, 0); + layoutData->addWidget(m_labelProgramSize, 5, 1); + layoutData->addWidget(labelMemSize, 6, 0); + layoutData->addWidget(m_labelMemSize, 6, 1); + layoutData->addWidget(labelAlign, 7, 0); + layoutData->addWidget(m_labelAlign, 7, 1); + + QHBoxLayout *layoutButton = new QHBoxLayout; + layoutButton->setAlignment(Qt::AlignRight); + QPushButton *buttonClose = new QPushButton("Close"); + connect(buttonClose, SIGNAL(clicked()), this, SLOT(close())); + + layoutButton->addWidget(buttonClose); + + mainLayout->addLayout(layoutData); + mainLayout->addLayout(layoutButton); + + setLayout(mainLayout); +} +/*QString foo(QByteArray b){ + QString n = QString::number(hexToInt(b.toHex())); + return "0x" + b.toHex() + " (" + n + ")10"; +}*/ +void DialogElfProgram::setData(struct elfProgram *sElfP){ + m_labelProgramType->setText(printHex(sElfP->p_type.toHex())); + //m_labelProgramType->setText(foo(sElfP->p_type)); + m_labelProgFlags->setText(printHex(sElfP->p_flags.toHex())); + //qDebug() << sElfP->p_offset.toHex(); + //m_labelOffset->setText(QString::number(hexToInt(sElfP->p_offset.toHex()))); + m_labelOffset->setText(printHex(sElfP->p_offset.toHex())); + m_labelVA->setText(printHex(sElfP->p_vaddr.toHex())); + m_labelPA->setText(printHex(sElfP->p_paddr.toHex())); + m_labelProgramSize->setText(printHex(sElfP->p_filesz.toHex())); + m_labelMemSize->setText(printHex(sElfP->p_memsz.toHex())); + m_labelAlign->setText(printHex(sElfP->p_align.toHex())); +} +DialogElfProgram::~DialogElfProgram() { + delete m_labelProgramType; + delete m_labelProgFlags; + delete m_labelOffset; + delete m_labelVA; + delete m_labelPA; + delete m_labelProgramSize; + delete m_labelMemSize; + delete m_labelAlign; +} diff --git a/RElicAnalysis/elf/dialogelfprogram.h b/RElicAnalysis/elf/dialogelfprogram.h new file mode 100644 index 0000000..f69b0e1 --- /dev/null +++ b/RElicAnalysis/elf/dialogelfprogram.h @@ -0,0 +1,32 @@ +#ifndef DIALOGELFPROGRAM_H +#define DIALOGELFPROGRAM_H + +#include +#include +#include +#include +#include +#include +#include "../elfdata.h" +#include "../data.h" +#include "../functions.h" + + +class DialogElfProgram: public QDialog { + public: + DialogElfProgram(); + ~DialogElfProgram(); + void setData(struct elfProgram *); + + private: + QLabel *m_labelProgramType; + QLabel *m_labelProgFlags; + QLabel *m_labelOffset; + QLabel *m_labelVA; + QLabel *m_labelPA; + QLabel *m_labelProgramSize; + QLabel *m_labelMemSize; + QLabel *m_labelAlign; +}; + +#endif // DIALOGELFPROGRAM_H diff --git a/RElicAnalysis/elf/dialogelfsection.cpp b/RElicAnalysis/elf/dialogelfsection.cpp new file mode 100644 index 0000000..53eb774 --- /dev/null +++ b/RElicAnalysis/elf/dialogelfsection.cpp @@ -0,0 +1,85 @@ +#include "dialogelfsection.h" + +DialogElfSection::DialogElfSection() { + setWindowTitle("ELF Section"); + setFixedSize(350, 250); + + QVBoxLayout *mainLayout = new QVBoxLayout; + + QGridLayout *layoutData = new QGridLayout; + QLabel *labelSectionName = new QLabel("Section name: "); + m_labelSectionName = new QLabel; + QLabel *labelType = new QLabel("Type: "); + m_labelType = new QLabel; + QLabel *labelFlags = new QLabel("Flags: "); + m_labelFlags = new QLabel; + QLabel *labelAddress = new QLabel("Address: "); + m_labelAddress = new QLabel; + QLabel *labelOffset = new QLabel("Offset: "); + m_labelOffset = new QLabel; + QLabel *labelSectionSize = new QLabel("Section size: "); + m_labelSectionSize = new QLabel; + QLabel *labelLink = new QLabel("Link: "); + m_labelLink = new QLabel; + QLabel *labelInfo = new QLabel("Info: "); + m_labelInfo = new QLabel; + QLabel *labelAddressAlign = new QLabel("Address Align: "); + m_labelAddressAlign = new QLabel; + QLabel *labelEntrySize = new QLabel("Entry size: "); + m_labelEntrySize = new QLabel; + + layoutData->addWidget(labelSectionName, 0, 0); + layoutData->addWidget(m_labelSectionName, 0, 1); + layoutData->addWidget(labelType, 1, 0); + layoutData->addWidget(m_labelType, 1, 1); + layoutData->addWidget(labelFlags, 2, 0); + layoutData->addWidget(m_labelFlags, 2, 1); + layoutData->addWidget(labelAddress, 3, 0); + layoutData->addWidget(m_labelAddress, 3, 1); + layoutData->addWidget(labelOffset, 4, 0); + layoutData->addWidget(m_labelOffset, 4, 1); + layoutData->addWidget(labelSectionSize, 5, 0); + layoutData->addWidget(m_labelSectionSize, 5, 1); + layoutData->addWidget(labelLink, 6, 0); + layoutData->addWidget(m_labelLink, 6, 1); + layoutData->addWidget(labelInfo, 7, 0); + layoutData->addWidget(m_labelInfo, 7, 1); + layoutData->addWidget(labelAddressAlign, 8, 0); + layoutData->addWidget(m_labelAddressAlign, 8, 1); + + QHBoxLayout *layoutButton = new QHBoxLayout; + layoutButton->setAlignment(Qt::AlignRight); + QPushButton *buttonClose = new QPushButton("Close"); + connect(buttonClose, SIGNAL(clicked()), this, SLOT(close())); + + layoutButton->addWidget(buttonClose); + + mainLayout->addLayout(layoutData); + mainLayout->addLayout(layoutButton); + + setLayout(mainLayout); +} +void DialogElfSection::setData(struct elfSection *sElfS){ + m_labelSectionName->setText(sElfS->sh_name); + m_labelType->setText(printHex(sElfS->sh_type.toHex())); + m_labelFlags->setText(sElfS->sh_flags.toHex()); + m_labelAddress->setText(printHex(sElfS->sh_addr.toHex())); + m_labelOffset->setText(printHex(sElfS->sh_offset.toHex())); + m_labelSectionSize->setText(printHex(sElfS->sh_size.toHex())); + m_labelLink->setText(printHex(sElfS->sh_link.toHex())); + m_labelInfo->setText(printHex(sElfS->sh_info.toHex())); + m_labelAddressAlign->setText(printHex(sElfS->sh_addralign.toHex())); + m_labelEntrySize->setText(printHex(sElfS->sh_entsize.toHex())); +} +DialogElfSection::~DialogElfSection() { + delete m_labelSectionName; + delete m_labelType; + delete m_labelFlags; + delete m_labelAddress; + delete m_labelOffset; + delete m_labelSectionSize; + delete m_labelLink; + delete m_labelInfo; + delete m_labelAddressAlign; + delete m_labelEntrySize; +} diff --git a/RElicAnalysis/elf/dialogelfsection.h b/RElicAnalysis/elf/dialogelfsection.h new file mode 100644 index 0000000..49336c3 --- /dev/null +++ b/RElicAnalysis/elf/dialogelfsection.h @@ -0,0 +1,33 @@ +#ifndef DIALOGELFSECTION_H +#define DIALOGELFSECTION_H + +#include +#include +#include +#include +#include +#include +#include "../data.h" +#include "../functions.h" + + +class DialogElfSection: public QDialog { + public: + DialogElfSection(); + ~DialogElfSection(); + void setData(struct elfSection *); + + private: + QLabel *m_labelSectionName; + QLabel *m_labelType; + QLabel *m_labelFlags; + QLabel *m_labelAddress; + QLabel *m_labelOffset; + QLabel *m_labelSectionSize; + QLabel *m_labelLink; + QLabel *m_labelInfo; + QLabel *m_labelAddressAlign; + QLabel *m_labelEntrySize; +}; + +#endif // DIALOGELFSECTION_H diff --git a/RElicAnalysis/elf/dialogelfsymbol.cpp b/RElicAnalysis/elf/dialogelfsymbol.cpp new file mode 100644 index 0000000..100f3a2 --- /dev/null +++ b/RElicAnalysis/elf/dialogelfsymbol.cpp @@ -0,0 +1,30 @@ +#include "dialogelfsymbol.h" + +DialogElfSymbol::DialogElfSymbol(): QDialog() { + setWindowTitle("ELF Section"); + setFixedSize(350, 250); + + QVBoxLayout *mainLayout = new QVBoxLayout; + + QGridLayout *layoutData = new QGridLayout; + + + + QHBoxLayout *layoutButton = new QHBoxLayout; + layoutButton->setAlignment(Qt::AlignRight); + QPushButton *buttonClose = new QPushButton("Close"); + connect(buttonClose, SIGNAL(clicked()), this, SLOT(close())); + + layoutButton->addWidget(buttonClose); + + mainLayout->addLayout(layoutData); + mainLayout->addLayout(layoutButton); + + setLayout(mainLayout); +} +void DialogElfSymbol::setData(struct elfSymbol *sElfS) { + +} +DialogElfSymbol::~DialogElfSymbol() { + +} diff --git a/RElicAnalysis/elf/dialogelfsymbol.h b/RElicAnalysis/elf/dialogelfsymbol.h new file mode 100644 index 0000000..e6e429d --- /dev/null +++ b/RElicAnalysis/elf/dialogelfsymbol.h @@ -0,0 +1,21 @@ +#ifndef DIALOGELFSYMBOL_H +#define DIALOGELFSYMBOL_H + +#include +#include +#include +#include +#include +#include +#include "../data.h" +#include "../functions.h" + + +class DialogElfSymbol: public QDialog { + public: + DialogElfSymbol(); + ~DialogElfSymbol(); + void setData(struct elfSymbol *); +}; + +#endif // DIALOGELFSYMBOL_H diff --git a/RElicAnalysis/elf/mdielf.cpp b/RElicAnalysis/elf/mdielf.cpp new file mode 100644 index 0000000..71c51dc --- /dev/null +++ b/RElicAnalysis/elf/mdielf.cpp @@ -0,0 +1,506 @@ +#include "mdielf.h" +#include "../stylesheet.h" + + +MdiElf::MdiElf(ProjectElf *projectElf): QMdiSubWindow() { + m_projectElf = projectElf; + m_elfData = projectElf->getElfData(); + + m_modelWidgetElf = new ModelWidgetELF; + m_dialogElfIdent = new DialogElfIdent(m_elfData); + m_dialogElfHeader = new DialogElfHeader(m_elfData); + m_dialogElfProgram = new DialogElfProgram; + m_dialogElfSection = new DialogElfSection; + m_dialogElfSymbol = new DialogElfSymbol; + + setWindowTitle("Hex dump"); + resize(this->width(), this->height()); + setWindowFlags(Qt::FramelessWindowHint); + + QWidget *mainWidget = new QWidget; + + QHBoxLayout *mainLayout = new QHBoxLayout; + QVBoxLayout *layoutDockLeft = new QVBoxLayout; + QVBoxLayout *layoutDockRight = new QVBoxLayout; + QHBoxLayout *layoutTextEdit = new QHBoxLayout; + QVBoxLayout *layoutCentral = new QVBoxLayout; + mainLayout->setContentsMargins(QMargins(0,0,0,0)); + layoutDockLeft->setContentsMargins(QMargins(0,0,0,0)); + layoutDockRight->setContentsMargins(QMargins(0,0,0,0)); + layoutTextEdit->setContentsMargins(QMargins(0,0,0,0)); + layoutCentral->setContentsMargins(QMargins(0,0,0,0)); + mainLayout->setSpacing(0); + + /**************************/ + /***** Dock left part *****/ + /**************************/ + // Widget for exploring + QWidget *barExplorer = new QWidget; + barExplorer->setStyleSheet(styleBar); + barExplorer->setMaximumHeight(20); + barExplorer->resize(100, barExplorer->height()); + barExplorer->setMaximumWidth(300); + QHBoxLayout *layoutBarExplorer = new QHBoxLayout; + layoutBarExplorer->setAlignment(Qt::AlignLeft); + layoutBarExplorer->setContentsMargins(QMargins(0,0,0,0)); + layoutBarExplorer->setSpacing(0); + + m_labelFilename = new QLabel; + m_labelFilename->setStyleSheet("QLabel{margin:0px;}QLabel{color:#fff;}"); + m_labelFilename->setFont(fontBar); + m_labelFilename->setFixedSize(250,20); + layoutBarExplorer->addWidget(m_labelFilename); + barExplorer->setLayout(layoutBarExplorer); + + // Tree view + m_treeExplorer = new QTreeWidget; + m_treeExplorer->setMaximumWidth(250); + m_treeExplorer->header()->hide(); + m_treeExplorer->setColumnCount(1); + m_treeExplorer->setStyleSheet("border:none; border-left:1 px solid #000;"); + connect(m_treeExplorer, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(_itemClickedExplorer(QTreeWidgetItem*, int))); + + layoutDockLeft->addWidget(barExplorer); + layoutDockLeft->addWidget(m_treeExplorer); + + // Widget for caracteristics + QWidget *barCaracteristics = new QWidget; + barCaracteristics->setStyleSheet(styleBar); + barCaracteristics->setMaximumHeight(20); + barCaracteristics->resize(100, 300); + barCaracteristics->setMaximumWidth(300); + QHBoxLayout *layoutBarCaracteristics = new QHBoxLayout; + layoutBarCaracteristics->setAlignment(Qt::AlignLeft); + layoutBarCaracteristics->setContentsMargins(QMargins(0,0,0,0)); + layoutBarCaracteristics->setSpacing(0); + + QLabel *labelCaracteristics = new QLabel("Caracteristics"); + labelCaracteristics->setStyleSheet(labelBar); + labelCaracteristics->setFont(fontBar); + labelCaracteristics->setFixedSize(250,20); + layoutBarCaracteristics->addWidget(labelCaracteristics); + barCaracteristics->setLayout(layoutBarCaracteristics); + + m_textEditCaracteristics = new QTextEdit; + m_textEditCaracteristics->setMaximumWidth(250); + m_textEditCaracteristics->setReadOnly(true); + m_textEditCaracteristics->setStyleSheet("border:none; border-left:1 px solid #000;"); + + layoutDockLeft->addWidget(barCaracteristics); + layoutDockLeft->addWidget(m_textEditCaracteristics); + + // Widget for functions + QWidget *barFunctions = new QWidget; + barFunctions->setStyleSheet(styleBar); + barFunctions->setMaximumHeight(20); + barFunctions->resize(100, 300); + barFunctions->setMaximumWidth(300); + QHBoxLayout *layoutBarFunctions = new QHBoxLayout; + layoutBarFunctions->setAlignment(Qt::AlignLeft); + layoutBarFunctions->setContentsMargins(QMargins(0,0,0,0)); + layoutBarFunctions->setSpacing(0); + + QLabel *labelFunctions = new QLabel("Functions"); + labelFunctions->setStyleSheet(labelBar); + labelFunctions->setFont(fontBar); + labelFunctions->setFixedSize(250,20); + layoutBarFunctions->addWidget(labelFunctions); + barFunctions->setLayout(layoutBarFunctions); + + // Tree view + m_treeFunctions = new QTreeWidget; + m_treeFunctions->setMaximumWidth(250); + m_treeFunctions->header()->hide(); + m_treeFunctions->setColumnCount(1); + m_treeFunctions->setStyleSheet("border:none; border-left:1 px solid #000;"); + connect(m_treeFunctions, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(_itemClickedFunctions(QTreeWidgetItem*, int))); + + layoutDockLeft->addWidget(barFunctions); + layoutDockLeft->addWidget(m_treeFunctions); + + /**************************/ + /***** Text edit part *****/ + /**************************/ + /* Hex part */ + QVBoxLayout *layoutHex = new QVBoxLayout; + layoutHex->setContentsMargins(QMargins(0,0,0,0)); + QHBoxLayout *layoutBarHex = new QHBoxLayout; + layoutBarHex->setAlignment(Qt::AlignLeft); + layoutBarHex->setContentsMargins(QMargins(0,0,0,0)); + layoutBarHex->setSpacing(0); + QLabel *labelTitleHex = new QLabel("Hex dump"); + labelTitleHex->setStyleSheet(labelBar); + labelTitleHex->setFont(fontBar); + labelTitleHex->setFixedSize(250, 20); + layoutBarHex->addWidget(labelTitleHex); + + QWidget *barHex = new QWidget; + barHex->setMinimumHeight(20); + barHex->setStyleSheet("border-bottom:1px solid #000;background-color:#656565;"); + barHex->setLayout(layoutBarHex); + + m_treeHexDump = new QTreeWidget; + m_treeHexDump->header()->hide(); + m_treeHexDump->setColumnCount(1); + m_treeHexDump->setStyleSheet("border:none; border-left:1 px solid #000;"); + + layoutHex->addWidget(barHex); + layoutHex->addWidget(m_treeHexDump); + layoutHex->setContentsMargins(QMargins(0,0,0,0)); + + layoutTextEdit->addLayout(layoutHex); + + /***************************/ + /***** Dock Right part *****/ + /***************************/ + // Globa objects + QWidget *barGlobalObjects = new QWidget; + barGlobalObjects->setStyleSheet(styleBar); + barGlobalObjects->setMaximumHeight(20); + barGlobalObjects->resize(100, barExplorer->height()); + barGlobalObjects->setMaximumWidth(300); + QHBoxLayout *layoutGlobalVariables = new QHBoxLayout; + layoutGlobalVariables->setAlignment(Qt::AlignLeft); + layoutGlobalVariables->setContentsMargins(QMargins(0,0,0,0)); + layoutGlobalVariables->setSpacing(0); + + QLabel *labelglobalObjects = new QLabel("Global objects"); + labelglobalObjects->setStyleSheet("QLabel{margin:0px;}QLabel{color:#fff;}"); + labelglobalObjects->setFont(fontBar); + labelglobalObjects->setFixedSize(250,20); + + layoutGlobalVariables->addWidget(labelglobalObjects); + barGlobalObjects->setLayout(layoutGlobalVariables); + + m_treeGlobalObjects = new QTreeWidget; + m_treeGlobalObjects->setMaximumWidth(250); + m_treeGlobalObjects->header()->hide(); + m_treeGlobalObjects->setColumnCount(1); + m_treeGlobalObjects->setStyleSheet("border:none; border-left:1 px solid #000;"); + + layoutDockRight->addWidget(barGlobalObjects); + layoutDockRight->addWidget(m_treeGlobalObjects); + + // Dyn symbols + QWidget *barDynSymbols = new QWidget; + barDynSymbols->setStyleSheet(styleBar); + barDynSymbols->setMaximumHeight(20); + barDynSymbols->resize(100, barExplorer->height()); + barDynSymbols->setMaximumWidth(300); + QHBoxLayout *layoutDynSymbols = new QHBoxLayout; + layoutDynSymbols->setAlignment(Qt::AlignLeft); + layoutDynSymbols->setContentsMargins(QMargins(0,0,0,0)); + layoutDynSymbols->setSpacing(0); + + QLabel *labelDynSymbols = new QLabel("Dyn symbols"); + labelDynSymbols->setStyleSheet("QLabel{margin:0px;}QLabel{color:#fff;}"); + labelDynSymbols->setFont(fontBar); + labelDynSymbols->setFixedSize(250,20); + + layoutDynSymbols->addWidget(labelDynSymbols); + barDynSymbols->setLayout(layoutDynSymbols); + + m_treeDynSymbols = new QTreeWidget; + m_treeDynSymbols->setMaximumWidth(250); + m_treeDynSymbols->header()->hide(); + m_treeDynSymbols->setColumnCount(1); + m_treeDynSymbols->setStyleSheet("border:none; border-left:1 px solid #000;"); + + layoutDockRight->addWidget(barDynSymbols); + layoutDockRight->addWidget(m_treeDynSymbols); + + // Hash table + QWidget *barHashTable = new QWidget; + barHashTable->setStyleSheet(styleBar); + barHashTable->setMaximumHeight(20); + barHashTable->resize(100, barExplorer->height()); + barHashTable->setMaximumWidth(300); + QHBoxLayout *layoutHashTable = new QHBoxLayout; + layoutHashTable->setAlignment(Qt::AlignLeft); + layoutHashTable->setContentsMargins(QMargins(0,0,0,0)); + layoutHashTable->setSpacing(0); + + QLabel *labelHashTable = new QLabel("Hash table"); + labelHashTable->setStyleSheet("QLabel{margin:0px;}QLabel{color:#fff;}"); + labelHashTable->setFont(fontBar); + labelHashTable->setFixedSize(250,20); + + layoutHashTable->addWidget(labelHashTable); + barHashTable->setLayout(layoutHashTable); + + m_treeHashTable = new QTreeWidget; + m_treeHashTable->setMaximumWidth(250); + m_treeHashTable->header()->hide(); + m_treeHashTable->setColumnCount(1); + m_treeHashTable->setStyleSheet("border:none; border-left:1 px solid #000;"); + + layoutDockRight->addWidget(barHashTable); + layoutDockRight->addWidget(m_treeHashTable); + + layoutCentral->addLayout(layoutTextEdit); + + mainLayout->addLayout(layoutDockLeft); + mainLayout->addLayout(layoutCentral); + mainLayout->addLayout(layoutDockRight); + mainWidget->setLayout(mainLayout); + setWidget(mainWidget); +} +/* + * In this function, we show the result of the ELF object which has been parsed + * These data are stored in the object ElfData + * This function is called from the MdiElfHandler::showMdiSubWindow() + */ +void MdiElf::addBinaryCodeElf(){ + m_labelFilename->setText(m_projectElf->getProjectName()); + + _addExplorerElf(m_elfData); + + _addCaracteristics(m_elfData); + + _addHexDumpElf(m_elfData); +} +void MdiElf::_addCaracteristics(ElfData *elfData) { + FileInfo *fileInfo = m_projectElf->getFileInfo(); + struct elfIdent *sElfId = elfData->getIdentification(); + struct elfHdr *sElfHdr = elfData->getHeader(); + + QString s = "Filename: " + fileInfo->getFilename() + "\n"; + s += "ELF architecture: " + m_elfData->mapArchitecture(hexToInt(sElfId->arch.toHex())) + "\n"; + s += "ELF Header size: " + QString::number(hexToInt(sElfHdr->e_ehsize.toHex())) + "\n"; + s += "ELF number programs: " + QString::number(hexToInt(sElfHdr->e_phnum.toHex())) + "\n"; + s += "ELF programs offset: " + QString::number(hexToInt(sElfHdr->e_phoff.toHex())) + "\n"; + 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"; + + m_textEditCaracteristics->setPlainText(s); +} +void MdiElf::_addExplorerElf(ElfData *elfData){ + QTreeWidgetItem *itemId = new QTreeWidgetItem(m_treeExplorer); + itemId->setText(0, "Identification"); + QTreeWidgetItem *itemHdr = new QTreeWidgetItem(m_treeExplorer); + itemHdr->setText(0, "ELF Header"); + QTreeWidgetItem *itemProg = new QTreeWidgetItem(m_treeExplorer); + itemProg->setText(0, "ELF Program headers"); + QTreeWidgetItem *itemSection = new QTreeWidgetItem(m_treeExplorer); + itemSection->setText(0, "ELF Section headers"); + + // Programs part + QList *sElfProg = elfData->getProgramHeaders(); + for (qsizetype i = 0; i < sElfProg->size(); i++){ + QTreeWidgetItem *itemChild = new QTreeWidgetItem; + struct elfProgram *sElfP = sElfProg->at(i); + bool ok; + QString text = elfData->mapProgramType(sElfP->p_type.toHex().toInt(&ok, 16)); + itemChild->setText(0, text); + itemProg->addChild(itemChild); + m_modelWidgetElf->addWidgetItem(itemChild, sElfP); + } + + // Sections part + QList *sElfSection = elfData->getSectionHeaders(); + for (qsizetype i = 0; i < sElfSection->size(); i++){ + QTreeWidgetItem *itemChild = new QTreeWidgetItem; + struct elfSection *sElfS = sElfSection->at(i); + + if (sElfS->sh_name.isEmpty()) + itemChild->setText(0, "NULL"); + else + itemChild->setText(0, sElfS->sh_name); + itemSection->addChild(itemChild); + + /* Add to the model ElfWidget, the item can be clicked and get more information regarding the section */ + m_modelWidgetElf->addWidgetItem(itemChild, sElfS); + } + + // Symbols part + QList *sElfSymbols = elfData->getSymbols(); + for (qsizetype i = 0; i < sElfSymbols->size(); i++){ + struct elfSymbol *elfS = sElfSymbols->at(i); + // st_info type-> 1 = objects + // st_info type -> 2 = function + // st_info type -> 4 = file objects + /* + * We can use macro these macros: + * ELF64_ST_BIND(elfS[i].st_info) + * ELF64_ST_TYPE(elfS[i].st_info); + * + * bind values: + * 0 -> local + * 1 -> global + * 2 -> weak + */ + unsigned char bind = (unsigned char)(elfS->st_info >> 4); + int type = (elfS->st_info) & 0xf; + + // Add functions to the TreeWidget + if (type == 2) { + QTreeWidgetItem *itemChild = new QTreeWidgetItem(m_treeFunctions); + itemChild->setText(0, elfS->st_name); + + // Should I add to a model ? We can get more information regarding the objects, + // such as the address + //m_modelWidgetElf->addWidgetItem(itemChild, elfS); + } + // Add global objects and file objects + if (type == 0 || type == 4 || type == 1) { + QTreeWidgetItem *itemChild = new QTreeWidgetItem(m_treeGlobalObjects); + //qDebug() << elfS->st_name << " " << printHex(elfS->st_value); + itemChild->setText(0, elfS->st_name); + + //m_modelWidgetElf->addWidgetItem(itemChild, elfS); + } + } + + // Dyn symbols + QList *sElfDynSymbols = elfData->getDynSymbols(); + for (qsizetype i = 0; i < sElfDynSymbols->size(); i++){ + struct elfSymbol *elfS = sElfDynSymbols->at(i); + QTreeWidgetItem *itemChild = new QTreeWidgetItem(m_treeDynSymbols); + itemChild->setText(0, elfS->st_name); + } +} +void MdiElf::_addHexDumpElf(ElfData *elfData){ + struct elfIdent *sElfIdent = elfData->getIdentification(); + struct elfHdr *sElfHdr = elfData->getHeader(); + QList *sElfProg = elfData->getProgramHeaders(); + QList *sElfSec = elfData->getSectionHeaders(); + + // Identification part + QString strId = sElfIdent->signature[0].toHex() + sElfIdent->signature[1].toHex() + sElfIdent->signature[2].toHex() + sElfIdent->signature[3].toHex(); + strId += sElfIdent->arch.toHex() + sElfIdent->endianess.toHex(); + strId += sElfIdent->version.toHex() + sElfIdent->abi.toHex() + sElfIdent->vers_abi.toHex(); + strId = printPrettyHex(strId); + + QTreeWidgetItem *itemId = new QTreeWidgetItem(m_treeHexDump); + itemId->setText(0, "Identification"); + QTreeWidgetItem *itemIdData = new QTreeWidgetItem; + itemIdData->setText(0, strId); + itemId->addChild(itemIdData); + + // ELF Header part + QString strHdr = sElfHdr->e_type.toHex() + sElfHdr->e_machine.toHex() + sElfHdr->e_version.toHex(); + strHdr += sElfHdr->e_entry.toHex() + sElfHdr->e_phoff.toHex() + sElfHdr->e_shoff.toHex(); + strHdr += sElfHdr->e_flags.toHex() + sElfHdr->e_ehsize.toHex() + sElfHdr->e_phentsize.toHex(); + strHdr += sElfHdr->e_phnum.toHex() + sElfHdr->e_shentsize.toHex() + sElfHdr->e_shnum.toHex(); + strHdr += sElfHdr->e_shstrndx.toHex(); + strHdr = printPrettyHex(strHdr); + + QTreeWidgetItem *itemElfHdr = new QTreeWidgetItem(m_treeHexDump); + itemElfHdr->setText(0, "ELF Header"); + QTreeWidgetItem *itemElfHdrData = new QTreeWidgetItem; + itemElfHdrData->setText(0, strHdr); + itemElfHdr->addChild(itemElfHdrData); + + // Elf program part + QTreeWidgetItem *itemProgram = new QTreeWidgetItem(m_treeHexDump); + itemProgram->setText(0, "ELF Programs header"); + for (qsizetype i = 0; i < sElfProg->size(); i++){ + struct elfProgram *sElfP = sElfProg->at(i); + QString strProg = sElfP->p_type.toHex() + sElfP->p_offset.toHex() + sElfP->p_vaddr.toHex(); + strProg += sElfP->p_paddr.toHex() + sElfP->p_filesz.toHex() + sElfP->p_memsz.toHex(); + strProg += sElfP->p_flags.toHex() + sElfP->p_align.toHex(); + strProg = printPrettyHex(strProg); + + QTreeWidgetItem *itemChild = new QTreeWidgetItem; + itemChild->setText(0, strProg); + itemProgram->addChild(itemChild); + } + + // Elf section part + QTreeWidgetItem *itemSection = new QTreeWidgetItem(m_treeHexDump); + itemSection->setText(0, "ELF Sections header"); + for (qsizetype i = 0; i < sElfSec->size(); i++){ + struct elfSection *sElfS = sElfSec->at(i); + + /*QString strSec = sElfS->sh_type.toHex() + " " + sElfS->sh_flags.toHex() + " "; + strSec += sElfS->sh_addr.toHex() + " " + sElfS->sh_offset.toHex() + " "; + strSec += sElfS->sh_size.toHex() + " " + sElfS->sh_link.toHex() + " "; + strSec += sElfS->sh_info.toHex() + " " + sElfS->sh_addralign.toHex() + " "; + strSec += sElfS->sh_entsize.toHex(); + strSec = printPrettyHex(strSec);*/ + QString strSec = sElfS->sh_type.toHex(' ') + " " + sElfS->sh_flags.toHex(' ') + " "; + strSec += sElfS->sh_addr.toHex(' ') + " " + sElfS->sh_offset.toHex(' ') + " "; + strSec += sElfS->sh_size.toHex(' ') + " " + sElfS->sh_link.toHex(' ') + " "; + strSec += sElfS->sh_info.toHex(' ') + " " + sElfS->sh_addralign.toHex(' ') + " "; + strSec += sElfS->sh_entsize.toHex(' '); + + QTreeWidgetItem *itemChild = new QTreeWidgetItem; + itemChild->setText(0, strSec); + itemSection->addChild(itemChild); + } +} +void MdiElf::_itemClickedExplorer(QTreeWidgetItem *item, int column){ + /* + * When the user click on the treeExplorer, we retrieve the item clicked + * and show the correct dialog containing information about the item + */ + QModelIndex index = m_treeExplorer->indexFromItem(item, column); + + // If the item has no parent + if (item->parent() == NULL) { + switch (index.row()){ + case 0: // Identification + _showElfIdent(m_elfData->getIdentification()); + break; + case 1: // ELF Header + _showElfHeader(m_elfData->getHeader()); + break; + /*case 2: // Program part + break; + case 3: // Section part + break;*/ + default: + break; + } + } + else { + // Get the parent + QTreeWidgetItem *parent = item->parent(); + QModelIndex indexP = m_treeExplorer->indexFromItem(parent, column); + + switch (indexP.row()){ + case 2: { // Program part + struct elfProgram *elfP = m_modelWidgetElf->findWidgetItemProgram(item); + _showElfProgram(elfP); + break; + } + case 3: { + struct elfSection *elfS = m_modelWidgetElf->findWidgetItemSection(item); + if (elfS != NULL) + _showElfSection(elfS); + break; + } + } + } +} +void MdiElf::_itemClickedFunctions(QTreeWidgetItem *item, int column){ + QModelIndex index = m_treeExplorer->indexFromItem(item, column); + + struct elfSymbol *sElfS = m_modelWidgetElf->findWidgetItemSymbol(item); +} +void MdiElf::_showElfIdent(struct elfIdent *sElfIdent){ + m_dialogElfIdent->exec(); +} +void MdiElf::_showElfHeader(struct elfHdr *sElfHdr){ + m_dialogElfHeader->exec(); +} +void MdiElf::_showElfProgram(struct elfProgram *sElfP){ + m_dialogElfProgram->setData(sElfP); + m_dialogElfProgram->exec(); +} +void MdiElf::_showElfSection(struct elfSection *sElfS){ + m_dialogElfSection->setData(sElfS); + m_dialogElfSection->exec(); +} +MdiElf::~MdiElf() { + delete m_treeFunctions; + delete m_treeExplorer; + delete m_treeGlobalObjects; + delete m_textEditCaracteristics; + delete m_dialogElfIdent; + delete m_dialogElfHeader; + delete m_dialogElfProgram; + delete m_dialogElfSection; + delete m_dialogElfSymbol; +} diff --git a/RElicAnalysis/elf/mdielf.h b/RElicAnalysis/elf/mdielf.h new file mode 100644 index 0000000..0590eab --- /dev/null +++ b/RElicAnalysis/elf/mdielf.h @@ -0,0 +1,65 @@ +#ifndef MDIELF_H +#define MDIELF_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../projectelf.h" +#include "../modelwidgetelf.h" +#include "dialogelfident.h" +#include "dialogelfheader.h" +#include "dialogelfprogram.h" +#include "dialogelfsection.h" +#include "dialogelfsymbol.h" + + +class MdiElf: public QMdiSubWindow { + Q_OBJECT +public: + MdiElf(ProjectElf *); + ~MdiElf(); + void addBinaryCodeElf(); + +private slots: + void _itemClickedExplorer(QTreeWidgetItem *, int); + void _itemClickedFunctions(QTreeWidgetItem *, int); + +private: + + DialogElfIdent *m_dialogElfIdent; + DialogElfHeader *m_dialogElfHeader; + DialogElfProgram *m_dialogElfProgram; + DialogElfSection *m_dialogElfSection; + DialogElfSymbol *m_dialogElfSymbol; + ElfData *m_elfData; + ModelWidgetELF *m_modelWidgetElf; + QLabel *m_labelFilename; + QTreeWidget *m_treeExplorer; + QTreeWidget *m_treeFunctions; + QTreeWidget *m_treeDynSymbols; + QTreeWidget *m_treeGlobalObjects; + QTreeWidget *m_treeHashTable; + QTreeWidget *m_treeHexDump; + QTextEdit *m_textEditCaracteristics; + QTextEdit *m_textAnalyzing; + ProjectElf *m_projectElf; + QListView *m_viewHex; + void _addHexTab(); + void _addExplorerElf(ElfData *); + void _addCaracteristics(ElfData *); + void _addHexDumpElf(ElfData *); + void _showElfIdent(struct elfIdent *); + void _showElfHeader(struct elfHdr *); + void _showElfProgram(struct elfProgram *); + void _showElfSection(struct elfSection *); +}; + +#endif // MDIELF_H diff --git a/RElicAnalysis/elf/mdielfdisassembled.cpp b/RElicAnalysis/elf/mdielfdisassembled.cpp new file mode 100644 index 0000000..645e650 --- /dev/null +++ b/RElicAnalysis/elf/mdielfdisassembled.cpp @@ -0,0 +1,108 @@ +#include "mdielfdisassembled.h" +#include + +MdiElfDisassembled::MdiElfDisassembled(ProjectElf *projectElf): QMdiSubWindow() { + m_projectElf = projectElf; + ElfData *elfData = projectElf->getElfData(); + + setWindowTitle("Disassembly"); + resize(this->width(), this->height()); + setWindowFlags(Qt::FramelessWindowHint); + + QWidget *widget = new QWidget; + + // 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; + m_viewAnalyse->setModel(m_modelAnalyse); + m_viewAnalyse->setSelectionMode(QAbstractItemView::NoSelection); + //m_viewAnalyse->setStyleSheet("border: none"); + + mainLayout->addWidget(m_viewExplorer); + mainLayout->addWidget(m_viewAnalyse); + + widget->setLayout(mainLayout); + setWidget(widget); +} +/* + * This function sanitize the struct elfObjectDisas for user friendly + */ +QString MdiElfDisassembled::sanitizeASMCode(struct elfObjectDisas *obj){ + QString hex; + hex.setNum(obj->addr, 16); + QByteArray hexCmd = obj->hexCmd.toHex(' '); + size_t len = hexCmd.size(); + + int maxTab = TABS - len; + 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; +} diff --git a/RElicAnalysis/elf/mdielfdisassembled.h b/RElicAnalysis/elf/mdielfdisassembled.h new file mode 100644 index 0000000..f7c7f30 --- /dev/null +++ b/RElicAnalysis/elf/mdielfdisassembled.h @@ -0,0 +1,36 @@ +#ifndef MDIELFDISASSEMBLED_H +#define MDIELFDISASSEMBLED_H + +#include +#include +#include +#include +#include +#include +#include +#include "../projectelf.h" + +/* Used for printing the ASM code */ +#define TABS 60 + +class MdiElfDisassembled: public QMdiSubWindow { + Q_OBJECT +public: + MdiElfDisassembled(ProjectElf *); + ~MdiElfDisassembled(); + +private: + ProjectElf *m_projectElf; + QListView *m_viewExplorer; + QListView *m_viewAnalyse; + QStandardItemModel *m_modelExplorer; + QStandardItemModel *m_modelAnalyse; + QList m_listModelExplorer; + QString sanitizeASMCode(struct elfObjectDisas *); + +private slots: + void _itemClicked(const QModelIndex &); +}; + + +#endif // MDIELFDISASSEMBLED_H diff --git a/RElicAnalysis/elf/mdielfhandler.cpp b/RElicAnalysis/elf/mdielfhandler.cpp new file mode 100644 index 0000000..8a2325c --- /dev/null +++ b/RElicAnalysis/elf/mdielfhandler.cpp @@ -0,0 +1,31 @@ +#include "mdielfhandler.h" +#include "../centralwidget.h" + +/* + * This class handle ELF project and send data to all QWidgets and children + * in the centralWidget + */ + +MdiElfHandler::MdiElfHandler(CentralWidget *centralWidget, ProjectElf *projectElf) { + m_centralWidget = centralWidget; + m_projectElf = projectElf; + m_mdiElf = new MdiElf(projectElf); + m_mdiElfView = new MdiElfView(projectElf); + m_mdiElfDisassembled = new MdiElfDisassembled(projectElf); +} +void MdiElfHandler::showMdiSubWindow(){ + m_centralWidget->addSubWindow(m_mdiElfDisassembled)->show(); + m_centralWidget->addSubWindow(m_mdiElf)->show(); + m_centralWidget->addSubWindow(m_mdiElfView)->show(); + + /* Set the MdiElf as current tab */ + m_centralWidget->setActiveSubWindow(m_mdiElf); + + // Add the result of the parse + m_mdiElf->addBinaryCodeElf(); +} +MdiElfHandler::~MdiElfHandler(){ + delete m_mdiElf; + delete m_mdiElfDisassembled; + delete m_mdiElfView; +} diff --git a/RElicAnalysis/elf/mdielfhandler.h b/RElicAnalysis/elf/mdielfhandler.h new file mode 100644 index 0000000..7b890de --- /dev/null +++ b/RElicAnalysis/elf/mdielfhandler.h @@ -0,0 +1,25 @@ +#ifndef MDIELFHANDLER_H +#define MDIELFHANDLER_H + +#include "mdielf.h" +#include "mdielfdisassembled.h" +#include "mdielfview.h" +#include "../projectelf.h" + + +class CentralWidget; +class MdiElfHandler { + public: + MdiElfHandler(CentralWidget *, ProjectElf *); + ~MdiElfHandler(); + void showMdiSubWindow(); + + private: + CentralWidget *m_centralWidget; + ProjectElf *m_projectElf; + MdiElf *m_mdiElf; + MdiElfDisassembled *m_mdiElfDisassembled; + MdiElfView *m_mdiElfView; +}; + +#endif // MDIELFHANDLER_H diff --git a/RElicAnalysis/elf/mdielfview.cpp b/RElicAnalysis/elf/mdielfview.cpp new file mode 100644 index 0000000..e7f0f46 --- /dev/null +++ b/RElicAnalysis/elf/mdielfview.cpp @@ -0,0 +1,107 @@ +#include "mdielfview.h" +#include "../functions.h" + +MdiElfView::MdiElfView(ProjectElf *projectElf): QMdiSubWindow() { + setWindowTitle("Logical view"); + m_elfData = projectElf->getElfData(); + + scroll = new QScrollArea; + scroll->setWidgetResizable(false); + r = new RenderArea; + r->setElfData(m_elfData); + scroll->setFixedSize(1000, 500); + scroll->setWidget(r); + + + setWidget(scroll); +} +MdiElfView::~MdiElfView(){ + delete r; + delete scroll; +} + +RenderArea::RenderArea(QWidget *parent): QWidget(parent){ + setBackgroundRole(QPalette::Base); + //setAutoFillBackground(true); + //QScrollArea *scroll = new QScrollArea(this); + //QVBoxLayout *layout = new QVBoxLayout; + //layout->addWidget(scroll); + //setLayout(layout); + //setFixedSize(1000, 500); + setMinimumSize(1000, 500); + //m_elfData = elfData; +} +void RenderArea::setElfData(ElfData *elfData){ + m_elfData = elfData; +} +void RenderArea::paintEvent(QPaintEvent *event){ + /* Elf header */ + QPainter painterEHdr(this); + defineRect(&painterEHdr); + painterEHdr.drawRect(50, 0, 300, 50); + + QPainter pEHdrText(this); + pEHdrText.drawText(QPoint(70, 30), "ELF Header"); + + QPainter pEHdrOffset(this); + pEHdrOffset.drawText(QPoint(360, 20), "Offset: 0x0 bytes"); + QString sizeEhdr; + + sizeEhdr = "Size: " + QString::number(m_elfData->getSizeofElf_Ehdr()) + " bytes"; + + QPainter pPHdrSize(this); + pPHdrSize.drawText(QPoint(360, 40), sizeEhdr); + + /* Program header */ + // Now, we loop for all programs + int pos = 50; + int posText = 80; + int posOffsetText = 70; + QList *sElfProg = m_elfData->getProgramHeaders(); + for (qsizetype i = 0; i < sElfProg->size(); i++){ + struct elfProgram *sElfP = sElfProg->at(i); + QString text = m_elfData->mapProgramType(hexToInt(sElfP->p_type.toHex())); + + QPainter painter(this); + defineRect(&painter); + painter.drawRect(50, pos, 300, 50); + + QPainter pProgText(this); + pProgText.drawText(QPoint(70, posText), "Prog Header: " + text); + + QPainter pPHdrOffset(this); + QString offset_hex = sElfP->p_offset.toHex(); + + //int p = getLastPositionNull(offset_hex); + //offset_hex = offset_hex.remove(0, p); + pPHdrOffset.drawText(QPoint(360, posOffsetText), "Offset: 0x" + offset_hex + " bytes"); + + QPainter pPHdrSize(this); + pPHdrSize.drawText(QPoint(360, posOffsetText + 20), "Size: 0x" + sElfP->p_filesz.toHex() + " bytes"); + //qDebug() << text << posText; + pos += 50; + posText += 50; + posOffsetText += 50; + //update(); + } + + /* Section header */ +} +void RenderArea::defineRect(QPainter *painter){ + painter->setRenderHint(QPainter::Antialiasing); + painter->setBrush(Qt::NoBrush); + /*QPen pen; + pen.setColor(QColor(0, 0, 0, 255)); + painterIHdr.setPen(pen);*/ + painter->setPen(Qt::black); +} + +int RenderArea::getLastPositionNull(QString s){ + int p = 0; + for (int i = 0; i < s.size(); i++){ + if (s[i] != '0') + break; + p++; + } + return p; +} diff --git a/RElicAnalysis/elf/mdielfview.h b/RElicAnalysis/elf/mdielfview.h new file mode 100644 index 0000000..bd73f0f --- /dev/null +++ b/RElicAnalysis/elf/mdielfview.h @@ -0,0 +1,48 @@ +#ifndef MDIELFVIEW_H +#define MDIELFVIEW_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../projectelf.h" + + +class RenderArea : public QWidget { + +public: + explicit RenderArea(QWidget * = nullptr); + void setElfData(ElfData *); +protected: + void paintEvent(QPaintEvent *event) override; +private: + void defineRect(QPainter *); + ElfData *m_elfData; + int getLastPositionNull(QString); +}; + + + +class MdiElfView: public QMdiSubWindow { + Q_OBJECT +public: + MdiElfView(ProjectElf *); + ~MdiElfView(); + + +private: + ElfData *m_elfData; + QScrollArea *scroll; + RenderArea *r; +}; + +#endif // MDIELFVIEW_H diff --git a/RElicAnalysis/elfReading_en_GB.ts b/RElicAnalysis/elfReading_en_GB.ts new file mode 100644 index 0000000..76f52a4 --- /dev/null +++ b/RElicAnalysis/elfReading_en_GB.ts @@ -0,0 +1,3 @@ + + + diff --git a/RElicAnalysis/elfdata.cpp b/RElicAnalysis/elfdata.cpp new file mode 100644 index 0000000..ba79346 --- /dev/null +++ b/RElicAnalysis/elfdata.cpp @@ -0,0 +1,351 @@ +#include "elfdata.h" +#include + +ElfData::ElfData() { + m_architecture = 0; + m_sElfId = (struct elfIdent*)malloc(sizeof(struct elfIdent)); + m_sElfHdr = (struct elfHdr*)malloc(sizeof(struct elfHdr)); + m_listProgs = new QList; + m_listSections = new QList; + m_listSymbols = new QList; + m_listTextSymbols = new QList; + m_listHashes = new QList; + 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); +} + +QHash *> ElfData::getDisasCode(){ + return m_hash; +} + +void ElfData::setArchitecture(int a){ + m_architecture = a; +} + +int ElfData::getArchitecture(){ + return m_architecture; +} + +void ElfData::setSizeofElf_Ehdr(size_t s){ + m_sizeofElf_Ehdr = s; +} + +void ElfData::setSizeofElf_Phdr(size_t s){ + m_sizeofElf_Phdr = s; +} + +void ElfData::setSizeofElf_Shdr(size_t s){ + m_sizeofElf_Shdr = s; +} + +size_t ElfData::getSizeofElf_Ehdr(){ + return m_sizeofElf_Ehdr; +} + +size_t ElfData::getSizeofElf_Phdr(){ + return m_sizeofElf_Phdr; +} + +size_t ElfData::getSizeofElf_Shdr(){ + return m_sizeofElf_Shdr; +} + +void ElfData::setIdentification(struct elfIdent *sElfIdent){ + memcpy(m_sElfId, sElfIdent, sizeof(struct elfIdent)); +} +void ElfData::setHeader(struct elfHdr* sElfHdr){ + memcpy(m_sElfHdr, sElfHdr, sizeof(struct elfHdr)); +} +void ElfData::setProgramHeader(struct elfProgram *p){ + m_listProgs->append(p); +} +void ElfData::setSectionHeader(struct elfSection *s){ + m_listSections->append(s); +} +void ElfData::setSymbol(struct elfSymbol * s){ + m_listSymbols->append(s); +} +void ElfData::setDynSymbols(struct elfSymbol *s){ + m_listDynSymbols->append(s); +} +void ElfData::setHash(struct elfHash *h){ + m_listHashes->append(h); +} +void ElfData::setTextSymbol(struct elfSymbol *sElfS){ + m_listTextSymbols->append(sElfS); +} + +struct elfIdent *ElfData::getIdentification(){ + return m_sElfId; +} +struct elfHdr *ElfData::getHeader(){ + return m_sElfHdr; +} +QList *ElfData::getProgramHeaders(){ + return m_listProgs; +} +QList *ElfData::getSectionHeaders(){ + return m_listSections; +} +QList *ElfData::getSymbols(){ + return m_listSymbols; +} +QList *ElfData::getDynSymbols(){ + return m_listDynSymbols; +} +QList *ElfData::getTextSymbols() { + return m_listTextSymbols; +} +QList *ElfData::getHashes(){ + return m_listHashes; +} +QString ElfData::mapProgramType(int type){ + QString text; + switch(type){ + case 0x0: + text = "NULL"; + break; + case 0x1: + text = "LOAD"; + break; + case 0x2: + text = "DYNAMIC"; + break; + case 0x3: + text = "INTERP"; + break; + case 0x4: + text = "NOTE"; + break; + case 0x5: + text = "SHLIB"; + break; + case 0x6: + text = "PHDR"; + break; + case 7: + text = "LOPROC"; + break; + case 8: + text = "GNU_STACK"; + break; + case 0x6474e550: + text = "GNU_EH_FRAME"; + break; + case 0x6474e551: + text = "GNU_STACK"; + break; + case 0x6474e552: + text = "GNU_RELRO"; + break; + case 0x6474e553: + text = "GNU_PROPERTY"; + break; + default: + text = "UNKNOW"; + break; + } + return text; +} +QString ElfData::mapSectionType(int type){ + QString text; + switch(type){ + case 0x0: + text = "SHT_NULL"; + break; + case 0x1: + text = "SHT_PROGBITS"; + break; + case 0x2: + text = "SHT_SYMTAB"; + break; + case 0x3: + text = "SHT_STRTAB"; + break; + case 0x4: + text = "SHT_RELA"; + break; + case 0x5: + text = "SHT_HASH"; + break; + case 0x6: + text = "SHT_DYNAMIC"; + break; + case 0x7: + text = "SHT_NOTE"; + break; + case 0x8: + text = "SHT_NOBITS"; + break; + case 0x9: + text = "SHT_REL"; + break; + case 0xa: + text = "SHT_SHLIB"; + break; + case 0xb: + text = "SHT_DYNSYM"; + break; + case 0xc: + text = "SHT_NUM"; + break; + case 0x70000000: + text = "SHT_LOPROC"; + break; + case 0x7fffffff: + text = "SHT_HIPROC"; + break; + /*case 0x80000000: + text = "SHT_LOUSER"; + break; + case 0xffffffff: + text = "SHT_HIUSER"; + break;*/ + default: + text = "UNKNOW"; + break; + } + return text; +} +QString ElfData::mapArchitecture(int archi) { + QString s = ""; + switch(archi){ + case 0: + s = "NONE"; + break; + case 1: + s = "32 bits"; + break; + case 2: + s = "64 bits"; + break; + } + return s; +} +QString ElfData::mapEndianess(int endianess){ + QString s = ""; + switch (endianess){ + case 0: + s = "NONE"; + break; + case 1: + s = "LSB"; + break; + case 2: + s = "MSB"; + break; + } + return s; +} +QString ElfData::mapABI(int abi){ + QString s = ""; + switch(abi){ + case 0: // ELFOSABI_NONE + s = "UNIX System V"; + break; + case 1: // ELFOSABI_SYSV + s = "UNIX System V"; + break; + case 2: // ELFOSABI_HPUX + s = "HP-UX"; + break; + case 3: // ELFOSABI_NETBSD + s = "NetBSD"; + break; + case 4: // ELFOSABI_LINUX + s = "Linux"; + break; + case 5: // ELFOSABI_SOLARIS + s = "Solaris"; + break; + case 6: // ELFOSABI_IRIX + s = "IRIX"; + break; + case 7: // ELFOSABI_FREEBSD + s = "FreeBSD"; + break; + case 8: // ELFOSABI_TRU64 + s = "TRU64 UNIX"; + break; + case 9: // ELFOSABI_ARM + s = "ARM architecture"; + break; + case 10: // ELFOSABI_STANDALONE + s = "Stand-alone (embedded)"; + break; + } + + return s; +} +QString ElfData::mapTypeElf(int type){ + QString s = ""; + switch(type){ + case 0: // ET_NONE + s= "Unknown"; + break; + case 1: // ET_REL + s = "Relocatable file"; + break; + case 2: // ET_EXEC + s = "Executable file"; + break; + case 3: // ET_DYN + s = "Shared object"; + break; + case 4: // ET_CORE + s = "Core file"; + break; + } + + return s; +} +QString ElfData::mapMachineType(int machine){ + QString s; + + return s; +} +QString ElfData::mapSymbolType(int type) { + QString s; + + return s; +} +ElfData::~ElfData() { + free(m_sElfId); + free(m_sElfHdr); + + //for (qsizetype i = 0; i < m_listProgs->size(); i++) + // free(m_listProgs->at(i)); + //free(m_listProgs); + + // Crash here, why ? + //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); + + // Clean from dynamic variables from parsingelf file + delete m_listProgs; + delete m_listSections; + delete m_listSymbols; + delete m_listTextSymbols; + 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]); + } +} diff --git a/RElicAnalysis/elfdata.h b/RElicAnalysis/elfdata.h new file mode 100644 index 0000000..f9aa5fe --- /dev/null +++ b/RElicAnalysis/elfdata.h @@ -0,0 +1,71 @@ +#ifndef ELFDATA_H +#define ELFDATA_H + +#include +#include +#include "data.h" + +enum Architecture{ + ARCH_ELF32, + ARCH_ELF64 +}; + +class ElfData { + public: + ElfData(); + ~ElfData(); + void setArchitecture(int); // Passing enum Architecture + void setIdentification(struct elfIdent *); + void setHeader(struct elfHdr *); + void setProgramHeader(struct elfProgram *); + void setSectionHeader(struct elfSection *); + void setSymbol(struct elfSymbol *); + void setDynSymbols(struct elfSymbol *); + void setHash(struct elfHash *); + void setTextSymbol(struct elfSymbol *); + void setSizeofElf_Ehdr(size_t); + void setSizeofElf_Phdr(size_t); + void setSizeofElf_Shdr(size_t); + + int getArchitecture(); + struct elfIdent *getIdentification(); + struct elfHdr *getHeader(); + QList *getProgramHeaders(); + QList *getSectionHeaders(); + QList *getSymbols(); + QList *getDynSymbols(); + QList *getHashes(); + QList *getTextSymbols(); + size_t getSizeofElf_Ehdr(); + size_t getSizeofElf_Phdr(); + size_t getSizeofElf_Shdr(); + + QString mapProgramType(int); + QString mapSectionType(int); + QString mapArchitecture(int); + QString mapEndianess(int); + QString mapABI(int); + QString mapTypeElf(int); + QString mapMachineType(int); + QString mapSymbolType(int); + + void addToHash(QByteArray, struct elfObjectDisas *); + QHash *> getDisasCode(); + + private: + int m_architecture; + size_t m_sizeofElf_Ehdr; + size_t m_sizeofElf_Phdr; + size_t m_sizeofElf_Shdr; + struct elfIdent *m_sElfId; + struct elfHdr *m_sElfHdr; + QList *m_listProgs; + QList *m_listSections; + QList *m_listSymbols; + QList *m_listDynSymbols; + QList *m_listTextSymbols; + QList *m_listHashes; + QHash *> m_hash; +}; + +#endif // ELFDATA_H diff --git a/RElicAnalysis/fileinfo.cpp b/RElicAnalysis/fileinfo.cpp new file mode 100644 index 0000000..e2d67c3 --- /dev/null +++ b/RElicAnalysis/fileinfo.cpp @@ -0,0 +1,83 @@ +#include "fileinfo.h" +#include +#include +#include + +FileInfo::FileInfo(QFile &file) { + QFileInfo info(file); + struct stat st_stat; + int fd; + int length; + + if (!info.exists()){ + return; + } + + m_sizeFile = info.size(); + m_path = info.absolutePath(); + 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 + */ + fd = open(fullPath.toLatin1().constData(), O_RDONLY); + if (fd < 0){ + qDebug() << "Failed to read the file"; + } + fstat(fd, &st_stat); + m_rawData = (char *)malloc(st_stat.st_size); + + length = read(fd, m_rawData, st_stat.st_size); + + close(fd); + + this->_getSignature(); +} +size_t FileInfo::getSizeFile(){ + return m_sizeFile; +} +QString FileInfo::getFilename(){ + return m_filename; +} +QString FileInfo::getPath(){ + return m_path; +} +int FileInfo::getFileType(){ + return m_fileType; +} +void FileInfo::_getSignature(){ + // ELF file + /*char signature[4]; + sprintf(signature, "%c%c%c%c", m_rawData[0], m_rawData[1], m_rawData[2], m_rawData[3]); + qDebug() << signature;*/ + if (m_rawData[0] == 0x7f && m_rawData[1] == 0x45 && m_rawData[2] == 0x4c && m_rawData[3] == 0x46) + m_fileType = SIGNATURE_ELF; + else + m_fileType = SIGNATURE_UNKNOWN; +} +char *FileInfo::getRawData(){ + return m_rawData; +} +FileInfo::~FileInfo(){ + free(m_rawData); +} diff --git a/RElicAnalysis/fileinfo.h b/RElicAnalysis/fileinfo.h new file mode 100644 index 0000000..003eeb7 --- /dev/null +++ b/RElicAnalysis/fileinfo.h @@ -0,0 +1,28 @@ +#ifndef FILEINFO_H +#define FILEINFO_H + +#include +#include +#include "data.h" + + +class FileInfo { + public: + FileInfo(QFile &); + ~FileInfo(); + size_t getSizeFile(); + QString getFilename(); + QString getPath(); + int getFileType(); + char *getRawData(); + private: + size_t m_sizeFile; + QString m_filename; + QString m_path; + char *m_rawData; + int m_fileType; + char *m_signature; + void _getSignature(); +}; + +#endif // FILEINFO_H diff --git a/RElicAnalysis/functions.cpp b/RElicAnalysis/functions.cpp new file mode 100644 index 0000000..1af32c0 --- /dev/null +++ b/RElicAnalysis/functions.cpp @@ -0,0 +1,48 @@ +#include "functions.h" + +int hexToInt(QByteArray b){ + bool ok; + int i = b.toInt(&ok, 16); + if (ok) + return i; + else + return 0; +} +QString printHex(QByteArray b){ + /*QString tmp = b; + QString s = "0x"; + for (int i = 0; i < tmp.size(); i++){ + if (i % 2 == 0 && i > 0){ + s += ' '; + } + s += tmp[i]; + } + return s*/ + return "0x" + b; +} +/* + * This function format the hex string into a pretty hex string + */ +QString printPrettyHex(QString s){ + QString str; + for (int i = 0; i < s.size(); i++){ + if (i % 2 == 0 && i > 0){ + str += ' '; + } + str += s[i]; + } + return str; +} + +/* + * This function cut the QByteArray b + */ +QByteArray cutByteArray(QByteArray b){ + int p = 0; + for(int i = 0; i < b.size(); i++){ + if (b[i] != 0) + break; + p++; + } + return b.remove(0, p); +} diff --git a/RElicAnalysis/functions.h b/RElicAnalysis/functions.h new file mode 100644 index 0000000..5e86984 --- /dev/null +++ b/RElicAnalysis/functions.h @@ -0,0 +1,12 @@ +#ifndef FUNCTIONS_H +#define FUNCTIONS_H + +#include +#include + +int hexToInt(QByteArray); +QString printHex(QByteArray); +QString printPrettyHex(QString); +QByteArray cutByteArray(QByteArray); + +#endif // FUNCTIONS_H diff --git a/RElicAnalysis/handleproject.cpp b/RElicAnalysis/handleproject.cpp new file mode 100644 index 0000000..96865c0 --- /dev/null +++ b/RElicAnalysis/handleproject.cpp @@ -0,0 +1,87 @@ +#include "handleproject.h" +#include "mainwindow.h" + +HandleProject::HandleProject(MainWindow *mainWindow) { + m_mainWindow = mainWindow; + m_projectElf = NULL; + m_projectOpened = false; + m_projectType = PROJECT_NONE; + m_fileInfo = NULL; +} + +void HandleProject::handleOpenFile(QFile &file){ + int signFile; + m_fileInfo = new FileInfo(file); + + signFile = m_fileInfo->getFileType(); + + if (signFile == SIGNATURE_ELF){ + m_projectType = PROJECT_ELF; + m_projectOpened = true; + m_projectElf = new ProjectElf; + m_elfData = new ElfData; + + m_projectElf->setFileInfo(m_fileInfo); + m_projectElf->setProjectName(m_fileInfo->getFilename()); + + int res = elfFile(m_fileInfo->getRawData(), m_elfData); + if (res == READ_FILE_ERROR){ + QMessageBox::critical(NULL, "Error", "Failed to read the file"); + m_projectOpened = false; + m_projectType = 0; + delete m_projectElf; + delete m_elfData; + return; + } + else if(res == READ_FILE_32BIT){ + QMessageBox::critical(NULL, "Error", "Cannot read ELF 32 bits"); + m_projectOpened = false; + m_projectType = 0; + delete m_projectElf; + delete m_elfData; + return; + } + m_projectElf->setElfData(m_elfData); + + // Create ELF Class + // And set data to this class + CentralWidget *central = m_mainWindow->getCentralWidget(); + + m_elfHandler = new MdiElfHandler(central, m_projectElf); + + m_elfHandler->showMdiSubWindow(); + } + else if (signFile == SIGNATURE_PE){ + + } + else if (signFile == SIGNATURE_PNG){ + + } + else + QMessageBox::warning(NULL, "Error", "The file specified is not recognized"); +} +void HandleProject::handleCloseFile(){ + switch(m_projectType){ + case PROJECT_ELF: + delete m_projectElf; + delete m_elfData; + delete m_elfHandler; + m_projectOpened = false; + delete m_fileInfo; + break; + } + m_projectType = PROJECT_NONE; +} +bool HandleProject::projectOpened(){ + return m_projectOpened; +} +HandleProject::~HandleProject() { + if (m_projectElf != NULL) + delete m_projectElf; + if (m_fileInfo != NULL) + delete m_fileInfo; + if (m_elfData != NULL) + delete m_elfData; + if (m_elfHandler != NULL) + delete m_elfHandler; +} diff --git a/RElicAnalysis/handleproject.h b/RElicAnalysis/handleproject.h new file mode 100644 index 0000000..508e24c --- /dev/null +++ b/RElicAnalysis/handleproject.h @@ -0,0 +1,41 @@ +#ifndef HANDLEPROJECT_H +#define HANDLEPROJECT_H + +#include +#include +#include "project.h" +#include "projectelf.h" +#include "data.h" +#include "elfdata.h" +#include "fileinfo.h" +#include "parsingelf.h" +#include "elf/mdielfhandler.h" + +/* Create our project types */ +#define PROJECT_NONE 0x0 +#define PROJECT_ELF 0x1 +#define PROJECT_PE 0x2 +#define PROJECT_PNG 0x3 + + +class MainWindow; +class HandleProject { + public: + HandleProject(MainWindow *mainWindow); + ~HandleProject(); + void handleOpenFile(QFile &); + void handleCloseFile(); + bool projectOpened(); + + private: + int m_projectType; + bool m_projectOpened; // Project open or close + MainWindow *m_mainWindow; + Project *m_project; + ProjectElf *m_projectElf; + ElfData *m_elfData; + FileInfo *m_fileInfo; + MdiElfHandler *m_elfHandler; +}; + +#endif // HANDLEPROJECT_H diff --git a/RElicAnalysis/main.cpp b/RElicAnalysis/main.cpp new file mode 100644 index 0000000..fad66e4 --- /dev/null +++ b/RElicAnalysis/main.cpp @@ -0,0 +1,23 @@ +#include "mainwindow.h" + +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + + QTranslator translator; + const QStringList uiLanguages = QLocale::system().uiLanguages(); + for (const QString &locale : uiLanguages) { + const QString baseName = "RElicAnalysis" + QLocale(locale).name(); + if (translator.load(":/i18n/" + baseName)) { + a.installTranslator(&translator); + break; + } + } + MainWindow w; + w.show(); + return a.exec(); +} diff --git a/RElicAnalysis/mainwindow.cpp b/RElicAnalysis/mainwindow.cpp new file mode 100644 index 0000000..e4ad82e --- /dev/null +++ b/RElicAnalysis/mainwindow.cpp @@ -0,0 +1,27 @@ +#include "mainwindow.h" + +MainWindow::MainWindow(): QMainWindow() { + m_project = NULL; + m_handleProject = new HandleProject(this); + m_centralWidget = new CentralWidget(this); + m_menuBar = new MenuBar(m_centralWidget, m_handleProject); + + setWindowTitle("RElicAnalysis"); + setWindowState(Qt::WindowMaximized); + setMinimumSize(1500, 700); + + setCentralWidget(m_centralWidget); + setMenuBar(m_menuBar); +} +void MainWindow::closeCurrentProject(){ + +} +CentralWidget *MainWindow::getCentralWidget(){ + return m_centralWidget; +} +MainWindow::~MainWindow() { + delete m_centralWidget; + delete m_menuBar; + if (m_project != NULL) + delete m_project; +} diff --git a/RElicAnalysis/mainwindow.h b/RElicAnalysis/mainwindow.h new file mode 100644 index 0000000..9a28512 --- /dev/null +++ b/RElicAnalysis/mainwindow.h @@ -0,0 +1,28 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include "menubar.h" +#include "centralwidget.h" +#include "projectelf.h" +#include "project.h" +#include "handleproject.h" + + +class MainWindow : public QMainWindow { + Q_OBJECT + + public: + MainWindow(); + ~MainWindow(); + void closeCurrentProject(); + CentralWidget *getCentralWidget(); + + private: + CentralWidget *m_centralWidget; + MenuBar *m_menuBar; + HandleProject *m_handleProject; + Project *m_project; + ProjectElf *m_projectElf; +}; +#endif // MAINWINDOW_H diff --git a/RElicAnalysis/mainwindow.ui b/RElicAnalysis/mainwindow.ui new file mode 100644 index 0000000..cd4835e --- /dev/null +++ b/RElicAnalysis/mainwindow.ui @@ -0,0 +1,31 @@ + + + MainWindow + + + + 0 + 0 + 800 + 600 + + + + MainWindow + + + + + + 0 + 0 + 800 + 22 + + + + + + + + diff --git a/RElicAnalysis/menubar.cpp b/RElicAnalysis/menubar.cpp new file mode 100644 index 0000000..709b36d --- /dev/null +++ b/RElicAnalysis/menubar.cpp @@ -0,0 +1,81 @@ +#include "menubar.h" +#include "centralwidget.h" + + +MenuBar::MenuBar(CentralWidget *centralWidget, HandleProject *project) { + m_handleProject = project; + m_centralWidget = centralWidget; + m_dialogAbout = new DialogAbout; + + // Style sheet + setStyleSheet("border-bottom:1px solid #000;"); + + // Create menu + QMenu *menuFile = new QMenu("File"); + QMenu *menuAbout = new QMenu("About"); + + // Menu file + QAction *actionOpenFile = new QAction("Open ELF file", this); + actionOpenFile->setShortcut(QKeySequence("ctrl+O")); + connect(actionOpenFile, SIGNAL(triggered()), this, SLOT(_openFile())); + + QAction *actionCloseFile = new QAction("Fermer le fichier", this); + actionCloseFile->setShortcut(QKeySequence("ctrl+W")); + connect(actionCloseFile, SIGNAL(triggered()), this, SLOT(_closeFile())); + menuFile->addSeparator(); + + QAction *actionQuit = new QAction("Quitter", this); + actionQuit->setShortcut(QKeySequence("ctrl+Q")); + connect(actionQuit, SIGNAL(triggered()), this, SLOT(_quitApp())); + + menuFile->addAction(actionOpenFile); + menuFile->addAction(actionCloseFile); + menuFile->addAction(actionQuit); + + // Menu about + QAction *actionAbout = new QAction("A propos", this); + connect(actionAbout, SIGNAL(triggered()), m_dialogAbout, SLOT(exec())); + menuAbout->addAction(actionAbout); + + // add menu to menuBar + addMenu(menuFile); + addMenu(menuAbout); +} +/* + * This function open the file + */ +void MenuBar::_openFile() { + // Check if we have a project open + // If yes, clean it + if (m_handleProject->projectOpened() == true){ + unsigned int r = QMessageBox::question(NULL, "Open binary file", "A file is open, you should close the file first", QMessageBox::Cancel); + } + else { + QString path = QFileDialog::getOpenFileName(NULL, "Open binary file", "", "File (*)"); + if(!path.isEmpty()) { + QFile file(path); + if(file.open(QIODevice::ReadWrite | QIODevice::Text)){ + m_handleProject->handleOpenFile(file); + } + else if(file.open(QIODevice::ReadOnly)) { + unsigned int r = QMessageBox::question(NULL, "Open binary file", "The file is in read-only. Wish you to open it ?", QMessageBox::Yes | QMessageBox::No); + + if(r == QMessageBox::Yes){ + m_handleProject->handleOpenFile(file); + } + } + file.close(); + } + } +} +void MenuBar::_closeFile(){ + // We can close the project + m_handleProject->handleCloseFile(); +} +void MenuBar::_quitApp(){ + m_handleProject->handleCloseFile(); + qApp->quit(); +} +MenuBar::~MenuBar() { + delete m_dialogAbout; +} diff --git a/RElicAnalysis/menubar.h b/RElicAnalysis/menubar.h new file mode 100644 index 0000000..2028320 --- /dev/null +++ b/RElicAnalysis/menubar.h @@ -0,0 +1,31 @@ +#ifndef MENUBAR_H +#define MENUBAR_H + +#include +#include +#include +#include +#include +#include "handleproject.h" +#include "dialogabout.h" + +class CentralWidget; +class MenuBar : public QMenuBar { + Q_OBJECT + + public : + MenuBar(CentralWidget *, HandleProject *); + ~MenuBar(); + + private slots: + void _openFile(); + void _closeFile(); + void _quitApp(); + + private: + HandleProject *m_handleProject; + CentralWidget *m_centralWidget; + DialogAbout *m_dialogAbout; +}; + +#endif // MENUBAR_H diff --git a/RElicAnalysis/modelwidgetelf.cpp b/RElicAnalysis/modelwidgetelf.cpp new file mode 100644 index 0000000..32f8852 --- /dev/null +++ b/RElicAnalysis/modelwidgetelf.cpp @@ -0,0 +1,49 @@ +#include "modelwidgetelf.h" + +/* + * The model + */ +ModelWidgetELF::ModelWidgetELF() { + +} +void ModelWidgetELF::addWidgetItem(QTreeWidgetItem *item, struct elfProgram *elf){ + m_hashPrograms[item] = elf; +} +void ModelWidgetELF::addWidgetItem(QTreeWidgetItem *item, struct elfSection *elf){ + m_hashSections[item] = elf; +} +void ModelWidgetELF::addWidgetItem(QTreeWidgetItem *item, struct elfSymbol *elf){ + m_hashSymbols[item] = elf; +} +struct elfProgram *ModelWidgetELF::findWidgetItemProgram(QTreeWidgetItem *item){ + struct elfProgram *elfP = NULL; + QHash ::const_iterator hash = m_hashPrograms.find(item); + while (hash != m_hashPrograms.end() && hash.key() == item){ + QTreeWidgetItem *i = hash.key(); + //qDebug() << i->text(0) << " " << m_hashPrograms.value(i); + elfP = m_hashPrograms.value(i); + hash++; + } + return elfP; +} +struct elfSection *ModelWidgetELF::findWidgetItemSection(QTreeWidgetItem *item){ + struct elfSection *elfS = NULL; + QHash ::const_iterator hash = m_hashSections.find(item); + while (hash != m_hashSections.end() && hash.key() == item){ + QTreeWidgetItem *i = hash.key(); + elfS = m_hashSections.value(i); + hash++; + } + return elfS; +} +struct elfSymbol *ModelWidgetELF::findWidgetItemSymbol(QTreeWidgetItem *item){ + struct elfSymbol *elfS = NULL; + QHash ::const_iterator hash = m_hashSymbols.find(item); + while (hash != m_hashSymbols.end() && hash.key() == item){ + QTreeWidgetItem *i = hash.key(); + elfS = m_hashSymbols.value(i); + hash++; + } + return elfS; +} +ModelWidgetELF::~ModelWidgetELF() {} diff --git a/RElicAnalysis/modelwidgetelf.h b/RElicAnalysis/modelwidgetelf.h new file mode 100644 index 0000000..0d291e2 --- /dev/null +++ b/RElicAnalysis/modelwidgetelf.h @@ -0,0 +1,28 @@ +#ifndef MODELWIDGETELF_H +#define MODELWIDGETELF_H + +#include +#include +#include "data.h" + +/* + * This class contains all ElfData and used by QTreeWidgetItem + */ +class ModelWidgetELF { + public: + ModelWidgetELF(); + ~ModelWidgetELF(); + void addWidgetItem(QTreeWidgetItem *, struct elfProgram *); + void addWidgetItem(QTreeWidgetItem *, struct elfSection *); + void addWidgetItem(QTreeWidgetItem *, struct elfSymbol *); + struct elfProgram *findWidgetItemProgram(QTreeWidgetItem *); + struct elfSection *findWidgetItemSection(QTreeWidgetItem *); + struct elfSymbol *findWidgetItemSymbol(QTreeWidgetItem *); + + private: + QHash m_hashPrograms; + QHash m_hashSections; + QHash m_hashSymbols; +}; + +#endif // MODELWIDGETELF_H diff --git a/RElicAnalysis/parsingelf.cpp b/RElicAnalysis/parsingelf.cpp new file mode 100644 index 0000000..2471304 --- /dev/null +++ b/RElicAnalysis/parsingelf.cpp @@ -0,0 +1,442 @@ +#include "parsingelf.h" +#include +#include +#include +#include +#include + + +int elfFile(const char *buffer, ElfData *elfData){ + struct elfIdent *sElfId = (struct elfIdent*)malloc(sizeof(struct elfIdent)); + if (sElfId == NULL){ + qDebug() << "Failed"; + return READ_FILE_ERROR; + } + memset(sElfId, 0, sizeof(struct elfIdent)); + + // Copy to our structure + for(int i = 0; i < 4; i ++) + sElfId->signature[i] = QByteArray(1, buffer[i]); + sElfId->arch = QByteArray(1, buffer[4]); + sElfId->endianess = QByteArray(1, buffer[5]); + sElfId->version = QByteArray(1, buffer[6]); + sElfId->abi = QByteArray(1, buffer[7]); + sElfId->vers_abi = QByteArray(1, buffer[8]); + for(int i = 0; i < 7; i++) + sElfId->padding[i] = QByteArray(1, buffer[i + 9]); + + elfData->setIdentification(sElfId); + free(sElfId); + + /* Parsing Elf Hdr */ + if (buffer[4] == ELFCLASS_64){ + elfData->setArchitecture(ARCH_ELF64); + bool res = elf64(buffer, elfData); + if (res) + return READ_FILE_NO_ERROR; + else + return READ_FILE_ERROR; + } + else if(buffer[4] == ELFCLASS_32){ + elfData->setArchitecture(ARCH_ELF32); + return READ_FILE_32BIT; + } + + return READ_FILE_NO_ERROR; +} +/*void getIdentification(struct elf_ident **sElfIdent, const char *buffer){ + // Shift +4 to avoid the ELF signature + *sElfIdent = (struct elf_ident*)(buffer + 4); +}*/ +bool elf64(const char *buffer, ElfData *elfData){ + //*ehdr = (Elf64_Ehdr*)(buffer); + struct elfHdr *elfHdr = (struct elfHdr*)malloc(sizeof(struct elfHdr)); + size_t lenEhdr = sizeof(Elf64_Ehdr); + size_t lenPhdr = sizeof(Elf64_Phdr); + size_t lenShdr = sizeof(Elf64_Shdr); + size_t offset; + Elf64_Ehdr *ehdr = NULL; + quint16 shstrndx; + bool ok, res; + int phnum, shnum; + + if (elfHdr == NULL) + return false; + + // Set ELF headers size to ElfData + elfData->setSizeofElf_Ehdr(lenEhdr); + elfData->setSizeofElf_Phdr(lenPhdr); + elfData->setSizeofElf_Shdr(lenShdr); + + memset(elfHdr, 0, sizeof(struct elfHdr)); + + ehdr = (Elf64_Ehdr*)(buffer); + + // Get ELF header + elfHdr->e_type = convertFrom16bits(ehdr->e_type); + elfHdr->e_machine = convertFrom16bits(ehdr->e_machine); + elfHdr->e_version = convertFrom32bits(ehdr->e_version); + elfHdr->e_entry = convertFrom64bits(ehdr->e_entry); + elfHdr->e_phoff = convertFrom64bits(ehdr->e_phoff); + elfHdr->e_shoff = convertFrom64bits(ehdr->e_shoff); + elfHdr->e_flags = convertFrom32bits(ehdr->e_flags); + elfHdr->e_ehsize = convertFrom16bits(ehdr->e_ehsize); + elfHdr->e_phentsize = convertFrom16bits(ehdr->e_phentsize); + elfHdr->e_phnum = convertFrom16bits(ehdr->e_phnum); + elfHdr->e_shentsize = convertFrom16bits(ehdr->e_shentsize); + elfHdr->e_shnum = convertFrom16bits(ehdr->e_shnum); + elfHdr->e_shstrndx = convertFrom16bits(ehdr->e_shstrndx); + + // Get the string table index + shstrndx = ehdr->e_shstrndx; + + elfData->setHeader(elfHdr); + free(elfHdr); + + // Get program headers + phnum = elfHdr->e_phnum.toHex().toInt(&ok, 16); + + // Get the first program header offset + offset = elfHdr->e_phoff.toHex().toInt(&ok, 16); + //qDebug() << "Offset hdr:" << offset; + + res = elf64ProgramHdr(buffer, elfData, offset, phnum); + + if (!res) + return false; + + // Get section headers + offset = elfHdr->e_shoff.toHex().toInt(&ok, 16); + //qDebug() << "Offset section: " << offset; + shnum = elfHdr->e_shnum.toHex().toInt(&ok, 16); + + res = elf64SectionHdr(buffer, elfData, offset, shstrndx, shnum); + if (!res) + return false; + + return true; +} +void elf32(int fd, off_t fileLen, Elf32_Ehdr *ehdr){ + +} +bool elf64ProgramHdr(const char *buffer, ElfData *elfData, size_t offset, int phnum){ + Elf64_Phdr *phdr = (Elf64_Phdr*)(buffer + offset); + bool ok; + + // We malloc the variable and we free it in the elfData destructor + struct elfProgram *elfP = (struct elfProgram *)malloc(phnum * sizeof(struct elfProgram)); + if (elfP == NULL) + return false; + + for (int i = 0; i < phnum; i++){ + memset(&elfP[i], 0, sizeof(struct elfProgram)); + + elfP[i].p_type = convertFrom32bits(phdr[i].p_type); + elfP[i].p_flags = convertFrom32bits(phdr[i].p_flags); + elfP[i].p_offset = convertFrom64bits(phdr[i].p_offset); + elfP[i].p_vaddr = convertFrom64bits(phdr[i].p_vaddr); + elfP[i].p_paddr = convertFrom64bits(phdr[i].p_paddr); + elfP[i].p_filesz = convertFrom64bits(phdr[i].p_filesz); + elfP[i].p_memsz = convertFrom64bits(phdr[i].p_memsz); + elfP[i].p_align = convertFrom64bits(phdr[i].p_align); + + + elfData->setProgramHeader(&elfP[i]); + } + return true; +} +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; + // 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); + + // Get the string table header + Elf64_Shdr *strtab = &shdr[shstrndx]; + 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; + int indexDynStrTab = 0; + int indexTextTab = 0; + int indexFiniTab = 0; + int indexHashTab = 0; + int indexDynSymTab = 0; + + for (int i = 0; i < shnum; i++){ + memset(&elfS[i], 0, sizeof(struct elfSection)); + + elfS[i].sh_name = QByteArray(b + shdr[i].sh_name); + //qDebug() << "Section: " << elfS[i].sh_name; + elfS[i].sh_type = convertFrom32bits(shdr[i].sh_type); + elfS[i].sh_flags = convertFrom64bits(shdr[i].sh_flags); + elfS[i].sh_addr = convertFrom64bits(shdr[i].sh_addr); + elfS[i].sh_offset = convertFrom64bits(shdr[i].sh_offset); + elfS[i].sh_size = convertFrom64bits(shdr[i].sh_size); + elfS[i].sh_link = convertFrom32bits(shdr[i].sh_link); + 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(); + elfData->setSectionHeader(&elfS[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; + + if (shdr[i].sh_type == 0x01 && strcmp(shname, ".text") == 0){ + indexTextTab = i; + } + + if (shdr[i].sh_type == 0x01 && strcmp(shname, ".fini") == 0) + indexFiniTab = i; + + // .data + if (shdr[i].sh_type == 0x01){ } + + // .hash + if (shdr[i].sh_type == 0x05 && strcmp(shname, ".hash") == 0) + indexHashTab = i; + + if (shdr[i].sh_type == 0xb && strcmp(shname, ".dynsym") == 0) + indexDynSymTab = i; + + if (shdr[i].sh_type == 0x3 && strcmp(shname, ".dynstr") == 0) + 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); + } + + } + + // 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 + + // Hash table + shdrhash = &shdr[indexHashTab]; + + return true; +} +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]; + //Elf64_Shdr *shdrhash = &shdr[indexHashTab]; + //size_t dynsymnum = shdrdynsym->sh_size / shdrdynsym->sh_entsize; + + const char *b2 = buffer + shdrDynStr->sh_offset; + 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)); + 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); + elfS[i].st_shndx = convertFrom16bits(symtab[i].st_shndx); + elfS[i].st_value = convertFrom64bits(symtab[i].st_value); + + elfData->setDynSymbols(&elfS[i]); + } + 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); + + struct elfSymbol *elfS = (struct elfSymbol*)malloc(symtabnum * sizeof(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); + 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); + free(sData->s_object_asm); + free(sData); + } + + 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]); + } + + /* + * 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 + */ + } + + return true; +} +void getSymbolsText(struct elfSection *sElfS, int indexTextTab, int inexFiniTab){ + +} +bool getHashes(const char *buffer, ElfData *elfData){ + return true; +} +void elf32SectionHdr(int fd, Elf32_Off phoff, off_t shnum){ + +} +QByteArray convertFrom16bits(quint16 value){ + QBuffer buf; + buf.open(QBuffer::ReadWrite); + QDataStream ds(&buf); + ds << value; + QByteArray ba = buf.buffer(); + buf.close(); + return cutByteArray(ba); + //return ba; +} +QByteArray convertFrom32bits(quint32 value){ + QBuffer buf; + buf.open(QBuffer::ReadWrite); + QDataStream ds(&buf); + ds << value; + QByteArray ba = buf.buffer(); + buf.close(); + return cutByteArray(ba); + //return ba; +} +QByteArray convertFrom64bits(quint64 value){ + QBuffer buf; + buf.open(QBuffer::ReadWrite); + QDataStream ds(&buf); + ds << value; + QByteArray ba = buf.buffer(); + buf.close(); + return cutByteArray(ba); + //return ba; +} diff --git a/RElicAnalysis/parsingelf.h b/RElicAnalysis/parsingelf.h new file mode 100644 index 0000000..982ad3f --- /dev/null +++ b/RElicAnalysis/parsingelf.h @@ -0,0 +1,52 @@ +#ifndef PARSINGELF_H +#define PARSINGELF_H + +#include +#include +#include +#include +#include "data.h" +#include "elfdata.h" +#include "disasasm.h" +#include "functions.h" + +/* + * These values are important, they match directly from the buffer ELFCLASSxx + * Cf: https://man7.org/linux/man-pages/man5/elf.5.html + */ +#define ELFCLASS_64 2 /* ELFCLASS64 */ +#define ELFCLASS_32 1 /* ELFCLASS32 */ + +#define READ_FILE_NO_ERROR 0 +#define READ_FILE_ERROR 1 +#define READ_FILE_32BIT 2 + +// https://refspecs.linuxfoundation.org/elf/gabi4+/ch4.eheader.html#elfid +// https://man7.org/linux/man-pages/man5/elf.5.html +// Sizeof 12 bytes +struct elf_ident{ + unsigned char arch; + unsigned char endianess; + unsigned char version; + unsigned char abi; + unsigned char vers_abi; + unsigned char padding[7]; +} __attribute__((packed)); + +int elfFile(const char *, ElfData *); +// /void getIdentification(struct elf_ident **, const char *); +void elf32(int, off_t, Elf32_Ehdr*); +bool elf64(const char *, ElfData *); +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 getDynSym(const char *, ElfData *, Elf64_Shdr *, int, int, int); +void getSymbolsText(struct elfSection *, int, int); +bool getHashes(const char *, ElfData *); +QByteArray convertFrom16bits(quint16); +QByteArray convertFrom32bits(quint32); +QByteArray convertFrom64bits(quint64); + +#endif // PARSINGELF_H diff --git a/RElicAnalysis/project.cpp b/RElicAnalysis/project.cpp new file mode 100644 index 0000000..ac06910 --- /dev/null +++ b/RElicAnalysis/project.cpp @@ -0,0 +1,21 @@ +#include "project.h" + +Project::Project() {} +void Project::setFileInfo(FileInfo *f){ + m_fileInfo = f; +} +void Project::setProjectName(QString name){ + m_projectName = name; +} +FileInfo *Project::getFileInfo(){ + return m_fileInfo; +} +QString Project::getProjectName(){ + return m_projectName; +} +void Project::setPath(QString p){ + m_projectPath = p; +} +QString Project::getPath(){ + return m_projectPath; +} diff --git a/RElicAnalysis/project.h b/RElicAnalysis/project.h new file mode 100644 index 0000000..49509fe --- /dev/null +++ b/RElicAnalysis/project.h @@ -0,0 +1,29 @@ +#ifndef PROJECT_H +#define PROJECT_H + +#include +#include "fileinfo.h" + +/* + * This class contains information regarding the project + * Such as the filename, the path, and so on + */ + +class Project +{ + public: + Project(); + void setFileInfo(FileInfo *); + void setProjectName(QString); + FileInfo *getFileInfo(); + QString getProjectName(); + void setPath(QString); + QString getPath(); + + private: + FileInfo *m_fileInfo; + QString m_projectName; + QString m_projectPath; +}; + +#endif // PROJECT_H diff --git a/RElicAnalysis/projectelf.cpp b/RElicAnalysis/projectelf.cpp new file mode 100644 index 0000000..8f8a1e4 --- /dev/null +++ b/RElicAnalysis/projectelf.cpp @@ -0,0 +1,10 @@ +#include "projectelf.h" + +ProjectElf::ProjectElf() {} + +void ProjectElf::setElfData(ElfData *elfData){ + m_elfData = elfData; +} +ElfData *ProjectElf::getElfData(){ + return m_elfData; +} diff --git a/RElicAnalysis/projectelf.h b/RElicAnalysis/projectelf.h new file mode 100644 index 0000000..e86dd94 --- /dev/null +++ b/RElicAnalysis/projectelf.h @@ -0,0 +1,20 @@ +#ifndef PROJECTELF_H +#define PROJECTELF_H + +#include "project.h" +#include "elfdata.h" + + +class ProjectElf : public Project { + public: + ProjectElf(); + void setElfData(ElfData *); + ElfData *getElfData(); + + private: + ElfData *m_elfData; +}; + + + +#endif // PROJECTELF_H diff --git a/RElicAnalysis/stylesheet.h b/RElicAnalysis/stylesheet.h new file mode 100644 index 0000000..bc3f75b --- /dev/null +++ b/RElicAnalysis/stylesheet.h @@ -0,0 +1,11 @@ +#ifndef STYLESHEET_H +#define STYLESHEET_H + +#include +#include + +QString styleBar("border-bottom:1px solid #000;background-color:#656565;color:#fff;padding:2px;margin:0px"); +QString labelBar("QLabel{margin:0px;}QLabel{color:#fff;}"); +QFont fontBar("Arial MT", 11); + +#endif // STYLESHEET_H