├── .appveyor.yml ├── .gitignore ├── .gitmodules ├── .vscode └── settings.json ├── CMakeLists.txt ├── LICENSE ├── Language ├── PE-bear.ts ├── Readme.md └── zh_CN │ └── PELanguage.qm ├── README.md ├── SIG.txt ├── build.sh ├── build_codelite.sh ├── build_qt4.sh ├── build_qt5.sh ├── build_qt6.sh ├── disasm ├── CMakeLists.txt ├── Disasm.cpp ├── Disasm.h ├── MnemType.h ├── PeDisasm.cpp ├── PeDisasm.h ├── bear_disasm.h ├── cdis │ ├── CDisasm.cpp │ └── CDisasm.h └── udis │ ├── UDisasm.cpp │ └── UDisasm.h ├── logo ├── main_ico.png └── main_ico_old.png ├── macos_wrap.sh ├── pe-bear ├── .gitignore ├── CMakeLists.txt ├── DateDisplay.cpp ├── DateDisplay.h ├── DisasmView.cpp ├── DisasmView.h ├── ExeDependentAction.cpp ├── ExeDependentAction.h ├── HexCompareView.cpp ├── HexCompareView.h ├── HexDumpModel.cpp ├── HexDumpModel.h ├── HexView.cpp ├── HexView.h ├── OffsetHeader.cpp ├── OffsetHeader.h ├── PEDockedWidget.cpp ├── PEDockedWidget.h ├── PEFileTreeModel.cpp ├── PEFileTreeModel.h ├── QtCompat.h ├── REbear.h ├── SectionsDiagram.cpp ├── SectionsDiagram.h ├── TempBuffer.h ├── ViewSettings.cpp ├── ViewSettings.h ├── application.qrc ├── base │ ├── BearVers.cpp │ ├── BearVers.h │ ├── CollectorThread.cpp │ ├── CollectorThread.h │ ├── CommentHandler.cpp │ ├── CommentHandler.h │ ├── ImportsAutoadderSettings.h │ ├── MainSettings.cpp │ ├── MainSettings.h │ ├── Modification.cpp │ ├── Modification.h │ ├── PeHandler.cpp │ ├── PeHandler.h │ ├── PeHandlerFactory.cpp │ ├── PeHandlerFactory.h │ ├── PeHandlersManager.cpp │ ├── PeHandlersManager.h │ ├── RegKeyManager.cpp │ ├── RegKeyManager.h │ ├── Releasable.h │ ├── StringsCollection.h │ └── threads │ │ ├── CalcThread.cpp │ │ ├── CalcThread.h │ │ ├── CollectorThread.h │ │ ├── SignFinderThread.cpp │ │ ├── SignFinderThread.h │ │ ├── StringExtThread.cpp │ │ ├── StringExtThread.h │ │ └── SupportedHashes.h ├── gui │ ├── CommentView.cpp │ ├── CommentView.h │ ├── ContentPreview.cpp │ ├── ContentPreview.h │ ├── DarkStyle.h │ ├── DataDirWrapperSplitter.cpp │ ├── DataDirWrapperSplitter.h │ ├── DetailsTab.cpp │ ├── DetailsTab.h │ ├── DosHdrTableModel.cpp │ ├── DosHdrTableModel.h │ ├── GeneralPanel.cpp │ ├── GeneralPanel.h │ ├── HexDiffModel.cpp │ ├── HexDiffModel.h │ ├── PackersTableModel.cpp │ ├── PackersTableModel.h │ ├── PeTreeModel.cpp │ ├── PeTreeModel.h │ ├── PeWrapperModel.cpp │ ├── PeWrapperModel.h │ ├── ResourceDirSplitter.cpp │ ├── ResourceDirSplitter.h │ ├── TreeModel.cpp │ ├── TreeModel.h │ ├── WrapperSplitter.cpp │ ├── WrapperSplitter.h │ ├── WrapperTreeView.cpp │ ├── WrapperTreeView.h │ ├── followable_table │ │ ├── FollowableOffsetedView.h │ │ ├── MouseTrackingTableView.h │ │ ├── OffsetedView.cpp │ │ └── OffsetedView.h │ ├── pe_models.h │ ├── pe_models │ │ ├── BoundImpTreeModel.cpp │ │ ├── BoundImpTreeModel.h │ │ ├── ClrHdrTreeModel.cpp │ │ ├── ClrHdrTreeModel.h │ │ ├── DebugTreeModel.cpp │ │ ├── DebugTreeModel.h │ │ ├── DelayImpTreeModel.cpp │ │ ├── DelayImpTreeModel.h │ │ ├── ExceptionTreeModel.cpp │ │ ├── ExceptionTreeModel.h │ │ ├── ExportsTreeModel.cpp │ │ ├── ExportsTreeModel.h │ │ ├── FileHdrTreeModel.cpp │ │ ├── FileHdrTreeModel.h │ │ ├── ImportsTreeModel.cpp │ │ ├── ImportsTreeModel.h │ │ ├── LdConfigTreeModel.cpp │ │ ├── LdConfigTreeModel.h │ │ ├── OptionalHdrTreeModel.cpp │ │ ├── OptionalHdrTreeModel.h │ │ ├── RelocsTreeModel.cpp │ │ ├── RelocsTreeModel.h │ │ ├── ResourcesTreeModel.cpp │ │ ├── ResourcesTreeModel.h │ │ ├── RichHdrTreeModel.cpp │ │ ├── RichHdrTreeModel.h │ │ ├── SecHdrsTreeModel.cpp │ │ ├── SecHdrsTreeModel.h │ │ ├── SecurityTreeModel.cpp │ │ ├── SecurityTreeModel.h │ │ ├── TLSTreeModel.cpp │ │ └── TLSTreeModel.h │ └── windows │ │ ├── DiffWindow.cpp │ │ ├── DiffWindow.h │ │ ├── ImportsAddWindow.cpp │ │ ├── ImportsAddWindow.h │ │ ├── MainWindow.cpp │ │ ├── MainWindow.h │ │ ├── OffsetsBrowseWindow.cpp │ │ ├── OffsetsBrowseWindow.h │ │ ├── PatternSearchWindow.cpp │ │ ├── PatternSearchWindow.h │ │ ├── SectionAddWindow.cpp │ │ ├── SectionAddWindow.h │ │ ├── SignaturesBrowseWindow.cpp │ │ ├── SignaturesBrowseWindow.h │ │ ├── StringsBrowseWindow.cpp │ │ ├── StringsBrowseWindow.h │ │ ├── UserConfigWindow.cpp │ │ └── UserConfigWindow.h ├── gui_base │ ├── AddressInputDialog.cpp │ ├── AddressInputDialog.h │ ├── ClipboardUtil.cpp │ ├── ClipboardUtil.h │ ├── ExtTableView.cpp │ ├── ExtTableView.h │ ├── FollowablePeTreeView.cpp │ ├── FollowablePeTreeView.h │ ├── HexInputDialog.cpp │ ├── HexInputDialog.h │ ├── HexMimeSource.cpp │ ├── HexMimeSource.h │ ├── HexSpinBox.cpp │ ├── HexSpinBox.h │ ├── OffsetDependentAction.cpp │ ├── OffsetDependentAction.h │ ├── PEViewsManager.cpp │ ├── PEViewsManager.h │ ├── PeGuiItem.cpp │ ├── PeGuiItem.h │ ├── PeTableModel.cpp │ ├── PeTableModel.h │ ├── PeTreeView.cpp │ ├── PeTreeView.h │ ├── TreeCpView.cpp │ ├── TreeCpView.h │ ├── WrapperInterface.cpp │ ├── WrapperInterface.h │ ├── WrapperTableModel.cpp │ └── WrapperTableModel.h ├── icons │ ├── Add.ico │ ├── Delete.ico │ ├── DeleteAll.ico │ ├── EP.ico │ ├── List.ico │ ├── Locked.ico │ ├── Preview.ico │ ├── Save.ico │ ├── add_entry.ico │ ├── add_subentry.ico │ ├── app32.ico │ ├── app32_w.ico │ ├── app64.ico │ ├── app64_w.ico │ ├── arr_down.ico │ ├── arr_up.ico │ ├── arrow-right.ico │ ├── data_dir_color.ico │ ├── data_dir_gray.ico │ ├── disasm.ico │ ├── dos.ico │ ├── down.ico │ ├── dump.ico │ ├── enlarge.ico │ ├── eraser.ico │ ├── go_to_raw.ico │ ├── go_to_rva.ico │ ├── hdr.ico │ ├── information.ico │ ├── magic_wand.ico │ ├── move.ico │ ├── move0.ico │ ├── red_pin.ico │ ├── reload.ico │ ├── resize.ico │ ├── save_black.ico │ ├── section.ico │ ├── shrink.ico │ ├── space.ico │ ├── space_down.ico │ ├── space_this.ico │ ├── space_up.ico │ ├── star.ico │ ├── transform.ico │ ├── transform0.ico │ ├── undo.ico │ ├── unmodify.ico │ ├── up.ico │ └── wrong_way.ico ├── main.cpp ├── main_ico.ico ├── main_ico_old.ico ├── rebear_res.rc ├── rebear_ver_short.h ├── resources.h └── resources.rc └── xdg ├── appdata.metainfo.xml.in └── launcher.desktop.in /.gitignore: -------------------------------------------------------------------------------- 1 | build_qt4/* 2 | build_qt5/* 3 | build_qt6/* 4 | build_udis/* 5 | *.bak 6 | 7 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "capstone"] 2 | path = capstone 3 | url = https://github.com/capstone-engine/capstone 4 | [submodule "bearparser"] 5 | path = bearparser 6 | url = https://github.com/hasherezade/bearparser 7 | [submodule "sig_finder"] 8 | path = sig_finder 9 | url = https://github.com/hasherezade/sig_finder.git 10 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "ranges": "cpp" 4 | } 5 | } -------------------------------------------------------------------------------- /Language/Readme.md: -------------------------------------------------------------------------------- 1 | # How to load a language file 2 | 3 | 1. The directory with languages (named `Language`) must be in same directory as PE-bear executable, or in User Data Directory (`Settings` -> `Configure...` -> `User Data Directory`). 4 | 2. Create a subdirectory with the name of the language version that you want to add (i.e. `zh_CN`) 5 | 3. Rename the Language file to `PELanguage.qm` and put it into the created folder 6 | 4. Restart PE-bear. Now, you should see the added language under `Settings` -> `Configure...` -> `Language`. 7 | 5. Select your language from the list, and restart PE-bear. The interface should be updated to the new language. 8 | 9 | # How to translate 10 | Download the language file, use QT linguist to load and select the language to be translated, and click Publish to generate qm file after translation. 11 | # reference data 12 | * https://doc.qt.io/qt-5/qtlinguist-index.html 13 | * https://doc.qt.io/qt-5/linguist-translators.html 14 | -------------------------------------------------------------------------------- /Language/zh_CN/PELanguage.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/Language/zh_CN/PELanguage.qm -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ./build_qt6.sh 4 | -------------------------------------------------------------------------------- /build_codelite.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Trying to build PE-bear..." 4 | 5 | #QT check 6 | 7 | QT_VER=$(qmake -v) 8 | str="$QT_VER" 9 | substr="Qt version 6" 10 | 11 | echo $QT_VER 12 | if [[ $str == *"$substr"* ]]; then 13 | echo "[+] Qt6 found!" 14 | else 15 | str2=$(whereis qt6) 16 | substr2="/qt6" 17 | if [[ $str2 == *"$substr2"* ]]; then 18 | echo "[+] Qt6 found!" 19 | else 20 | echo "Install Qt6 SDK first" 21 | exit -1 22 | fi 23 | fi 24 | 25 | CMAKE_VER=$(cmake --version) 26 | CMAKEV="cmake version" 27 | if echo "$CMAKE_VER" | grep -q "$CMAKEV"; then 28 | echo "[+] CMake found!" 29 | else 30 | echo "[-] CMake NOT found!" 31 | echo "Install cmake first" 32 | exit -1 33 | fi 34 | echo $CMAKE_VER 35 | mkdir build_qt6 36 | echo "[+] build directory created" 37 | cd build_qt6 38 | cmake -G"CodeLite - Unix Makefiles" -DCMAKE_INSTALL_PREFIX:PATH=$(pwd) .. 39 | cmake --build . --target install 40 | make 41 | cd .. 42 | 43 | -------------------------------------------------------------------------------- /build_qt4.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Trying to build PE-bear..." 4 | 5 | #QT check 6 | 7 | QT_VER=$(qmake -v) 8 | QTV="version" 9 | if echo "$QT_VER" | grep -q "$QTV"; then 10 | QT4_FOUND=$(whereis qt4) 11 | if echo "$QT4_FOUND" | grep -q "lib"; then 12 | echo "[+] Qt4 found!" 13 | else 14 | echo "Install Qt4 SDK first" 15 | exit -2 16 | fi 17 | else 18 | echo "Install Qt4 SDK first" 19 | exit -1 20 | fi 21 | 22 | CMAKE_VER=$(cmake --version) 23 | CMAKEV="cmake version" 24 | if echo "$CMAKE_VER" | grep -q "$CMAKEV"; then 25 | echo "[+] CMake found!" 26 | else 27 | echo "[-] CMake NOT found!" 28 | echo "Install cmake first" 29 | exit -1 30 | fi 31 | 32 | echo $CMAKE_VER 33 | mkdir build_qt4 34 | echo "[+] build directory created" 35 | cd build_qt4 36 | cmake -DUSE_QT4=ON -DCMAKE_INSTALL_PREFIX:PATH=$(pwd) .. 37 | cmake --build . --target install 38 | make 39 | cd .. 40 | -------------------------------------------------------------------------------- /build_qt5.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Trying to build PE-bear..." 4 | 5 | #QT check 6 | 7 | QT_VER=$(qmake -v) 8 | str="$QT_VER" 9 | substr="Qt version 5" 10 | 11 | echo $QT_VER 12 | if [[ $str == *"$substr"* ]]; then 13 | echo "[+] Qt5 found!" 14 | else 15 | str2=$(whereis qt5) 16 | substr2="/qt5" 17 | if [[ $str2 == *"$substr2"* ]]; then 18 | echo "[+] Qt5 found!" 19 | else 20 | echo "Install Qt5 SDK first" 21 | exit -1 22 | fi 23 | fi 24 | 25 | 26 | CMAKE_VER=$(cmake --version) 27 | CMAKEV="cmake version" 28 | if echo "$CMAKE_VER" | grep -q "$CMAKEV"; then 29 | echo "[+] CMake found!" 30 | else 31 | echo "[-] CMake NOT found!" 32 | echo "Install cmake first" 33 | exit -1 34 | fi 35 | echo $CMAKE_VER 36 | mkdir build_qt5 37 | echo "[+] build directory created" 38 | cd build_qt5 39 | cmake -DUSE_QT5=ON -DCMAKE_INSTALL_PREFIX:PATH=$(pwd) .. 40 | cmake --build . --target install 41 | make 42 | cd .. 43 | 44 | -------------------------------------------------------------------------------- /build_qt6.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Trying to build PE-bear..." 4 | 5 | #QT check 6 | 7 | QT_VER=$(qmake -v) 8 | str="$QT_VER" 9 | substr="Qt version 6" 10 | 11 | echo $QT_VER 12 | if [[ $str == *"$substr"* ]]; then 13 | echo "[+] Qt6 found!" 14 | else 15 | str2=$(whereis qt6) 16 | substr2="/qt6" 17 | if [[ $str2 == *"$substr2"* ]]; then 18 | echo "[+] Qt6 found!" 19 | else 20 | echo "Install Qt6 SDK first" 21 | exit -1 22 | fi 23 | fi 24 | 25 | CMAKE_VER=$(cmake --version) 26 | CMAKEV="cmake version" 27 | if echo "$CMAKE_VER" | grep -q "$CMAKEV"; then 28 | echo "[+] CMake found!" 29 | else 30 | echo "[-] CMake NOT found!" 31 | echo "Install cmake first" 32 | exit -1 33 | fi 34 | echo $CMAKE_VER 35 | mkdir build_qt6 36 | echo "[+] build directory created" 37 | cd build_qt6 38 | cmake -DCMAKE_INSTALL_PREFIX:PATH=$(pwd) .. 39 | cmake --build . --target install 40 | make 41 | cd .. 42 | 43 | -------------------------------------------------------------------------------- /disasm/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 3.12) 2 | project (libdisasm) 3 | 4 | # Offer the user the choice of overriding the installation directories 5 | set(INSTALL_LIB_DIR lib CACHE PATH "Installation directory for libraries") 6 | set(INSTALL_BIN_DIR bin CACHE PATH "Installation directory for executables") 7 | 8 | if(USE_QT4) 9 | find_package (Qt4 REQUIRED) 10 | include_directories( ${QT_INCLUDE_DIR} ${QT_QTCORE_INCLUDE_DIR} ) 11 | INCLUDE( ${QT_USE_FILE} ) 12 | ADD_DEFINITIONS( ${QT_DEFINITIONS} ) 13 | else() 14 | find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) 15 | find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED) 16 | get_target_property(QtCore_location Qt${QT_VERSION_MAJOR}::Core LOCATION) 17 | endif() 18 | 19 | include_directories ( ${UDIS86_DIR} ${CAPSTONE_INC} ) 20 | include_directories( ${PARSER_INC} ) 21 | 22 | if (USE_UDIS86) 23 | set (disasm_wrappers_srcs 24 | udis/UDisasm.cpp 25 | ) 26 | set (disasm_wrappers_hdrs 27 | udis/UDisasm.h 28 | ) 29 | message(STATUS "udis_dir='${UDIS86_DIR}'") 30 | message(STATUS "udis_lib='${UDIS86_LIB}'") 31 | else() 32 | set (disasm_wrappers_srcs 33 | cdis/CDisasm.cpp 34 | ) 35 | set (disasm_wrappers_hdrs 36 | cdis/CDisasm.h 37 | ) 38 | message(STATUS "capstone_includes='${CAPSTONE_INC}'") 39 | message(STATUS "capstone_lib='${CAPSTONE_LIB}'") 40 | endif () 41 | 42 | # multi-processor compilation 43 | if(MSVC) 44 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") 45 | endif() 46 | 47 | set (disasm_srcs 48 | Disasm.cpp 49 | PeDisasm.cpp 50 | ${disasm_wrappers_srcs} 51 | ) 52 | 53 | set (disasm_hdrs 54 | bear_disasm.h 55 | Disasm.h 56 | PeDisasm.h 57 | MnemType.h 58 | ${disasm_wrappers_hdrs} 59 | ) 60 | 61 | add_library( ${PROJECT_NAME} STATIC ${disasm_srcs} ${disasm_hdrs} ) 62 | 63 | if (USE_UDIS86) 64 | set (def 65 | "BUILD_WITH_UDIS86" 66 | ) 67 | list(APPEND deflist ${def}) 68 | set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_DEFINITIONS "${deflist}") 69 | endif() 70 | 71 | if (USE_UDIS86) 72 | target_link_libraries( ${PROJECT_NAME} ${PARSER_LIB} ${UDIS86_LIB} ) 73 | else() 74 | target_link_libraries( ${PROJECT_NAME} ${PARSER_LIB} ${CAPSTONE_LIB} ) 75 | endif() 76 | 77 | if(USE_QT4) 78 | target_link_libraries ( ${PROJECT_NAME} ${QT_QTCORE_LIBRARIES} ) 79 | else() 80 | target_link_libraries( ${PROJECT_NAME} Qt${QT_VERSION_MAJOR}::Core) 81 | endif() 82 | 83 | -------------------------------------------------------------------------------- /disasm/Disasm.cpp: -------------------------------------------------------------------------------- 1 | #include "Disasm.h" 2 | #include 3 | 4 | using namespace pe_bear; 5 | using namespace minidis; 6 | 7 | const int Disasm::MAX_ARG_NUM = 3; 8 | 9 | void pe_bear::resetCond(cond_buf &buf) 10 | { 11 | buf.CF = FLAG_UNK; 12 | buf.PF = FLAG_UNK; 13 | buf.AF = FLAG_UNK; 14 | buf.ZF = FLAG_UNK; 15 | buf.SF = FLAG_UNK; 16 | buf.IF = FLAG_UNK; 17 | buf.DF = FLAG_UNK; 18 | buf.OF = FLAG_UNK; 19 | buf.cx = FLAG_UNK; 20 | buf.affectedCounter = 0; 21 | } 22 | 23 | Disasm::Disasm() 24 | : is_init(false), m_buf(NULL), m_bufSize(0), 25 | startOffset(0), m_offset(0), m_disasmSize(0), 26 | m_iptr(0) 27 | { 28 | } 29 | 30 | Disasm::~Disasm() 31 | { 32 | is_init = false; 33 | } 34 | 35 | uint64_t Disasm::trimToBitMode(int64_t value, uint8_t bits) 36 | { 37 | offset_t lval = value; 38 | const size_t max_bits = sizeof(lval) * 8; 39 | const size_t dif = max_bits - bits; 40 | lval = (lval << dif) >> dif; 41 | return lval; 42 | } 43 | 44 | 45 | int64_t Disasm::signExtend(int64_t operand, size_t opSize) 46 | { 47 | size_t opBits = opSize * 8; 48 | int64_t lval = operand; 49 | size_t dif = sizeof(lval) * 8 - opBits; 50 | lval = (operand << dif) >> dif; 51 | return lval; 52 | } 53 | 54 | QString Disasm::printBytes(const uint8_t* buf, const size_t size) 55 | { 56 | QString str; 57 | for (size_t i = 0; i < size; i++) { 58 | #if QT_VERSION >= 0x050000 59 | str += QString().asprintf("%02X", buf[i]); 60 | #else 61 | str += QString().sprintf("%02X", buf[i]); 62 | #endif 63 | } 64 | return str; 65 | } 66 | 67 | offset_t Disasm::getJmpDestAddr(offset_t currVA, int instrLen, int lVal) const 68 | { 69 | if (currVA == INVALID_ADDR) { 70 | return INVALID_ADDR; 71 | } 72 | int delta = instrLen + lVal; 73 | const offset_t addr = (offset_t)((int64_t)currVA + (int64_t)delta); 74 | return addr; 75 | } 76 | 77 | bool Disasm::isBranching(minidis::mnem_type m_mnemType) 78 | { 79 | switch (m_mnemType) { 80 | case MT_COND_JUMP: 81 | case MT_LOOP: 82 | return true; 83 | } 84 | return isUnconditionalBranching(m_mnemType); 85 | } 86 | 87 | bool Disasm::isUnconditionalBranching(minidis::mnem_type m_mnemType) 88 | { 89 | switch (m_mnemType) { 90 | case MT_JUMP: 91 | case MT_CALL: 92 | return true; 93 | } 94 | return false; 95 | } 96 | -------------------------------------------------------------------------------- /disasm/MnemType.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace minidis { 5 | 6 | const BYTE OP_RET = 0xc3; 7 | 8 | typedef enum { 9 | MT_INVALID, // invalid instruction 10 | MT_RET, 11 | MT_NOP, 12 | MT_INTX, 13 | MT_INT3, 14 | MT_CALL, 15 | MT_JUMP, 16 | MT_COND_JUMP, 17 | MT_LOOP, 18 | MT_PUSH, 19 | MT_POP, 20 | MT_ARITHMETICAL, 21 | MT_MOV, 22 | MT_TEST, 23 | MT_OTHER, 24 | MT_NONE, // invalid input 25 | COUNT_MT 26 | } mnem_type; 27 | 28 | }; /* namespace minidis */ 29 | -------------------------------------------------------------------------------- /disasm/PeDisasm.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Disasm.h" 4 | 5 | #ifdef BUILD_WITH_UDIS86 6 | #include "udis/UDisasm.h" 7 | typedef pe_bear::UDisasm __disasm_super; 8 | #else 9 | #include "cdis/CDisasm.h" 10 | typedef pe_bear::CDisasm __disasm_super; 11 | #endif 12 | 13 | #define DISASM_PREVIEW_SIZE 0x200 14 | 15 | namespace pe_bear { 16 | 17 | class PeDisasm : public __disasm_super 18 | { 19 | 20 | public: 21 | PeDisasm(PEFile *pe, size_t previewSize = DISASM_PREVIEW_SIZE); 22 | bool init(const offset_t offset, Executable::exe_arch arch, Executable::exe_bits bitMode); 23 | bool fillTable(); 24 | 25 | bool isRvaContnuous(int index) const; 26 | 27 | offset_t getRawAt(int index) const; 28 | offset_t getRvaAt(int index) const; 29 | 30 | offset_t getVaAt(int index) const 31 | { 32 | offset_t myRva = getRvaAt(index); 33 | if (myRva == INVALID_ADDR || !m_PE){ 34 | return INVALID_ADDR; 35 | } 36 | return m_PE->rvaToVa(myRva); 37 | } 38 | 39 | /* returns target VA or INVALID_ADDR */ 40 | offset_t getTargetVA(int index, bool &isOk) const; 41 | 42 | /* wrapper over getTargetVA, 43 | returns target RVA (if the target address belongs to the current module) or INVALID_ADDR 44 | * */ 45 | offset_t getTargetRVA(int index, bool &isOk) const; 46 | 47 | /* wrapper over getArgVA, 48 | returns target RVA (if the target address belongs to the current module) or INVALID_ADDR 49 | * */ 50 | offset_t getArgRVA(int index, int argNum, bool &isOk) const; 51 | 52 | /* returns target Raw or INVALID_ADDR */ 53 | offset_t getTargetRaw(int index, bool &isOk) const; 54 | 55 | /* distance between current RVA and Target RVA */ 56 | int32_t getTargetDelta(int index) const; 57 | 58 | bool isCallToRet(int index) const; 59 | 60 | QString getStringAt(offset_t rva) const; 61 | 62 | offset_t convertToRVA(offset_t raw) const 63 | { 64 | offset_t myRVA = INVALID_ADDR; 65 | try { 66 | myRVA = m_PE->convertAddr(raw, Executable::RAW, Executable::RVA); 67 | } catch (const CustomException&) { 68 | myRVA = raw; 69 | } 70 | return myRVA; 71 | } 72 | 73 | virtual offset_t convertToVA(offset_t raw) const 74 | { 75 | offset_t myVA = INVALID_ADDR; 76 | try { 77 | myVA = m_PE->convertAddr(raw, Executable::RAW, Executable::VA); 78 | } catch (const CustomException&) { 79 | myVA = raw; 80 | } 81 | return myVA; 82 | } 83 | 84 | protected: 85 | bool fillOffsetTable(); 86 | 87 | std::vector offsetTable; 88 | PEFile *m_PE; 89 | offset_t firstOffset; 90 | size_t previewSize; 91 | 92 | bool isBitModeAuto; 93 | bool isInit; 94 | 95 | }; /* class PeDisasm */ 96 | 97 | }; /* namespace pe_bear */ 98 | 99 | -------------------------------------------------------------------------------- /disasm/bear_disasm.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | -------------------------------------------------------------------------------- /disasm/udis/UDisasm.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include "../Disasm.h" 7 | #include "../MnemType.h" 8 | 9 | namespace pe_bear { 10 | 11 | //---------------------------------------------- 12 | 13 | class UDisasm : public Disasm 14 | { 15 | public: 16 | const static int MAX_ARG_NUM; 17 | 18 | UDisasm(); 19 | ~UDisasm(); 20 | 21 | bool init(uint8_t* buf, size_t bufSize, size_t disasmSize, offset_t offset, Executable::exe_bits bitMode); 22 | bool fillTable(); 23 | bool clearTable(); 24 | size_t getChunkSize(int index) const; 25 | 26 | //get Raw offset of the instruction 27 | offset_t getRawAt(int index) const; 28 | 29 | offset_t getArgVA(int index, int argNum, bool &isOk) const; 30 | 31 | QString translateBranching(int index) const; 32 | 33 | bool isAddrOperand(int index) const; 34 | 35 | bool isPushRet(int push_index,/*out*/ int* ret_index = NULL) const; 36 | 37 | uint64_t getJmpDestAddr(uint64_t currVA, int instrLen, int lVal) const; 38 | 39 | int64_t getSignedLVal(size_t index, size_t operandNum, bool &isOk) const 40 | { 41 | if (index >= chunksCount()) return 0; 42 | ud_t udObj = m_table.at(index); 43 | return getSignedLVal(udObj, operandNum, isOk); 44 | } 45 | //--- 46 | 47 | size_t chunksCount() const { return this->m_table.size(); } 48 | 49 | bool isBranching(size_t index) const 50 | { 51 | if (index >= chunksCount()) return false; 52 | return isBranching(m_table.at(index)); 53 | } 54 | 55 | bool isUnconditionalBranching(size_t index) const 56 | { 57 | if (index >= chunksCount()) return false; 58 | return isUnconditionalBranching(m_table.at(index)); 59 | } 60 | 61 | QString mnemStr(size_t index) const 62 | { 63 | if (index >= this->chunksCount()) { 64 | return ""; 65 | } 66 | ud_t udObj = m_table.at(index); 67 | const char* str = ud_insn_asm(&udObj); 68 | if (!str) return ""; 69 | return str; 70 | } 71 | 72 | QString getHexStr(size_t index) const 73 | { 74 | if (index >= this->chunksCount()) { 75 | return ""; 76 | } 77 | ud_t ud_obj = m_table.at(index); 78 | char *hex_str = ud_insn_hex(&ud_obj); 79 | if (!hex_str) return ""; 80 | return hex_str; 81 | } 82 | 83 | bool isImmediate(size_t index) const 84 | { 85 | if (index >= this->chunksCount()) { 86 | return false; 87 | } 88 | const ud_t &ud_obj = m_table.at(index); 89 | ud_type type = ud_obj.operand[0].type; 90 | if (type != UD_OP_IMM) { 91 | return false; 92 | } 93 | return true; 94 | } 95 | 96 | int32_t getImmediateVal(size_t index) const 97 | { 98 | if (!isImmediate(index)) { 99 | return 0; 100 | } 101 | const ud_t &ud_obj = m_table.at(index); 102 | int32_t val = ud_obj.operand[0].lval.sdword; 103 | return val; 104 | } 105 | 106 | minidis::mnem_type getMnemType(size_t index) const; 107 | 108 | bool isFollowable(const int y) const; 109 | 110 | protected: 111 | static bool isBranching(ud_t ud_obj); 112 | static bool isUnconditionalBranching(ud_t ud_obj); 113 | 114 | int64_t getSignedLVal(ud_t &obj, size_t operandNum, bool &isOk) const; /* TODO: test it!!! */ 115 | 116 | size_t disasmNext(); 117 | 118 | ud_t ud_obj; 119 | std::vector m_table; 120 | 121 | }; /* class Disasm */ 122 | 123 | }; /* namespace pe_bear */ 124 | 125 | -------------------------------------------------------------------------------- /logo/main_ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/logo/main_ico.png -------------------------------------------------------------------------------- /logo/main_ico_old.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/logo/main_ico_old.png -------------------------------------------------------------------------------- /macos_wrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | MCDEPLOY=$1 4 | echo $MCDEPLOY #the given path to macdeploy 5 | if [[ -z $MCDEPLOY ]]; then 6 | #locate macdeployqt: 7 | MPATH=`whereis macdeployqt` 8 | echo $MPATH 9 | 10 | read P1 MCDEPLOY <<<$(IFS=":"; echo $MPATH) 11 | 12 | if [[ -z $MCDEPLOY ]]; then 13 | echo "macdeployqt not found" 14 | exit -1 15 | fi 16 | fi 17 | 18 | APP_PATH="./build_qt6/pe-bear/" 19 | # clean the previous build 20 | rm -rf $APP_PATH/PE-bear.app 21 | 22 | #build stuff 23 | ./build_qt6.sh 24 | 25 | #strip the created build 26 | strip $APP_PATH/PE-bear.app/Contents/MacOS/PE-bear 27 | 28 | #wrap by macdeployqt: 29 | $MCDEPLOY $APP_PATH/PE-bear.app 30 | 31 | # if wrapping succeeded, zip and store: 32 | if [[ $? == 0 ]]; then 33 | CURR_DIR=`pwd` 34 | ZIP_OUT=$CURR_DIR/PE-bear.app.zip 35 | 36 | cd $APP_PATH 37 | zip $ZIP_OUT ./PE-bear.app -r 38 | echo "Wrapped: "$ZIP_OUT 39 | cd $CURR_DIR 40 | fi 41 | -------------------------------------------------------------------------------- /pe-bear/.gitignore: -------------------------------------------------------------------------------- 1 | ipch/* 2 | *.aps 3 | 4 | -------------------------------------------------------------------------------- /pe-bear/DateDisplay.cpp: -------------------------------------------------------------------------------- 1 | #include "DateDisplay.h" 2 | 3 | #include 4 | 5 | QString getDateString(const quint64 timestamp) 6 | { 7 | if (timestamp == 0 || timestamp == (-1)) { 8 | return ""; 9 | } 10 | const time_t rawtime = (const time_t)timestamp; 11 | QString format = "dddd, dd.MM.yyyy hh:mm:ss"; 12 | #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 13 | QDateTime date1(QDateTime::fromSecsSinceEpoch(rawtime)); 14 | #else 15 | QDateTime date1(QDateTime::fromTime_t(rawtime)); 16 | #endif 17 | return date1.toUTC().toString(format) + " UTC"; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /pe-bear/DateDisplay.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef WITH_QT5 4 | #include 5 | #else 6 | #include 7 | #endif 8 | 9 | #include 10 | 11 | QString getDateString(const quint64 timestamp); 12 | 13 | -------------------------------------------------------------------------------- /pe-bear/ExeDependentAction.cpp: -------------------------------------------------------------------------------- 1 | #include "ExeDependentAction.h" 2 | 3 | void ExeDependentAction::updateEnabled() 4 | { 5 | bool isSet = this->currHndl != NULL; 6 | this->setEnabled(this->currHndl != NULL); 7 | } 8 | 9 | void ExeDependentAction::init() 10 | { 11 | connect(this, SIGNAL(triggered()), this, SLOT(onTriggered())); 12 | updateEnabled(); 13 | } 14 | 15 | void ExeDependentAction::onHandlerSelected(PeHandler *hndl) 16 | { 17 | if (this->currHndl == hndl) return; 18 | this->currHndl = hndl; 19 | 20 | updateEnabled(); 21 | emit currHndlChanged(); 22 | } 23 | //------------------------- 24 | 25 | void ExeDependentMenu::addAction(QAction *action) 26 | { 27 | if (!action) return; 28 | 29 | ExeDependentAction *exeAction = dynamic_cast (action); 30 | if (exeAction) { 31 | connect(this, SIGNAL(handlerSet(PeHandler*)), action, SLOT(onHandlerSelected(PeHandler*)) ); 32 | } 33 | QMenu::addAction(action); 34 | } 35 | 36 | void ExeDependentMenu::removeAction(QAction *action) 37 | { 38 | if (!action) return; 39 | 40 | ExeDependentAction *exeAction = dynamic_cast (action); 41 | if (exeAction) { 42 | disconnect(this, SIGNAL(handlerSet(PeHandler*)), action, SLOT(onHandlerSelected(PeHandler*)) ); 43 | } 44 | QMenu::removeAction(action); 45 | } 46 | 47 | void ExeDependentMenu::onExeChanged(PeHandler* hndl) 48 | { 49 | if (this->myHndl == hndl) { 50 | return; //no changes 51 | } 52 | this->myHndl = hndl; 53 | 54 | bool isEnabled = this->myHndl != NULL; 55 | this->setEnabled(isEnabled); 56 | 57 | emit handlerSet(this->myHndl); 58 | } 59 | -------------------------------------------------------------------------------- /pe-bear/ExeDependentAction.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "QtCompat.h" 5 | #include "base/PeHandlersManager.h" 6 | 7 | class ExeDependentAction : public QAction 8 | { 9 | Q_OBJECT 10 | 11 | signals: 12 | void currHndlChanged(); 13 | 14 | public slots: 15 | void onHandlerSelected(PeHandler *hndl); 16 | 17 | public : 18 | ExeDependentAction(QObject *parent) : QAction(parent), currHndl(NULL) { init(); } 19 | ExeDependentAction(const QString text, QObject *parent) : QAction(text, parent), currHndl(NULL) { init(); } 20 | ExeDependentAction(const QIcon ico, const QString text, QObject *parent) : QAction(ico, text, parent), currHndl(NULL) { init(); } 21 | 22 | signals: 23 | void triggered(PeHandler*); 24 | 25 | private slots: 26 | void onTriggered() { emit triggered(currHndl); } 27 | 28 | protected: 29 | void init(); 30 | void updateEnabled(); 31 | 32 | PeHandler *currHndl; 33 | }; 34 | 35 | class ExeDependentMenu : public QMenu 36 | { 37 | Q_OBJECT 38 | 39 | signals: 40 | void handlerSet(PeHandler* hndl); 41 | 42 | protected slots: 43 | void onExeChanged(PeHandler* hndl); 44 | 45 | public: 46 | ExeDependentMenu(QWidget *parent = 0) : QMenu(parent), myHndl(NULL) {} 47 | virtual ~ExeDependentMenu() { } 48 | 49 | void addAction(QAction *action); 50 | void removeAction(QAction *action); 51 | 52 | protected: 53 | PeHandler* myHndl; 54 | }; 55 | -------------------------------------------------------------------------------- /pe-bear/HexCompareView.cpp: -------------------------------------------------------------------------------- 1 | #include "HexCompareView.h" 2 | 3 | #define MIN_FIELD_HEIGHT 18 4 | #define MIN_FIELD_WIDTH 10 5 | 6 | MenuHeader::MenuHeader(QWidget *parent) 7 | : QHeaderView(Qt::Vertical, parent), tableModel(NULL) 8 | { 9 | #if QT_VERSION >= 0x050000 10 | setSectionsClickable(true); 11 | setSectionsMovable(false); 12 | #else 13 | setClickable(true); 14 | setMovable(false); 15 | #endif 16 | setAutoFillBackground(true); 17 | 18 | this->setContextMenuPolicy(Qt::CustomContextMenu); 19 | connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(customMenuEvent(QPoint)) ); 20 | 21 | this->copyAction = new QAction(tr("Copy the offset"), this); 22 | connect(copyAction, SIGNAL(triggered()), this, SLOT(copyOffset())); 23 | 24 | this->defaultMenu.addAction(copyAction); 25 | } 26 | 27 | void MenuHeader::customMenuEvent(QPoint p) 28 | { 29 | if (this->selectedOffset == INVALID_ADDR) { 30 | return; 31 | } 32 | const QPoint p2 = this->mapToGlobal(p); 33 | this->defaultMenu.exec(p2); 34 | } 35 | 36 | void MenuHeader::mousePressEvent(QMouseEvent *event) 37 | { 38 | QPoint p = event->pos(); 39 | int indx = logicalIndexAt(p) ; 40 | 41 | if (this->tableModel) { 42 | 43 | QVariant data = this->tableModel->headerData(indx, Qt::Vertical, Qt::DisplayRole); 44 | bool isOk; 45 | offset_t offset = data.toString().toLongLong(&isOk, 16); 46 | if (isOk) { 47 | selectedOffset = offset; 48 | } 49 | copyAction->setText(tr("Copy the offset: ") + QString::number(selectedOffset, 16).toUpper()); 50 | } 51 | QHeaderView::mousePressEvent(event); 52 | } 53 | 54 | //---- 55 | 56 | HexCompareView::HexCompareView(QWidget *parent) 57 | { 58 | vHdr = new MenuHeader(parent); 59 | this->setVerticalHeader(vHdr); 60 | 61 | init(); 62 | initHeader(); 63 | } 64 | 65 | void HexCompareView::init() 66 | { 67 | setShowGrid(false); 68 | setDragEnabled(false); 69 | setAutoFillBackground(true); 70 | setAlternatingRowColors(true); 71 | 72 | this->resizeColumnsToContents(); 73 | this->resizeRowsToContents(); 74 | 75 | this->setCursor(Qt::PointingHandCursor); 76 | setSelectionBehavior(QTreeWidget::SelectItems); 77 | setSelectionMode(QTreeWidget::ExtendedSelection); 78 | setDragDropMode(QAbstractItemView::NoDragDrop); 79 | 80 | this->setContentsMargins(0, 0, 0, 0); 81 | this->setContextMenuPolicy(Qt::CustomContextMenu); 82 | } 83 | 84 | void HexCompareView::initHeader() 85 | { 86 | horizontalHeader()->setContentsMargins(QMargins(0, 0, 0, 0)); 87 | verticalHeader()->setContentsMargins(QMargins(0, 0, 0, 0)); 88 | this->horizontalHeader()->setMinimumSectionSize(MIN_FIELD_WIDTH); 89 | this->verticalHeader()->setMinimumSectionSize(MIN_FIELD_HEIGHT); 90 | 91 | #if QT_VERSION >= 0x050000 92 | this->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); 93 | this->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); 94 | this->verticalHeader()->setSectionsClickable(true); 95 | #else 96 | this->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents); 97 | this->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents); 98 | this->verticalHeader()->setClickable(true); 99 | #endif 100 | } 101 | -------------------------------------------------------------------------------- /pe-bear/HexCompareView.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "QtCompat.h" 8 | #include "REbear.h" 9 | #include "base/PeHandlersManager.h" 10 | #include "PEFileTreeModel.h" 11 | 12 | #include "gui_base/ExtTableView.h" 13 | 14 | class MenuHeader : public QHeaderView 15 | { 16 | Q_OBJECT 17 | public: 18 | MenuHeader(QWidget *parent); 19 | 20 | virtual void setTableModel(QAbstractItemModel *model) 21 | { 22 | this->tableModel = model; 23 | } 24 | 25 | QMenu defaultMenu; 26 | 27 | public slots: 28 | virtual void customMenuEvent(QPoint p); 29 | 30 | void copyOffset() 31 | { 32 | QMimeData *mimeData = new QMimeData; 33 | mimeData->setText(QString::number(selectedOffset, 16)); 34 | QApplication::clipboard()->setMimeData(mimeData); 35 | } 36 | 37 | protected: 38 | void mousePressEvent(QMouseEvent *event); 39 | 40 | QAbstractItemModel *tableModel; 41 | QAction *copyAction; 42 | 43 | offset_t selectedOffset; 44 | }; 45 | 46 | 47 | class HexCompareView : public ExtTableView 48 | { 49 | Q_OBJECT 50 | 51 | public: 52 | HexCompareView(QWidget *parent = 0); 53 | 54 | virtual void setModel(QAbstractItemModel *model) override 55 | { 56 | ExtTableView::setModel(model); 57 | if (vHdr) { 58 | vHdr->setTableModel(model); 59 | } 60 | } 61 | 62 | protected: 63 | void init(); 64 | void initHeader(); 65 | 66 | MenuHeader *vHdr; 67 | }; 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /pe-bear/HexDumpModel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "QtCompat.h" 5 | #include "gui_base/PeTableModel.h" 6 | #include "ViewSettings.h" 7 | 8 | class HexDumpModel : public PeTableModel//QAbstractTableModel, public PeViewItem 9 | { 10 | Q_OBJECT 11 | 12 | signals: 13 | void scrollReset(); 14 | 15 | public slots: 16 | void setHexView(bool isSet) { showHex = isSet; reset(); } 17 | 18 | void setShownContent(offset_t start, bufsize_t size); 19 | 20 | public: 21 | HexDumpModel(PeHandler *peHndl, bool isHex, QObject *parent = 0); 22 | 23 | Executable::addr_type getAddrType() { return this->addrType; } 24 | bool isHexView() const { return showHex; } 25 | 26 | bufsize_t getPageSize() { return pageSize; }; 27 | offset_t getStartOff() { return startOff; } 28 | 29 | int rowCount(const QModelIndex &parent) const; 30 | int columnCount(const QModelIndex &parent) const; 31 | 32 | QVariant data(const QModelIndex &index, int role) const; 33 | virtual bool setData(const QModelIndex &, const QVariant &, int role); 34 | 35 | QVariant headerData(int section, Qt::Orientation orientation, int role) const; 36 | Qt::ItemFlags flags(const QModelIndex &index) const; 37 | 38 | virtual offset_t contentOffsetAt(const QModelIndex &index) const; 39 | QVariant getRawContentAt(const QModelIndex &index) const; 40 | QVariant getElement(offset_t offset) const; 41 | 42 | virtual ViewSettings* getSettings() 43 | { 44 | return &settings; 45 | } 46 | 47 | void changeSettings(HexViewSettings &newSettings) 48 | { 49 | settings = newSettings; 50 | } 51 | 52 | protected: 53 | Executable::addr_type addrType; 54 | 55 | private: 56 | HexViewSettings settings; 57 | bool showHex; 58 | offset_t startOff, endOff; 59 | bufsize_t pageSize; 60 | 61 | friend class HexTableView; 62 | friend class OffsetHeader; 63 | }; 64 | -------------------------------------------------------------------------------- /pe-bear/HexView.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "QtCompat.h" 8 | #include "REbear.h" 9 | #include "base/PeHandlersManager.h" 10 | #include "PEFileTreeModel.h" 11 | 12 | #include "gui_base/ExtTableView.h" 13 | #include "gui_base/ClipboardUtil.h" 14 | 15 | #include "HexDumpModel.h" 16 | #include "OffsetHeader.h" 17 | 18 | 19 | class HexItemDelegate: public QStyledItemDelegate 20 | { 21 | Q_OBJECT 22 | public: 23 | HexItemDelegate(QObject* parent); 24 | 25 | virtual void setModelData(QWidget * editor, QAbstractItemModel * model, 26 | const QModelIndex & index) const override; 27 | 28 | QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, 29 | const QModelIndex &index) const override; 30 | Q_SIGNALS: 31 | void dataSet(int col, int row) const; 32 | 33 | private: 34 | void selectNextParentItem(const QModelIndex &index) const; 35 | 36 | QRegularExpressionValidator validator; 37 | }; 38 | 39 | //--- 40 | 41 | class HexTableView : public ExtTableView //TreeCpView 42 | { 43 | Q_OBJECT 44 | public: 45 | HexTableView(QWidget *parent); 46 | virtual QSize span(const QModelIndex &index) const { return QSize(0,0); } 47 | 48 | virtual void setModel(HexDumpModel *model); 49 | 50 | void setVHdrVisible(bool isVisible); 51 | virtual void keyPressEvent(QKeyEvent *event); 52 | 53 | public slots: 54 | void onDataSet(int col, int row); 55 | void onScrollReset(); 56 | void onModelUpdated() { reset(); } 57 | void changeSettings(HexViewSettings &settings); 58 | 59 | virtual void copySelected(); 60 | virtual void pasteToSelected(); 61 | virtual void clearSelected(); 62 | virtual void fillSelected(); 63 | 64 | void setPageUp(); 65 | void setPageDown(); 66 | void undoOffset(); 67 | void undoLastModification(); 68 | void updateUndoAction(); 69 | 70 | public slots: 71 | void onResetRequested() { reset(); } 72 | 73 | protected: 74 | bool isIndexListContinuous(QModelIndexList &list); 75 | 76 | inline void adjustMinWidth(); 77 | int hexColWidth; 78 | bool isVHdrVisible; 79 | void init(); 80 | void initHeader(); 81 | void initHeaderMenu(); 82 | void initMenu(); 83 | 84 | QAction *back, *undo; 85 | 86 | OffsetHeader* vHdr; 87 | QHeaderView *hHdr; 88 | HexDumpModel *hexModel; 89 | QScrollBar vScrollbar; 90 | }; 91 | 92 | -------------------------------------------------------------------------------- /pe-bear/OffsetHeader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "QtCompat.h" 7 | #include "REbear.h" 8 | #include "base/PeHandlersManager.h" 9 | #include "PEFileTreeModel.h" 10 | 11 | #include "HexDumpModel.h" 12 | 13 | class OffsetHeader : public QHeaderView 14 | { 15 | Q_OBJECT 16 | public: 17 | OffsetHeader(QWidget *parent); 18 | virtual void setHexModel(HexDumpModel *model) { this->hexModel = model; } 19 | 20 | QMenu defaultMenu; 21 | 22 | public slots: 23 | virtual void customMenuEvent(QPoint p); 24 | void followOffset(); 25 | void copyOffset(); 26 | offset_t getSelectedOffset(); 27 | 28 | protected: 29 | void mousePressEvent(QMouseEvent *event); 30 | 31 | HexDumpModel *hexModel; 32 | QAction *followAction; 33 | QAction *copyAction; 34 | 35 | Executable::addr_type selectedType; 36 | offset_t selectedOffset; 37 | }; 38 | -------------------------------------------------------------------------------- /pe-bear/QtCompat.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) 6 | #include 7 | #else 8 | #include 9 | typedef QRegExp QRegularExpression; 10 | typedef QRegExpValidator QRegularExpressionValidator; 11 | #endif 12 | 13 | #if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0) 14 | #define QT_SkipEmptyParts Qt::SkipEmptyParts 15 | #else 16 | #define QT_SkipEmptyParts QString::SkipEmptyParts 17 | #endif 18 | -------------------------------------------------------------------------------- /pe-bear/REbear.h: -------------------------------------------------------------------------------- 1 | // RE-bear release version and settings 2 | #pragma once 3 | #include 4 | #include "rebear_ver_short.h" 5 | 6 | #define TITLE "PE-bear" 7 | #define V_MAJOR REBEAR_MAJOR_VERSION 8 | #define V_MINOR REBEAR_MINOR_VERSION 9 | #define V_PATCH REBEAR_MICRO_VERSION 10 | #define V_PATCH_SUB REBEAR_PATCH_VERSION 11 | #define V_DESC "" 12 | 13 | #define DISASMDMP_BG "black" 14 | #define DISASMDMP_TXT "lime" 15 | 16 | #define HEXDIFF_BG "#E5E6F8" 17 | #define HEXDIFF_ALTBG "snow" 18 | 19 | #define HEXDMP_ALTBG "snow" 20 | #define HEXDMP_BG "rgba(229,230,248,160)" // light blue 21 | #define HEXDMP_TXT "black" 22 | #define HEXDMP_HBG "#00008A" // dark blue 23 | #define HEXDMP_HTXT "white" 24 | #define DIAGRAM_BG "#e3e4fa" 25 | 26 | #define ERR_COLOR "#FF0000" 27 | #define APPROVED_COLOR "#40EE40" // lightgreen 28 | 29 | #define PREVIEW_SIZE 0x200 30 | 31 | #define MY_SITE_LINK "https://hasherezade.net/" 32 | #define PEBEAR_LINK "https://pe-bear.hasherezade.net/" 33 | #define SOURCE_LINK "https://github.com/hasherezade/pe-bear/" 34 | 35 | #define CAPSTONE_LICENSE "https://github.com/capstone-engine/capstone/blob/master/LICENSE.TXT" 36 | #define BEARPARSER_LICENSE "https://github.com/hasherezade/bearparser/blob/master/LICENSE" 37 | -------------------------------------------------------------------------------- /pe-bear/TempBuffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | //util: 7 | struct TempBuffer 8 | { 9 | public: 10 | TempBuffer() 11 | :buf(NULL), buf_size(0) 12 | { 13 | } 14 | 15 | bool init(size_t _buf_size) 16 | { 17 | buf = (BYTE*)calloc(_buf_size, 1); 18 | if (!buf) { 19 | return false; 20 | } 21 | buf_size = _buf_size; 22 | return true; 23 | } 24 | 25 | bool init(const BYTE *_buf, size_t _buf_size) 26 | { 27 | buf = (BYTE*)calloc(_buf_size, 1); 28 | if (!buf) { 29 | return false; 30 | } 31 | buf_size = _buf_size; 32 | ::memcpy(buf, _buf, _buf_size); 33 | return true; 34 | } 35 | 36 | ~TempBuffer() 37 | { 38 | if (buf) { 39 | free(buf); 40 | buf = NULL; 41 | } 42 | buf_size = 0; 43 | } 44 | 45 | BYTE* getContent() { return buf; } 46 | 47 | protected: 48 | BYTE *buf; 49 | size_t buf_size; 50 | }; 51 | -------------------------------------------------------------------------------- /pe-bear/ViewSettings.cpp: -------------------------------------------------------------------------------- 1 | #include "ViewSettings.h" 2 | 3 | QPixmap ViewSettings::makeScaledPixMap(const QString &resource, int width, int height) 4 | { 5 | QPixmap pix(resource); 6 | pix = pix.scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation); 7 | return pix; 8 | } 9 | 10 | QIcon ViewSettings::makeScaledIcon(const QString &resource, int width, int height) 11 | { 12 | return QIcon(ViewSettings::makeScaledPixMap(resource, width, height)); 13 | } 14 | -------------------------------------------------------------------------------- /pe-bear/application.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | main_ico.ico 4 | icons/EP.ico 5 | icons/arrow-right.ico 6 | icons/section.ico 7 | icons/Delete.ico 8 | icons/app32.ico 9 | icons/app64.ico 10 | icons/Save.ico 11 | icons/Add.ico 12 | icons/hdr.ico 13 | icons/dos.ico 14 | icons/app32_w.ico 15 | icons/app64_w.ico 16 | icons/Locked.ico 17 | icons/DeleteAll.ico 18 | icons/eraser.ico 19 | icons/go_to_raw.ico 20 | icons/go_to_rva.ico 21 | icons/List.ico 22 | icons/Preview.ico 23 | icons/down.ico 24 | icons/up.ico 25 | icons/wrong_way.ico 26 | icons/space.ico 27 | icons/space_down.ico 28 | icons/space_up.ico 29 | icons/space_this.ico 30 | icons/undo.ico 31 | icons/arr_down.ico 32 | icons/arr_up.ico 33 | icons/enlarge.ico 34 | icons/shrink.ico 35 | icons/add_entry.ico 36 | icons/add_subentry.ico 37 | icons/move.ico 38 | icons/red_pin.ico 39 | icons/resize.ico 40 | icons/unmodify.ico 41 | icons/star.ico 42 | icons/data_dir_color.ico 43 | icons/data_dir_gray.ico 44 | icons/save_black.ico 45 | icons/reload.ico 46 | icons/dump.ico 47 | icons/information.ico 48 | icons/magic_wand.ico 49 | icons/disasm.ico 50 | icons/transform.ico 51 | 52 | 53 | -------------------------------------------------------------------------------- /pe-bear/base/BearVers.cpp: -------------------------------------------------------------------------------- 1 | #include "BearVers.h" 2 | #include "../QtCompat.h" 3 | using namespace pe_bear; 4 | 5 | BearVers::BearVers(int ma, int mi, int p, int s, const QString &desc) 6 | : vMajor(ma), vMinor(mi), vPatch(p), vSub(s), vDesc(desc), 7 | valid(true) 8 | { 9 | } 10 | 11 | BearVers::BearVers(QString replyString) 12 | : vMajor(0), vMinor(0), vPatch(0), vSub(0), vDesc(""), valid(false) 13 | { 14 | replyString = replyString.trimmed(); 15 | QStringList strings = replyString.split(".", QT_SkipEmptyParts); 16 | if (strings.length() < 3) return; 17 | 18 | this->vMajor = strings[0].toInt(); 19 | this->vMinor = strings[1].toInt(); 20 | this->vPatch = strings[2].toInt(); 21 | this->vSub = (strings.length() > 3) ? 0 : strings[3].toInt(); 22 | valid = true; 23 | } 24 | 25 | QString BearVers::toString() 26 | { 27 | if (!isValid()) return ""; 28 | QString str = QString::number(vMajor) + "." + QString::number(vMinor) + "." + QString::number(vPatch); 29 | if (vSub != 0) { 30 | str += "." + QString::number(vSub); 31 | } 32 | if (vDesc.length() > 0) { 33 | str += "-" + vDesc; 34 | } 35 | return str; 36 | } 37 | 38 | int BearVers::operator==(BearVers const &ver2) const 39 | { 40 | return ((ver2.vMajor == this->vMajor) 41 | && (ver2.vMinor == this->vMinor) 42 | && (ver2.vPatch == this->vPatch) 43 | && (ver2.vSub == this->vSub)); 44 | } 45 | 46 | bool BearVers::operator< (BearVers const &ver2) const 47 | { 48 | if (ver2.vMajor > this->vMajor) return true; 49 | if (ver2.vMajor < this->vMajor) return false; 50 | 51 | if (ver2.vMinor > this->vMinor) return true; 52 | if (ver2.vMinor < this->vMinor) return false; 53 | 54 | if (ver2.vPatch > this->vPatch) return true; 55 | if (ver2.vPatch < this->vPatch) return false; 56 | 57 | if (ver2.vSub > this->vSub) return true; 58 | if (ver2.vSub < this->vSub) return false; 59 | return false; 60 | } 61 | 62 | BearVers::VersionStatus BearVers::compare(BearVers &ver) 63 | { 64 | if (!this->isValid() || !ver.isValid()) return BearVers::VER_INVALID; 65 | if ((*this) == ver) { 66 | return BearVers::VER_OK; 67 | } 68 | if (ver > (*this)) { 69 | return BearVers::VER_OLD; 70 | } 71 | return BearVers::VER_NEW; 72 | } 73 | -------------------------------------------------------------------------------- /pe-bear/base/BearVers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace pe_bear { 6 | class BearVers 7 | { 8 | public: 9 | enum VersionStatus { VER_INVALID = (-1), VER_OK, VER_OLD, VER_NEW }; 10 | 11 | BearVers(int major, int minor, int patch, int sub, const QString &desc=""); 12 | BearVers(QString s); 13 | bool isValid() { return valid; } 14 | 15 | VersionStatus compare(BearVers &latestVer); 16 | QString toString(); 17 | 18 | int operator==(BearVers const &ver) const; 19 | int operator!=(BearVers const &ver) const { return !((*this) == ver); } 20 | 21 | bool operator< (BearVers const &ver) const; 22 | bool operator> (BearVers const &ver) const { if ((*this) == ver) return false; return !((*this) < ver); } 23 | 24 | protected: 25 | int vMajor, vMinor, vPatch, vSub; 26 | QString vDesc; 27 | bool valid; 28 | }; 29 | }; // namespace pe_bear 30 | -------------------------------------------------------------------------------- /pe-bear/base/CommentHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | class Comment; 8 | class CommentHandler; 9 | 10 | //------------------- 11 | 12 | class Comment 13 | { 14 | public: 15 | Comment(offset_t Offset, QString Content) : 16 | offset(Offset), 17 | content(Content) { } 18 | 19 | offset_t offset; 20 | QString content; 21 | uint32_t id; 22 | }; 23 | 24 | //------------------- 25 | 26 | class CommentHandler : public QObject 27 | { 28 | Q_OBJECT 29 | signals: 30 | void commentsUpdated(); 31 | 32 | protected slots: 33 | void onLoaded(); 34 | 35 | public: 36 | CommentHandler() : QObject(), isLoaded(false), t(NULL) {} 37 | ~CommentHandler() { clear(); } 38 | 39 | QString getCommentAt(offset_t rva); 40 | void setComment(offset_t rva, QString comment); 41 | //--- 42 | bool saveToFile(QString fileName); 43 | bool loadFromFile(QString fileName); 44 | size_t commentsNum() { return commentsMap.size(); } 45 | 46 | std::vector commentsVec; 47 | size_t getCommentsNum(); 48 | 49 | protected: 50 | // BEGIN inner class: LoaderThread 51 | class LoaderThread : public QThread 52 | { 53 | public: 54 | LoaderThread(QString filePath, CommentHandler *handler) 55 | : cmntHndl(handler), fPath(filePath) 56 | { 57 | } 58 | 59 | void breakReading(); 60 | 61 | private: 62 | void run(); 63 | void loadFromQFile(QString path); 64 | 65 | bool isLoaded; 66 | QString fPath; 67 | CommentHandler *cmntHndl; 68 | 69 | bool isBreakReading; 70 | QMutex m_readMutex; 71 | }; 72 | // END of inner class: LoaderThread 73 | 74 | static bool isFileOk(QString fileName); 75 | static bool _preprocessFile(QString &path, std::map &all_comments); 76 | 77 | void _insertComment(offset_t rva, QString &comment); 78 | bool _updateComment(offset_t rva, QString &comment); 79 | void clear(); 80 | 81 | std::map commentsMap; 82 | bool isLoaded; //indicates if tags are fresh or loaded from file 83 | QMutex m_loadMutex; 84 | LoaderThread *t; 85 | 86 | //friend class LoaderThread; 87 | }; 88 | 89 | 90 | -------------------------------------------------------------------------------- /pe-bear/base/ImportsAutoadderSettings.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | //--- 5 | 6 | struct ImportsAutoadderSettings 7 | { 8 | ImportsAutoadderSettings() : addNewSec(false), separateOFT(false) {} 9 | 10 | bool addImport(const QString &dll, const QString &func) 11 | { 12 | if (dll.length() == 0 || func.length() == 0) return false; 13 | if (dllFunctions.contains(dll)) { 14 | if (dllFunctions[dll].contains(func)) return false; // already exists 15 | } 16 | dllFunctions[dll].append(func); 17 | return true; 18 | } 19 | 20 | bool removeImport(const QString &dll, const QString &func) 21 | { 22 | if (!dllFunctions.contains(dll)) { 23 | return false; 24 | } 25 | if (!dllFunctions[dll].contains(func)) { 26 | return false; 27 | } 28 | dllFunctions[dll].removeAll(func); 29 | if (dllFunctions[dll].size() == 0) { 30 | dllFunctions.remove(dll); 31 | } 32 | return true; 33 | } 34 | 35 | size_t calcDllNamesSpace() const 36 | { 37 | size_t areaSize = 0; 38 | for (auto itr = dllFunctions.begin(); itr != dllFunctions.end(); ++itr) { 39 | const QString dllName = itr.key(); 40 | areaSize += (dllName.length() + 1); 41 | } 42 | return areaSize; 43 | } 44 | 45 | size_t calcFuncNamesSpace() const 46 | { 47 | size_t areaSize = 0; 48 | for (auto dItr = dllFunctions.begin(); dItr != dllFunctions.end(); ++dItr) { 49 | const QStringList funcs = dItr.value(); 50 | for (auto fItr = funcs.begin(); fItr != funcs.end(); ++fItr) { 51 | const QString func = *fItr; 52 | areaSize += (func.length() + 1); 53 | } 54 | } 55 | return areaSize; 56 | } 57 | 58 | size_t calcThunksCount() const 59 | { 60 | size_t thunksNeeded = 0; 61 | for (auto dItr = dllFunctions.begin(); dItr != dllFunctions.end(); ++dItr) { 62 | const QStringList funcs = dItr.value(); 63 | thunksNeeded += (funcs.size() + 1); // records for all the functions, plus the terminator 64 | } 65 | return thunksNeeded; 66 | } 67 | 68 | bool addNewSec; 69 | bool separateOFT; //< separate Original First Thunk from First Thunk 70 | QMap dllFunctions; 71 | }; 72 | -------------------------------------------------------------------------------- /pe-bear/base/PeHandlerFactory.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "PeHandlerFactory.h" 3 | 4 | bool PeHandlerFactory::addHandler(QString path, bool canTruncate) 5 | { 6 | FileBuffer *fileBuffer = NULL; 7 | PEFile *newPE = NULL; 8 | try { 9 | const size_t peMinSize = sizeof(IMAGE_DOS_HEADER) + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) + sizeof(IMAGE_OPTIONAL_HEADER64); 10 | fileBuffer = new FileBuffer(path, peMinSize, canTruncate); 11 | newPE = makePeFile(fileBuffer); 12 | if (!newPE) { 13 | delete fileBuffer; fileBuffer = NULL; 14 | } 15 | } catch (CustomException &e) { 16 | Logger::append(Logger::D_ERROR, e.what()); 17 | return false; 18 | } 19 | if (!newPE) return false; 20 | 21 | PeHandler* hndl = new PeHandler(newPE, fileBuffer); 22 | bool isInserted = this->myManager.insertHandler(hndl); 23 | return isInserted; 24 | } 25 | 26 | PEFile* PeHandlerFactory::makePeFile(FileBuffer* fileBuffer) 27 | { 28 | PEFile *newPE = NULL; 29 | if (!fileBuffer) return NULL; 30 | try { 31 | newPE = new PEFile(fileBuffer); 32 | } 33 | catch (CustomException &e) { 34 | Logger::append(Logger::D_ERROR, e.what()); 35 | } 36 | return newPE; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /pe-bear/base/PeHandlerFactory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PeHandlersManager.h" 4 | 5 | class PeHandlerFactory : public ExeHandlerFactory 6 | { 7 | Q_OBJECT 8 | public : 9 | PeHandlerFactory(PeHandlersManager &manager, ExeFactory::exe_type type, bool canTruncate = true) 10 | : ExeHandlerFactory(manager, type, canTruncate) {} 11 | 12 | virtual bool addHandler(QString path, bool canTruncate); 13 | 14 | protected: 15 | virtual PEFile* makePeFile(FileBuffer* buffer); 16 | }; 17 | -------------------------------------------------------------------------------- /pe-bear/base/PeHandlersManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "../REbear.h" 7 | #include 8 | 9 | #include "Modification.h" 10 | #include "CommentHandler.h" 11 | #include "PeHandler.h" 12 | 13 | #define SIZE_UNLIMITED (-1) 14 | //------------------------------------------------- 15 | 16 | class PeHandlersManager; 17 | 18 | class ExeHandlerFactory : public QObject 19 | { 20 | Q_OBJECT 21 | public : 22 | ExeHandlerFactory(PeHandlersManager &manager, ExeFactory::exe_type type, bool canTruncate) 23 | : QObject(), 24 | myManager(manager), exeType(type), allowTruncated(canTruncate) {} 25 | 26 | virtual bool addHandler(QString path, bool canTruncate) = 0; 27 | virtual bool addHandler(QString path) { return addHandler(path, this->allowTruncated); } 28 | 29 | protected: 30 | virtual ~ExeHandlerFactory() {} // will be deleted in its manager 31 | 32 | ExeFactory::exe_type exeType; 33 | PeHandlersManager &myManager; 34 | bool allowTruncated; 35 | 36 | friend class PeHandlersManager; 37 | }; 38 | 39 | //------------------------------------------------- 40 | 41 | class PeHandlersManager : public QObject 42 | { 43 | Q_OBJECT 44 | 45 | signals: 46 | void exeHandlerAdded(PeHandler*); 47 | void exeHandlerRemoved(PeHandler*); 48 | 49 | void PeListUpdated(); 50 | void matchedSignatures(); 51 | 52 | public: 53 | PeHandlersManager(); 54 | ~PeHandlersManager(); 55 | bool addSupportedType(ExeFactory::exe_type, ExeHandlerFactory *factory); 56 | 57 | bool isSupportedType(ExeFactory::exe_type); 58 | bool openExe(QString path, ExeFactory::exe_type type, bool canTruncate); 59 | 60 | bool insertHandler(PeHandler* hndl); 61 | PeHandler* getPeHandler(PEFile* pe); 62 | PeHandler* getByName(QString name); 63 | 64 | bool removePe(PEFile* pe); 65 | void clear(); 66 | std::map &getHandlersMap() { return PeHandlers; } 67 | QList getFilenames() { return nameToHandlerMap.keys(); } 68 | 69 | public slots: 70 | void checkAllSignatures(); 71 | 72 | protected: 73 | std::map PeHandlers; 74 | QMap nameToHandlerMap; 75 | std::map supportedTypes; 76 | QMutex m_loadMutex; 77 | }; 78 | -------------------------------------------------------------------------------- /pe-bear/base/RegKeyManager.cpp: -------------------------------------------------------------------------------- 1 | #ifdef _WINDOWS 2 | #include 3 | #include 4 | #include 5 | #endif //_WINDOWS 6 | 7 | #include "RegKeyManager.h" 8 | 9 | std::string PART = "file\\shell\\Open with "; 10 | 11 | bool RegKeyManager::removeRegPath(const std::string &extension, const std::string &appName) 12 | { 13 | #ifdef _WINDOWS 14 | int res1 = 0, res2 = 0; 15 | HKEY hKey = 0; 16 | 17 | std::string fullName = extension; 18 | fullName.append(PART).append(appName); 19 | LPCSTR lpSubKey = fullName.c_str(); 20 | 21 | LONG res = RegCreateKeyA(HKEY_CLASSES_ROOT, lpSubKey, &hKey); 22 | if (res != ERROR_SUCCESS) { 23 | return false; 24 | } 25 | 26 | res1 = RegDeleteKeyA(hKey, "command"); 27 | res2 = RegDeleteKeyA(hKey, ""); 28 | 29 | res = RegCloseKey(HKEY_CLASSES_ROOT); 30 | if (res != ERROR_SUCCESS) { 31 | return false; 32 | } 33 | if (res1 == ERROR_SUCCESS || res2 == ERROR_SUCCESS) { 34 | return true; 35 | } 36 | #endif //_WINDOWS 37 | return false; 38 | } 39 | 40 | bool RegKeyManager::addRegPath(const std::string &extension, const std::string &appName, const std::string &path) 41 | { 42 | #ifdef _WINDOWS 43 | 44 | int res1 = 0, res2 = 0; 45 | HKEY hKey = 0; 46 | 47 | std::string fullName = extension; 48 | fullName.append(PART).append(appName); // example: "dllfile\\shell\\Open with PE-bear"; 49 | const std::string cmdName = fullName + "\\command"; 50 | 51 | // set command: 52 | const std::string cmdPath = path + " \"%1\""; 53 | LONG res = RegCreateKeyA(HKEY_CLASSES_ROOT, cmdName.c_str(), &hKey); 54 | if (res != ERROR_SUCCESS) { 55 | return false; 56 | } 57 | res1 = RegSetValueExA(hKey, NULL, 0, REG_SZ, (BYTE*)cmdPath.c_str(), cmdPath.length()); 58 | res = RegCloseKey(HKEY_CLASSES_ROOT); 59 | if (res1 != ERROR_SUCCESS || res != ERROR_SUCCESS) { 60 | return false; 61 | } 62 | 63 | //set icon: 64 | hKey = 0; 65 | res = RegCreateKeyA(HKEY_CLASSES_ROOT, fullName.c_str(), &hKey); 66 | if (res != ERROR_SUCCESS) { 67 | return false; 68 | } 69 | 70 | const std::string iconPath = path + ",0"; 71 | res1 = RegSetValueExA(hKey, "Icon", 0, REG_SZ, (BYTE*)iconPath.c_str(), iconPath.length()); 72 | 73 | res = RegCloseKey(HKEY_CLASSES_ROOT); 74 | if (res1 != ERROR_SUCCESS || res != ERROR_SUCCESS) { 75 | return false; 76 | } 77 | if (res1 == ERROR_SUCCESS) { 78 | return true; 79 | } 80 | #endif //_WINDOWS 81 | return false; 82 | } 83 | 84 | 85 | bool RegKeyManager::isKeySet(const std::string &extension, const std::string &appName) 86 | { 87 | #ifdef _WINDOWS 88 | 89 | HKEY hKey = 0; 90 | std::string fullName = extension; 91 | fullName.append(PART).append(appName); 92 | LPCSTR lpSubKey = fullName.c_str(); 93 | 94 | LONG res = RegOpenKeyExA(HKEY_CLASSES_ROOT, lpSubKey, 0, KEY_READ, &hKey); 95 | if (res != ERROR_SUCCESS) { 96 | return false; 97 | } 98 | res = RegCloseKey(HKEY_CLASSES_ROOT); 99 | if (res == ERROR_SUCCESS) { 100 | return true; 101 | } 102 | #endif //_WINDOWS 103 | return false; 104 | } 105 | 106 | -------------------------------------------------------------------------------- /pe-bear/base/RegKeyManager.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace RegKeyManager { 4 | bool removeRegPath(const std::string &extension, const std::string &appName); 5 | bool addRegPath(const std::string &extension, const std::string &appName, const std::string &value); 6 | bool isKeySet(const std::string &extension, const std::string &appName); 7 | }; 8 | -------------------------------------------------------------------------------- /pe-bear/base/Releasable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | //----------------- 5 | 6 | class Releasable 7 | { 8 | public: 9 | Releasable() : refCntr(0) {} 10 | 11 | void release() { if (refCntr > 0) refCntr--; else delete this; } 12 | void incRefCntr() { this->refCntr++; } 13 | size_t getRefCntr() { return refCntr; } 14 | protected: 15 | virtual ~Releasable() {} 16 | size_t refCntr; // reference Counter 17 | }; 18 | 19 | 20 | -------------------------------------------------------------------------------- /pe-bear/base/threads/CalcThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "CollectorThread.h" 3 | #include "SupportedHashes.h" 4 | #include "../PeHandler.h" 5 | 6 | class CalcThread : public CollectorThread 7 | { 8 | Q_OBJECT 9 | 10 | public: 11 | 12 | CalcThread(AbstractByteBuffer* buf, offset_t checksumOffset) 13 | : CollectorThread(buf), checksumOff(checksumOffset) 14 | { 15 | } 16 | 17 | signals: 18 | void gotHash(QString hash, int type); 19 | 20 | private: 21 | void run(); 22 | QString makeImpHash(PEFile* pe); 23 | QString makeRichHdrHash(PEFile* pe); 24 | 25 | offset_t checksumOff; 26 | }; 27 | 28 | ///---- 29 | 30 | class HashCalcThreadManager : public CollectorThreadManager 31 | { 32 | public: 33 | HashCalcThreadManager(PeHandler *peHndl) 34 | : m_peHndl(peHndl) 35 | { 36 | } 37 | 38 | bool setupThread() 39 | { 40 | if (!m_peHndl) return false; 41 | PEFile* pe = m_peHndl->getPe(); 42 | if (!pe) return false; 43 | 44 | offset_t checksumOffset = m_peHndl->optHdrWrapper.getFieldOffset(OptHdrWrapper::CHECKSUM); 45 | CalcThread *calcThread = new CalcThread(pe->getFileBuffer(), checksumOffset); 46 | this->myThread = calcThread; 47 | 48 | QObject::connect(calcThread, SIGNAL(gotHash(QString, int)), m_peHndl, SLOT(onHashReady(QString, int))); 49 | return true; 50 | } 51 | 52 | protected: 53 | PeHandler *m_peHndl; 54 | }; 55 | 56 | ///---- 57 | 58 | -------------------------------------------------------------------------------- /pe-bear/base/threads/CollectorThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | ///---- 7 | 8 | class CollectorThread : public QThread 9 | { 10 | Q_OBJECT 11 | public: 12 | CollectorThread(AbstractByteBuffer* inpBuf) 13 | : m_buf(nullptr), stopRequested(false) 14 | { 15 | if (inpBuf && inpBuf->getContent()) { 16 | m_buf = new ByteBuffer(inpBuf->getContent(), inpBuf->getContentSize()); 17 | } 18 | } 19 | 20 | ~CollectorThread() 21 | { 22 | if (m_buf) { 23 | delete m_buf; 24 | } 25 | } 26 | 27 | bool isByteArrInit() { return (m_buf && m_buf->getContent()); } 28 | 29 | void stop() 30 | { 31 | QMutexLocker lock(&stopMutex); 32 | stopRequested = true; 33 | } 34 | 35 | bool isStopRequested() 36 | { 37 | QMutexLocker lock(&stopMutex); 38 | return stopRequested; 39 | } 40 | 41 | protected: 42 | ByteBuffer* m_buf; 43 | QMutex myMutex; 44 | QMutex stopMutex; 45 | bool stopRequested; 46 | }; 47 | 48 | //--- 49 | 50 | class CollectorThreadManager : public QObject 51 | { 52 | Q_OBJECT 53 | 54 | public: 55 | CollectorThreadManager() : QObject(), myThread(nullptr), isQueued(false) 56 | { 57 | } 58 | 59 | ~CollectorThreadManager() 60 | { 61 | deleteThread(); 62 | } 63 | 64 | void stopThread() 65 | { 66 | if (this->myThread) { 67 | this->myThread->stop(); 68 | } 69 | } 70 | 71 | void deleteThread() 72 | { 73 | if (this->myThread) { 74 | this->myThread->stop(); 75 | while (myThread->isFinished() == false) { 76 | myThread->wait(); 77 | } 78 | delete myThread; 79 | myThread = nullptr; 80 | } 81 | } 82 | 83 | bool recreateThread() 84 | { 85 | if (this->myThread) { 86 | this->myThread->stop(); 87 | isQueued = true; 88 | return false; //previous thread didn't finished 89 | } 90 | bool isOk = false; 91 | try { 92 | if (setupThread()) { 93 | runThread(); 94 | isOk = true; 95 | } 96 | } catch (const BufferException&) { 97 | isOk = false; 98 | } 99 | return isOk; 100 | } 101 | 102 | 103 | protected slots: 104 | bool resetOnFinished() 105 | { 106 | if (myThread && myThread->isFinished()) { 107 | delete myThread; 108 | myThread = nullptr; 109 | } 110 | bool isOk = false; 111 | try { 112 | if (isQueued) { 113 | if (setupThread()) { 114 | runThread(); 115 | isOk = true; 116 | } 117 | } 118 | } 119 | catch (const BufferException&) { 120 | isOk = false; 121 | isQueued = false; // failed to run, remove from the queue 122 | } 123 | return isOk; 124 | } 125 | 126 | protected: 127 | virtual bool setupThread() = 0; 128 | 129 | virtual void runThread() 130 | { 131 | if (!myThread) return; 132 | QObject::connect(myThread, SIGNAL(finished()), this, SLOT(resetOnFinished())); 133 | if (!myThread->isStopRequested()) { 134 | myThread->start(); 135 | } 136 | this->isQueued = false; 137 | } 138 | 139 | bool isQueued; 140 | CollectorThread *myThread; 141 | QMutex myMutex; 142 | }; 143 | 144 | ///---- 145 | 146 | -------------------------------------------------------------------------------- /pe-bear/base/threads/SignFinderThread.cpp: -------------------------------------------------------------------------------- 1 | #include "SignFinderThread.h" 2 | 3 | void SignFinderThread::run() 4 | { 5 | emit searchStarted(true); 6 | QMutexLocker lock(&myMutex); 7 | this->m_matched.packerAtOffset.clear(); 8 | if (!isByteArrInit()) { 9 | return; 10 | } 11 | findInBuffer(); 12 | emit gotMatches(&m_matched); 13 | emit searchStarted(false); 14 | } 15 | 16 | void SignFinderThread::findInBuffer() 17 | { 18 | if (!m_buf || startOffset == INVALID_ADDR) return; 19 | 20 | offset_t offset = startOffset; 21 | offset_t fullSize = m_buf->getContentSize(); 22 | int proc = 0; 23 | int maxProgress = 1000; 24 | bool found = false; 25 | offset_t currOffset = offset; 26 | { //scope0 27 | QMutexLocker stopLock(&this->stopMutex); 28 | if (this->stopRequested) return; 29 | size_t processed = findPackerSign(offset); 30 | currOffset += processed; 31 | 32 | } //!scope0 33 | 34 | if (currOffset == (fullSize - 1)) { 35 | emit progressUpdated(maxProgress); 36 | return; 37 | } 38 | const double max = fullSize; 39 | const double curr = currOffset; 40 | const int progress = int((curr/max) * maxProgress); 41 | if (progress > proc) { 42 | proc = progress; 43 | emit progressUpdated(proc); 44 | } 45 | } 46 | 47 | size_t SignFinderThread::findPackerSign(offset_t startingRaw) 48 | { 49 | if (!m_buf && startingRaw == INVALID_ADDR) { 50 | return 0; 51 | } 52 | BYTE* content = m_buf->getContent(); 53 | if (!content) { 54 | return 0; 55 | } 56 | const size_t contentSize = m_buf->getContentSize(); 57 | if (startingRaw >= contentSize) { 58 | return 0; 59 | } 60 | std::vector matchedSet; 61 | size_t processed = this->m_signFinder.getMatching(content + startingRaw, contentSize - startingRaw, matchedSet, true); 62 | addFoundPackers(startingRaw, matchedSet); 63 | return processed; 64 | } 65 | 66 | size_t SignFinderThread::addFoundPackers(offset_t startingRaw, std::vector &matchedSet) 67 | { 68 | size_t foundCount = matchedSet.size(); 69 | if (!foundCount) { 70 | return 0; 71 | } 72 | size_t count = 0; 73 | for (auto sItr = matchedSet.begin(); sItr != matchedSet.end(); ++sItr) { 74 | sig_finder::Match match = *sItr; 75 | if (!match.sign) { 76 | continue; 77 | } 78 | count++; 79 | this->m_matched.packerAtOffset.append(MatchedSign(startingRaw + match.offset, match.sign->size())); 80 | } 81 | return count; 82 | } 83 | -------------------------------------------------------------------------------- /pe-bear/base/threads/StringExtThread.cpp: -------------------------------------------------------------------------------- 1 | #include "StringExtThread.h" 2 | 3 | size_t StringExtThread::extractStrings(StringsCollection &mapToFill, const size_t minStr, const size_t maxStr, bool acceptNonTerminated) 4 | { 5 | if (!m_buf) return 0; 6 | 7 | int progress = 0; 8 | emit loadingStrings(progress); 9 | 10 | const size_t contentSize = m_buf->getContentSize(); 11 | size_t maxSize = contentSize; 12 | 13 | // remove null padding at the end 14 | for (; maxSize > 0; maxSize--) { 15 | QMutexLocker stopLock(&this->stopMutex); 16 | if (this->stopRequested) break; 17 | 18 | const char* ptr = (char*)m_buf->getContentAt((maxSize - 1), 1); 19 | const char nextC = ptr ? (*ptr) : 0; 20 | if (nextC != 0) break; 21 | } 22 | 23 | for (offset_t step = 0; step < maxSize; step++) { 24 | 25 | { //scope0 26 | QMutexLocker stopLock(&this->stopMutex); 27 | if (this->stopRequested) break; 28 | 29 | bool isWide = false; 30 | const char *ptr = (char*)m_buf->getContentAt(step, 1); 31 | const char nextC = ptr ? (*ptr) : 0; 32 | if (!nextC || !IS_PRINTABLE(nextC) || isspace(nextC) ) { 33 | continue; 34 | } 35 | const size_t remainingSize = maxSize - step; 36 | const size_t maxLen = (maxStr != 0 && maxStr < remainingSize) ? maxStr : remainingSize; 37 | QString str = m_buf->getStringValue(step, maxLen, acceptNonTerminated); 38 | if (str.length() == 1) { 39 | isWide = true; 40 | str = m_buf->getWAsciiStringValue(step, maxLen / 2, acceptNonTerminated); 41 | } 42 | if (!str.length() || str.length() < minStr) { 43 | continue; 44 | } 45 | mapToFill.insert(step, str, isWide); 46 | step += util::getStringSize(str, isWide); 47 | step--; 48 | } //!scope0 49 | 50 | int proc = int(((float)step / (float)maxSize) * 100); 51 | if ((proc - progress) > 1) { 52 | progress = proc; 53 | emit loadingStrings(progress); 54 | } 55 | } 56 | return mapToFill.size(); 57 | } 58 | 59 | void StringExtThread::run() 60 | { 61 | QMutexLocker lock(&myMutex); 62 | 63 | this->mapToFill->clear(); 64 | 65 | if (!isByteArrInit()) { 66 | emit gotStrings(nullptr); 67 | return; 68 | } 69 | const size_t minLen = this->minStrLen > 2 ? this->minStrLen : 2; 70 | extractStrings(*mapToFill, minLen, 0, true); 71 | if (!this->stopRequested) { 72 | // emit strings only if the thread finished 73 | emit gotStrings(mapToFill); 74 | } 75 | } 76 | 77 | //------------------------------------------------- 78 | 79 | -------------------------------------------------------------------------------- /pe-bear/base/threads/StringExtThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "CollectorThread.h" 3 | #include "../StringsCollection.h" 4 | #include "../PeHandler.h" 5 | 6 | class StringExtThread : public CollectorThread 7 | { 8 | Q_OBJECT 9 | 10 | public: 11 | StringExtThread(AbstractByteBuffer *inpBuf, size_t _minStrLen) 12 | : CollectorThread(inpBuf), minStrLen(_minStrLen), mapToFill(nullptr) 13 | { 14 | mapToFill = new StringsCollection(); 15 | } 16 | 17 | ~StringExtThread() 18 | { 19 | this->mapToFill->release(); 20 | } 21 | 22 | signals: 23 | void gotStrings(StringsCollection* mapToFill); 24 | void loadingStrings(int progress); 25 | 26 | private: 27 | void run(); 28 | size_t extractStrings(StringsCollection &mapToFill, const size_t minStr, const size_t maxStr = 0, bool acceptNonTerminated = true); 29 | 30 | StringsCollection *mapToFill; 31 | size_t minStrLen; 32 | }; 33 | 34 | ///---- 35 | 36 | class StringThreadManager : public CollectorThreadManager 37 | { 38 | public: 39 | StringThreadManager(PeHandler *peHndl, size_t minStrLen) 40 | : m_peHndl(peHndl), m_minStrLen(minStrLen) 41 | { 42 | } 43 | 44 | bool setupThread() 45 | { 46 | if (!m_peHndl) return false; 47 | 48 | PEFile* pe = m_peHndl->getPe(); 49 | if (!pe) return false; 50 | 51 | StringExtThread* stringThread = new StringExtThread(pe->getFileBuffer(), m_minStrLen); 52 | this->myThread = stringThread; 53 | QObject::connect(stringThread, SIGNAL(gotStrings(StringsCollection*)), m_peHndl, SLOT(onStringsReady(StringsCollection*))); 54 | QObject::connect(stringThread, SIGNAL(loadingStrings(int)), m_peHndl, SLOT(onStringsLoadingProgress(int))); 55 | return true; 56 | } 57 | protected: 58 | PeHandler *m_peHndl; 59 | size_t m_minStrLen; 60 | }; 61 | -------------------------------------------------------------------------------- /pe-bear/base/threads/SupportedHashes.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class SupportedHashes { 4 | public: 5 | enum hash_type { 6 | CHECKSUM = 0, 7 | RICH_HDR_MD5, 8 | IMP_MD5, 9 | MD5, 10 | SHA1, 11 | SHA256, 12 | HASHES_NUM 13 | }; 14 | }; 15 | 16 | -------------------------------------------------------------------------------- /pe-bear/gui/CommentView.cpp: -------------------------------------------------------------------------------- 1 | #include "CommentView.h" 2 | 3 | 4 | //------------------------------------------------------------------------------- 5 | 6 | CommentView::CommentView(PeHandler *peHandler, QWidget *parent) 7 | : QWidget(parent), PeGuiItem(peHandler), commentHndl(NULL) 8 | { 9 | if (peHandler) commentHndl = &peHandler->comments; 10 | 11 | this->filter = tr("Tag files (*.tag);;Text files (*.txt);;All Files (*)"); 12 | } 13 | 14 | void CommentView::onSetComment(offset_t offset) 15 | { 16 | bool isOk = false; 17 | QString prev = this->commentHndl->getCommentAt(offset); 18 | QString title = "RVA : "+ QString::number(offset, 16).toUpper(); 19 | QString text = QInputDialog::getText(this, title, tr("Comment"), QLineEdit::Normal, prev, &isOk); 20 | if (!isOk) return; 21 | 22 | this->commentHndl->setComment(offset, text); 23 | emit commentModified(); 24 | } 25 | 26 | void CommentView::onSaveComments() 27 | { 28 | QFileDialog dialog; 29 | MainSettings *set = this->getSettings(); 30 | if (set) { 31 | dialog.setDirectory(set->userDataDir()); 32 | } 33 | QString fName = dialog.getSaveFileName(NULL, tr("Save"), "", filter); 34 | if (fName.size() == 0) { 35 | return; 36 | } 37 | if (this->commentHndl->saveToFile(fName) == false) { 38 | QMessageBox::warning(this, tr("Failed"), tr("Saving failed!"), QMessageBox::Ok); 39 | } 40 | } 41 | 42 | void CommentView::onLoadComments() 43 | { 44 | QFileDialog dialog; 45 | MainSettings *set = this->getSettings(); 46 | if (set) { 47 | dialog.setDirectory(set->userDataDir()); 48 | } 49 | QString fName = dialog.getOpenFileName(NULL, tr("Open"), "", filter); 50 | if (fName.size() == 0) return; 51 | 52 | if (loadComments(fName) == false) { 53 | QMessageBox::warning(this, tr("Failed"), tr("Loading failed!"), QMessageBox::Ok); 54 | return; 55 | } 56 | //--- 57 | /*size_t loadedNum = this->commentHndl->commentsNum(); 58 | QString infoStr = "Loaded " + QString::number(loadedNum) + " tag" + ((loadedNum > 1) ? "s!" : "!"); 59 | QMessageBox::information(this, "Done!", infoStr, QMessageBox::Ok);*/ 60 | } 61 | 62 | bool CommentView::loadComments(QString fName) 63 | { 64 | if (this->commentHndl->loadFromFile(fName) == false) { 65 | return false; 66 | } 67 | emit commentModified(); 68 | return true; 69 | } 70 | -------------------------------------------------------------------------------- /pe-bear/gui/CommentView.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | #include "../QtCompat.h" 6 | #include "../gui_base/PeGuiItem.h" 7 | #include "../base/CommentHandler.h" 8 | 9 | class CommentView : public QWidget, public PeGuiItem, public MainSettingsHolder 10 | { 11 | Q_OBJECT 12 | 13 | signals: 14 | void commentModified(); 15 | 16 | public slots: 17 | void onSetComment(offset_t offset); 18 | void onSaveComments(); 19 | void onLoadComments(); 20 | public: 21 | bool loadComments(QString fName); 22 | CommentView(PeHandler *peHandler, QWidget *parent); 23 | 24 | protected: 25 | CommentHandler *commentHndl; 26 | 27 | private: 28 | QString filter; 29 | }; 30 | -------------------------------------------------------------------------------- /pe-bear/gui/ContentPreview.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "../QtCompat.h" 5 | #include "../gui_base/PeGuiItem.h" 6 | #include "../HexView.h" 7 | 8 | class ContentPreview : public QSplitter, public PeViewItem 9 | { 10 | Q_OBJECT 11 | public: 12 | ContentPreview(PeHandler *peHndl, QWidget *parent); 13 | ~ContentPreview(); 14 | 15 | signals: 16 | void signalChangeHexViewSettings(HexViewSettings &settings); 17 | 18 | public slots: 19 | // forward the settings change to the individual HexTableView-s: 20 | void changeHexViewSettings(HexViewSettings &_settings) 21 | { 22 | emit signalChangeHexViewSettings(_settings); 23 | } 24 | 25 | protected slots: 26 | void onGoToRVA(); 27 | void onSliderMoved(int val); 28 | 29 | protected: 30 | void applyViewsSettings(); 31 | void connectViewsSignals(); 32 | 33 | void createModels(); 34 | void deleteModels(); 35 | 36 | QScrollBar *hexScroll, *textScroll; 37 | HexTableView hexView, textView; 38 | HexDumpModel *hexModel, *textModel; 39 | 40 | QMenu defaultMenu; 41 | }; 42 | -------------------------------------------------------------------------------- /pe-bear/gui/DataDirWrapperSplitter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "../QtCompat.h" 5 | #include "../gui/pe_models.h" 6 | #include "WrapperTreeView.h" 7 | #include "WrapperSplitter.h" 8 | 9 | class DataDirWrapperSplitter : public WrapperSplitter, public PeViewItem 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | DataDirWrapperSplitter(PeHandler *peHndl, pe::dir_entry dirId, QWidget *parent) 15 | : PeViewItem(peHndl), WrapperSplitter(parent), dataDirId(dirId), moveDirTable(NULL) 16 | { 17 | } 18 | 19 | DataDirWrapperSplitter(PeHandler *peHndl, pe::dir_entry dirId, PeTreeModel *upModel, PeTreeModel *downModel, QWidget *parent) 20 | : PeViewItem(peHndl), WrapperSplitter(upModel, downModel, parent), dataDirId(dirId), moveDirTable(NULL) 21 | { 22 | initToolbar(); 23 | } 24 | 25 | virtual ~DataDirWrapperSplitter() {} 26 | 27 | virtual bool initToolbar(); 28 | virtual void setScaledIcons(); 29 | QString chooseDumpOutDir(); 30 | 31 | public slots: 32 | void onMoveDirTable(); 33 | void onGlobalFontChanged() 34 | { 35 | setScaledIcons(); 36 | } 37 | 38 | protected: 39 | QAction* moveDirTable; 40 | pe::dir_entry dataDirId; 41 | }; 42 | 43 | //----------------------------- 44 | 45 | class SecurityDirSplitter : public DataDirWrapperSplitter 46 | { 47 | Q_OBJECT 48 | public: 49 | SecurityDirSplitter(PeHandler *peHndl, WrapperTableModel *upModel, WrapperTableModel *downModel, QWidget *parent) 50 | : DataDirWrapperSplitter(peHndl, pe::DIR_SECURITY, upModel, downModel, parent), saveCertAction(NULL) 51 | { 52 | initToolbar(); 53 | } 54 | 55 | virtual bool initToolbar(); 56 | virtual void setScaledIcons(); 57 | 58 | public slots: 59 | void onSaveCert(); 60 | 61 | private: 62 | QAction* saveCertAction; 63 | }; 64 | -------------------------------------------------------------------------------- /pe-bear/gui/DosHdrTableModel.cpp: -------------------------------------------------------------------------------- 1 | #include "DosHdrTableModel.h" 2 | 3 | enum COLS { 4 | COL_OFFSET = 0, 5 | COL_NAME, 6 | COL_VALUE, 7 | MAX_COL 8 | }; 9 | 10 | 11 | DosHdrTableModel::DosHdrTableModel(PeHandler *peHndl, QObject *parent) 12 | : WrapperTableModel(peHndl, parent) 13 | { 14 | connectSignals(); 15 | } 16 | 17 | QVariant DosHdrTableModel::headerData(int section, Qt::Orientation orientation, int role) const 18 | { 19 | if (role != Qt::DisplayRole) return QVariant(); 20 | switch (section) { 21 | case COL_OFFSET: return tr("Offset"); 22 | case COL_NAME: return tr("Name"); 23 | case COL_VALUE: return tr("Value"); 24 | } 25 | return QVariant(); 26 | } 27 | 28 | Qt::ItemFlags DosHdrTableModel::flags(const QModelIndex &index) const 29 | { 30 | if (!index.isValid()) return Qt::NoItemFlags; 31 | 32 | if (index.column() == COL_VALUE) return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable; 33 | 34 | return Qt::ItemIsEnabled | Qt::ItemIsSelectable; 35 | } 36 | 37 | bool DosHdrTableModel::isComplexValue(const QModelIndex &index) const 38 | { 39 | int fId = getFID(index); 40 | 41 | if (fId == DosHdrWrapper::RES || fId == DosHdrWrapper::RES2) return true; 42 | return false; 43 | } 44 | 45 | QVariant DosHdrTableModel::data(const QModelIndex &index, int role) const 46 | { 47 | if (role == Qt::ForegroundRole) return this->addrColor(index); 48 | if (role == Qt::FontRole) { 49 | if (index.column() == COL_OFFSET || index.column() == COL_VALUE) { 50 | return offsetFont; 51 | } 52 | } 53 | if (role == Qt::ToolTipRole) return toolTip(index); 54 | if (role == Qt::DisplayRole || role == Qt::EditRole) { 55 | 56 | if (index.column() == COL_OFFSET) return QString::number(getFieldOffset(index), 16); 57 | if (index.column() == COL_NAME) { 58 | int fId = getFID(index); 59 | return wrapper()->getFieldName(fId); 60 | } 61 | return this->dataValue(index); 62 | } 63 | return QVariant(); 64 | } 65 | 66 | bool DosHdrTableModel::setData(const QModelIndex &index, const QVariant &value, int role) 67 | { 68 | if (!index.isValid()) return false; 69 | 70 | int fId = getFID(index); 71 | offset_t offset = wrapper()->getFieldOffset(fId); 72 | bufsize_t fieldSize = wrapper()->getFieldSize(fId); 73 | 74 | bool isModified = false; 75 | 76 | if (this->isComplexValue(index)) { 77 | this->myPeHndl->backupModification(offset, fieldSize); 78 | isModified = setComplexValue(index, value, role); 79 | } else { 80 | QString text = value.toString(); 81 | bool isOk = false; 82 | ULONGLONG number = text.toLongLong(&isOk, 16); 83 | if (!isOk) return false; 84 | 85 | this->myPeHndl->backupModification(offset, fieldSize); 86 | isModified = wrapper()->setNumValue(fId, index.column(), number); 87 | } 88 | 89 | if (isModified) { 90 | this->myPeHndl->setBlockModified(offset, fieldSize); 91 | return true; 92 | } 93 | this->myPeHndl->unbackupLastModification(); 94 | return false; 95 | } 96 | 97 | -------------------------------------------------------------------------------- /pe-bear/gui/DosHdrTableModel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | #include "../QtCompat.h" 8 | #include "PeWrapperModel.h" 9 | #include "../gui_base/WrapperTableModel.h" 10 | 11 | class DosHdrTableModel : public WrapperTableModel 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | enum COLS { 17 | COL_OFFSET = 0, 18 | COL_NAME, 19 | COL_VALUE, 20 | MAX_COL 21 | }; 22 | 23 | DosHdrTableModel(PeHandler *peHndl, QObject *parent = 0); 24 | virtual ~DosHdrTableModel() { } 25 | 26 | virtual int columnCount(const QModelIndex &parent) const { return MAX_COL; } 27 | 28 | virtual Qt::ItemFlags flags(const QModelIndex &index) const; 29 | virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; 30 | virtual QVariant data(const QModelIndex &index, int role) const; 31 | virtual bool setData(const QModelIndex &index, const QVariant &value, int role); 32 | 33 | bool containsValue(QModelIndex index) const { return (index.column() == COL_VALUE); } 34 | 35 | protected: 36 | virtual int getSID(const QModelIndex &index) const { return index.column() - COL_VALUE; } 37 | virtual bool isComplexValue(const QModelIndex &index) const; 38 | 39 | virtual ExeElementWrapper* wrapper() const { return &myPeHndl->dosHdrWrapper; } 40 | }; 41 | -------------------------------------------------------------------------------- /pe-bear/gui/GeneralPanel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "../QtCompat.h" 5 | #include "../gui_base/PeGuiItem.h" 6 | #include "../gui_base/ExtTableView.h" 7 | 8 | #include "PackersTableModel.h" 9 | #include "windows/StringsBrowseWindow.h" 10 | 11 | 12 | class InfoTableModel : public PeTableModel 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | InfoTableModel(PeHandler *peHndl, QObject *parent = 0); 18 | virtual ~InfoTableModel() { } 19 | 20 | QVariant headerData(int section, Qt::Orientation orientation, int role) const; 21 | Qt::ItemFlags flags(const QModelIndex &index) const; 22 | 23 | int columnCount(const QModelIndex &parent) const { return 1; } 24 | int rowCount(const QModelIndex &parent) const; 25 | 26 | QVariant data(const QModelIndex &index, int role) const; 27 | bool setData(const QModelIndex &, const QVariant &, int); 28 | 29 | QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const 30 | { 31 | return createIndex(row, column); //no index item pointer 32 | } 33 | 34 | QModelIndex parent(const QModelIndex &index) const { return QModelIndex(); } // no parent 35 | }; 36 | 37 | //---- 38 | 39 | class GeneralPanel : public QSplitter, public PeViewItem 40 | { 41 | Q_OBJECT 42 | public: 43 | GeneralPanel(PeHandler *peHndl, QWidget *parent); 44 | 45 | protected slots: 46 | void refreshView(); 47 | 48 | protected: 49 | void init(); 50 | void connectSignals(); 51 | 52 | QDockWidget *packersDock; 53 | QTextEdit md5Text; 54 | QTextEdit pathText; 55 | 56 | ExtTableView generalInfo; 57 | InfoTableModel generalInfoModel; 58 | FollowablePeTreeView packersTree; 59 | 60 | PackersTableModel packersModel; 61 | }; 62 | -------------------------------------------------------------------------------- /pe-bear/gui/HexDiffModel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include 5 | 6 | #include "../QtCompat.h" 7 | #include "../ViewSettings.h" 8 | 9 | #define HEX_COL_NUM 16 10 | #define COL_NUM (HEX_COL_NUM) 11 | #define COL_WIDTH 20 12 | 13 | enum ContentIndx { LEFT = 0, RIGHT = 1, CNTR = 2 }; 14 | 15 | class HexDiffModel : public QAbstractTableModel 16 | { 17 | Q_OBJECT 18 | 19 | public slots: 20 | void setRelativeOffset(bool flag) { relativeOffset = flag; reset(); } 21 | void setContent(BYTE* contentPtr, int size, offset_t contentOffset, ContentIndx indx); 22 | void clearContent(ContentIndx indx); 23 | void setHexView(bool isSet) { showHex = isSet; reset();} 24 | void setStartingOffset(offset_t start) { startOff = start; reset(); } 25 | void setPage(const int page) { startOff = pageSize * page; reset(); } 26 | 27 | void onGoToPrevDiff(); 28 | void onGoToNextDiff(); 29 | 30 | void changeSettings(HexViewSettings &newSettings) 31 | { 32 | settings = newSettings; 33 | reset(); 34 | } 35 | 36 | public: 37 | static const bufsize_t DIFF_NOT_FOUND = bufsize_t(-1); 38 | static bufsize_t getDiffStart(BYTE *content1Ptr, bufsize_t size1, BYTE *content2Ptr, bufsize_t size2); 39 | static bufsize_t getDiffEnd(BYTE *content1Ptr, bufsize_t size1, BYTE *content2Ptr, bufsize_t size2); 40 | //------ 41 | HexDiffModel(ContentIndx indx, QObject *parent = 0); 42 | 43 | bool isHexView() { return showHex; } 44 | bufsize_t getPageSize() { return pageSize; }; 45 | bufsize_t getStartOff() { return startOff; } 46 | 47 | int rowCount(const QModelIndex &parent) const; 48 | int columnCount(const QModelIndex &parent) const; 49 | 50 | QVariant data(const QModelIndex &index, int role) const; 51 | bool setData(const QModelIndex &, const QVariant &, int) { return false; } //external modifications not allowed 52 | 53 | QVariant headerData(int section, Qt::Orientation orientation, int role) const; 54 | Qt::ItemFlags flags(const QModelIndex &index) const; 55 | bool isRelativeOffset() const { return relativeOffset; } 56 | 57 | protected: 58 | void reset() 59 | { 60 | //> 61 | this->beginResetModel(); 62 | this->endResetModel(); 63 | //< 64 | } 65 | 66 | private: 67 | bool relativeOffset; 68 | offset_t contentOffset[CNTR]; 69 | BYTE* contentPtr[CNTR]; 70 | bufsize_t contentSize[CNTR]; 71 | ContentIndx myIndx; 72 | 73 | QColor diffColor; 74 | QColor limitColor; 75 | //QColor activeColor; 76 | 77 | bool showHex; 78 | bufsize_t startOff; 79 | bufsize_t pageSize; 80 | 81 | HexViewSettings settings; 82 | }; 83 | -------------------------------------------------------------------------------- /pe-bear/gui/PackersTableModel.cpp: -------------------------------------------------------------------------------- 1 | #include "PackersTableModel.h" 2 | 3 | enum COLS { 4 | COL_OFFSET = 0, 5 | COL_NAME, 6 | COL_SIG, 7 | COL_SECTION, 8 | MAX_COL 9 | }; 10 | 11 | PackersTableModel::PackersTableModel(PeHandler *peHndl, QObject *parent) 12 | : PeTableModel(peHndl, parent) 13 | { 14 | offsetFont.setCapitalization(QFont::AllUppercase); 15 | } 16 | 17 | QVariant PackersTableModel::headerData(int section, Qt::Orientation orientation, int role) const 18 | { 19 | if (role != Qt::DisplayRole) return QVariant(); 20 | if (orientation == Qt::Horizontal) { 21 | switch (section) { 22 | case COL_OFFSET: return tr("Offset"); 23 | case COL_NAME: return tr("Name"); 24 | case COL_SIG: return tr("Signature"); 25 | case COL_SECTION: return tr("Section"); 26 | } 27 | } 28 | return QVariant(); 29 | } 30 | 31 | Qt::ItemFlags PackersTableModel::flags(const QModelIndex &index) const 32 | { 33 | if (!index.isValid()) 34 | return Qt::NoItemFlags; 35 | return Qt::ItemIsEnabled | Qt::ItemIsSelectable; 36 | } 37 | 38 | int PackersTableModel::columnCount(const QModelIndex &parent) const 39 | { 40 | return MAX_COL; 41 | } 42 | 43 | int PackersTableModel::rowCount(const QModelIndex &parent) const 44 | { 45 | return this->myPeHndl->packerAtOffset.size(); 46 | } 47 | 48 | QVariant PackersTableModel::data(const QModelIndex &index, int role) const 49 | { 50 | int row = index.row(); 51 | int column = index.column(); 52 | 53 | if (role == Qt::ForegroundRole) return this->addrColor(index); 54 | 55 | if (column == COL_OFFSET) { 56 | if (role == Qt::FontRole) return offsetFont; 57 | } 58 | if (role == Qt::ToolTipRole) return toolTip(index); 59 | if (role != Qt::DisplayRole && role != Qt::EditRole) return QVariant(); 60 | 61 | int size = this->myPeHndl->packerAtOffset.size(); 62 | if (size <= row) return QVariant(); 63 | 64 | FoundPacker &found = this->myPeHndl->packerAtOffset[row]; 65 | 66 | uint32_t offset = found.offset; 67 | 68 | SectionHdrWrapper *sec = m_PE->getSecHdrAtOffset(offset, Executable::RAW); 69 | switch (column) { 70 | case COL_OFFSET: return QString::number(offset, 16); 71 | case COL_SIG: return QString::fromStdString(found.packerName); 72 | case COL_NAME: return QString::fromStdString(found.packerBytes); 73 | case COL_SECTION: { 74 | if (sec) return sec->mappedName; 75 | } 76 | } 77 | return QVariant(); 78 | } 79 | 80 | offset_t PackersTableModel::getFieldOffset(QModelIndex index) const 81 | { 82 | if (!index.isValid()) return 0; 83 | int row = index.row(); 84 | int size = this->myPeHndl->packerAtOffset.size(); 85 | if (size <= row) return 0; 86 | 87 | FoundPacker &found = this->myPeHndl->packerAtOffset[row]; 88 | return found.offset; 89 | } 90 | 91 | bufsize_t PackersTableModel::getFieldSize(QModelIndex index) const 92 | { 93 | if (!index.isValid()) return 0; 94 | int row = index.row(); 95 | int size = this->myPeHndl->packerAtOffset.size(); 96 | if (size <= row) return 0; 97 | FoundPacker &found = this->myPeHndl->packerAtOffset[row]; 98 | return found.size; 99 | } 100 | -------------------------------------------------------------------------------- /pe-bear/gui/PackersTableModel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #include "../QtCompat.h" 9 | #include "../gui_base/FollowablePeTreeView.h" 10 | 11 | class PackersTableModel : public PeTableModel 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | PackersTableModel(PeHandler *peHndl, QObject *parent = 0); 17 | 18 | QVariant headerData(int section, Qt::Orientation orientation, int role) const; 19 | Qt::ItemFlags flags(const QModelIndex &index) const; 20 | 21 | int columnCount(const QModelIndex &parent) const; 22 | int rowCount(const QModelIndex &parent) const; 23 | 24 | QVariant data(const QModelIndex &index, int role) const; 25 | bool setData(const QModelIndex &, const QVariant &, int) { return false; } //external modifications not allowed 26 | 27 | QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const { return createIndex(row, column); } //no index item pointer 28 | QModelIndex parent(const QModelIndex &index) const { return QModelIndex(); } // no parent 29 | 30 | offset_t getFieldOffset(QModelIndex index) const; 31 | bufsize_t getFieldSize(QModelIndex index) const; 32 | 33 | protected: 34 | QFont offsetFont; 35 | }; 36 | -------------------------------------------------------------------------------- /pe-bear/gui/PeTreeModel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "TreeModel.h" 4 | #include "../gui_base/PeGuiItem.h" 5 | 6 | class PeTreeItem : public TreeItem, public PeViewItem 7 | { 8 | Q_OBJECT 9 | 10 | public: 11 | PeTreeItem(PeHandler *peHndl, int fID, int sID, PeTreeItem *parent = NULL); 12 | 13 | virtual QVariant data(int column) const = 0; 14 | 15 | virtual bool setData(int column, const QVariant &value, int role); 16 | virtual QVariant toolTip(int column) const; 17 | 18 | virtual bool canFollow(int column, int row) const; 19 | virtual bool containsRVA(int column, int row) const; 20 | 21 | virtual Qt::ItemFlags flags(int column) const 22 | { 23 | return Qt::NoItemFlags; 24 | } 25 | 26 | virtual int getFID() const { return this->fID; } 27 | virtual int getSID() const { return this->sID; } 28 | 29 | protected: 30 | virtual bool setDataValue(int column, const QVariant &value) 31 | { 32 | return false; 33 | } 34 | 35 | int fID; 36 | int sID; 37 | 38 | QFont offsetFont; 39 | QColor offsetFontColor; 40 | QColor errColor; 41 | }; 42 | 43 | //-------------------------------------------------------------------------- 44 | 45 | class PeTreeModel : public TreeModel, public PeViewItem 46 | { 47 | Q_OBJECT 48 | 49 | signals: 50 | void modelUpdated(); 51 | 52 | public slots: 53 | virtual void onNeedReset() 54 | { 55 | reset(); 56 | emit modelUpdated(); 57 | } 58 | 59 | protected: 60 | virtual void connectSignals(); 61 | 62 | void reset() 63 | { 64 | //> 65 | this->beginResetModel(); 66 | this->endResetModel(); 67 | //< 68 | } 69 | 70 | public : 71 | PeTreeModel(PeHandler *peHndl, QObject *parent, bool isExpandable = true); 72 | 73 | virtual ~PeTreeModel() 74 | { 75 | PeTreeModel::counter--; 76 | } 77 | 78 | virtual bool isExpandable() { return m_isExpandable; } 79 | virtual Executable::addr_type addrTypeAt(QModelIndex index) const; 80 | 81 | virtual QVariant addrColor(const QModelIndex &index) const; 82 | virtual QVariant toolTip(QModelIndex index) const; 83 | 84 | virtual offset_t getFieldOffset(QModelIndex index) const; // TODO: refactor it 85 | virtual bufsize_t getFieldSize(QModelIndex index) const; // TODO: refactor it 86 | 87 | QFont offsetFont; 88 | QColor offsetFontColor, errColor; 89 | 90 | protected: 91 | bool m_isExpandable; 92 | static size_t counter; 93 | }; 94 | 95 | //-------------------------------------------------------------------------- 96 | -------------------------------------------------------------------------------- /pe-bear/gui/PeWrapperModel.cpp: -------------------------------------------------------------------------------- 1 | #include "PeWrapperModel.h" 2 | 3 | bool PeWrapperModel::setData(const QModelIndex &index, const QVariant &value, int role) 4 | { 5 | if (!index.isValid()) return false; 6 | 7 | size_t fID = this->getFID(index); 8 | size_t sID = this->getSID(index); 9 | 10 | ExeElementWrapper* wrap = wrapperAt(index); 11 | if (!wrap) return false; 12 | 13 | ExeElementWrapper* mainWrapper = wrapper(); 14 | if (!mainWrapper) return false; 15 | 16 | if (wrap != mainWrapper) { //it is subWrapper 17 | fID = sID; 18 | sID = FIELD_NONE; 19 | } 20 | 21 | QString text = value.toString(); 22 | 23 | bool isOk = false; 24 | ULONGLONG number = text.toULongLong(&isOk, 16); 25 | if (!isOk) return false; 26 | 27 | offset_t offset = wrap->getFieldOffset(fID); 28 | if (offset == INVALID_ADDR) { 29 | return false; 30 | } 31 | bufsize_t fieldSize = wrap->getFieldSize(fID); 32 | 33 | this->myPeHndl->backupModification(offset, fieldSize); 34 | 35 | bool isModified = wrap->setNumValue(fID, sID, number); 36 | if (isModified) { 37 | this->myPeHndl->setBlockModified(offset, fieldSize); 38 | return true; 39 | } 40 | this->myPeHndl->unbackupLastModification(); 41 | return false; 42 | } 43 | 44 | Qt::ItemFlags PeWrapperModel::flags(const QModelIndex &index) const 45 | { 46 | if (!index.isValid()) return Qt::NoItemFlags; 47 | Qt::ItemFlags f = Qt::ItemIsEnabled | Qt::ItemIsSelectable; 48 | 49 | if (this->containsOffset(index)) return f; 50 | if (this->containsValue(index)) return f | Qt::ItemIsEditable; 51 | return f; 52 | } 53 | 54 | QString PeWrapperModel::makeDockerTitle(size_t upId) 55 | { 56 | ExeNodeWrapper* node = dynamic_cast(wrapper()); 57 | if (node == NULL) { 58 | return "-"; 59 | } 60 | ExeNodeWrapper *childEntry = node->getEntryAt(upId); 61 | if (childEntry == NULL) { 62 | return "-"; 63 | } 64 | QString name = childEntry->getName(); 65 | size_t funcNum = childEntry->getEntriesCount(); 66 | QString numDesc = funcNum == 1 ? tr(" entry") : tr(" entries"); 67 | QString desc = name + " [ " + QString::number(funcNum) + numDesc + " ]"; 68 | return desc; 69 | } 70 | -------------------------------------------------------------------------------- /pe-bear/gui/PeWrapperModel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PeTreeModel.h" 4 | #include "../gui_base/WrapperInterface.h" 5 | 6 | class PeWrapperModel : public PeTreeModel, public WrapperInterface 7 | { 8 | Q_OBJECT 9 | 10 | public slots: 11 | virtual void setParentId(size_t parentId) 12 | { 13 | /* only if the down table shows the details of the row from the up table */ 14 | } 15 | 16 | public: 17 | PeWrapperModel(PeHandler *peHndl, QObject *parent = 0) 18 | : PeTreeModel(peHndl, parent), WrapperInterface() 19 | { 20 | } 21 | 22 | virtual ~PeWrapperModel() 23 | { 24 | } 25 | 26 | //--- 27 | virtual Executable::addr_type addrTypeAt(QModelIndex index) const { return WrapperInterface::addrTypeAt(index); } 28 | virtual offset_t getFieldOffset(QModelIndex index) const { return WrapperInterface::getFieldOffset(index); } 29 | virtual bufsize_t getFieldSize(QModelIndex index) const { return WrapperInterface::getFieldSize(index); } 30 | //--- 31 | /* sets data value, do backup and notifies handler */ 32 | virtual bool setData(const QModelIndex &index, const QVariant &value, int role); 33 | virtual Qt::ItemFlags flags(const QModelIndex &index) const; 34 | 35 | virtual QString makeDockerTitle(size_t upId); 36 | 37 | virtual int getFID(const QModelIndex &index) const 38 | { 39 | if (!index.isValid()) { 40 | return FIELD_NONE; 41 | } 42 | PeTreeItem *item = static_cast(index.internalPointer()); 43 | if (item) { 44 | return item->getFID(); 45 | } 46 | return index.row(); 47 | } 48 | 49 | virtual int getSID(const QModelIndex &index) const 50 | { 51 | if (!index.isValid()) { 52 | return FIELD_NONE; 53 | } 54 | PeTreeItem *item = static_cast(index.internalPointer()); 55 | if (item) { 56 | return item->getSID(); 57 | } 58 | return index.column(); 59 | } 60 | }; 61 | -------------------------------------------------------------------------------- /pe-bear/gui/ResourceDirSplitter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "../QtCompat.h" 5 | #include "../gui/pe_models.h" 6 | #include "WrapperTreeView.h" 7 | #include "DataDirWrapperSplitter.h" 8 | 9 | //----------------------------- 10 | 11 | class ResourcesDirSplitter : public DataDirWrapperSplitter 12 | { 13 | Q_OBJECT 14 | 15 | protected slots: 16 | void normalizeSelectedId(size_t parentRowId); 17 | void onUpIdSelected(size_t); 18 | void childIdSelected(int childId); 19 | void refreshLeafContent(); 20 | 21 | signals: 22 | void parentIdSelected(size_t parentId); 23 | 24 | public: 25 | ResourcesDirSplitter(PeHandler *peHndl, WrapperTableModel *upModel, WrapperTableModel *downModel, QWidget *parent); 26 | virtual ~ResourcesDirSplitter(); 27 | 28 | virtual bool initToolbar(); 29 | virtual void resizeComponents(); 30 | 31 | public slots: 32 | void onSaveEntries(); 33 | 34 | protected: 35 | enum res_view_type 36 | { 37 | RES_VIEW_RAW = 0, 38 | RES_VIEW_PIX = 1, 39 | RES_VIEW_COUNT 40 | }; 41 | 42 | void changeView(res_view_type viewType); 43 | void clearContentDisplay(); 44 | bool displayResVersion(ResourceVersionWrapper *resContent); 45 | bool displayResStrings(ResourceStringsWrapper *resContent); 46 | bool displayText(ResourceContentWrapper *resContent); 47 | bool displayBitmap(ResourceContentWrapper *resContent); 48 | bool displayIcon(ResourceContentWrapper *resContent, const pe::resource_type &type); 49 | virtual void init(WrapperTableModel *upModel, WrapperTableModel *downModel); 50 | void fillList(size_t num); 51 | 52 | QAction* saveAction; 53 | QComboBox elementsList; 54 | QTabWidget leafTab; 55 | 56 | QSplitter contentDock; 57 | QTextEdit contentText; 58 | QTextEdit contentPixmap; 59 | QLabel pixmapInfo; 60 | int contentTab; 61 | }; 62 | 63 | -------------------------------------------------------------------------------- /pe-bear/gui/TreeModel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "../QtCompat.h" 5 | 6 | //--- 7 | 8 | class TreeItem : public QObject 9 | { 10 | Q_OBJECT 11 | public: 12 | explicit TreeItem(TreeItem *parentItem = nullptr); 13 | explicit TreeItem(const QList &data, TreeItem *parentItem = nullptr); 14 | virtual ~TreeItem(); 15 | 16 | TreeItem *child(int row); 17 | virtual int childCount() const; 18 | virtual int columnCount() const; 19 | virtual QVariant data(int column) const; 20 | virtual int row() const; 21 | TreeItem *parentItem(); 22 | 23 | virtual void appendChild(TreeItem *child); 24 | virtual void detachChild(TreeItem *child); 25 | virtual void removeAllChildren(); 26 | 27 | protected: 28 | QList m_childItems; 29 | QList m_itemData; 30 | TreeItem *m_parentItem; 31 | }; 32 | 33 | //--- 34 | 35 | class TreeModel : public QAbstractItemModel 36 | { 37 | Q_OBJECT 38 | 39 | public: 40 | explicit TreeModel(QObject *parent = nullptr); 41 | ~TreeModel(); 42 | 43 | virtual QVariant data(const QModelIndex &index, int role) const override; 44 | 45 | virtual Qt::ItemFlags flags(const QModelIndex &index) const override; 46 | 47 | virtual QVariant headerData(int section, Qt::Orientation orientation, 48 | int role = Qt::DisplayRole) const override; 49 | 50 | virtual QModelIndex index(int row, int column, 51 | const QModelIndex &parent = QModelIndex()) const override; 52 | 53 | virtual QModelIndex parent(const QModelIndex &index) const override; 54 | 55 | virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override; 56 | 57 | virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override; 58 | 59 | protected: 60 | 61 | TreeItem *rootItem; 62 | }; 63 | -------------------------------------------------------------------------------- /pe-bear/gui/WrapperSplitter.cpp: -------------------------------------------------------------------------------- 1 | #include "WrapperSplitter.h" 2 | 3 | //--------------------------------------------------------------------------- 4 | 5 | WrapperSplitter::WrapperSplitter(QWidget *parent) 6 | : QSplitter(Qt::Vertical, parent), 7 | upModel(NULL), downModel(NULL), 8 | upTree(NULL), downTree(NULL), 9 | dock(NULL), 10 | toolBar(this), title(""), 11 | recordId(0) 12 | { 13 | //empty 14 | } 15 | 16 | WrapperSplitter::WrapperSplitter(PeTreeModel *upModel, PeTreeModel *downModel, QWidget *parent) 17 | : QSplitter(Qt::Vertical, parent), 18 | upModel(NULL), downModel(NULL), 19 | upTree(NULL), downTree(NULL), 20 | dock(NULL), 21 | toolBar(this), title(""), 22 | recordId(0) 23 | { 24 | init(upModel, downModel); 25 | } 26 | 27 | void WrapperSplitter::init(PeTreeModel *upModel, PeTreeModel *downModel) 28 | { 29 | this->upModel = upModel; 30 | this->downModel = downModel; 31 | 32 | toolBar.setMaximumHeight(20); 33 | addWidget(&toolBar); 34 | initToolbar(); 35 | 36 | if (upModel) { 37 | upTree.setModel(this->upModel); 38 | this->upModel->setParent(&this->upTree); 39 | this->upTree.expandAll(); 40 | addWidget(&upTree); 41 | connect(&upTree, SIGNAL(parentIdSelected(size_t)), this, SLOT(setParentIdInDocker(size_t))); 42 | } 43 | 44 | if (downModel) { 45 | connect(&upTree, SIGNAL(parentIdSelected(size_t)), downModel, SLOT(setParentId(size_t))); 46 | connect(downModel, SIGNAL(modelUpdated()), this, SLOT(reloadDocketTitle())); 47 | 48 | downTree.setModel(this->downModel); 49 | this->downModel->setParent(&downTree); 50 | downTree.expandAll(); 51 | this->dock.setFeatures(QDockWidget::NoDockWidgetFeatures); 52 | dock.setWidget(&this->downTree); 53 | reloadDocketTitle(); 54 | addWidget(&dock); 55 | } 56 | } 57 | 58 | void WrapperSplitter::reloadDocketTitle() 59 | { 60 | if (!upModel) { 61 | dock.setWindowTitle(""); 62 | return; 63 | } 64 | WrapperInterface *wrapperI = dynamic_cast(upModel); 65 | if (wrapperI == NULL) { 66 | return; 67 | } 68 | QString desc = wrapperI->makeDockerTitle(this->recordId); 69 | this->dock.setWindowTitle(desc); 70 | } 71 | 72 | void WrapperSplitter::setParentIdInDocker(size_t upId) 73 | { 74 | this->recordId = upId; 75 | reloadDocketTitle(); 76 | } 77 | -------------------------------------------------------------------------------- /pe-bear/gui/WrapperSplitter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "../QtCompat.h" 5 | #include "../gui/pe_models.h" 6 | #include "WrapperTreeView.h" 7 | 8 | class WrapperSplitter : public QSplitter 9 | { 10 | Q_OBJECT 11 | 12 | public slots: 13 | virtual void setParentIdInDocker(size_t); 14 | virtual void reloadDocketTitle(); 15 | 16 | public: 17 | WrapperSplitter(QWidget *parent); 18 | WrapperSplitter(PeTreeModel *upModel, PeTreeModel *downModel, QWidget *parent); 19 | 20 | virtual ~WrapperSplitter() 21 | { 22 | delete upModel; 23 | delete downModel; 24 | } 25 | 26 | virtual bool initToolbar() { return false; } 27 | 28 | QModelIndexList getUpperViewSelected() 29 | { 30 | return upTree.selectionModel()->selectedIndexes(); 31 | } 32 | 33 | QToolBar toolBar; 34 | QDockWidget dock; 35 | QString title; 36 | 37 | protected: 38 | virtual void init(PeTreeModel *upModel, PeTreeModel *downModel); 39 | 40 | PeTreeModel *upModel, *downModel; 41 | WrapperTreeView upTree; 42 | FollowablePeTreeView downTree; 43 | 44 | size_t recordId; 45 | }; 46 | -------------------------------------------------------------------------------- /pe-bear/gui/WrapperTreeView.cpp: -------------------------------------------------------------------------------- 1 | #include "WrapperTreeView.h" 2 | 3 | //--------------------------------------------------------------------------- 4 | void WrapperTreeView::selectionChanged(const QItemSelection &newSel, const QItemSelection &prevSel) 5 | { 6 | FollowablePeTreeView::selectionChanged(newSel, prevSel); 7 | 8 | WrapperInterface *topModel = dynamic_cast (this->model()); 9 | if (!topModel) return; 10 | 11 | ExeElementWrapper *mainWrapper = topModel->wrapper(); 12 | if (mainWrapper == NULL) return; 13 | if (newSel.indexes().size() == 0) return; 14 | 15 | QModelIndex index = newSel.indexes().at(0); 16 | size_t parentId = (index.isValid()) ? index.row() : 0; 17 | emit parentIdSelected(parentId); 18 | } 19 | -------------------------------------------------------------------------------- /pe-bear/gui/WrapperTreeView.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "../QtCompat.h" 5 | #include "../gui_base/FollowablePeTreeView.h" 6 | #include "../gui_base/WrapperTableModel.h" 7 | 8 | class WrapperTreeView : public FollowablePeTreeView 9 | { 10 | Q_OBJECT 11 | signals: 12 | void parentIdSelected(size_t parentId); 13 | public: 14 | WrapperTreeView(QWidget *parent) : FollowablePeTreeView(parent) {} 15 | void selectionChanged(const QItemSelection &newSel, const QItemSelection &prevSel); 16 | }; 17 | -------------------------------------------------------------------------------- /pe-bear/gui/followable_table/FollowableOffsetedView.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "OffsetedView.h" 5 | 6 | namespace util { 7 | inline QString translateAddrTypeName(const Executable::addr_type addrType) 8 | { 9 | switch (addrType) { 10 | case Executable::RAW : return "Raw"; 11 | case Executable::RVA : return "RVA"; 12 | case Executable::VA : return "VA"; 13 | } 14 | return ""; 15 | } 16 | }; 17 | //--- 18 | 19 | class FollowableOffsetedView : public OffsetedView 20 | { 21 | Q_OBJECT 22 | 23 | signals: 24 | void targetClicked(offset_t offset, Executable::addr_type); 25 | 26 | public: 27 | enum ACTIONS 28 | { 29 | ACTION_FOLLOW = 0, 30 | COUNT_ACTIONS 31 | }; 32 | 33 | FollowableOffsetedView(QWidget *parent, Executable::addr_type targetAddrType = Executable::RVA) 34 | : OffsetedView(parent, targetAddrType), 35 | m_ContextMenu(this), 36 | m_isMenuEnabled(true) 37 | { 38 | for (int i = 0; i < COUNT_ACTIONS; i++) { 39 | m_contextActions[i] = nullptr; 40 | } 41 | initContextMenu(); 42 | enableMenu(true); 43 | connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(customMenuEvent(QPoint))); 44 | } 45 | 46 | QMenu& getMenu() { return m_ContextMenu; } 47 | 48 | void enableMenu(bool enable) 49 | { 50 | if (enable) 51 | this->setContextMenuPolicy(Qt::CustomContextMenu); 52 | else 53 | this->setContextMenuPolicy(Qt::DefaultContextMenu); 54 | 55 | m_isMenuEnabled = enable; 56 | } 57 | 58 | bool enableAction(enum FollowableOffsetedView::ACTIONS id, bool state) 59 | { 60 | if (id >= COUNT_ACTIONS || m_contextActions[id] == nullptr) { 61 | return false; 62 | } 63 | m_contextActions[id]->setEnabled(state); 64 | return true; 65 | } 66 | 67 | protected slots: 68 | bool updateActionsToOffset() 69 | { 70 | offset_t currentOffset = getSelectedOffset(); 71 | if (currentOffset == INVALID_ADDR) { 72 | m_contextActions[ACTION_FOLLOW]->setText("Cannot follow"); 73 | m_contextActions[ACTION_FOLLOW]->setEnabled(false); 74 | return false; 75 | } 76 | m_contextActions[ACTION_FOLLOW]->setText("Follow "+ util::translateAddrTypeName(m_targetAddrType) +": "+ QString::number(currentOffset, 16)); 77 | m_contextActions[ACTION_FOLLOW]->setEnabled(true); 78 | return true; 79 | } 80 | 81 | void customMenuEvent(QPoint p) 82 | { 83 | if (!updateActionsToOffset()) return; 84 | m_ContextMenu.exec(mapToGlobal(p)); 85 | } 86 | 87 | void followSelectedOffset() 88 | { 89 | offset_t currentOffset = getSelectedOffset(); 90 | if (currentOffset != INVALID_ADDR) { 91 | emit targetClicked(currentOffset, m_targetAddrType); 92 | } 93 | } 94 | 95 | protected: 96 | 97 | void initContextMenu() 98 | { 99 | 100 | m_contextActions[ACTION_FOLLOW] = new QAction("Follow", &m_ContextMenu); 101 | m_ContextMenu.addAction(m_contextActions[ACTION_FOLLOW]); 102 | connect(m_contextActions[ACTION_FOLLOW], SIGNAL(triggered()), this, SLOT(followSelectedOffset())); 103 | } 104 | 105 | virtual offset_t getSelectedOffset() 106 | { 107 | if (this->selectedIndexes().size() == 0) return INVALID_ADDR; 108 | QModelIndex current = this->selectedIndexes().back(); 109 | return getOffsetFromUserData(current); 110 | } 111 | 112 | bool m_isMenuEnabled; 113 | QMenu m_ContextMenu; 114 | QAction* m_contextActions[COUNT_ACTIONS]; 115 | }; 116 | -------------------------------------------------------------------------------- /pe-bear/gui/followable_table/MouseTrackingTableView.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../QtCompat.h" 4 | 5 | class MouseTrackingTableView : public QTableView 6 | { 7 | Q_OBJECT 8 | 9 | signals: 10 | void mouseClicked(const QModelIndex &index); 11 | void moudeDblClicked(const QModelIndex &index); 12 | void mouseHovered(const QModelIndex &index); 13 | void mouseLeave(); 14 | 15 | public: 16 | MouseTrackingTableView(QWidget *parent) 17 | : QTableView(parent) 18 | { 19 | setMouseTracking(true); 20 | } 21 | 22 | void mousePressEvent(QMouseEvent *ev) 23 | { 24 | if (!ev) return; 25 | QModelIndex index = this->indexAt(ev->pos()); 26 | ev->accept(); 27 | emit mouseClicked(index); 28 | 29 | return QTableView::mousePressEvent(ev); 30 | } 31 | 32 | void mouseMoveEvent(QMouseEvent *ev) 33 | { 34 | if (!ev) return; 35 | QModelIndex index = this->indexAt(ev->pos()); 36 | ev->accept(); 37 | emit mouseHovered(index); 38 | 39 | return QTableView::mouseMoveEvent(ev); 40 | } 41 | 42 | void leaveEvent(QEvent *ev) 43 | { 44 | if (!ev) return; 45 | ev->accept(); 46 | emit mouseLeave(); 47 | 48 | setCursor(Qt::ArrowCursor); 49 | return QTableView::leaveEvent(ev); 50 | } 51 | 52 | }; 53 | -------------------------------------------------------------------------------- /pe-bear/gui/followable_table/OffsetedView.cpp: -------------------------------------------------------------------------------- 1 | #include "OffsetedView.h" 2 | 3 | void OffsetedView::setModel(QAbstractItemModel *model) 4 | { 5 | QItemSelectionModel *prev = this->selectionModel(); 6 | QTableView::setModel(model); 7 | if (prev) { 8 | disconnect(prev, SIGNAL(currentRowChanged(const QModelIndex&, const QModelIndex&)), 9 | this, SLOT(onIndexChanged(const QModelIndex&, const QModelIndex&))); 10 | } 11 | connect(this->selectionModel(), SIGNAL(currentRowChanged(const QModelIndex&, const QModelIndex&)), 12 | this, SLOT(onIndexChanged(const QModelIndex&, const QModelIndex&))); 13 | } 14 | 15 | void OffsetedView::mousePressEvent(QMouseEvent *ev) 16 | { 17 | if (!ev) return; 18 | ev->accept(); 19 | QModelIndex index = this->indexAt(ev->pos()); 20 | if (index.isValid()) { 21 | const offset_t offset = getOffsetFromUserData(index); 22 | //mouse click should always emit the target, without verifying 23 | emitSelectedTarget(offset, m_targetAddrType, false); 24 | } 25 | return MouseTrackingTableView::mousePressEvent(ev); 26 | } 27 | 28 | void OffsetedView::onIndexChanged(const QModelIndex ¤t, const QModelIndex &previous) 29 | { 30 | const offset_t offset = getOffsetFromUserData(current); 31 | //protect from emitting the same target more than once (from various events) 32 | emitSelectedTarget(offset, m_targetAddrType, true); 33 | } 34 | 35 | -------------------------------------------------------------------------------- /pe-bear/gui/followable_table/OffsetedView.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "MouseTrackingTableView.h" 5 | 6 | class OffsetedView : public MouseTrackingTableView 7 | { 8 | Q_OBJECT 9 | 10 | signals: 11 | void offsetChanged(const offset_t offset, const Executable::addr_type aType); 12 | 13 | public: 14 | OffsetedView(QWidget *parent, Executable::addr_type targetAddrType = Executable::RVA) 15 | : MouseTrackingTableView(parent), m_targetAddrType(targetAddrType), 16 | m_prevOffset(INVALID_ADDR) 17 | { 18 | setMouseTracking(true); 19 | } 20 | 21 | void setModel(QAbstractItemModel *model); 22 | 23 | //events: 24 | void mousePressEvent(QMouseEvent *ev); //emits target 25 | 26 | protected slots: 27 | void onIndexChanged(const QModelIndex ¤t, const QModelIndex &previous); //emits target 28 | 29 | 30 | protected: 31 | virtual offset_t getOffsetFromUserData(const QModelIndex ¤t) 32 | { 33 | QAbstractItemModel *model = this->model(); 34 | if (!model|| !current.isValid()) return INVALID_ADDR; 35 | 36 | bool isOk; 37 | qint64 userData = model->data(current, Qt::UserRole).toULongLong(&isOk); 38 | return isOk ? userData : INVALID_ADDR; 39 | } 40 | 41 | const Executable::addr_type m_targetAddrType; 42 | 43 | private: 44 | void emitSelectedTarget(const offset_t offset, Executable::addr_type aType, bool verify) 45 | { 46 | //protect from emitting the same target more than once (from various events) 47 | if (verify && m_prevOffset == offset && m_prevType == aType) { 48 | return; 49 | } 50 | m_prevOffset = offset; 51 | m_prevType = aType; 52 | //emit target: 53 | emit offsetChanged(offset, aType); 54 | } 55 | 56 | offset_t m_prevOffset; // previously selected target 57 | Executable::addr_type m_prevType; 58 | }; 59 | -------------------------------------------------------------------------------- /pe-bear/gui/pe_models.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "pe_models/BoundImpTreeModel.h" 4 | #include "pe_models/DebugTreeModel.h" 5 | #include "pe_models/DelayImpTreeModel.h" 6 | #include "pe_models/ExceptionTreeModel.h" 7 | #include "pe_models/ExportsTreeModel.h" 8 | #include "pe_models/FileHdrTreeModel.h" 9 | #include "pe_models/ImportsTreeModel.h" 10 | #include "pe_models/LdConfigTreeModel.h" 11 | #include "pe_models/OptionalHdrTreeModel.h" 12 | #include "pe_models/RelocsTreeModel.h" 13 | #include "pe_models/ResourcesTreeModel.h" 14 | #include "pe_models/SecHdrsTreeModel.h" 15 | #include "pe_models/SecurityTreeModel.h" 16 | #include "pe_models/TLSTreeModel.h" 17 | #include "pe_models/RichHdrTreeModel.h" 18 | #include "pe_models/ClrHdrTreeModel.h" 19 | -------------------------------------------------------------------------------- /pe-bear/gui/pe_models/BoundImpTreeModel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "../../gui_base/WrapperTableModel.h" 8 | 9 | 10 | class BoundImpTreeModel : public WrapperTableModel 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | BoundImpTreeModel(PeHandler *peHndl, QObject *parent = 0) 16 | : WrapperTableModel(peHndl, parent) 17 | { 18 | } 19 | 20 | virtual int columnCount(const QModelIndex &parent) const; 21 | 22 | virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; 23 | virtual QVariant data(const QModelIndex &index, int role) const; 24 | virtual bool setData(const QModelIndex &index, const QVariant &value, int role); 25 | virtual QVariant toolTip(const QModelIndex &index) const; 26 | 27 | virtual bool containsValue(QModelIndex index) const { return (index.column() >= NAME); } 28 | 29 | protected: 30 | virtual int getFID(const QModelIndex &index) const { return index.column() - ADDED_COLS_NUM; } 31 | virtual int getSID(const QModelIndex &index) const { return index.row(); } 32 | 33 | inline int32_t columnToFID(int column) const { return column - ADDED_COLS_NUM; } 34 | 35 | virtual ExeElementWrapper* wrapper() const { return &myPeHndl->boundImpDirWrapper; } 36 | virtual ExeElementWrapper* wrapperAt(QModelIndex index) const { return myPeHndl->boundImpDirWrapper.getEntryAt(index.row()); } 37 | 38 | enum cols { 39 | OFFSET, 40 | NAME, 41 | ADDED_COLS_NUM 42 | }; 43 | }; 44 | -------------------------------------------------------------------------------- /pe-bear/gui/pe_models/ClrHdrTreeModel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include 5 | #include 6 | #include "../../gui_base/PeTreeView.h" 7 | #include "../../gui_base/WrapperTableModel.h" 8 | #include "../../gui/PeTreeModel.h" 9 | #include "../PeWrapperModel.h" 10 | 11 | 12 | class ClrHdrTreeItem : public PeTreeItem 13 | { 14 | Q_OBJECT 15 | 16 | protected: 17 | enum ViewLevel { DESC = 0, DETAILS = 1 }; 18 | typedef enum ViewLevel level_t; 19 | 20 | QList childItems; 21 | ClrHdrTreeItem *parentItem; 22 | level_t level; 23 | ClrDirWrapper::FieldID role; 24 | ClrDirWrapper &clrDir; 25 | 26 | public: 27 | ClrHdrTreeItem( 28 | PeHandler *peHndl, 29 | level_t level = DESC, 30 | ClrDirWrapper::FieldID role = ClrDirWrapper::NONE, 31 | ClrHdrTreeItem *parent = NULL 32 | ); 33 | 34 | int columnCount() const; 35 | 36 | virtual Qt::ItemFlags flags(int column) const; 37 | virtual QVariant data(int column) const; 38 | 39 | bool setDataValue(int column, const QVariant &value); 40 | virtual QVariant foreground(int column) const; 41 | virtual QVariant background(int column) const; 42 | 43 | /* PEGuiItem interface */ 44 | virtual offset_t getContentOffset() const; 45 | virtual bufsize_t getContentSize() const; 46 | 47 | protected: 48 | virtual bool isChildOk(TreeItem* child) 49 | { 50 | const ClrHdrTreeItem *ptr = dynamic_cast(child); 51 | return (ptr)? true : false; 52 | } 53 | 54 | friend class ClrTreeModel; 55 | }; 56 | 57 | //------------------- 58 | 59 | class ClrFlagsTreeItem : public ClrHdrTreeItem 60 | { 61 | Q_OBJECT 62 | 63 | public: 64 | ClrFlagsTreeItem(PeHandler *peHndl, level_t level = DESC, DWORD flags = 0, ClrHdrTreeItem *parent = NULL); 65 | virtual QVariant data(int column) const; 66 | void loadChildren(); 67 | 68 | protected: 69 | 70 | DWORD getAllFlags() const; 71 | DWORD flags; 72 | }; 73 | 74 | //------------------- 75 | 76 | class ClrTreeModel : public PeWrapperModel 77 | { 78 | Q_OBJECT 79 | 80 | protected slots: 81 | void reload(); 82 | 83 | public: 84 | ClrTreeModel(PeHandler *peHndl, QObject *parent = 0); 85 | 86 | virtual int columnCount(const QModelIndex &parent) const; 87 | 88 | virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; 89 | virtual QVariant data(const QModelIndex &index, int role) const; 90 | virtual bool setData(const QModelIndex &index, const QVariant &value, int role); 91 | 92 | Qt::ItemFlags flags(const QModelIndex &index) const; 93 | 94 | virtual bool containsValue(QModelIndex index) const; 95 | QString makeDockerTitle(size_t upId); 96 | 97 | protected: 98 | virtual ExeElementWrapper* wrapper() const { return &myPeHndl->clrDirWrapper; } 99 | 100 | ClrFlagsTreeItem* flagsItem; 101 | }; 102 | -------------------------------------------------------------------------------- /pe-bear/gui/pe_models/DebugTreeModel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "../../gui_base/WrapperTableModel.h" 8 | 9 | class DebugTreeModel : public WrapperTableModel 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | DebugTreeModel(PeHandler *peHndl, QObject *parent = 0) 15 | : WrapperTableModel(peHndl, parent) 16 | { 17 | this->connectSignals(); 18 | } 19 | 20 | virtual int columnCount(const QModelIndex &parent) const; 21 | 22 | virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; 23 | virtual QVariant data(const QModelIndex &index, int role) const; 24 | 25 | virtual bool setData(const QModelIndex &index, const QVariant &value, int role); 26 | virtual Qt::ItemFlags flags(const QModelIndex &index) const; 27 | 28 | virtual QVariant toolTip(const QModelIndex &index) const; 29 | 30 | virtual bool containsValue(QModelIndex index) const { return true; } 31 | 32 | protected: 33 | virtual int getFID(const QModelIndex &index) const { return index.column() - ADDED_COLS_NUM; } 34 | virtual int getSID(const QModelIndex &index) const { return index.row(); } 35 | 36 | virtual ExeElementWrapper* wrapper() const { return &myPeHndl->debugDirWrapper; } 37 | virtual ExeElementWrapper* wrapperAt(QModelIndex index) const; 38 | 39 | inline int32_t columnToFID(int column) const { return column - ADDED_COLS_NUM; } 40 | inline int32_t FIDtoColumn(int fId) const { return (fId + ADDED_COLS_NUM); } 41 | 42 | virtual bool isComplexValue(const QModelIndex &index) const { return (index.column() >= ADDED_COLS_NUM) ? true : false; } 43 | 44 | enum FieldID { 45 | NONE = FIELD_NONE, 46 | OFFSET, 47 | NAME, 48 | ADDED_COLS_NUM 49 | }; 50 | }; 51 | 52 | //------------------------------------------------------------------------------------------- 53 | 54 | class DebugRDSIEntryTreeModel : public WrapperTableModel 55 | { 56 | Q_OBJECT 57 | 58 | public slots: 59 | void setParentId(size_t _parentId) 60 | { 61 | this->parentId = _parentId; 62 | reset(); 63 | } 64 | 65 | public: 66 | DebugRDSIEntryTreeModel(PeHandler *peHndl, QObject *parent = 0) 67 | : WrapperTableModel(peHndl, parent) 68 | { 69 | connect(peHndl, SIGNAL(modified()), this, SLOT(onNeedReset())); 70 | } 71 | 72 | int rowCount(const QModelIndex &parent) const; 73 | int columnCount(const QModelIndex &parent) const { return MAX_COL; } 74 | 75 | QVariant data(const QModelIndex &index, int role) const; 76 | bool setData(const QModelIndex &index, const QVariant &value, int role); 77 | QVariant headerData(int section, Qt::Orientation orientation, int role) const; 78 | Qt::ItemFlags flags(const QModelIndex &index) const; 79 | 80 | virtual bool containsValue(QModelIndex index) const { return index.column() == VALUE; } 81 | 82 | virtual ExeElementWrapper* wrapper() const; 83 | virtual ExeElementWrapper* wrapperAt(QModelIndex index) const; 84 | 85 | protected: 86 | bool setTextData(const QModelIndex &index, const QVariant &value, int role); 87 | virtual int getFID(const QModelIndex &index) const { return index.row(); } 88 | virtual int getSID(const QModelIndex &index) const { return index.column(); } 89 | 90 | enum FieldID { 91 | NONE = FIELD_NONE, 92 | OFFSET = 0, 93 | NAME, 94 | VALUE, 95 | MAX_COL 96 | }; 97 | 98 | size_t parentId; 99 | }; 100 | ///--- 101 | -------------------------------------------------------------------------------- /pe-bear/gui/pe_models/DelayImpTreeModel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "../../gui_base/WrapperTableModel.h" 8 | #include 9 | 10 | class DelayImpTreeModel : public WrapperTableModel 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | DelayImpTreeModel(PeHandler *peHndl, QObject *parent = 0) 16 | : WrapperTableModel(peHndl, parent) 17 | { 18 | } 19 | 20 | virtual int columnCount(const QModelIndex &parent) const; 21 | 22 | virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; 23 | virtual QVariant data(const QModelIndex &index, int role) const; 24 | virtual bool setData(const QModelIndex &index, const QVariant &value, int role); 25 | 26 | virtual bool containsValue(QModelIndex index) const { return (index.column() >= NAME); } 27 | 28 | protected: 29 | virtual int getFID(const QModelIndex &index) const { return index.column() - ADDED_COLS_NUM; } 30 | virtual int getSID(const QModelIndex &index) const { return index.row(); } 31 | 32 | inline int32_t columnToFID(int column) const { return column - ADDED_COLS_NUM; } 33 | 34 | virtual ExeElementWrapper* wrapper() const { return &myPeHndl->delayImpDirWrapper; } 35 | virtual ExeElementWrapper* wrapperAt(QModelIndex index) const { return myPeHndl->delayImpDirWrapper.getEntryAt(index.row()); } 36 | 37 | enum cols { 38 | OFFSET, 39 | NAME, 40 | ADDED_COLS_NUM 41 | }; 42 | 43 | friend class DelayImpTreeView; 44 | }; 45 | 46 | //---------------------------------------------------------------------- 47 | 48 | class DelayImpFuncModel : public WrapperTableModel 49 | { 50 | Q_OBJECT 51 | 52 | public slots: 53 | void setParentId(size_t libraryId) { this->libraryId = libraryId; reset(); } 54 | 55 | public: 56 | DelayImpFuncModel(PeHandler *peHndl, QObject *parent = 0); 57 | 58 | virtual int columnCount(const QModelIndex &parent) const; 59 | virtual int rowCount(const QModelIndex &parent) const; 60 | 61 | virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; 62 | virtual QVariant data(const QModelIndex &index, int role) const; 63 | 64 | virtual bool setData(const QModelIndex &index, const QVariant &value, int role); 65 | virtual Qt::ItemFlags flags(const QModelIndex &index) const; 66 | 67 | //virtual bool containsOffset(QModelIndex index) const { return false; } // Do not show offset! 68 | virtual Executable::addr_type offsetAddrType() const; 69 | virtual bool containsValue(QModelIndex index) const { return true; } 70 | 71 | protected: 72 | virtual ExeNodeWrapper* wrapper() const; 73 | virtual ExeElementWrapper* wrapperAt(QModelIndex index) const; 74 | 75 | virtual bool isComplexValue(const QModelIndex &index) const { return false; } 76 | 77 | virtual int getFID(const QModelIndex &index) const { return index.column() - ADDED_COLS_NUM; } 78 | virtual int getSID(const QModelIndex &index) const { return index.row(); } 79 | 80 | inline int32_t columnToFID(int column) const { return (column - ADDED_COLS_NUM); } 81 | inline int32_t FIDtoColumn(int fId) const { return (fId + ADDED_COLS_NUM); } 82 | 83 | enum FieldID { 84 | NONE = FIELD_NONE, 85 | OFFSET, 86 | NAME, 87 | ORDINAL, 88 | HINT, 89 | ADDED_COLS_NUM 90 | }; 91 | size_t libraryId; 92 | }; 93 | -------------------------------------------------------------------------------- /pe-bear/gui/pe_models/ExceptionTreeModel.cpp: -------------------------------------------------------------------------------- 1 | #include "ExceptionTreeModel.h" 2 | 3 | //----------------------------------------------------------------------------- 4 | 5 | #define NOT_FILLED "-" 6 | 7 | int ExceptionTreeModel::columnCount(const QModelIndex &parent) const 8 | { 9 | ExceptionDirWrapper* wrap = dynamic_cast(wrapper()); 10 | if (!wrap) return 0; 11 | ExeNodeWrapper* entry = wrap->getEntryAt(0); 12 | if (!entry) return 0; 13 | uint32_t cntr = entry->getFieldsCount() + ADDED_COLS_NUM; 14 | return cntr; 15 | } 16 | 17 | QVariant ExceptionTreeModel::headerData(int section, Qt::Orientation orientation, int role) const 18 | { 19 | if (role != Qt::DisplayRole) return QVariant(); 20 | switch (section) { 21 | case OFFSET: return tr("Offset"); 22 | } 23 | ExceptionDirWrapper* impWrap = dynamic_cast(wrapper()); 24 | if (!impWrap) return QVariant(); 25 | int32_t fID = this->columnToFID(section); 26 | return impWrap->getFieldName(0, fID); 27 | } 28 | 29 | ExeElementWrapper* ExceptionTreeModel::wrapperAt(QModelIndex index) const 30 | { 31 | ExceptionDirWrapper* wrap = dynamic_cast(wrapper()); 32 | if (!wrap) return NULL; 33 | return wrap->getEntryAt(index.row()); 34 | } 35 | 36 | QVariant ExceptionTreeModel::data(const QModelIndex &index, int role) const 37 | { 38 | ExceptionDirWrapper* impWrap = dynamic_cast(wrapper()); 39 | if (!impWrap) return QVariant(); 40 | 41 | int column = index.column(); 42 | if (role == Qt::ForegroundRole) return this->addrColor(index); 43 | 44 | if (role == Qt::FontRole) return offsetFont; 45 | if (role == Qt::ToolTipRole) return toolTip(index); 46 | 47 | ExceptionEntryWrapper* entry = dynamic_cast(wrapperAt(index)); 48 | if (!entry) return QVariant(); 49 | 50 | if (role != Qt::DisplayRole && role != Qt::EditRole) return QVariant(); 51 | 52 | switch (column) { 53 | case OFFSET: return QString::number(getFieldOffset(index), 16); 54 | } 55 | bool isOk = false; 56 | uint64_t val = entry->getNumValue(getFID(index), &isOk); 57 | if (!isOk) return "UNK"; /* other type? */ 58 | 59 | return QString::number(val, 16); 60 | } 61 | 62 | bool ExceptionTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) 63 | { 64 | if (!index.isValid()) return false; 65 | 66 | size_t fID = getFID(index); 67 | 68 | if (!wrapper()) return false; 69 | ExceptionEntryWrapper* entry = dynamic_cast(wrapperAt(index)); 70 | if (!entry) return false; 71 | 72 | bool isOk = false; 73 | ULONGLONG number = value.toString().toLongLong(&isOk, 16); 74 | if (!isOk) return false; 75 | 76 | const offset_t offset = entry->getFieldOffset(fID); 77 | const bufsize_t fieldSize = entry->getFieldSize(fID); 78 | 79 | this->myPeHndl->backupModification(offset, fieldSize); 80 | const bool isModified = entry->setNumValue(fID, index.column(), number); 81 | if (isModified) { 82 | this->myPeHndl->setBlockModified(offset, fieldSize); 83 | return true; 84 | } 85 | this->myPeHndl->unbackupLastModification(); 86 | return false; 87 | } 88 | -------------------------------------------------------------------------------- /pe-bear/gui/pe_models/ExceptionTreeModel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "../../gui_base/WrapperTableModel.h" 8 | 9 | 10 | class ExceptionTreeModel : public WrapperTableModel 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | ExceptionTreeModel(PeHandler *peHndl, QObject *parent = 0) 16 | : WrapperTableModel(peHndl, parent) {} 17 | 18 | virtual int columnCount(const QModelIndex &parent) const; 19 | 20 | virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; 21 | virtual QVariant data(const QModelIndex &index, int role) const; 22 | virtual bool setData(const QModelIndex &index, const QVariant &value, int role); 23 | 24 | virtual bool containsValue(QModelIndex index) const { return true; } 25 | 26 | protected: 27 | virtual int getFID(const QModelIndex &index) const { return index.column() - ADDED_COLS_NUM; } 28 | virtual int getSID(const QModelIndex &index) const { return index.column(); } 29 | 30 | virtual ExeElementWrapper* wrapper() const { return &myPeHndl->exceptDirWrapper; } 31 | virtual ExeElementWrapper* wrapperAt(QModelIndex index) const; 32 | 33 | inline int32_t columnToFID(int column) const { return column - ADDED_COLS_NUM; } 34 | inline int32_t FIDtoColumn(int fId) const { return (fId + ADDED_COLS_NUM); } 35 | 36 | virtual bool isComplexValue(const QModelIndex &index) const { if (index.column() >= ADDED_COLS_NUM) return true; return false; } 37 | 38 | enum FieldID { 39 | NONE = FIELD_NONE, 40 | OFFSET, 41 | ADDED_COLS_NUM 42 | }; 43 | friend class ExceptionTreeView; 44 | }; 45 | 46 | 47 | class ExceptionTreeView : public FollowablePeTreeView 48 | { 49 | Q_OBJECT 50 | 51 | public: 52 | ExceptionTreeView(QWidget *parent) : FollowablePeTreeView(parent) {} 53 | }; 54 | -------------------------------------------------------------------------------- /pe-bear/gui/pe_models/ExportsTreeModel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "../../gui_base/WrapperTableModel.h" 8 | 9 | //---------------------------- 10 | 11 | class ExportsTreeModel : public WrapperTableModel 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | ExportsTreeModel(PeHandler *peHndl, QObject *parent = 0) 17 | : WrapperTableModel(peHndl, parent) {} 18 | 19 | virtual int columnCount(const QModelIndex &parent) const { return COLS_NUM; } 20 | 21 | virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; 22 | virtual QVariant data(const QModelIndex &index, int role) const; 23 | 24 | virtual bool containsValue(QModelIndex index) const { return (index.column() == VALUE); } 25 | QString makeDockerTitle(size_t id); 26 | 27 | protected: 28 | virtual int getFID(const QModelIndex &index) const { return index.row(); } 29 | virtual int getSID(const QModelIndex &index) const { return index.column(); } 30 | 31 | virtual ExeElementWrapper* wrapper() const { return myPeHndl ? &myPeHndl->exportDirWrapper : NULL; } 32 | 33 | enum cols { 34 | OFFSET, 35 | NAME, 36 | VALUE, 37 | VALUE2, 38 | COLS_NUM 39 | }; 40 | friend class LdConfigTreeView; 41 | }; 42 | 43 | //---------------------------------------------------------------------- 44 | 45 | class ExportedFuncTreeModel : public WrapperTableModel 46 | { 47 | Q_OBJECT 48 | 49 | public: 50 | ExportedFuncTreeModel(PeHandler *peHndl, QObject *parent = 0) 51 | : WrapperTableModel(peHndl, parent) {} 52 | 53 | int rowCount(const QModelIndex &parent) const; 54 | int columnCount(const QModelIndex &parent) const { return MAX_COL; } 55 | 56 | QVariant data(const QModelIndex &index, int role) const; 57 | QVariant headerData(int section, Qt::Orientation orientation, int role) const; 58 | 59 | virtual bool setData(const QModelIndex &index, const QVariant &value, int role); 60 | virtual Qt::ItemFlags flags(const QModelIndex &index) const; 61 | 62 | virtual bool containsValue(QModelIndex index) const { return index.column() == VALUE; } 63 | virtual ExeElementWrapper* wrapper() const { return myPeHndl ? &myPeHndl->exportDirWrapper : NULL; } 64 | virtual ExeElementWrapper* wrapperAt(QModelIndex index) const { return myPeHndl->exportDirWrapper.getEntryAt(index.row()); } 65 | 66 | virtual Executable::addr_type addrTypeAt(QModelIndex index) const;// { return WrapperInterface::addrTypeAt(index); } 67 | protected: 68 | virtual int getFID(const QModelIndex &index) const { return index.column() - VALUE; } 69 | virtual int getSID(const QModelIndex &index) const { return index.column(); } 70 | 71 | enum FieldID { 72 | NONE = FIELD_NONE, 73 | OFFSET = 0, 74 | ORDINAL, 75 | VALUE, 76 | NAME_RVA, 77 | NAME, 78 | FORWARDER, 79 | MAX_COL 80 | }; 81 | }; 82 | -------------------------------------------------------------------------------- /pe-bear/gui/pe_models/FileHdrTreeModel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include 5 | #include 6 | #include "../../gui_base/PeTreeView.h" 7 | #include "../PeWrapperModel.h" 8 | 9 | class FileHdrTreeItem : public PeTreeItem 10 | { 11 | Q_OBJECT 12 | 13 | protected: 14 | enum ViewLevel { DESC = 0, DETAILS = 1 }; 15 | typedef enum ViewLevel level_t; 16 | 17 | QList childItems; 18 | FileHdrTreeItem *parentItem; 19 | level_t level; 20 | FileHdrWrapper::FieldID role; 21 | 22 | public: 23 | FileHdrTreeItem(PeHandler *peHndl, level_t level = DESC, FileHdrWrapper::FieldID role = FileHdrWrapper::NONE, FileHdrTreeItem *parent = NULL); 24 | int columnCount() const; 25 | 26 | virtual Qt::ItemFlags flags(int column) const; 27 | virtual QVariant data(int column) const; 28 | 29 | bool setDataValue(int column, const QVariant &value); 30 | virtual QVariant foreground(int column) const; 31 | virtual QVariant background(int column) const; 32 | 33 | /* PEGuiItem interface */ 34 | virtual offset_t getContentOffset() const; 35 | virtual bufsize_t getContentSize() const; 36 | 37 | protected: 38 | virtual bool isChildOk(TreeItem* child) { FileHdrTreeItem *ptr = dynamic_cast(child); return (child)? true : false; } 39 | 40 | FileHdrWrapper &fileHdr; 41 | 42 | friend class FileHdrTreeModel; 43 | }; 44 | 45 | //------------------- 46 | 47 | class FileHdrCharactTreeItem : public FileHdrTreeItem 48 | { 49 | Q_OBJECT 50 | public: 51 | FileHdrCharactTreeItem(PeHandler *peHndl, level_t level = DESC, DWORD characteristics = 0, FileHdrTreeItem *parent = NULL); 52 | virtual QVariant data(int column) const; 53 | void loadChildren(); 54 | 55 | protected: 56 | DWORD characteristics; 57 | }; 58 | 59 | //------------------- 60 | 61 | class FileHdrTreeModel : public PeWrapperModel 62 | { 63 | Q_OBJECT 64 | 65 | protected slots: 66 | void reload(); 67 | 68 | public: 69 | FileHdrTreeModel(PeHandler *peHndl, QObject *parent = 0); 70 | virtual ~FileHdrTreeModel() { } 71 | 72 | QVariant data(const QModelIndex &index, int role) const; 73 | bool setData(const QModelIndex &, const QVariant &, int); 74 | QVariant headerData(int section, Qt::Orientation orientation, int role) const; 75 | Qt::ItemFlags flags(const QModelIndex &index) const; 76 | 77 | virtual bool containsValue(QModelIndex index) const; 78 | 79 | /* PEGuiItem interface */ 80 | virtual offset_t getContentOffset() const; 81 | virtual bufsize_t getContentSize() const; 82 | 83 | protected: 84 | virtual ExeElementWrapper* wrapper() const { return &myPeHndl->fileHdrWrapper; } 85 | 86 | private: 87 | FileHdrCharactTreeItem *charactItem; 88 | }; 89 | -------------------------------------------------------------------------------- /pe-bear/gui/pe_models/ImportsTreeModel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "../../gui_base/WrapperTableModel.h" 8 | 9 | 10 | class ImportsTreeModel : public WrapperTableModel 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | ImportsTreeModel(PeHandler *peHndl, QObject *parent = 0) 16 | : WrapperTableModel(peHndl, parent) 17 | { 18 | } 19 | 20 | virtual int columnCount(const QModelIndex &parent) const; 21 | 22 | virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; 23 | virtual QVariant data(const QModelIndex &index, int role) const; 24 | 25 | virtual bool setData(const QModelIndex &index, const QVariant &value, int role); 26 | virtual Qt::ItemFlags flags(const QModelIndex &index) const; 27 | 28 | virtual bool containsValue(QModelIndex index) const { return true; } 29 | 30 | protected: 31 | virtual int getFID(const QModelIndex &index) const { return index.column() - ADDED_COLS_NUM; } 32 | virtual int getSID(const QModelIndex &index) const { return index.row(); } 33 | 34 | virtual ExeElementWrapper* wrapper() const { return &myPeHndl->importDirWrapper; } 35 | virtual ExeElementWrapper* wrapperAt(QModelIndex index) const; 36 | 37 | inline int32_t columnToFID(int column) const { return column - ADDED_COLS_NUM; } 38 | inline int32_t FIDtoColumn(int fId) const { return (fId + ADDED_COLS_NUM); } 39 | 40 | virtual bool isComplexValue(const QModelIndex &index) const { if (index.column() >= ADDED_COLS_NUM) return true; return false; } 41 | 42 | enum FieldID { 43 | NONE = FIELD_NONE, 44 | OFFSET, 45 | NAME, 46 | FUNC_NUM, 47 | IS_BOUND, 48 | ADDED_COLS_NUM 49 | }; 50 | }; 51 | 52 | //---------------------------------------------------------------------- 53 | 54 | class ImportedFuncModel : public WrapperTableModel 55 | { 56 | Q_OBJECT 57 | 58 | public slots: 59 | void setParentId(size_t libraryId) { this->libraryId = libraryId; reset(); } 60 | 61 | public: 62 | ImportedFuncModel(PeHandler *peHndl, QObject *parent = 0); 63 | 64 | virtual int columnCount(const QModelIndex &parent) const; 65 | virtual int rowCount(const QModelIndex &parent) const; 66 | 67 | virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; 68 | virtual QVariant data(const QModelIndex &index, int role) const; 69 | 70 | virtual bool setData(const QModelIndex &index, const QVariant &value, int role); 71 | virtual Qt::ItemFlags flags(const QModelIndex &index) const; 72 | 73 | virtual Executable::addr_type offsetAddrType() const { return Executable::RVA; } 74 | virtual bool containsValue(QModelIndex index) const { return true; } 75 | 76 | protected: 77 | virtual ImportEntryWrapper* wrapper() const; 78 | virtual ExeElementWrapper* wrapperAt(QModelIndex index) const; 79 | 80 | virtual bool isComplexValue(const QModelIndex &index) const { return false; } 81 | 82 | virtual int getFID(const QModelIndex &index) const { return index.column() - ADDED_COLS_NUM; } 83 | virtual int getSID(const QModelIndex &index) const { return index.row(); } 84 | 85 | inline int32_t columnToFID(int column) const { return (column - ADDED_COLS_NUM); } 86 | inline int32_t FIDtoColumn(int fId) const { return (fId + ADDED_COLS_NUM); } 87 | 88 | enum FieldID { 89 | NONE = FIELD_NONE, 90 | CALL_VIA, 91 | NAME, 92 | ORDINAL, 93 | ADDED_COLS_NUM 94 | }; 95 | size_t libraryId; 96 | }; 97 | -------------------------------------------------------------------------------- /pe-bear/gui/pe_models/RelocsTreeModel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "../../gui_base/WrapperTableModel.h" 8 | 9 | class RelocsTreeModel : public WrapperTableModel 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | RelocsTreeModel(PeHandler *peHndl, QObject *parent = 0) 15 | : WrapperTableModel(peHndl, parent) 16 | { 17 | } 18 | 19 | virtual int columnCount(const QModelIndex &parent) const; 20 | 21 | virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; 22 | virtual QVariant data(const QModelIndex &index, int role) const; 23 | virtual bool setData(const QModelIndex &index, const QVariant &value, int role); 24 | 25 | virtual bool containsValue(QModelIndex index) const { return (getFID(index) < RelocBlockWrapper::ENTRIES_PTR); } 26 | 27 | protected: 28 | virtual int getFID(const QModelIndex &index) const { return index.column() - ADDED_COLS_NUM; } 29 | virtual int getSID(const QModelIndex &index) const { return index.column(); } 30 | 31 | virtual ExeElementWrapper* wrapper() const { return &myPeHndl->relocDirWrapper; } 32 | virtual ExeElementWrapper* wrapperAt(QModelIndex index) const; 33 | 34 | inline int32_t columnToFID(int column) const { return column - ADDED_COLS_NUM; } 35 | inline int32_t FIDtoColumn(int fId) const { return (fId + ADDED_COLS_NUM); } 36 | 37 | virtual bool isComplexValue(const QModelIndex &index) const { if (index.column() >= ADDED_COLS_NUM) return true; return false; } 38 | 39 | enum FieldID { 40 | NONE = FIELD_NONE, 41 | OFFSET, 42 | ADDED_COLS_NUM 43 | }; 44 | friend class RelocsTreeView; 45 | }; 46 | 47 | 48 | class RelocEntriesModel : public WrapperTableModel 49 | { 50 | Q_OBJECT 51 | 52 | public slots: 53 | void setParentId(size_t parentId) { this->parentId = parentId; reset(); } 54 | 55 | public: 56 | RelocEntriesModel(PeHandler *peHndl, QObject *parent = 0) 57 | : WrapperTableModel(peHndl, parent), parentId(0) 58 | { 59 | } 60 | 61 | int rowCount(const QModelIndex &parent) const; 62 | int columnCount(const QModelIndex &parent) const { return MAX_COL; } 63 | 64 | QVariant data(const QModelIndex &index, int role) const; 65 | QVariant headerData(int section, Qt::Orientation orientation, int role) const; 66 | 67 | virtual bool containsValue(QModelIndex index) const { return index.column() == VALUE; } 68 | virtual ExeElementWrapper* wrapper() const { return myPeHndl->relocDirWrapper.getEntryAt(parentId);} 69 | virtual ExeElementWrapper* wrapperAt(QModelIndex index) const;// 70 | 71 | Executable::addr_type addrTypeAt(QModelIndex index) const; 72 | 73 | protected: 74 | virtual int getFID(const QModelIndex &index) const { return index.row(); } 75 | virtual int getSID(const QModelIndex &index) const { return index.column(); } 76 | 77 | enum FieldID { 78 | NONE = FIELD_NONE, 79 | OFFSET = 0, 80 | VALUE, 81 | TYPE, 82 | DELTA, 83 | RELOC_RVA, 84 | MAX_COL 85 | }; 86 | 87 | size_t parentId; 88 | }; 89 | -------------------------------------------------------------------------------- /pe-bear/gui/pe_models/RichHdrTreeModel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include 5 | #include 6 | #include "../../gui_base/PeTreeView.h" 7 | #include "../../gui_base/WrapperTableModel.h" 8 | #include "../../gui/PeTreeModel.h" 9 | 10 | class RichHdrTreeItem : public PeTreeItem 11 | { 12 | Q_OBJECT 13 | 14 | protected: 15 | RichHdrWrapper::FieldID role; 16 | 17 | public: 18 | RichHdrTreeItem(PeHandler *peHndl, RichHdrWrapper::FieldID role = RichHdrWrapper::NONE, RichHdrTreeItem *parent = NULL); 19 | int columnCount() const; 20 | 21 | virtual Qt::ItemFlags flags(int column) const; 22 | virtual QVariant data(int column) const; 23 | 24 | bool setDataValue(int column, const QVariant &value); 25 | virtual QVariant foreground(int column) const; 26 | virtual QVariant background(int column) const; 27 | 28 | /* PEGuiItem interface */ 29 | virtual offset_t getContentOffset() const; 30 | virtual bufsize_t getContentSize() const; 31 | 32 | protected: 33 | virtual bool isChildOk(TreeItem* child) { RichHdrTreeItem *ptr = dynamic_cast(child); return (child)? true : false; } 34 | 35 | RichHdrWrapper* getRichHdr() const 36 | { 37 | if (!myPeHndl) return NULL; 38 | return &myPeHndl->richHdrWrapper; 39 | } 40 | 41 | QColor approvedColor; 42 | 43 | friend class RichHdrTreeModel; 44 | }; 45 | 46 | 47 | class RichHdrTreeModel : public WrapperTableModel 48 | { 49 | Q_OBJECT 50 | 51 | protected slots: 52 | void onNeedReset(); 53 | 54 | public: 55 | RichHdrTreeModel(PeHandler *peHndl, QObject *parent = 0); 56 | virtual ~RichHdrTreeModel() { } 57 | 58 | virtual int columnCount(const QModelIndex &parent) const; 59 | 60 | QVariant data(const QModelIndex &index, int role) const; 61 | bool setData(const QModelIndex &, const QVariant &, int); 62 | QVariant headerData(int section, Qt::Orientation orientation, int role) const; 63 | Qt::ItemFlags flags(const QModelIndex &index) const; 64 | 65 | virtual bool containsValue(QModelIndex index) const; 66 | 67 | /* PEGuiItem interface */ 68 | virtual offset_t getContentOffset() const; 69 | virtual bufsize_t getContentSize() const; 70 | 71 | protected: 72 | virtual ExeElementWrapper* wrapper() const { return &myPeHndl->richHdrWrapper; } 73 | }; 74 | -------------------------------------------------------------------------------- /pe-bear/gui/pe_models/SecHdrsTreeModel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "../../gui_base/PeTreeView.h" 8 | #include "../TreeModel.h" 9 | #include "../PeTreeModel.h" 10 | 11 | class SecHdrsTreeModel; 12 | class SecTreeItem : public PeTreeItem 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | static QStringList fetchSecHdrCharact(DWORD characteristics); 18 | 19 | //--- 20 | SecTreeItem(PeHandler* peHndl, int secIndx = (-1), int level = 0, SecTreeItem *parent = NULL); 21 | 22 | int columnCount() const; 23 | 24 | QVariant foreground(int column) const; 25 | QVariant background(int column) const; 26 | QVariant toolTip(int column) const; 27 | 28 | QVariant edit(int column) const; 29 | Qt::ItemFlags flags(int column) const; 30 | QVariant data(int column) const; 31 | 32 | public slots: 33 | /* PEGuiItem interface */ 34 | virtual offset_t getContentOffset() const; 35 | virtual bufsize_t getContentSize() const; 36 | 37 | protected: 38 | void updateSectionsList(); 39 | virtual bool isChildOk(TreeItem* child) { return (dynamic_cast(child) != 0); } 40 | virtual bool setDataValue(int column, const QVariant &value); 41 | 42 | inline SectionHdrWrapper* getMySection() const; 43 | 44 | private: 45 | int secIndx; 46 | int level; 47 | 48 | friend class SecHdrsTreeModel; 49 | }; 50 | 51 | 52 | class SecHdrsTreeModel : public PeTreeModel 53 | { 54 | Q_OBJECT 55 | 56 | signals: 57 | void sectionHdrsModified(PEFile* m_PE); 58 | 59 | public slots: 60 | void onSectionNumChanged(); 61 | 62 | public: 63 | SecHdrsTreeModel(PeHandler* peHndl, QObject *parent = 0); 64 | ~SecHdrsTreeModel() { } 65 | 66 | virtual QVariant data(const QModelIndex &index, int role) const override; 67 | bool setData(const QModelIndex &index, const QVariant &value, int role); 68 | QVariant headerData(int section, Qt::Orientation orientation, int role) const; 69 | Qt::ItemFlags flags(const QModelIndex &index) const; 70 | 71 | virtual Executable::addr_type addrTypeAt(QModelIndex index) const; 72 | 73 | /* PEGuiItem interface */ 74 | virtual offset_t getContentOffset() const; 75 | virtual bufsize_t getContentSize() const; 76 | }; 77 | -------------------------------------------------------------------------------- /pe-bear/gui/pe_models/SecurityTreeModel.cpp: -------------------------------------------------------------------------------- 1 | #include "SecurityTreeModel.h" 2 | 3 | //----------------------------------------------------------------------------- 4 | 5 | QVariant SecurityTreeModel::headerData(int section, Qt::Orientation orientation, int role) const 6 | { 7 | if (role != Qt::DisplayRole) return QVariant(); 8 | 9 | switch (section) { 10 | case OFFSET: return tr("Offset"); 11 | case NAME: return tr("Name"); 12 | case VALUE : return tr("Value"); 13 | case VALUE2: return tr("Meaning"); 14 | } 15 | return QVariant(); 16 | } 17 | 18 | QVariant SecurityTreeModel::data(const QModelIndex &index, int role) const 19 | { 20 | SecurityDirWrapper* wrap = dynamic_cast(wrapper()); 21 | if (!wrap) return QVariant(); 22 | 23 | int column = index.column(); 24 | if (role == Qt::ForegroundRole) return this->addrColor(index); 25 | if (role == Qt::FontRole) { 26 | if (this->containsOffset(index) || this->containsValue(index)) { 27 | return offsetFont; 28 | } 29 | return QVariant(); 30 | } 31 | if (role == Qt::ToolTipRole) return toolTip(index); 32 | 33 | if (role != Qt::DisplayRole && role != Qt::EditRole) return QVariant(); 34 | int fId = getFID(index); 35 | switch (column) { 36 | case OFFSET: return QString::number(getFieldOffset(index), 16); 37 | case NAME: return (wrap->getFieldName(fId)); 38 | case VALUE2: return wrap->translateFieldContent(fId); 39 | } 40 | return dataValue(index); 41 | } 42 | 43 | //---------------------------------------------------------------------------- 44 | -------------------------------------------------------------------------------- /pe-bear/gui/pe_models/SecurityTreeModel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "../../gui_base/WrapperTableModel.h" 8 | 9 | 10 | class SecurityTreeModel : public WrapperTableModel 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | SecurityTreeModel(PeHandler *peHndl, QObject *parent = 0) 16 | : WrapperTableModel(peHndl, parent) {} 17 | 18 | virtual int columnCount(const QModelIndex &parent) const { return COLS_NUM; } 19 | 20 | virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; 21 | virtual QVariant data(const QModelIndex &index, int role) const; 22 | 23 | virtual bool containsValue(QModelIndex index) const { return (index.column() == VALUE); } 24 | 25 | protected: 26 | virtual int getFID(QModelIndex index) const { return index.row(); } 27 | virtual int getSID(QModelIndex index) const { return index.column(); } 28 | 29 | virtual ExeElementWrapper* wrapper() const { return &myPeHndl->securityDirWrapper; } 30 | 31 | enum cols { 32 | OFFSET, 33 | NAME, 34 | VALUE, 35 | VALUE2, 36 | COLS_NUM 37 | }; 38 | friend class SecurityTreeView; 39 | }; 40 | -------------------------------------------------------------------------------- /pe-bear/gui/pe_models/TLSTreeModel.cpp: -------------------------------------------------------------------------------- 1 | #include "TLSTreeModel.h" 2 | 3 | ///------------------------ 4 | 5 | QVariant TLSTreeModel::data(const QModelIndex &index, int role) const 6 | { 7 | if (role == Qt::ForegroundRole) return this->addrColor(index); 8 | 9 | if (role == Qt::ToolTipRole) return toolTip(index); 10 | if (role == Qt::FontRole) { 11 | if (index.column() != COL_NAME) return offsetFont; 12 | return QVariant(); 13 | } 14 | 15 | int row = index.row(); 16 | int column = index.column(); 17 | int fId = this->getFID(index); 18 | 19 | if (role != Qt::DisplayRole && role != Qt::EditRole) return QVariant(); 20 | 21 | switch (column) { 22 | case COL_OFFSET: return QString::number(getFieldOffset(index), 16); 23 | case COL_NAME: return (wrapper()->getFieldName(fId)); 24 | } 25 | bool isOk = false; 26 | uint64_t val = wrapper()->getNumValue(fId, &isOk); 27 | if (!isOk) return "UNK"; 28 | 29 | return QString::number(val, 16); 30 | } 31 | 32 | QVariant TLSTreeModel::headerData(int section, Qt::Orientation orientation, int role) const 33 | { 34 | if(role != Qt::DisplayRole) return QVariant(); 35 | switch (section) { 36 | case COL_OFFSET : return tr("Offset"); 37 | case COL_NAME : return tr("Name"); 38 | case COL_VALUE : return tr("Value"); 39 | } 40 | return QVariant(); 41 | } 42 | 43 | QString TLSTreeModel::makeDockerTitle(size_t upId) 44 | { 45 | ExeNodeWrapper *w = dynamic_cast(wrapper()); 46 | if (w == NULL) return ""; 47 | size_t entriesNum = w->getEntriesNum(); 48 | 49 | std::string name = "TLS Callbacks"; 50 | QString numDesc = entriesNum == 1 ? tr(" entry") : tr(" entries"); 51 | QString desc = QString::fromStdString(name) + " [ " + QString::number(entriesNum) + numDesc + " ]"; 52 | return desc; 53 | } 54 | 55 | //----------------------------------------------------------------------------------- 56 | 57 | int TLSCallbacksModel::rowCount(const QModelIndex &parent) const 58 | { 59 | ExeNodeWrapper *w = dynamic_cast(wrapper()); 60 | if (w == NULL) return 0; 61 | 62 | return w->getEntriesNum(); 63 | } 64 | 65 | QVariant TLSCallbacksModel::data(const QModelIndex &index, int role) const 66 | { 67 | if (role == Qt::ForegroundRole) return this->addrColor(index); 68 | 69 | if (role == Qt::ToolTipRole) return toolTip(index); 70 | if (role == Qt::FontRole) return offsetFont; 71 | 72 | int row = index.row(); 73 | int column = index.column(); 74 | int fId = this->getFID(index); 75 | 76 | if (role != Qt::DisplayRole && role != Qt::EditRole) return QVariant(); 77 | 78 | switch (column) { 79 | case OFFSET: return QString::number(getFieldOffset(index), 16); 80 | } 81 | bool isOk = false; 82 | uint64_t val = wrapperAt(index)->getNumValue(0, &isOk); 83 | if (!isOk) return "UNK"; 84 | 85 | return QString::number(val, 16); 86 | } 87 | 88 | QVariant TLSCallbacksModel::headerData(int section, Qt::Orientation orientation, int role) const 89 | { 90 | if(role != Qt::DisplayRole) return QVariant(); 91 | switch (section) { 92 | case OFFSET : return tr("Offset"); 93 | case VALUE : return tr("Callback"); 94 | } 95 | return QVariant(); 96 | } 97 | -------------------------------------------------------------------------------- /pe-bear/gui/pe_models/TLSTreeModel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | #include "../../gui_base/WrapperTableModel.h" 8 | 9 | class TLSTreeModel : public WrapperTableModel 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | TLSTreeModel(PeHandler *peHndl, QObject *parent = 0) 15 | : WrapperTableModel(peHndl, parent) 16 | { 17 | } 18 | 19 | int columnCount(const QModelIndex &parent) const { return MAX_COL; } 20 | 21 | QVariant data(const QModelIndex &index, int role) const; 22 | QVariant headerData(int section, Qt::Orientation orientation, int role) const; 23 | 24 | virtual bool containsValue(QModelIndex index) const { return index.column() == COL_VALUE; } 25 | virtual ExeElementWrapper* wrapper() const { return &myPeHndl->tlsDirWrapper; } 26 | 27 | virtual QString makeDockerTitle(size_t upId); 28 | 29 | protected: 30 | virtual int getFID(const QModelIndex &index) const { return index.row(); } 31 | virtual int getSID(const QModelIndex &index) const { return index.column(); } 32 | 33 | enum FieldID { 34 | NONE = FIELD_NONE, 35 | COL_OFFSET = 0, 36 | COL_NAME, 37 | COL_VALUE, 38 | MAX_COL 39 | }; 40 | }; 41 | 42 | //------------------------------------------------------------------------------------------- 43 | 44 | class TLSCallbacksModel : public WrapperTableModel 45 | { 46 | Q_OBJECT 47 | 48 | public: 49 | TLSCallbacksModel(PeHandler *peHndl, QObject *parent = 0) 50 | : WrapperTableModel(peHndl, parent) 51 | { 52 | } 53 | 54 | int rowCount(const QModelIndex &parent) const; 55 | int columnCount(const QModelIndex &parent) const { return MAX_COL; } 56 | 57 | QVariant data(const QModelIndex &index, int role) const; 58 | QVariant headerData(int section, Qt::Orientation orientation, int role) const; 59 | 60 | virtual bool containsValue(QModelIndex index) const { return index.column() == VALUE; } 61 | virtual ExeElementWrapper* wrapper() const { return &myPeHndl->tlsDirWrapper; } 62 | virtual ExeElementWrapper* wrapperAt(QModelIndex index) const { return myPeHndl->tlsDirWrapper.getEntryAt(getFID(index)); } 63 | 64 | protected: 65 | virtual int getFID(const QModelIndex &index) const { return index.row(); } 66 | virtual int getSID(const QModelIndex &index) const { return index.column(); } 67 | 68 | enum FieldID { 69 | NONE = FIELD_NONE, 70 | OFFSET = 0, 71 | VALUE, 72 | MAX_COL 73 | }; 74 | }; -------------------------------------------------------------------------------- /pe-bear/gui/windows/DiffWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "../../PEFileTreeModel.h" 7 | #include "../../gui/HexDiffModel.h" 8 | #include "../../gui_base/ExtTableView.h" 9 | 10 | #include "../../HexCompareView.h" 11 | 12 | //---------------------------------------------------- 13 | 14 | class DiffWindow : public QMainWindow 15 | { 16 | Q_OBJECT 17 | 18 | public: 19 | DiffWindow(PeHandlersManager &peManager, QWidget *parent); 20 | 21 | signals: 22 | void contentChanged(BYTE* contentPtr, int size, offset_t startOffset, ContentIndx indx); 23 | void contentCleared(ContentIndx indx); 24 | void addrFormatChanged(int fmt); 25 | 26 | public slots: 27 | void refresh(); 28 | void file1Selected(const QString &text); 29 | void file2Selected(const QString &text); 30 | void item1Marked(const QModelIndex & current, const QModelIndex & previous); 31 | void item2Marked(const QModelIndex & current, const QModelIndex & previous); 32 | 33 | void hexSelectedL(); 34 | void hexSelectedR(); 35 | void hexSelected(ContentIndx contentIndx); 36 | 37 | void changeHexViewSettings(HexViewSettings &_settings) 38 | { 39 | hexDumpModelL.changeSettings(_settings); 40 | hexDumpModelR.changeSettings(_settings); 41 | } 42 | 43 | void onGlobalFontChanged() 44 | { 45 | resizeComponents(); 46 | } 47 | 48 | private slots: 49 | void onSliderMoved(int val); 50 | void onAddrFormatSelected(int val); 51 | 52 | protected: 53 | void resizeComponents(); 54 | bool createFormatChanger(ContentIndx indx, QToolBar* parent); 55 | bool reselectPrevious(QList &stringsList, ContentIndx contentIndx); 56 | void createActions(); 57 | void destroyActions(); 58 | 59 | void removeUnusedTreeModels(); 60 | void setTreeModel(QTreeView &treeView, const QString &text); 61 | void setPEContent(const QString &fileName, int offset, ContentIndx contentIndx); 62 | void itemMarked(const QModelIndex & current, const QModelIndex &previous, QTreeView &treeView, ContentIndx contentIndx); 63 | 64 | PeHandlersManager &peManger; 65 | std::map peModels; 66 | 67 | QSplitter mainSplitter; 68 | QSplitter leftSplitter, rightSplitter; 69 | QTreeView PEsTree1, PEsTree2; 70 | 71 | QComboBox fileCombo[CNTR]; 72 | QTreeView treeView[CNTR]; 73 | 74 | HexDiffModel hexDumpModelL, hexDumpModelR; 75 | HexCompareView fileView[CNTR]; 76 | QScrollBar fileScrollBar[CNTR]; 77 | 78 | QTextEdit numEdit[CNTR]; 79 | 80 | offset_t contentOffset[CNTR]; 81 | BYTE* contentPtr[CNTR]; 82 | size_t contentSize[CNTR]; 83 | 84 | QToolBar toolBars[CNTR]; 85 | QComboBox addrFmtBox[CNTR]; 86 | QStatusBar statusBar; 87 | 88 | QAction *setHexView; 89 | QAction *nextDiff; 90 | 91 | QString currName[CNTR]; 92 | }; 93 | 94 | -------------------------------------------------------------------------------- /pe-bear/gui/windows/OffsetsBrowseWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include 5 | 6 | #include "../../QtCompat.h" 7 | #include "../../base/PeHandlersManager.h" 8 | #include "../../gui_base/FollowablePeTreeView.h" 9 | #include "../../gui_base/OffsetDependentAction.h" 10 | #include "../../gui/CommentView.h" 11 | 12 | //---------------------------------------------------- 13 | 14 | class OffsetsBrowseModel : public PeTableModel 15 | { 16 | Q_OBJECT 17 | 18 | public: 19 | OffsetsBrowseModel(PeHandler *peHndl, QObject *parent = 0) 20 | : PeTableModel(peHndl, parent) {} 21 | 22 | QVariant headerData(int section, Qt::Orientation orientation, int role) const; 23 | Qt::ItemFlags flags(const QModelIndex &index) const; 24 | 25 | int columnCount(const QModelIndex &parent) const { return MAX_COL; } 26 | int rowCount(const QModelIndex &parent) const; 27 | 28 | virtual Executable::addr_type addrTypeAt(QModelIndex index) const 29 | { 30 | return (index.column() == COL_OFFSET) ? Executable::RVA : Executable::NOT_ADDR; 31 | } 32 | 33 | QVariant data(const QModelIndex &index, int role) const; 34 | bool setData(const QModelIndex &, const QVariant &, int); 35 | 36 | QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const 37 | { 38 | return createIndex(row, column); //no index item pointer 39 | } 40 | 41 | QModelIndex parent(const QModelIndex &index) const 42 | { 43 | return QModelIndex(); 44 | } 45 | 46 | offset_t getFieldOffset(QModelIndex index) const; 47 | bufsize_t getFieldSize(QModelIndex index) const; 48 | 49 | enum COLS { 50 | COL_OFFSET = 0, 51 | COL_ID, 52 | COL_NAME, 53 | MAX_COL 54 | }; 55 | 56 | }; 57 | 58 | //---------------------------------------------------- 59 | 60 | class OffsetsBrowseWindow : public QMainWindow 61 | { 62 | Q_OBJECT 63 | 64 | protected slots: 65 | void onSaveComment() 66 | { 67 | if (this->commentsView) this->commentsView->onSaveComments(); 68 | } 69 | 70 | void onLoadComment() 71 | { 72 | if (this->commentsView) this->commentsView->onLoadComments(); 73 | } 74 | 75 | public: 76 | OffsetsBrowseWindow(PeHandler *peHndlr, QWidget *parent); 77 | virtual ~OffsetsBrowseWindow(); 78 | 79 | protected: 80 | /* events */ 81 | void dragEnterEvent(QDragEnterEvent* ev) { ev->accept(); } 82 | void dropEvent(QDropEvent* event); 83 | 84 | private: 85 | void createMenu(); 86 | FollowablePeTreeView tagsTree; 87 | CommentView *commentsView; 88 | OffsetsBrowseModel *tagModel; 89 | 90 | }; 91 | -------------------------------------------------------------------------------- /pe-bear/gui/windows/PatternSearchWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include 5 | 6 | #include "../../QtCompat.h" 7 | #include "../../base/PeHandler.h" 8 | #include "../../base/threads/SignFinderThread.h" 9 | #include "../../gui_base/HexSpinBox.h" 10 | 11 | //--- 12 | class PatternSearchWindow : public QDialog 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | PatternSearchWindow(QWidget *parent, PeHandler* peHndl); 18 | ~PatternSearchWindow() 19 | { 20 | if (threadMngr) { 21 | delete threadMngr; 22 | } 23 | } 24 | 25 | int exec() 26 | { 27 | if (!m_peHndl) return QDialog::Rejected; 28 | 29 | PEFile* peFile = this->m_peHndl->getPe(); 30 | if (!peFile) return QDialog::Rejected; 31 | 32 | offset_t maxOffset = peFile->getContentSize(); 33 | offset_t offset = m_peHndl->getDisplayedOffset(); 34 | 35 | startOffsetBox.setRange(0, maxOffset); 36 | startOffsetBox.setValue(offset); 37 | return QDialog::exec(); 38 | } 39 | 40 | protected slots: 41 | void onSearchClicked(); 42 | 43 | void matchesFound(MatchesCollection *thread); 44 | void onProgressUpdated(int progress); 45 | void onSearchStarted(bool isStarted); 46 | 47 | protected: 48 | QString fetchSignature(); 49 | 50 | QVBoxLayout topLayout; 51 | QHBoxLayout secPropertyLayout2; 52 | QHBoxLayout secPropertyLayout3; 53 | QHBoxLayout secPropertyLayout4; 54 | QHBoxLayout buttonLayout; 55 | 56 | QLabel patternLabel; 57 | QLineEdit patternEdit; 58 | 59 | QLabel offsetLabel; 60 | HexSpinBox startOffsetBox; 61 | QProgressBar progressBar; 62 | 63 | QPushButton searchButton; 64 | 65 | PeHandler* m_peHndl; 66 | SignFinderThreadManager *threadMngr; 67 | }; 68 | -------------------------------------------------------------------------------- /pe-bear/gui/windows/SectionAddWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "../../QtCompat.h" 5 | #include "../../base/PeHandlersManager.h" 6 | #include "../../gui_base/HexSpinBox.h" 7 | 8 | class SectionAddWindow : public QDialog 9 | { 10 | Q_OBJECT 11 | 12 | public: 13 | SectionAddWindow(QWidget *parent); 14 | ~SectionAddWindow() { } 15 | 16 | public slots: 17 | void onAddSectionToPe(PeHandler *peHndl); 18 | void onOkClicked(); 19 | void onFileChose(); 20 | 21 | protected: 22 | QVBoxLayout topLayout; 23 | QHBoxLayout secPropertyLayout; 24 | QHBoxLayout secPropertyLayout2; 25 | QHBoxLayout secPropertyLayout3; 26 | QHBoxLayout buttonLayout; 27 | 28 | QLabel secRsizeLabel; 29 | HexSpinBox secRsizeEdit; 30 | 31 | QLabel secVsizeLabel; 32 | HexSpinBox secVsizeEdit; 33 | 34 | QLabel secNameLabel; 35 | QLineEdit secNameEdit; 36 | 37 | enum access { READ = 0, WRITE, EXEC, ACCESS_NUM }; 38 | QCheckBox fileCBox; 39 | QCheckBox rightsCBox[ACCESS_NUM]; 40 | 41 | QPushButton fileButton, okButton, cancelButton; 42 | PeHandler *currPeHndl; 43 | QString filePath; 44 | }; 45 | -------------------------------------------------------------------------------- /pe-bear/gui/windows/UserConfigWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "../../QtCompat.h" 5 | #include "../../base/MainSettings.h" 6 | 7 | //---------------------------------------------------- 8 | 9 | class DirEdit : public QLineEdit 10 | { 11 | Q_OBJECT 12 | public: 13 | DirEdit(QWidget* parent = 0); 14 | 15 | protected slots: 16 | void validateDir(const QString &path); 17 | }; 18 | 19 | //---------------------------------------------------- 20 | 21 | class UserConfigWindow : public QDialog 22 | { 23 | Q_OBJECT 24 | 25 | public: 26 | UserConfigWindow(QWidget *parent = 0); 27 | void setMainSettings(MainSettings *settings); 28 | 29 | t_reload_mode getReloadMode(); 30 | void setReloadMode(const t_reload_mode rMode); 31 | 32 | protected slots: 33 | void refreshSettingsView(); 34 | void onDirChose(); 35 | 36 | private slots: 37 | void onOkClicked(); 38 | 39 | protected: 40 | void showEvent(QShowEvent * ev) { refreshSettingsView(); QDialog::showEvent(ev); } 41 | 42 | private: 43 | int getLanguageIndex(const QString &lang); 44 | int loadAvailableTranslations(const QString &rootDir); 45 | 46 | QVBoxLayout topLayout; 47 | QPushButton dirButton, okButton, cancelButton; 48 | QLabel uddDirLabel; 49 | DirEdit uddDirEdit; 50 | QLabel languageLabel; 51 | QComboBox languageEdit; 52 | 53 | QLabel reloadFileLabel; 54 | QComboBox reloadFileStates; 55 | QCheckBox autoSaveTagsCBox; 56 | 57 | MainSettings *settings; 58 | }; 59 | 60 | -------------------------------------------------------------------------------- /pe-bear/gui_base/AddressInputDialog.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "HexInputDialog.h" 6 | #include 7 | 8 | #include "../base/MainSettings.h" 9 | 10 | class AddressInputDialog : public HexInputDialog 11 | { 12 | Q_OBJECT 13 | protected slots: 14 | void onAddrTypeChanged(); 15 | void onAddrChanged(); 16 | 17 | public: 18 | AddressInputDialog(Executable *exe, bool isRaw, ColorSettings &addrColors, QWidget *parent); 19 | ~AddressInputDialog() 20 | { 21 | delete otherEdit; 22 | delete otherCaptionLabel; 23 | delete cbox_isRva; 24 | } 25 | 26 | Executable::addr_type getAddrType(); 27 | 28 | protected: 29 | offset_t convertToOther(offset_t val, Executable::addr_type aT); 30 | void validateAddr(); 31 | void setTextColor(); 32 | void setDescriptions(); 33 | 34 | Executable *myExe; 35 | ColorSettings &addrColors; 36 | 37 | QCheckBox *cbox_isRva; 38 | QLabel *otherCaptionLabel; 39 | QLineEdit *otherEdit; 40 | 41 | bool isRawAddr; 42 | }; 43 | 44 | -------------------------------------------------------------------------------- /pe-bear/gui_base/ClipboardUtil.cpp: -------------------------------------------------------------------------------- 1 | #include "ClipboardUtil.h" 2 | #include "../QtCompat.h" 3 | 4 | int ClipboardUtil::byteArrayToBuffer(QByteArray bytes, uchar *buf, int bufSize) 5 | { 6 | int size = bytes.size(); 7 | 8 | int clipIndx = 0; 9 | for (; clipIndx < size && clipIndx < bufSize; clipIndx++) { 10 | uchar b = bytes.at(clipIndx); 11 | if (buf) buf[clipIndx] = b; 12 | } 13 | return clipIndx; 14 | } 15 | 16 | QByteArray ClipboardUtil::getTextClip() 17 | { 18 | QString text = QApplication::clipboard()->text(); 19 | #if QT_VERSION >= 0x050000 20 | return text.toLatin1(); 21 | #else 22 | return text.toAscii(); 23 | #endif 24 | } 25 | 26 | QByteArray ClipboardUtil::getHexClip() 27 | { 28 | QString text = QApplication::clipboard()->text(); 29 | return parseBytesString(text, " "); 30 | } 31 | 32 | QByteArray ClipboardUtil::getOctetStreamClip() 33 | { 34 | const QMimeData *mimeData = QApplication::clipboard()->mimeData(); 35 | return mimeData->data("application/octet-stream"); 36 | } 37 | 38 | int ClipboardUtil::getFromClipboard(uchar *buf, int bufSize) 39 | { 40 | QByteArray bytes = getOctetStreamClip(); 41 | if (bytes.size() == 0 ) { //no octet stream provided, try to parse text... 42 | bytes = getHexClip(); 43 | if (bytes.size() == 0) bytes = getTextClip(); 44 | } 45 | if (bytes.size() == 0) return 0; 46 | return byteArrayToBuffer(bytes, buf, bufSize); 47 | } 48 | 49 | int ClipboardUtil::getFromClipboard(bool isHex, uchar *buf, int bufSize) 50 | { 51 | QByteArray bytes = getOctetStreamClip(); 52 | if (bytes.size() == 0 ) { //no octet stream provided, try to parse text... 53 | bytes = (isHex) ? getHexClip() : getTextClip(); 54 | } 55 | if (bytes.size() == 0) return 0; 56 | return byteArrayToBuffer(bytes, buf, bufSize); 57 | } 58 | 59 | QByteArray ClipboardUtil::parseBytesString(QString text, QString separator) 60 | { 61 | QByteArray emptyArr; 62 | if (text.length() == 0) return emptyArr; 63 | 64 | QStringList chunks = text.split(separator, QT_SkipEmptyParts); 65 | int size = chunks.size(); 66 | 67 | QByteArray bytes; 68 | //validate 69 | for (int i = 0; i < size; i++ ) { 70 | QString chunk = chunks[i]; 71 | if (chunk.size() != 2) { 72 | return emptyArr; // validation failed 73 | } 74 | 75 | #if QT_VERSION >= 0x050000 76 | char c = chunk[0].toLatin1(); 77 | #else 78 | char c = chunk[0].toAscii(); 79 | #endif 80 | if (!pe_util::isHexChar(c)) { 81 | return emptyArr; // validation failed 82 | } 83 | //validateion ok! 84 | bool isOk; 85 | uchar b = chunks[i].toShort(&isOk, 16); 86 | if (!isOk) return emptyArr; 87 | bytes.append(b); 88 | } 89 | return bytes; 90 | } 91 | 92 | -------------------------------------------------------------------------------- /pe-bear/gui_base/ClipboardUtil.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #if QT_VERSION >= 0x050000 8 | #include 9 | #endif 10 | 11 | #include 12 | 13 | class ClipboardUtil 14 | { 15 | public: 16 | /* Fills given buffer; in: allocated buffer of size bufSize; out: filledSize */ 17 | static int byteArrayToBuffer(QByteArray inArr, uchar *outBuf, int outBufSize); 18 | 19 | static int getFromClipboard(uchar *buf, int bufSize); 20 | static int getFromClipboard(bool isHex, uchar *buf, int bufSize); 21 | 22 | static inline QByteArray getTextClip(); 23 | static inline QByteArray getHexClip(); 24 | static inline QByteArray getOctetStreamClip(); 25 | 26 | static QByteArray parseBytesString(QString string, QString separator); 27 | //---- 28 | }; 29 | -------------------------------------------------------------------------------- /pe-bear/gui_base/ExtTableView.cpp: -------------------------------------------------------------------------------- 1 | #include "ExtTableView.h" 2 | #include 3 | 4 | ExtTableView::ExtTableView(QWidget *parent) 5 | : QTableView(parent), 6 | defaultMenu(this), myMenu(&defaultMenu) 7 | { 8 | init(); 9 | connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(customMenuEvent(QPoint)) ); 10 | enableMenu(false); 11 | } 12 | 13 | void ExtTableView::init() 14 | { 15 | QHeaderView *verticalHdr = this->verticalHeader(); 16 | if (verticalHdr) { 17 | #if QT_VERSION >= 0x050000 18 | verticalHdr->setSectionResizeMode(QHeaderView::ResizeToContents); 19 | #else 20 | verticalHdr->setResizeMode(QHeaderView::ResizeToContents); 21 | #endif 22 | } 23 | QHeaderView *horizontalHdr = this->horizontalHeader(); 24 | if (horizontalHdr) { 25 | #if QT_VERSION >= 0x050000 26 | horizontalHdr->setSectionResizeMode(QHeaderView::ResizeToContents); 27 | #else 28 | horizontalHdr->setResizeMode(QHeaderView::ResizeToContents); 29 | #endif 30 | } 31 | this->setWordWrap(false); 32 | } 33 | 34 | void ExtTableView::enableMenu(bool enable) 35 | { 36 | if (enable) this->setContextMenuPolicy(Qt::CustomContextMenu); 37 | else this->setContextMenuPolicy(Qt::DefaultContextMenu); 38 | } 39 | 40 | void ExtTableView::customMenuEvent(QPoint p) 41 | { 42 | if (myMenu == NULL) return; 43 | QPoint p2 = this->mapToGlobal(p); 44 | this->myMenu->exec(p2); 45 | } 46 | 47 | void ExtTableView::setMenu(QMenu *menu) 48 | { 49 | myMenu = menu; 50 | } 51 | 52 | void ExtTableView::removeAllActions() 53 | { 54 | if (myMenu != NULL) { 55 | QList actList = myMenu->actions(); 56 | for (int i = 0; i < actList.size(); i++) { 57 | myMenu->removeAction(actList[i]); 58 | } 59 | } 60 | } 61 | 62 | void ExtTableView::keyPressEvent(QKeyEvent *kEvent) 63 | { 64 | //the default table copy operation copy only one selected index 65 | if (kEvent->matches(QKeySequence::Copy)) { 66 | copySelected(); 67 | return; 68 | } else if (kEvent->matches(QKeySequence::Paste)) { 69 | pasteToSelected(); 70 | return; 71 | } 72 | QTableView::keyPressEvent(kEvent); 73 | } 74 | 75 | QString ExtTableView::getSelectedText(QString hSeparator, QString vSeperator) 76 | { 77 | QItemSelectionModel *model = this->selectionModel(); 78 | if (!model) return ""; 79 | 80 | QModelIndexList list = model->selectedIndexes(); 81 | std::sort(list.begin(), list.end()); 82 | 83 | int prevRow = -1; 84 | int prevCol = -1; 85 | 86 | const int size = list.size(); 87 | QStringList strings; 88 | 89 | for (int i = 0; i < size; i++) { 90 | 91 | QModelIndex index = list.at(i); 92 | 93 | if (prevRow != (-1) && index.row() != prevRow) { 94 | strings << vSeperator; 95 | } else if (prevCol != (-1)) { 96 | strings << hSeparator; 97 | } 98 | strings << index.data().toString(); 99 | 100 | prevRow = index.row(); 101 | prevCol = index.column(); 102 | } 103 | return strings.join(""); 104 | } 105 | 106 | void ExtTableView::copyText(QString hSeparator, QString vSeperator) 107 | { 108 | QApplication::clipboard()->clear(); 109 | QApplication::clipboard()->setText(getSelectedText(hSeparator, vSeperator)); 110 | } 111 | -------------------------------------------------------------------------------- /pe-bear/gui_base/ExtTableView.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "../QtCompat.h" 5 | 6 | class ExtTableView : public QTableView 7 | { 8 | Q_OBJECT 9 | 10 | public: 11 | ExtTableView(QWidget *parent = 0); 12 | 13 | void setMenu(QMenu *menu); 14 | QMenu* getMenu() { return myMenu; } 15 | void setDefaultMenu() { myMenu = &defaultMenu; } 16 | void enableMenu(bool enable); 17 | void removeAllActions(); 18 | 19 | protected slots: 20 | virtual void copySelected() { return copyText("", "\n"); } 21 | virtual void pasteToSelected() { /* not supported */ } 22 | 23 | virtual void copyText(QString hSeparator, QString vSeperator); 24 | virtual QString getSelectedText(QString hSeparator, QString vSeperator); 25 | virtual void customMenuEvent(QPoint p); 26 | QString errorString() { return lastErrorString; } 27 | 28 | protected: 29 | void init(); 30 | void keyPressEvent(QKeyEvent *kEvent); 31 | 32 | QMenu *myMenu; 33 | QMenu defaultMenu; 34 | QString lastErrorString; 35 | }; 36 | -------------------------------------------------------------------------------- /pe-bear/gui_base/FollowablePeTreeView.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "PeTreeView.h" 6 | 7 | //-------------------------------------------------------------------------- 8 | 9 | class FollowablePeTreeView : public PeTreeView, public MainSettingsHolder 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | FollowablePeTreeView(QWidget *parent); 15 | virtual ~FollowablePeTreeView() { } 16 | 17 | public slots: 18 | void mousePressEvent(QMouseEvent *event); 19 | void mouseMoveEvent(QMouseEvent *event); 20 | void setFollowOnClick(bool isEnabled); 21 | 22 | protected slots: 23 | void onSettingsChanged(); 24 | virtual void customMenuEvent(QPoint p); 25 | void followOffset(); 26 | 27 | protected: 28 | bool hasAnyActionEnabled(); 29 | 30 | QAction *followOffsetAction, *onClick; 31 | 32 | offset_t selectedOffset; 33 | Executable::addr_type addrType; 34 | }; 35 | -------------------------------------------------------------------------------- /pe-bear/gui_base/HexInputDialog.cpp: -------------------------------------------------------------------------------- 1 | #include "HexInputDialog.h" 2 | #include 3 | 4 | #if QT_VERSION >= 0x050000 5 | #include 6 | #else 7 | #include 8 | #endif 9 | 10 | HexInputDialog::HexInputDialog(QString title, QString caption, QWidget *parent) 11 | : QDialog(parent), le(NULL) 12 | { 13 | this->setModal(false); 14 | this->setWindowTitle(title); 15 | 16 | layout_middleBox = new QVBoxLayout(); 17 | 18 | vbox = new QVBoxLayout(); 19 | this->captionLabel = new QLabel(caption); 20 | layout_middleBox->addWidget(this->captionLabel); 21 | 22 | le = new QLineEdit(this); 23 | layout_middleBox->addWidget(le); 24 | 25 | validator = new QRegularExpressionValidator(QRegularExpression("[0-9A-Fa-f]{1,}")); 26 | le->setValidator(validator); 27 | vbox->addLayout(layout_middleBox); 28 | 29 | QDialogButtonBox * buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); 30 | vbox->addWidget(buttonBox); 31 | this->setLayout(vbox); 32 | 33 | connect(buttonBox, SIGNAL(accepted()), this, SLOT(accepted())); 34 | connect(buttonBox, SIGNAL(rejected()), this, SLOT(rejected())); 35 | } 36 | 37 | qulonglong HexInputDialog::getNumValue(bool *isValid) 38 | { 39 | bool is_converted = false; 40 | QString textVal = le->text(); 41 | qulonglong value = textVal.toULongLong(&is_converted, 16); 42 | 43 | if (isValid != nullptr) { 44 | (*isValid) = is_converted; 45 | } 46 | return value; 47 | } 48 | 49 | void HexInputDialog::setDefaultValue(qulonglong number) 50 | { 51 | le->setText(QString::number(number, 16).toUpper()); 52 | } 53 | 54 | void HexInputDialog::accepted() 55 | { 56 | bool isValid = false; 57 | getNumValue(&isValid); 58 | 59 | if (isValid == false) { 60 | QMessageBox::warning(this, tr("Warning!"), tr("Wrong number format supplied!")); 61 | return; 62 | } 63 | QDialog::accept(); 64 | } 65 | 66 | void HexInputDialog::rejected() 67 | { 68 | QDialog::reject(); 69 | } 70 | -------------------------------------------------------------------------------- /pe-bear/gui_base/HexInputDialog.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "../QtCompat.h" 5 | 6 | class HexInputDialog : public QDialog 7 | { 8 | Q_OBJECT 9 | 10 | public: 11 | HexInputDialog(QString title, QString caption, QWidget *parent = 0); 12 | 13 | ~HexInputDialog() 14 | { 15 | delete validator; 16 | delete le; 17 | delete captionLabel; 18 | delete layout_middleBox; 19 | delete vbox; 20 | } 21 | 22 | qulonglong getNumValue(bool *isValid = NULL); 23 | void setDefaultValue(qulonglong number); 24 | 25 | #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) 26 | void setRegex(const QRegularExpression ®ex) { validator->setRegularExpression(regex); } 27 | #else 28 | void setRegex(const QRegularExpression ®ex) { validator->setRegExp(regex); } 29 | #endif 30 | 31 | void setMaxLength(int len) { le->setMaxLength(len); } 32 | 33 | public slots: 34 | void rejected(); 35 | void accepted(); 36 | 37 | protected: 38 | 39 | QVBoxLayout *vbox, *layout_middleBox; 40 | QLabel *captionLabel; 41 | QLineEdit *le; 42 | QRegularExpressionValidator *validator; 43 | }; 44 | -------------------------------------------------------------------------------- /pe-bear/gui_base/HexMimeSource.cpp: -------------------------------------------------------------------------------- 1 | #include "HexMimeSource.h" 2 | 3 | 4 | HexMimeSource::HexMimeSource(BYTE *buf, uint64_t bufSize) 5 | { 6 | this->buf = buf; 7 | this->bufSize = bufSize; 8 | } 9 | 10 | bool HexMimeSource::provides(const char* typeName) const 11 | { 12 | if (strstr(typeName,"application/octet-stream")) { 13 | return true; 14 | } 15 | if (strstr(typeName,"text/plain")) { 16 | return true; 17 | } 18 | return false; 19 | } 20 | 21 | QByteArray HexMimeSource::encodedData(const char* typeName) const 22 | { 23 | QByteArray arr; 24 | if (this->buf == NULL || this->bufSize == 0) return arr; 25 | 26 | if (strstr(typeName,"application/octet-stream")) { 27 | for (int i = 0; i < bufSize; i++) { 28 | arr.append(buf[i]); 29 | } 30 | return arr; 31 | } 32 | if (strstr(typeName,"text/plain")) { 33 | for (int i = 0; i < bufSize; i++) { 34 | static char charVal[4]; 35 | memset(charVal,0,sizeof(charVal)); 36 | snprintf(charVal, sizeof(charVal) - 1, "%02X", buf[i]); 37 | arr.append(charVal); 38 | if (i < (bufSize - 1)) arr.append(' '); 39 | } 40 | return arr; 41 | } 42 | return arr; 43 | } 44 | 45 | const char* HexMimeSource::format(int n) const 46 | { 47 | if (n == 0) return "application/octet-stream"; 48 | if (n == 1) return "text/plain"; 49 | return NULL; 50 | } 51 | 52 | //-------------------------------------------------------------------- 53 | /* 54 | HexConverter::HexConverter(QObject *parent) 55 | : QObject(parent) 56 | { 57 | validator = new QRegularExpressionValidator(QRegularExpression("[0-9A-Fa-f]{1,8}"), this); 58 | } 59 | 60 | QString HexConverter::textFromValue(int value) const 61 | { 62 | return QString::number(value, 16).toUpper(); 63 | } 64 | 65 | int HexConverter::valueFromText(const QString &text) const 66 | { 67 | bool ok; 68 | int val = text.toInt(&ok, 16); 69 | if (ok) return val; 70 | return 0; 71 | } 72 | 73 | bool HexConverter::validate(QString &text, int pos) const 74 | { 75 | QValidator::State state = validator->validate(text, pos); 76 | //Invalid, Intermediate,Acceptable 77 | if (state == QValidator::Acceptable) return true; 78 | return false; 79 | } 80 | */ 81 | //-------------------------------------------------------------------- -------------------------------------------------------------------------------- /pe-bear/gui_base/HexMimeSource.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "../Util.h" 5 | 6 | class HexMimeSource : public QMimeSource 7 | { 8 | public: 9 | HexMimeSource(BYTE *buf, uint64_t bufSize); 10 | 11 | virtual const char* format(int n = 0) const; 12 | virtual bool provides(const char*) const; 13 | virtual QByteArray encodedData(const char*) const; 14 | 15 | protected: 16 | BYTE *buf; 17 | uint64_t bufSize; 18 | }; 19 | 20 | //-------------------------------------------------------------------- 21 | /*class HexConverter: public QObject 22 | { 23 | Q_OBJECT 24 | public: 25 | HexConverter(QObject *parent = 0); 26 | 27 | bool validate(QString &text, int pos = 0) const; 28 | int valueFromText(const QString &text) const; 29 | QString textFromValue(int value) const; 30 | 31 | private: 32 | QRegularExpressionValidator *validator; 33 | }; 34 | */ 35 | //-------------------------------------------------------------------- 36 | -------------------------------------------------------------------------------- /pe-bear/gui_base/HexSpinBox.cpp: -------------------------------------------------------------------------------- 1 | #include "HexSpinBox.h" 2 | 3 | HexSpinBox::HexSpinBox(QWidget *parent) 4 | : QSpinBox(parent) 5 | { 6 | validator = new QRegularExpressionValidator(QRegularExpression("0x[0-9A-Fa-f]{1,8}"), this); 7 | setPrefix("0x"); 8 | } 9 | 10 | QString HexSpinBox::textFromValue(int value) const 11 | { 12 | return QString::number(value, 16).toUpper(); 13 | } 14 | 15 | int HexSpinBox::valueFromText(const QString &text) const 16 | { 17 | bool ok; 18 | int val = text.toInt(&ok, 16); 19 | if (ok) return val; 20 | return 0; 21 | } 22 | 23 | QValidator::State HexSpinBox::validate(QString &text, int &pos) const 24 | { 25 | return validator->validate(text, pos); 26 | } 27 | 28 | -------------------------------------------------------------------------------- /pe-bear/gui_base/HexSpinBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "../QtCompat.h" 5 | 6 | class HexSpinBox : public QSpinBox 7 | { 8 | Q_OBJECT 9 | public: 10 | HexSpinBox(QWidget *parent = 0); 11 | 12 | protected: 13 | QValidator::State validate(QString &text, int &pos) const; 14 | int valueFromText(const QString &text) const; 15 | QString textFromValue(int value) const; 16 | 17 | private: 18 | QRegularExpressionValidator *validator; 19 | }; 20 | 21 | -------------------------------------------------------------------------------- /pe-bear/gui_base/OffsetDependentAction.cpp: -------------------------------------------------------------------------------- 1 | #include "OffsetDependentAction.h" 2 | 3 | 4 | OffsetDependentAction::OffsetDependentAction(const Executable::addr_type addrT, const QString &text, QObject* parent) 5 | : QAction(text, parent), 6 | addrType(addrT), title(text), offset(INVALID_ADDR) 7 | { 8 | onOffsetChanged(offset); 9 | connect(this, SIGNAL(triggered()), this, SLOT(onTriggered())); 10 | } 11 | 12 | void OffsetDependentAction::onOffsetChanged(offset_t offset) 13 | { 14 | this->offset = offset; 15 | if (offset == INVALID_ADDR) { 16 | this->setEnabled(false); 17 | this->setVisible(false); 18 | this->setText("-"); 19 | return; 20 | } 21 | this->setEnabled(true); 22 | this->setVisible(true); 23 | QString text = title + " "+ QString::number(offset, 16).toUpper(); 24 | this->setText(text); 25 | } 26 | 27 | void OffsetDependentAction::onOffsetChanged(offset_t offset, Executable::addr_type addrT) 28 | { 29 | this->addrType = addrT; 30 | onOffsetChanged(offset); 31 | } 32 | 33 | //---------------------------------------------- 34 | 35 | void OffsetDependentMenu::addAction(QAction *action) 36 | { 37 | if (!action) return; 38 | 39 | OffsetDependentAction *offAction = dynamic_cast (action); 40 | if (offAction) { 41 | connect(this, SIGNAL(offsetUpdated(offset_t, Executable::addr_type)), action, SLOT(onOffsetChanged(offset_t, Executable::addr_type)) ); 42 | } 43 | QMenu::addAction(action); 44 | } 45 | 46 | void OffsetDependentMenu::removeAction(QAction *action) 47 | { 48 | if (!action) return; 49 | 50 | OffsetDependentAction *offAction = dynamic_cast (action); 51 | if (offAction) { 52 | disconnect(this, SIGNAL(offsetUpdated(offset_t, Executable::addr_type)), action, SLOT(onOffsetChanged(offset_t, Executable::addr_type)) ); 53 | } 54 | QMenu::removeAction(action); 55 | } 56 | 57 | void OffsetDependentMenu::onOffsetChanged(offset_t offset, Executable::addr_type addrType) 58 | { 59 | if (this->offset == offset && this->addrType == addrType) { 60 | return; //no changes 61 | } 62 | emit offsetUpdated(offset, addrType); 63 | 64 | this->addrType = addrType; 65 | this->offset = offset; 66 | 67 | if (offset == INVALID_ADDR) { 68 | this->setEnabled(false); 69 | //this->setVisible(false); 70 | this->setTitle("-"); 71 | return; 72 | } 73 | this->setEnabled(true); 74 | QString text = title + " "+ QString::number(offset, 16).toUpper(); 75 | this->setTitle(text); 76 | } 77 | -------------------------------------------------------------------------------- /pe-bear/gui_base/OffsetDependentAction.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include 5 | 6 | #include "../QtCompat.h" 7 | 8 | class OffsetDependentAction : public QAction 9 | { 10 | Q_OBJECT 11 | public: 12 | OffsetDependentAction(const Executable::addr_type addrType, const QString &title, QObject* parent); 13 | 14 | void setTitle(const QString &title) { this->title = title; } 15 | 16 | offset_t getOffset() { return offset; } 17 | Executable::addr_type getAddrType() { return addrType; } 18 | 19 | public slots: 20 | void onOffsetChanged(offset_t offset); 21 | void onOffsetChanged(offset_t offset, Executable::addr_type addrType); 22 | 23 | signals: 24 | void triggered(offset_t offset, Executable::addr_type addrType); 25 | 26 | private slots: 27 | void onTriggered() { emit triggered(offset, addrType); } 28 | 29 | protected: 30 | Executable::addr_type addrType; 31 | offset_t offset; 32 | QString title; 33 | 34 | friend class OffsetDependentMenu; 35 | }; 36 | 37 | class OffsetDependentMenu : public QMenu 38 | { 39 | Q_OBJECT 40 | 41 | public: 42 | OffsetDependentMenu (const Executable::addr_type addrT, const QString &text, QWidget *parent) 43 | : QMenu(text, parent), 44 | addrType(addrT), offset(INVALID_ADDR), title(text) 45 | { 46 | onOffsetChanged(offset); 47 | } 48 | 49 | void addAction(QAction *action); 50 | void removeAction(QAction *action); 51 | 52 | public slots: 53 | void onOffsetChanged(offset_t offset) { onOffsetChanged(offset, this->addrType); } 54 | void onOffsetChanged(offset_t offset, Executable::addr_type addrType); 55 | 56 | signals: 57 | void offsetUpdated(offset_t, Executable::addr_type); 58 | 59 | protected: 60 | Executable::addr_type addrType; 61 | offset_t offset; 62 | QString title; 63 | }; 64 | -------------------------------------------------------------------------------- /pe-bear/gui_base/PEViewsManager.cpp: -------------------------------------------------------------------------------- 1 | #include "PEViewsManager.h" 2 | 3 | PEDockedWidget* PEViewsManager::getPeDockWidget(PeHandler* peHndl) 4 | { 5 | if (!peHndl) return NULL; 6 | std::map::iterator found = this->PeViews.find(peHndl); 7 | if (found != this->PeViews.end()) { 8 | return found->second; 9 | } 10 | 11 | PEDockedWidget* p = new PEDockedWidget(peHndl, this); 12 | if (!p) return NULL; //should not happen 13 | 14 | p->hide(); 15 | connect(this, SIGNAL(signalChangeHexViewSettings(HexViewSettings &)), p, SLOT(changeHexViewSettings(HexViewSettings &)) ); 16 | connect(this, SIGNAL(signalChangeDisasmViewSettings(DisasmViewSettings &)), p, SLOT(changeDisasmViewSettings(DisasmViewSettings &)) ); 17 | connect(this, SIGNAL(globalFontChanged()), p, SLOT(refreshFonts()) ); 18 | 19 | p->changeHexViewSettings(this->hexSettings); 20 | p->changeDisasmViewSettings(this->disasmSettings); 21 | 22 | p->setAllowedAreas(Qt::AllDockWidgetAreas);// Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); 23 | p->setFloating(false); 24 | p->setFeatures( QDockWidget::DockWidgetMovable 25 | | QDockWidget::DockWidgetClosable 26 | | QDockWidget::DockWidgetFloatable 27 | | QDockWidget::DockWidgetVerticalTitleBar 28 | ); 29 | this->addDockWidget(Qt::RightDockWidgetArea, p, Qt::Vertical); 30 | if (lastDock.size()) { 31 | this->tabifyDockWidget(lastDock.back(), p); 32 | p->setTabOrder(p, lastDock.back()); 33 | } 34 | lastDock.push_back(p); 35 | PeViews[peHndl] = p; 36 | p->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); 37 | p->goToEntryPoint(); 38 | return p; 39 | } 40 | 41 | bool PEViewsManager::removePeDockWidget(PeHandler* peHndl) 42 | { 43 | std::map::iterator found = this->PeViews.find(peHndl); 44 | if (found == this->PeViews.end()) return false; 45 | 46 | PEDockedWidget* peDock = found->second; 47 | if (peDock) peDock->close(); 48 | this->PeViews.erase(found); 49 | 50 | std::vector::iterator itr; 51 | for (itr = lastDock.begin(); itr != lastDock.end(); ++itr) { 52 | if (*itr == peDock) { 53 | lastDock.erase(itr); 54 | break; 55 | } 56 | } 57 | delete peDock; 58 | return true; 59 | } 60 | 61 | void PEViewsManager::clear() 62 | { 63 | std::map::iterator vItr; 64 | for (vItr = this->PeViews.begin(); vItr != this->PeViews.end(); ++vItr) { 65 | PeHandler* hndl = vItr->first; 66 | PEDockedWidget *peDock = vItr->second; 67 | if (peDock) peDock->close(); 68 | delete peDock; 69 | } 70 | this->PeViews.clear(); 71 | } 72 | 73 | PEViewsManager::~PEViewsManager() 74 | { 75 | clear(); 76 | } 77 | -------------------------------------------------------------------------------- /pe-bear/gui_base/PEViewsManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "../PEDockedWidget.h" 5 | 6 | class PEViewsManager : public QMainWindow 7 | { 8 | Q_OBJECT 9 | 10 | signals: 11 | void signalChangeHexViewSettings(HexViewSettings &); 12 | void signalChangeDisasmViewSettings(DisasmViewSettings &); 13 | void globalFontChanged(); 14 | 15 | public: 16 | PEViewsManager(QWidget* parent) 17 | : QMainWindow(parent) 18 | { 19 | } 20 | 21 | PEDockedWidget* getPeDockWidget(PeHandler* pe); 22 | bool removePeDockWidget(PeHandler* pe); 23 | void clear(); 24 | 25 | ~PEViewsManager(); 26 | 27 | public slots: 28 | 29 | void changeHexViewSettings(HexViewSettings &_settings) 30 | { 31 | hexSettings = _settings; 32 | emit signalChangeHexViewSettings(_settings); 33 | } 34 | 35 | void changeDisasmViewSettings(DisasmViewSettings &_settings) 36 | { 37 | disasmSettings = _settings; 38 | emit signalChangeDisasmViewSettings(_settings); 39 | } 40 | 41 | void onGlobalFontChanged() 42 | { 43 | emit globalFontChanged(); 44 | } 45 | 46 | protected: 47 | std::map PeViews; 48 | std::vector lastDock; 49 | 50 | HexViewSettings hexSettings; 51 | DisasmViewSettings disasmSettings; 52 | }; 53 | -------------------------------------------------------------------------------- /pe-bear/gui_base/PeGuiItem.cpp: -------------------------------------------------------------------------------- 1 | #include "PeGuiItem.h" 2 | 3 | #define DBG_LVL 0 4 | 5 | uint64_t PeGuiItem::counter = 0; 6 | 7 | PeGuiItem::PeGuiItem(PeHandler *peHndl) 8 | : m_PE(NULL), myPeHndl(NULL) 9 | { 10 | //if (!peHndl || !peHndl->getPe()) throw CustomException("Invalid initialization: PE Handler is NULL!"); 11 | if (peHndl) { 12 | peHndl->incRefCntr(); 13 | m_PE = peHndl->getPe(); 14 | } 15 | myPeHndl = peHndl; 16 | PeGuiItem::counter++; 17 | } 18 | 19 | PeGuiItem::~PeGuiItem() 20 | { 21 | if (myPeHndl) { 22 | myPeHndl->release(); 23 | } 24 | myPeHndl = NULL; 25 | m_PE = NULL; 26 | PeGuiItem::counter--; 27 | } 28 | 29 | //--------------------------------------------------------------------- 30 | 31 | MainSettings* MainSettingsHolder::mainSettings = NULL; 32 | 33 | MainSettings* MainSettingsHolder::getSettings() 34 | { 35 | if (MainSettingsHolder::mainSettings != NULL) { 36 | return MainSettingsHolder::mainSettings; 37 | } 38 | if (this->mySettings == NULL) { 39 | mySettings = new MainSettings(); 40 | } 41 | return mySettings; 42 | } 43 | -------------------------------------------------------------------------------- /pe-bear/gui_base/PeGuiItem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "../base/MainSettings.h" 7 | #include "../base/PeHandlersManager.h" 8 | 9 | #include "../ViewSettings.h" 10 | 11 | class PeGuiItem 12 | { 13 | public: 14 | /*throws Exception if PeHandler or PeFile is NULL! */ 15 | PeGuiItem(PeHandler *peHndl); 16 | virtual ~PeGuiItem(); 17 | 18 | virtual PeHandler* getPeHandler() const { return myPeHndl; } 19 | virtual PEFile* getPE() const { if (!myPeHndl) return NULL; return myPeHndl->getPe(); } 20 | 21 | ColorSettings addrColors; 22 | 23 | protected: 24 | static uint64_t counter; 25 | PeHandler* myPeHndl; 26 | PEFile* m_PE; 27 | }; 28 | 29 | //---- 30 | 31 | class PeViewItem : public PeGuiItem 32 | { 33 | public: 34 | PeViewItem(PeHandler *peHndl) : PeGuiItem(peHndl) {} 35 | virtual ~PeViewItem() {} 36 | 37 | virtual offset_t getContentOffset() const { return 0; } 38 | virtual bufsize_t getContentSize() const { return (m_PE) ? m_PE->getRawSize() : 0; } 39 | }; 40 | 41 | class MainSettingsHolder 42 | { 43 | public: 44 | static void setMainSettings(MainSettings* settings) { MainSettingsHolder::mainSettings = settings; } 45 | 46 | MainSettingsHolder() : mySettings(NULL) {} 47 | virtual ~MainSettingsHolder() { delete mySettings; } 48 | 49 | protected: 50 | MainSettings* getSettings(); 51 | static MainSettings* mainSettings; 52 | //--- 53 | MainSettings* mySettings; 54 | }; 55 | -------------------------------------------------------------------------------- /pe-bear/gui_base/PeTableModel.cpp: -------------------------------------------------------------------------------- 1 | #include "PeTableModel.h" 2 | 3 | #define COL_OFFSET 0 4 | 5 | //--------------------------------------- 6 | 7 | PeTableModel::PeTableModel(PeHandler *peHndl, QObject *parent) 8 | : PeTreeModel(peHndl, parent, false) 9 | { 10 | } 11 | 12 | Executable::addr_type PeTableModel::addrTypeAt(QModelIndex index) const 13 | { 14 | if (!index.isValid() || !m_PE) return Executable::NOT_ADDR; 15 | if (index.column() == COL_OFFSET) return Executable::RAW; 16 | return Executable::NOT_ADDR; 17 | } 18 | -------------------------------------------------------------------------------- /pe-bear/gui_base/PeTableModel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include 5 | 6 | #include "../QtCompat.h" 7 | #include "PeGuiItem.h" 8 | #include "TreeCpView.h" 9 | #include "../gui/PeTreeModel.h" 10 | 11 | //-------------------------------------------------------------------------- 12 | 13 | class PeTableModel : public PeTreeModel 14 | { 15 | Q_OBJECT 16 | 17 | public: 18 | PeTableModel(PeHandler *peHndl, QObject *parent); 19 | 20 | virtual ~PeTableModel() 21 | { 22 | } 23 | 24 | QModelIndex index(int row, int column, const QModelIndex &parent) const 25 | { 26 | return createIndex(row, column); 27 | } 28 | 29 | virtual Executable::addr_type addrTypeAt(QModelIndex index) const; 30 | 31 | virtual offset_t getFieldOffset(QModelIndex index) const { return 0; } 32 | virtual bufsize_t getFieldSize(QModelIndex index) const { return 0; } 33 | 34 | friend class PeTreeView; 35 | }; 36 | -------------------------------------------------------------------------------- /pe-bear/gui_base/PeTreeView.cpp: -------------------------------------------------------------------------------- 1 | #include "PeTreeView.h" 2 | 3 | //--------------------------------------- 4 | 5 | PeTreeView::PeTreeView(QWidget *parent) 6 | : TreeCpView(parent), 7 | myModel(NULL), autoExpand(true) 8 | { 9 | setMouseTracking(true); 10 | 11 | setSelectionBehavior(QAbstractItemView::SelectItems); 12 | setSelectionMode(SingleSelection); 13 | setAutoFillBackground(true); 14 | setAlternatingRowColors(true); 15 | 16 | if (header()) { 17 | #if QT_VERSION >= 0x050000 18 | header()->setSectionResizeMode(QHeaderView::Interactive); 19 | #else 20 | header()->setResizeMode(QHeaderView::Interactive); 21 | // header()->setResizeMode(0, QHeaderView::Fixed); 22 | header()->setMovable(false); 23 | #endif 24 | } 25 | } 26 | 27 | void PeTreeView::setModel(PeTreeModel *model) 28 | { 29 | if (this->myModel) { 30 | disconnect(this->myModel, SIGNAL(modelUpdated()), this, SLOT(onModelUpdated()) ); 31 | } 32 | 33 | this->myModel = model; 34 | TreeCpView::setModel(model); 35 | if (!model) return; 36 | 37 | bool expandable = model->isExpandable(); 38 | setItemsExpandable(expandable); 39 | setRootIsDecorated(expandable); 40 | this->setColumnWidth(0, 80); 41 | this->setContentsMargins(5, 5, 2, 2); 42 | connect(model, SIGNAL(modelUpdated()), this, SLOT(onModelUpdated()) ); 43 | } 44 | 45 | void PeTreeView::selectionChanged(const QItemSelection &newSel, const QItemSelection &prevSel) 46 | { 47 | if (!myModel || !(myModel->getPeHandler())) return; 48 | 49 | if (newSel.indexes().size() == 0) return; 50 | 51 | QModelIndex index = newSel.indexes().at(0); 52 | hoverIndex(index); 53 | } 54 | 55 | void PeTreeView::mousePressEvent(QMouseEvent *event) 56 | { 57 | if (!myModel || !(myModel->getPeHandler())) return; 58 | QModelIndex index = this->indexAt(event->pos()); 59 | hoverIndex(index); 60 | TreeCpView::mousePressEvent(event); 61 | } 62 | 63 | void PeTreeView::keyPressEvent(QKeyEvent *keyEv) 64 | { 65 | switch (keyEv->key()){ 66 | case Qt::Key_Plus : 67 | this->expandAll(); 68 | return; 69 | case Qt::Key_Minus : 70 | this->collapseAll(); 71 | return; 72 | } 73 | TreeCpView::keyPressEvent(keyEv); 74 | } 75 | 76 | void PeTreeView::hoverIndex(QModelIndex index) 77 | { 78 | if (!index.isValid()) return; 79 | if (!myModel || !myModel->getPeHandler()) return; 80 | 81 | offset_t offset = this->myModel->getFieldOffset(index); 82 | offset_t size = this->myModel->getFieldSize(index); 83 | 84 | if (!size) { 85 | offset = this->myModel->getContentOffset(); 86 | size = this->myModel->getContentSize(); 87 | } 88 | myModel->getPeHandler()->setHovered(false, offset, size); 89 | } 90 | 91 | //--------------------------------------- -------------------------------------------------------------------------------- /pe-bear/gui_base/PeTreeView.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "../QtCompat.h" 5 | #include "TreeCpView.h" 6 | #include "PeTableModel.h" 7 | 8 | //-------------------------------------------------------------------------- 9 | 10 | class PeTreeView : public TreeCpView 11 | { 12 | Q_OBJECT 13 | 14 | protected slots: 15 | void onModelUpdated() 16 | { 17 | if (this->itemsExpandable() && autoExpand) { 18 | this->expandAll(); 19 | } 20 | }; 21 | 22 | public : 23 | PeTreeView(QWidget *parent); 24 | 25 | virtual ~PeTreeView() 26 | { 27 | } 28 | 29 | void setModel(PeTreeModel *model); 30 | bool autoExpand; 31 | 32 | public slots: 33 | void expandAll() 34 | { 35 | if (itemsExpandable()) { 36 | TreeCpView::expandAll(); 37 | } 38 | } 39 | 40 | void collapseAll() 41 | { 42 | if (itemsExpandable()) { 43 | TreeCpView::collapseAll(); 44 | } 45 | } 46 | 47 | protected: 48 | void selectionChanged(const QItemSelection &newSel, const QItemSelection &prevSel); 49 | void mousePressEvent(QMouseEvent *event); 50 | void keyPressEvent(QKeyEvent *key); 51 | void hoverIndex(QModelIndex index); 52 | 53 | PeTreeModel *myModel; 54 | 55 | PeHandler* peHndl() 56 | { 57 | return (myModel) ? myModel->getPeHandler() : NULL; 58 | } 59 | 60 | PEFile* pe() 61 | { 62 | return (myModel) ? myModel->getPE() : NULL; 63 | } 64 | }; 65 | 66 | //----------------------------------------------------- 67 | -------------------------------------------------------------------------------- /pe-bear/gui_base/TreeCpView.cpp: -------------------------------------------------------------------------------- 1 | #include "TreeCpView.h" 2 | 3 | 4 | TreeCpView::TreeCpView(QWidget *parent) 5 | : QTreeView(parent), defaultMenu(this), 6 | myMenu(&defaultMenu) 7 | { 8 | connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(customMenuEvent(QPoint)) ); 9 | enableMenu(false); 10 | } 11 | 12 | void TreeCpView::resizeColsToContent() 13 | { 14 | QAbstractItemModel *model = this->model(); 15 | if (!model) return; 16 | 17 | int count = model->columnCount(QModelIndex()); 18 | for (int i = 0; i < count; i++) { 19 | resizeColumnToContents(i); 20 | } 21 | } 22 | 23 | void TreeCpView::enableMenu(bool enable) 24 | { 25 | if (enable) this->setContextMenuPolicy(Qt::CustomContextMenu); 26 | else this->setContextMenuPolicy(Qt::DefaultContextMenu); 27 | } 28 | 29 | void TreeCpView::customMenuEvent(QPoint p) 30 | { 31 | if (myMenu == NULL) return; 32 | QPoint p2 = this->mapToGlobal(p); 33 | this->myMenu->exec(p2); 34 | } 35 | 36 | void TreeCpView::keyPressEvent(QKeyEvent *keyEv) 37 | { 38 | if (keyEv->matches(QKeySequence::Copy)) { 39 | copySelected(); 40 | return; 41 | } 42 | QTreeView::keyPressEvent(keyEv); 43 | } 44 | 45 | void TreeCpView::setMenu(QMenu *menu) 46 | { 47 | myMenu = menu; 48 | } 49 | 50 | void TreeCpView::removeAllActions() 51 | { 52 | if (myMenu != NULL) { 53 | QList actList = myMenu->actions(); 54 | for (int i = 0; i < actList.size(); i++) { 55 | myMenu->removeAction(actList[i]); 56 | } 57 | } 58 | } 59 | 60 | void TreeCpView::copySelected() 61 | { 62 | QItemSelectionModel *model = this->selectionModel(); 63 | QModelIndexList list = model->selectedIndexes(); 64 | std::sort(list.begin(), list.end()); 65 | int row = -1; 66 | int col = -1; 67 | QString separator = " "; 68 | const int size = list.size(); 69 | QStringList strings; 70 | 71 | for (int i = 0; i < size; i++) { 72 | QModelIndex index = list.at(i); 73 | if (index.row() != row && row != (-1)) 74 | strings << "\n"; 75 | else if (col != -1) strings << separator; 76 | 77 | strings << index.data().toString(); 78 | row = index.row(); 79 | col = index.column(); 80 | } 81 | QApplication::clipboard()->clear(); 82 | QApplication::clipboard()->setText(strings.join("")); 83 | } -------------------------------------------------------------------------------- /pe-bear/gui_base/TreeCpView.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "../QtCompat.h" 5 | 6 | class TreeCpView : public QTreeView 7 | { 8 | Q_OBJECT 9 | 10 | public: 11 | TreeCpView(QWidget *parent); 12 | virtual ~TreeCpView() {} 13 | 14 | void resizeColsToContent(); 15 | 16 | void keyPressEvent(QKeyEvent *key); 17 | void setMenu(QMenu *menu); 18 | 19 | QMenu* getMenu() { return myMenu; } 20 | void setDefaultMenu() { myMenu = &defaultMenu; } 21 | void enableMenu(bool enable); 22 | void removeAllActions(); 23 | 24 | public slots: 25 | virtual void copySelected(); 26 | virtual void customMenuEvent(QPoint p); 27 | 28 | protected: 29 | QMenu *myMenu; 30 | QMenu defaultMenu; 31 | }; 32 | -------------------------------------------------------------------------------- /pe-bear/gui_base/WrapperInterface.cpp: -------------------------------------------------------------------------------- 1 | #include "WrapperInterface.h" 2 | 3 | #define COL_OFFSET 0 4 | 5 | //--------------------------------------- 6 | WrapperInterface::WrapperInterface() 7 | { 8 | } 9 | 10 | bool WrapperInterface::containsOffset(QModelIndex index) const 11 | { 12 | if (index.column() == COL_OFFSET) { 13 | return true; 14 | } 15 | return false; 16 | } 17 | 18 | QVariant WrapperInterface::dataValue(const QModelIndex &index) const 19 | { 20 | ExeElementWrapper *wrapper = this->wrapperAt(index); 21 | if (!wrapper) return false; 22 | 23 | if (isComplexValue(index)) return complexValue(index); 24 | 25 | bool isOk = false; 26 | uint64_t val = wrapper->getNumValue(getFID(index), getSID(index), &isOk); 27 | if (isOk) return QString::number(val, 16); 28 | 29 | return complexValue(index); 30 | } 31 | 32 | QVariant WrapperInterface::complexValue(const QModelIndex &index) const 33 | { 34 | if (!index.isValid()) return QVariant(); 35 | ExeElementWrapper *wrapper = this->wrapperAt(index); 36 | if (!wrapper) return false; 37 | 38 | int fId = getFID(index); 39 | int sId = getSID(index); 40 | 41 | bufsize_t fieldSize = wrapper->getFieldSize(fId, sId); 42 | WORD* ptr = (WORD*) wrapper->getFieldPtr(fId, sId); 43 | if (ptr == NULL || fieldSize == 0) return "INVALID"; 44 | 45 | size_t cntr = fieldSize / sizeof(WORD); 46 | const size_t CNTR_MAX = 50; 47 | QStringList strL; 48 | for (int i = 0; i < cntr && i < CNTR_MAX; i++) { 49 | strL.append(QString::number(ptr[i], 16)); 50 | } 51 | if (cntr > CNTR_MAX) strL.append("..."); 52 | return strL.join(", "); 53 | } 54 | 55 | Executable::addr_type WrapperInterface::addrTypeAt(QModelIndex index) const 56 | { 57 | if (containsOffset(index)) { 58 | return offsetAddrType(); 59 | } 60 | if (!containsValue(index)) return Executable::NOT_ADDR; 61 | 62 | ExeElementWrapper *wrapper = this->wrapperAt(index); 63 | if (!wrapper) return Executable::NOT_ADDR; 64 | 65 | Executable::addr_type aType = Executable::NOT_ADDR; 66 | aType = wrapper->containsAddrType(getFID(index), getSID(index)); 67 | return aType; 68 | } 69 | 70 | offset_t WrapperInterface::getFieldOffset(QModelIndex index) const 71 | { 72 | if (!index.isValid()) return 0; 73 | int fieldId = getFID(index); 74 | return wrapperAt(index) ? wrapperAt(index)->getFieldOffset(fieldId) : 0; 75 | } 76 | 77 | bufsize_t WrapperInterface::getFieldSize(QModelIndex index) const 78 | { 79 | if (!index.isValid()) return 0; 80 | int fieldId = getFID(index); 81 | return wrapperAt(index) ? wrapperAt(index)->getFieldSize(fieldId) : 0; 82 | } 83 | 84 | -------------------------------------------------------------------------------- /pe-bear/gui_base/WrapperInterface.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "PeGuiItem.h" 6 | 7 | 8 | class WrapperInterface 9 | { 10 | public: 11 | WrapperInterface(); 12 | virtual ~WrapperInterface() {} 13 | 14 | Executable::addr_type addrTypeAt(QModelIndex index) const; 15 | 16 | offset_t getFieldOffset(QModelIndex index) const; 17 | bufsize_t getFieldSize(QModelIndex index) const; 18 | 19 | virtual bool containsValue(QModelIndex index) const = 0; 20 | virtual bool containsOffset(QModelIndex index) const; 21 | virtual Executable::addr_type offsetAddrType() const { return Executable::RAW; } 22 | 23 | virtual ExeElementWrapper* wrapper() const = 0; 24 | virtual ExeElementWrapper* wrapperAt(QModelIndex index) const { return wrapper(); } 25 | 26 | virtual QString makeDockerTitle(size_t upId) { return ""; } 27 | 28 | protected: 29 | virtual int getFID(const QModelIndex &index) const { return index.row(); } 30 | virtual int getSID(const QModelIndex &index) const { return index.column(); } 31 | 32 | virtual QVariant dataValue(const QModelIndex &index) const; 33 | virtual bool isComplexValue(const QModelIndex &index) const { return false; } 34 | virtual QVariant complexValue(const QModelIndex &index) const;// TODO 35 | virtual bool setComplexValue(const QModelIndex &index, const QVariant &value, int role) { return false; } 36 | }; 37 | -------------------------------------------------------------------------------- /pe-bear/gui_base/WrapperTableModel.cpp: -------------------------------------------------------------------------------- 1 | #include "WrapperTableModel.h" 2 | 3 | #define COL_OFFSET 0 4 | 5 | //------------------------------------------- 6 | 7 | int64_t WrapperTableModel::counter = 0; 8 | 9 | bool WrapperTableModel::setData(const QModelIndex &index, const QVariant &value, int role) 10 | { 11 | if (!index.isValid()) return false; 12 | 13 | size_t fID = this->getFID(index); 14 | size_t sID = this->getSID(index); 15 | 16 | ExeElementWrapper* wrap = wrapperAt(index); 17 | if (!wrap) return false; 18 | 19 | ExeElementWrapper* mainWrapper = wrapper(); 20 | if (!mainWrapper) return false; 21 | 22 | if (wrap != mainWrapper) { //it is subWrapper 23 | fID = sID; 24 | sID = FIELD_NONE; 25 | } 26 | 27 | QString text = value.toString(); 28 | 29 | bool isOk = false; 30 | ULONGLONG number = text.toULongLong(&isOk, 16); 31 | if (!isOk) return false; 32 | 33 | offset_t offset = wrap->getFieldOffset(fID); 34 | if (offset == INVALID_ADDR) { 35 | return false; 36 | } 37 | bufsize_t fieldSize = wrap->getFieldSize(fID); 38 | 39 | this->myPeHndl->backupModification(offset, fieldSize); 40 | 41 | bool isModified = wrap->setNumValue(fID, sID, number); 42 | if (isModified) { 43 | this->myPeHndl->setBlockModified(offset, fieldSize); 44 | return true; 45 | } 46 | this->myPeHndl->unbackupLastModification(); 47 | return false; 48 | } 49 | 50 | Qt::ItemFlags WrapperTableModel::flags(const QModelIndex &index) const 51 | { 52 | if (!index.isValid()) return Qt::NoItemFlags; 53 | Qt::ItemFlags f = Qt::ItemIsEnabled | Qt::ItemIsSelectable; 54 | 55 | if (this->containsOffset(index)) return f; 56 | if (this->containsValue(index)) return f | Qt::ItemIsEditable; 57 | return f; 58 | } 59 | 60 | QString WrapperTableModel::makeDockerTitle(size_t upId) 61 | { 62 | ExeNodeWrapper* node = dynamic_cast(wrapper()); 63 | if (node == NULL) { 64 | return "-"; 65 | } 66 | ExeNodeWrapper *childEntry = node->getEntryAt(upId); 67 | if (childEntry == NULL) { 68 | return "-"; 69 | } 70 | QString name = childEntry->getName(); 71 | size_t funcNum = childEntry->getEntriesCount(); 72 | QString numDesc = funcNum == 1 ? tr(" entry") : tr(" entries"); 73 | QString desc = name + " [ " + QString::number(funcNum) + numDesc + " ]"; 74 | return desc; 75 | } 76 | -------------------------------------------------------------------------------- /pe-bear/gui_base/WrapperTableModel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "FollowablePeTreeView.h" 6 | #include "WrapperInterface.h" 7 | 8 | 9 | //--- 10 | class WrapperTableModel : public PeTableModel, public WrapperInterface 11 | { 12 | Q_OBJECT 13 | 14 | public slots: 15 | virtual void setParentId(size_t parentId) 16 | { 17 | /* only if the down table shows the details of the row from the up table */ 18 | } 19 | 20 | public: 21 | WrapperTableModel(PeHandler *peHndl, QObject *parent = 0) 22 | : PeTableModel(peHndl, parent), WrapperInterface() 23 | { 24 | WrapperTableModel::counter++; 25 | } 26 | 27 | virtual ~WrapperTableModel() { WrapperTableModel::counter--; } 28 | //--- 29 | virtual Executable::addr_type addrTypeAt(QModelIndex index) const { return WrapperInterface::addrTypeAt(index); } 30 | virtual offset_t getFieldOffset(QModelIndex index) const { return WrapperInterface::getFieldOffset(index); } 31 | virtual bufsize_t getFieldSize(QModelIndex index) const { return WrapperInterface::getFieldSize(index); } 32 | //--- 33 | /* sets data value, do backup and notifies handler */ 34 | virtual bool setData(const QModelIndex &index, const QVariant &value, int role); 35 | virtual Qt::ItemFlags flags(const QModelIndex &index) const; 36 | 37 | virtual int rowCount(const QModelIndex &parent) const { return wrapper() ? wrapper()->getFieldsCount() : 0; } 38 | 39 | virtual QString makeDockerTitle(size_t upId); 40 | 41 | protected: 42 | static int64_t counter; 43 | }; 44 | //------------ 45 | -------------------------------------------------------------------------------- /pe-bear/icons/Add.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/Add.ico -------------------------------------------------------------------------------- /pe-bear/icons/Delete.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/Delete.ico -------------------------------------------------------------------------------- /pe-bear/icons/DeleteAll.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/DeleteAll.ico -------------------------------------------------------------------------------- /pe-bear/icons/EP.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/EP.ico -------------------------------------------------------------------------------- /pe-bear/icons/List.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/List.ico -------------------------------------------------------------------------------- /pe-bear/icons/Locked.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/Locked.ico -------------------------------------------------------------------------------- /pe-bear/icons/Preview.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/Preview.ico -------------------------------------------------------------------------------- /pe-bear/icons/Save.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/Save.ico -------------------------------------------------------------------------------- /pe-bear/icons/add_entry.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/add_entry.ico -------------------------------------------------------------------------------- /pe-bear/icons/add_subentry.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/add_subentry.ico -------------------------------------------------------------------------------- /pe-bear/icons/app32.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/app32.ico -------------------------------------------------------------------------------- /pe-bear/icons/app32_w.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/app32_w.ico -------------------------------------------------------------------------------- /pe-bear/icons/app64.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/app64.ico -------------------------------------------------------------------------------- /pe-bear/icons/app64_w.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/app64_w.ico -------------------------------------------------------------------------------- /pe-bear/icons/arr_down.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/arr_down.ico -------------------------------------------------------------------------------- /pe-bear/icons/arr_up.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/arr_up.ico -------------------------------------------------------------------------------- /pe-bear/icons/arrow-right.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/arrow-right.ico -------------------------------------------------------------------------------- /pe-bear/icons/data_dir_color.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/data_dir_color.ico -------------------------------------------------------------------------------- /pe-bear/icons/data_dir_gray.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/data_dir_gray.ico -------------------------------------------------------------------------------- /pe-bear/icons/disasm.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/disasm.ico -------------------------------------------------------------------------------- /pe-bear/icons/dos.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/dos.ico -------------------------------------------------------------------------------- /pe-bear/icons/down.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/down.ico -------------------------------------------------------------------------------- /pe-bear/icons/dump.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/dump.ico -------------------------------------------------------------------------------- /pe-bear/icons/enlarge.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/enlarge.ico -------------------------------------------------------------------------------- /pe-bear/icons/eraser.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/eraser.ico -------------------------------------------------------------------------------- /pe-bear/icons/go_to_raw.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/go_to_raw.ico -------------------------------------------------------------------------------- /pe-bear/icons/go_to_rva.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/go_to_rva.ico -------------------------------------------------------------------------------- /pe-bear/icons/hdr.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/hdr.ico -------------------------------------------------------------------------------- /pe-bear/icons/information.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/information.ico -------------------------------------------------------------------------------- /pe-bear/icons/magic_wand.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/magic_wand.ico -------------------------------------------------------------------------------- /pe-bear/icons/move.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/move.ico -------------------------------------------------------------------------------- /pe-bear/icons/move0.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/move0.ico -------------------------------------------------------------------------------- /pe-bear/icons/red_pin.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/red_pin.ico -------------------------------------------------------------------------------- /pe-bear/icons/reload.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/reload.ico -------------------------------------------------------------------------------- /pe-bear/icons/resize.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/resize.ico -------------------------------------------------------------------------------- /pe-bear/icons/save_black.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/save_black.ico -------------------------------------------------------------------------------- /pe-bear/icons/section.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/section.ico -------------------------------------------------------------------------------- /pe-bear/icons/shrink.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/shrink.ico -------------------------------------------------------------------------------- /pe-bear/icons/space.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/space.ico -------------------------------------------------------------------------------- /pe-bear/icons/space_down.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/space_down.ico -------------------------------------------------------------------------------- /pe-bear/icons/space_this.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/space_this.ico -------------------------------------------------------------------------------- /pe-bear/icons/space_up.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/space_up.ico -------------------------------------------------------------------------------- /pe-bear/icons/star.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/star.ico -------------------------------------------------------------------------------- /pe-bear/icons/transform.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/transform.ico -------------------------------------------------------------------------------- /pe-bear/icons/transform0.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/transform0.ico -------------------------------------------------------------------------------- /pe-bear/icons/undo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/undo.ico -------------------------------------------------------------------------------- /pe-bear/icons/unmodify.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/unmodify.ico -------------------------------------------------------------------------------- /pe-bear/icons/up.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/up.ico -------------------------------------------------------------------------------- /pe-bear/icons/wrong_way.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/icons/wrong_way.ico -------------------------------------------------------------------------------- /pe-bear/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "QtCompat.h" 8 | #include "gui/windows/MainWindow.h" 9 | #include "base/MainSettings.h" 10 | 11 | QStringList collectSuppliedFiles() 12 | { 13 | QStringList args = QCoreApplication::arguments(); 14 | QStringList fNames; 15 | for (int i = 1; i < args.length(); i++) { 16 | fNames << args[i]; 17 | } 18 | return fNames; 19 | } 20 | 21 | int main(int argc, char *argv[]) 22 | { 23 | Q_INIT_RESOURCE(application); 24 | 25 | #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 26 | QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); 27 | #endif 28 | 29 | QApplication app(argc, argv); 30 | // workaround for a bug in Qt (not setting default font properly) 31 | QApplication::setFont(QApplication::font("QMessageBox")); 32 | 33 | // Load the settings 34 | MainSettings mainSettings; 35 | mainSettings.readPersistent(); 36 | 37 | // Load language file 38 | QTranslator translator; 39 | QString currLanguage = mainSettings.language; 40 | if (currLanguage.length() == 0) { 41 | currLanguage = QLocale::system().name(); 42 | } 43 | QString trPath = QDir::separator() + MainSettings::languageDir + QDir::separator() + currLanguage + QDir::separator() + "PELanguage.qm"; 44 | if (translator.load(QCoreApplication::applicationDirPath() + trPath) 45 | || translator.load(mainSettings.userDataDir() + trPath)) 46 | { 47 | app.installTranslator(&translator); 48 | mainSettings.language = currLanguage; 49 | } else { 50 | if (!mainSettings.language.startsWith("en_US")) { // en_US is built-in, so it does not require translation file 51 | mainSettings.language = ""; //if not US, and the language file could not be found, reset to default 52 | } 53 | } 54 | 55 | app.setApplicationName(TITLE); 56 | app.setWindowIcon(QIcon(":/main_ico.ico")); 57 | app.setQuitOnLastWindowClosed(true); 58 | 59 | MainWindow mainWin(mainSettings); 60 | mainWin.setIconSize(QSize(48, 48)); 61 | mainWin.resize(950, 650); 62 | 63 | QStringList fileNames = collectSuppliedFiles(); 64 | if (fileNames.length()) { 65 | mainWin.openMultiplePEs(fileNames); 66 | } 67 | mainWin.show(); 68 | int ret = app.exec(); 69 | return ret; 70 | } 71 | 72 | -------------------------------------------------------------------------------- /pe-bear/main_ico.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/main_ico.ico -------------------------------------------------------------------------------- /pe-bear/main_ico_old.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/main_ico_old.ico -------------------------------------------------------------------------------- /pe-bear/rebear_res.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/pe-bear/a6b9b0772b7226cf471f2ae470090a10ddfd99ae/pe-bear/rebear_res.rc -------------------------------------------------------------------------------- /pe-bear/rebear_ver_short.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define REBEAR_MAJOR_VERSION 0 4 | #define REBEAR_MINOR_VERSION 7 5 | #define REBEAR_MICRO_VERSION 1 6 | #define REBEAR_PATCH_VERSION 0 7 | 8 | #define REBEAR_VERSION_STR "0.7.1" 9 | -------------------------------------------------------------------------------- /pe-bear/resources.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define IDI_ICON1 101 4 | -------------------------------------------------------------------------------- /pe-bear/resources.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #include "resources.h" 4 | 5 | #define APSTUDIO_READONLY_SYMBOLS 6 | ///////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Generated from the TEXTINCLUDE 2 resource. 9 | // 10 | #include "windows.h" 11 | 12 | ///////////////////////////////////////////////////////////////////////////// 13 | #undef APSTUDIO_READONLY_SYMBOLS 14 | 15 | 16 | #ifdef APSTUDIO_INVOKED 17 | ///////////////////////////////////////////////////////////////////////////// 18 | // 19 | // TEXTINCLUDE 20 | // 21 | 22 | 1 TEXTINCLUDE 23 | BEGIN 24 | "resources.h\0" 25 | END 26 | 27 | 2 TEXTINCLUDE 28 | BEGIN 29 | "#include ""windows.h""\r\n" 30 | "\0" 31 | END 32 | 33 | 3 TEXTINCLUDE 34 | BEGIN 35 | "\r\n" 36 | "\0" 37 | END 38 | 39 | #endif // APSTUDIO_INVOKED 40 | 41 | ///////////////////////////////////////////////////////////////////////////// 42 | // 43 | // Icon 44 | // 45 | 46 | // Icon with lowest ID value placed first to ensure application icon 47 | // remains consistent on all systems. 48 | IDI_ICON1 ICON "main_ico.ico" 49 | ///////////////////////////////////////////////////////////////////////////// 50 | 51 | #ifndef APSTUDIO_INVOKED 52 | ///////////////////////////////////////////////////////////////////////////// 53 | 54 | ///////////////////////////////////////////////////////////////////////////// 55 | #endif // not APSTUDIO_INVOKED 56 | 57 | -------------------------------------------------------------------------------- /xdg/appdata.metainfo.xml.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | @SCHEME_NAME@ 4 | CC0-1.0 5 | GPL-2.0-or-later 6 | @PROJECT_NAME@ 7 | Portable Executable reversing tool with a friendly GUI 8 | 9 |

PE-bear is a multiplatform reversing tool for PE (Portable Executable) files. Its objective is to deliver fast and flexible "first view" for malware analysts, stable and capable to handle malformed PE files.

10 |
11 | 12 | 13 | PE-bear Linux sections 14 | https://hshrzd.files.wordpress.com/2013/06/pe-bear_linux-sections.png 15 | 16 | 17 | https://hshrzd.wordpress.com/pe-bear/ 18 | https://github.com/hasherezade/pe-bear/issues 19 | https://github.com/hasherezade 20 | @SCHEME_NAME@.desktop 21 | hasherezade 22 | 23 |
24 | -------------------------------------------------------------------------------- /xdg/launcher.desktop.in: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Type=Application 3 | Name=@PROJECT_NAME@ 4 | GenericName=Portable Executable reversing tool 5 | Categories=Development;Utility; 6 | Comment=Portable Executable reversing tool with a friendly GUI 7 | Icon=@SCHEME_NAME@ 8 | Exec=@PROJECT_NAME@ %F 9 | Terminal=false 10 | MimeType=application/vnd.microsoft.portable-executable;application/x-msdownload; 11 | 12 | --------------------------------------------------------------------------------