├── .appveyor.yml ├── .github └── workflows │ ├── cppcheck.yml │ └── main.yml ├── .gitignore ├── .travis.yml ├── CMakeLists.txt ├── Doxyfile ├── LICENSE ├── README.md ├── bearparser.cppcheck ├── bearparser_autobuild.sh ├── build.sh ├── build_codelite.sh ├── build_qt4.sh ├── build_qt5.sh ├── build_qt6.sh ├── commander ├── CMakeLists.txt ├── Commander.cpp ├── Commander.h ├── ExeCommander.cpp ├── ExeCommander.h ├── PECommander.cpp ├── PECommander.h └── main.cpp ├── parser ├── AbstractByteBuffer.cpp ├── ByteBuffer.cpp ├── CMakeLists.txt ├── ExeElementWrapper.cpp ├── ExeFactory.cpp ├── ExeNodeWrapper.cpp ├── Executable.cpp ├── FileBuffer.cpp ├── Formatter.cpp ├── MappedExe.cpp ├── Util.cpp ├── WrappedValue.cpp ├── include │ └── bearparser │ │ ├── AbstractByteBuffer.h │ │ ├── ByteBuffer.h │ │ ├── CustomException.h │ │ ├── ExeElementWrapper.h │ │ ├── ExeFactory.h │ │ ├── ExeNodeWrapper.h │ │ ├── Executable.h │ │ ├── FileBuffer.h │ │ ├── Formatter.h │ │ ├── MappedExe.h │ │ ├── Util.h │ │ ├── WatchedLocker.h │ │ ├── WrappedValue.h │ │ ├── bearparser.h │ │ ├── core.h │ │ ├── pe.h │ │ ├── pe │ │ ├── BoundImpDirWrapper.h │ │ ├── ClrDirWrapper.h │ │ ├── CommonOrdinalsLookup.h │ │ ├── DOSExe.h │ │ ├── DataDirEntryWrapper.h │ │ ├── DataDirWrapper.h │ │ ├── DebugDirWrapper.h │ │ ├── DelayImpDirWrapper.h │ │ ├── DosHdrWrapper.h │ │ ├── ExceptionDirWrapper.h │ │ ├── ExportDirWrapper.h │ │ ├── FileHdrWrapper.h │ │ ├── ImportBaseDirWrapper.h │ │ ├── ImportDirWrapper.h │ │ ├── LdConfigDirWrapper.h │ │ ├── OptHdrWrapper.h │ │ ├── PECore.h │ │ ├── PEFile.h │ │ ├── PENodeWrapper.h │ │ ├── RelocDirWrapper.h │ │ ├── ResourceDirWrapper.h │ │ ├── ResourceLeafWrapper.h │ │ ├── RichHdrWrapper.h │ │ ├── SectHdrsWrapper.h │ │ ├── SecurityDirWrapper.h │ │ ├── TlsDirWrapper.h │ │ ├── lookup │ │ │ ├── CommonOrdinalsMap.h │ │ │ ├── CommonOrdinalsOleaut32.h │ │ │ └── CommonOrdinalsWS2_32.h │ │ ├── pe_formats.h │ │ ├── pe_undoc.h │ │ └── rsrc │ │ │ ├── ResourceContentFactory.h │ │ │ ├── ResourceContentWrapper.h │ │ │ ├── ResourceStringsWrapper.h │ │ │ ├── ResourceVersionWrapper.h │ │ │ ├── ResourcesAlbum.h │ │ │ └── pe_rsrc.h │ │ └── win_hdrs │ │ ├── poppack.h │ │ ├── pshpack1.h │ │ ├── pshpack2.h │ │ ├── pshpack4.h │ │ ├── pshpack8.h │ │ └── win_types.h └── pe │ ├── BoundImpDirWrapper.cpp │ ├── ClrDirWrapper.cpp │ ├── DOSExe.cpp │ ├── DataDirEntryWrapper.cpp │ ├── DataDirWrapper.cpp │ ├── DebugDirWrapper.cpp │ ├── DelayImpDirWrapper.cpp │ ├── DosHdrWrapper.cpp │ ├── ExceptionDirWrapper.cpp │ ├── ExportDirWrapper.cpp │ ├── FileHdrWrapper.cpp │ ├── ImportBaseDirWrapper.cpp │ ├── ImportDirWrapper.cpp │ ├── LdConfigDirWrapper.cpp │ ├── OptHdrWrapper.cpp │ ├── PECore.cpp │ ├── PEFile.cpp │ ├── PENodeWrapper.cpp │ ├── RelocDirWrapper.cpp │ ├── ResourceDirWrapper.cpp │ ├── RichHdrWrapper.cpp │ ├── SectHdrsWrapper.cpp │ ├── SecurityDirWrapper.cpp │ ├── TlsDirWrapper.cpp │ └── rsrc │ ├── ResourceContentFactory.cpp │ ├── ResourceContentWrapper.cpp │ ├── ResourceStringsWrapper.cpp │ ├── ResourceVersionWrapper.cpp │ └── ResourcesAlbum.cpp ├── test.sh ├── test_qt4.sh └── tests_list.txt /.appveyor.yml: -------------------------------------------------------------------------------- 1 | version: '{branch}.{build}' 2 | skip_tags: true 3 | 4 | image: 5 | - Visual Studio 2022 6 | - Visual Studio 2019 7 | 8 | matrix: 9 | exclude: 10 | - platform: x86 11 | image: Visual Studio 2022 12 | - platform: x64 13 | image: Visual Studio 2019 14 | - platform: x86 15 | 16 | platform: 17 | - x64 18 | - x86 19 | 20 | branches: 21 | only: 22 | - master 23 | build: 24 | verbosity: detailed 25 | 26 | configuration: 27 | - Release 28 | 29 | environment: 30 | artifactName: $(APPVEYOR_PROJECT_NAME)-$(APPVEYOR_REPO_COMMIT)-$(PLATFORM) 31 | buildPlatform: $(PLATFORM) 32 | 33 | for: 34 | - 35 | matrix: 36 | only: 37 | - image: Visual Studio 2022 38 | - image: Visual Studio 2019 39 | 40 | install: 41 | - git submodule update --init --recursive 42 | - if [%buildPlatform%]==[x64] (set QT_VER=6) 43 | - if [%buildPlatform%]==[x64] (set QT=C:\Qt\6.8\msvc2022_64) 44 | - if [%buildPlatform%]==[x86] (set QT_VER=5) 45 | - if [%buildPlatform%]==[x86] (set QT=C:\Qt\5.15.2\msvc2019) 46 | - set QT_DIR=%QT% 47 | - set PATH=%PATH%;%QT%\bin;%QT%\lib\cmake 48 | 49 | before_build: 50 | - mkdir build 51 | - cd build 52 | 53 | build_script: 54 | - if [%buildPlatform%]==[x64] ( cmake .. -A x64 ) 55 | - if [%buildPlatform%]==[x86] ( cmake .. -A Win32 -DUSE_QT5=ON ) 56 | - cmake --build . --config %CONFIGURATION% 57 | 58 | after_build: 59 | - mkdir %artifactName% 60 | - cp -r commander/%CONFIGURATION%/* %artifactName% 61 | - cp "%QT%\bin\Qt%QT_VER%Core.dll" %artifactName% 62 | 63 | artifacts: 64 | - path: build\%artifactName% 65 | 66 | -------------------------------------------------------------------------------- /.github/workflows/cppcheck.yml: -------------------------------------------------------------------------------- 1 | name: Static analysis 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v4 10 | 11 | - name: Install Cppcheck 12 | run: | 13 | sudo apt update 14 | sudo apt --yes install cppcheck 15 | 16 | - name: Static analysis 17 | run: | 18 | cppcheck --project=bearparser.cppcheck --error-exitcode=1 --enable=warning 19 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions 2 | 3 | name: Doxygen Action 4 | 5 | on: push 6 | 7 | permissions: 8 | contents: write 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v4 16 | 17 | - name: Doxygen Action 18 | uses: mattnotmitt/doxygen-action@v1.1.0 19 | with: 20 | doxyfile-path: "./Doxyfile" # default is ./Doxyfile 21 | working-directory: "." # default is . 22 | 23 | - name: Deploy 24 | uses: peaceiris/actions-gh-pages@v3 25 | with: 26 | github_token: ${{ secrets.GITHUB_TOKEN }} 27 | publish_dir: ./docs/html 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | build 3 | build_qt6/ 4 | build_qt5/ 5 | build_qt4/ 6 | test_cases/ 7 | docs/ 8 | .vs/ 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | 3 | os: 4 | - linux 5 | # - osx 6 | 7 | compiler: 8 | - gcc 9 | - clang 10 | 11 | addons: 12 | apt: 13 | packages: 14 | - qt5-default 15 | - qt5-qmake 16 | 17 | before_install: 18 | - | 19 | if [ "$TRAVIS_OS_NAME" == "osx" ]; then 20 | brew update-reset; 21 | brew upgrade cmake -v; 22 | brew install qt5; 23 | export PATH="/usr/local/opt/qt/bin:$PATH"; 24 | export LDFLAGS="-L/usr/local/opt/qt/lib"; 25 | export CPPFLAGS="-I/usr/local/opt/qt/include"; 26 | export PKG_CONFIG_PATH="/usr/local/opt/qt/lib/pkgconfig"; 27 | fi 28 | 29 | before_script: 30 | - cmake --version 31 | - qmake -v 32 | - mkdir build 33 | - cd build 34 | 35 | script: 36 | - cmake -DCMAKE_INSTALL_PREFIX:PATH=$(pwd) .. 37 | - cmake --build . --target install 38 | - ctest -V 39 | 40 | 41 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 3.12) 2 | project (re-bear) 3 | 4 | option(CMD_BUILD_TESTING "Enable testing for bearcommander" ON) 5 | 6 | # modules: 7 | set ( M_BEARPARSER "parser" ) 8 | set ( M_BEARCOMMANDER "commander" ) 9 | 10 | option(USE_QT4 "Use Qt4" OFF ) 11 | option(USE_QT5 "Use Qt5" OFF ) 12 | 13 | # modules paths: 14 | set (BEARPARSER_INC "${M_BEARPARSER}/include") 15 | 16 | set (BEARPARSER_DIR "${CMAKE_SOURCE_DIR}/${M_BEARPARSER}" CACHE PATH "BearParser main path") 17 | set (COMMANDER_DIR "${CMAKE_SOURCE_DIR}/${M_BEARCOMMANDER}" CACHE PATH "BearCommander main path") 18 | 19 | # Add bearparser includes: 20 | include_directories( ${BEARPARSER_INC} ) 21 | 22 | # Add sub-directories 23 | # 24 | # libs 25 | 26 | add_subdirectory ( ${M_BEARPARSER} ) 27 | set (PARSER_LIB bearparser CACHE PATH "BearParser library path") 28 | 29 | # executables 30 | add_subdirectory( ${M_BEARCOMMANDER} ) 31 | 32 | # dependencies 33 | add_dependencies(bearcommander bearparser) 34 | 35 | # Setup testing 36 | if(CMD_BUILD_TESTING) 37 | enable_testing() 38 | 39 | # 0) does the application run 40 | add_test (TestRuns ${CMAKE_BINARY_DIR}/bearcommander) 41 | set_tests_properties(TestRuns PROPERTIES PASS_REGULAR_EXPRESSION "Bearparser") 42 | IF (NOT WIN32) 43 | # 1) external tests 44 | add_test (TestExternal ${CMAKE_SOURCE_DIR}/test.sh ${CMAKE_SOURCE_DIR}) 45 | set_tests_properties(TestExternal PROPERTIES PASS_REGULAR_EXPRESSION "All passed") 46 | ENDIF() 47 | endif() 48 | 49 | 50 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014-2025, hasherezade 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | bearparser 2 | ========== 3 | [![Build status](https://ci.appveyor.com/api/projects/status/8p6wp0bcq2mx8208?svg=true)](https://ci.appveyor.com/project/hasherezade/bearparser) 4 | [![Codacy Badge](https://api.codacy.com/project/badge/Grade/bc1bdddf14244559ab4786939c6f9569)](https://app.codacy.com/gh/hasherezade/bearparser/dashboard?branch=master) 5 | 6 | Portable Executable parsing library 7 | 8 | Requires: 9 | 10 | + Qt6 SDK 11 | + Qt6 Core 12 | + cmake http://www.cmake.org/ 13 | 14 | **Possible to build with older versions of QT (Qt4, Qt5) by setting an appropriate CMake flag: `USE_QT4` or `USE_QT5`** 15 | 16 | Example: 17 | 18 | ``` 19 | cmake -G "Unix Makefiles" -D USE_QT4=ON ../ 20 | ``` 21 | 22 | 23 | ## Read more on Wiki: 24 | 25 | https://github.com/hasherezade/bearparser/wiki 26 | 27 | ## PE-bear 28 | 29 | PE-bear logo 30 | 31 | Check also PE-bear - a GUI application using `bearparser`: 32 | + https://github.com/hasherezade/pe-bear 33 | 34 | -------------------------------------------------------------------------------- /bearparser.cppcheck: -------------------------------------------------------------------------------- 1 | 2 | 3 | build/cppcheck 4 | false 5 | true 6 | true 7 | 10 8 | 100 9 | 10 | 11 | 12 | 13 | 14 | posix 15 | qt 16 | windows 17 | 18 | 19 | noExplicitConstructor 20 | useStlAlgorithm 21 | cstyleCast 22 | constVariablePointer 23 | 24 | 25 | -------------------------------------------------------------------------------- /bearparser_autobuild.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "Trying to autobuild bearparser..." 3 | 4 | git clone https://github.com/hasherezade/bearparser.git 5 | echo "[+] bearparser cloned" 6 | echo $$ 7 | cd bearparser 8 | sh build.sh 9 | 10 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ./build_qt5.sh 4 | -------------------------------------------------------------------------------- /build_codelite.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Trying to build bearparser..." 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 | echo "Trying to autobuild bearparser..." 3 | 4 | #QT check 5 | 6 | QT_VER=`qmake -v` 7 | str=$QT_VER 8 | substr="Qt version 4" 9 | 10 | echo $QT_VER 11 | if [[ $str == *"$substr"* ]]; then 12 | echo "[+] Qt4 found!" 13 | else 14 | str2=`whereis qt4` 15 | substr2="lib" 16 | if [[ $str2 == *"$substr2"* ]]; then 17 | echo "[+] Qt4 found!" 18 | else 19 | echo "Install Qt4 SDK first" 20 | exit -1 21 | fi 22 | fi 23 | 24 | CMAKE_VER=`cmake --version` 25 | CMAKEV="cmake version" 26 | if echo "$CMAKE_VER" | grep -q "$CMAKEV"; then 27 | echo "[+] CMake found!" 28 | else 29 | echo "[-] CMake NOT found!" 30 | echo "Install cmake first" 31 | exit -1 32 | fi 33 | 34 | BUILD_DIR=build_qt4 35 | rm build 36 | mkdir $BUILD_DIR 37 | echo "[+] build directory created" 38 | ln -sf $BUILD_DIR build 39 | cd $BUILD_DIR 40 | cmake -G "CodeLite - Unix Makefiles" -DUSE_QT4=ON -DUSE_QT5=OFF -DCMAKE_INSTALL_PREFIX:PATH=$(pwd) .. 41 | cmake --build . --target install 42 | 43 | -------------------------------------------------------------------------------- /build_qt5.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "Trying to autobuild bearparser..." 3 | 4 | #QT check 5 | 6 | QT_VER=`qmake -v` 7 | str=$QT_VER 8 | substr="Qt version 5" 9 | 10 | echo $QT_VER 11 | if [[ $str == *"$substr"* ]]; then 12 | echo "[+] Qt5 found!" 13 | else 14 | str2=`whereis qt5` 15 | substr2="/qt5" 16 | if [[ $str2 == *"$substr2"* ]]; then 17 | echo "[+] Qt5 found!" 18 | else 19 | echo "Install Qt5 SDK first" 20 | exit -1 21 | fi 22 | fi 23 | 24 | CMAKE_VER=`cmake --version` 25 | CMAKEV="cmake version" 26 | if echo "$CMAKE_VER" | grep -q "$CMAKEV"; then 27 | echo "[+] CMake found!" 28 | else 29 | echo "[-] CMake NOT found!" 30 | echo "Install cmake first" 31 | exit -1 32 | fi 33 | 34 | BUILD_DIR=build_qt5 35 | 36 | rm build 37 | mkdir $BUILD_DIR 38 | echo "[+] build directory created" 39 | ln -sf $BUILD_DIR build 40 | cd $BUILD_DIR 41 | cmake -G "CodeLite - Unix Makefiles" -DUSE_QT4=OFF -DUSE_QT5=ON -DCMAKE_INSTALL_PREFIX:PATH=$(pwd) .. 42 | cmake --build . --target install 43 | 44 | -------------------------------------------------------------------------------- /build_qt6.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "Trying to autobuild bearparser..." 3 | 4 | #QT check 5 | 6 | QT_VER=$(qmake -v) 7 | str=$QT_VER 8 | substr="Qt version 6" 9 | 10 | echo "$QT_VER" 11 | if [[ $str == *"$substr"* ]]; then 12 | echo "[+] Qt6 found!" 13 | else 14 | str2=$(whereis qt6) 15 | substr2="/qt6" 16 | if [[ $str2 == *"$substr2"* ]]; then 17 | echo "[+] Qt6 found!" 18 | else 19 | echo "Install Qt6 SDK first" 20 | exit -1 21 | fi 22 | fi 23 | 24 | CMAKE_VER=$(cmake --version) 25 | CMAKEV="cmake version" 26 | if echo "$CMAKE_VER" | grep -q "$CMAKEV"; then 27 | echo "[+] CMake found!" 28 | else 29 | echo "[-] CMake NOT found!" 30 | echo "Install cmake first" 31 | exit -1 32 | fi 33 | 34 | BUILD_DIR=build_qt6 35 | 36 | rm build 37 | mkdir $BUILD_DIR 38 | echo "[+] build directory created" 39 | ln -sf $BUILD_DIR build 40 | cd $BUILD_DIR 41 | cmake -G "CodeLite - Unix Makefiles" -DUSE_QT4=OFF -DUSE_QT5=OFF -DCMAKE_INSTALL_PREFIX:PATH=$(pwd) .. 42 | cmake --build . --target install 43 | 44 | -------------------------------------------------------------------------------- /commander/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 3.12) 2 | project (bearcommander) 3 | 4 | if(USE_QT4) 5 | find_package (Qt4 REQUIRED) 6 | include_directories( ${QT_INCLUDE_DIR} ${QT_QTCORE_INCLUDE_DIR} ) 7 | INCLUDE( ${QT_USE_FILE} ) 8 | ADD_DEFINITIONS( ${QT_DEFINITIONS} ) 9 | else() 10 | find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) 11 | find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED) 12 | get_target_property(QtCore_location Qt${QT_VERSION_MAJOR}::Core LOCATION) 13 | endif() 14 | 15 | set (imps_srcs 16 | main.cpp 17 | Commander.cpp 18 | ExeCommander.cpp 19 | PECommander.cpp 20 | ) 21 | 22 | set (imps_hdrs 23 | Commander.h 24 | ExeCommander.h 25 | PECommander.h 26 | ) 27 | 28 | add_executable (${PROJECT_NAME} ${imps_hdrs} ${imps_srcs} ) 29 | target_link_libraries(${PROJECT_NAME} ${PARSER_LIB}) 30 | 31 | if(USE_QT4) 32 | target_link_libraries (${PROJECT_NAME} ${QT_QTCORE_LIBRARIES} ) 33 | else() 34 | target_link_libraries(${PROJECT_NAME} Qt${QT_VERSION_MAJOR}::Core) 35 | endif() 36 | 37 | #install 38 | INSTALL( TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX} COMPONENT ${PROJECT_NAME} ) 39 | 40 | -------------------------------------------------------------------------------- /commander/Commander.cpp: -------------------------------------------------------------------------------- 1 | #include "Commander.h" 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | Commander::Commander(CmdContext *v_context) 8 | : context(v_context) 9 | { 10 | if (this->context == NULL) throw CmdException("Uninitialized commander context!"); 11 | addCommand("q", new QuitCommand()); 12 | } 13 | 14 | void Commander::clearCommands() 15 | { 16 | std::map::iterator itr; 17 | for (itr = cmds.begin(); itr != cmds.end(); ++itr) { 18 | Command* cmd = itr->second; 19 | delete cmd; 20 | } 21 | this->cmds.clear(); 22 | } 23 | 24 | void Commander::printHelp() 25 | { 26 | std::cout << "Available commands: " << cmds.size() << endl; 27 | std::map::iterator itr; 28 | for (itr = cmds.begin(); itr != cmds.end(); ++itr) { 29 | Command *cmd = itr->second; 30 | if (cmd == NULL) continue; 31 | std::cout << itr->first << " \t- " << cmd->getDescription() << endl; 32 | } 33 | } 34 | 35 | Command* Commander::getCommand(const std::string& line) 36 | { 37 | std::string name = line; 38 | //TODO: split the line... 39 | if (cmds.find(name) == cmds.end() ) { 40 | std::cerr << "No such command" << endl; 41 | return NULL; 42 | } 43 | 44 | Command *cmd = this->cmds[name]; 45 | return cmd; 46 | } 47 | 48 | bool Commander::addCommand(const std::string& name, Command *cmd, bool overwrite) 49 | { 50 | if ( cmds.find(name) != cmds.end() ) { 51 | if (!overwrite) return false; // already exist 52 | delete this->cmds[name]; 53 | this->cmds[name] = NULL; 54 | } 55 | this->cmds[name] = cmd; 56 | return true; 57 | } 58 | 59 | void Commander::parseCommands() 60 | { 61 | const std::string PROMPT = "$ "; 62 | 63 | while (true) { 64 | if (this->context == NULL) throw CmdException("Uninitialized commander context!"); 65 | if (this->context->isEndProcessing()) break; 66 | 67 | std::cout << PROMPT; 68 | std::string line; 69 | std::cin >> line; 70 | 71 | Command *cmd = getCommand(line); 72 | 73 | if (cmd == NULL) { 74 | this->printHelp(); 75 | continue; 76 | } 77 | try { 78 | CmdParams *params = cmd->fetchParams(line); 79 | cmd->execute(params, this->context); 80 | } catch (CustomException &e) { 81 | std::cerr << "ERROR: " << e.what() << endl; 82 | } 83 | } 84 | } 85 | 86 | -------------------------------------------------------------------------------- /commander/Commander.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | class Commander; 11 | 12 | class CmdException : public CustomException 13 | { 14 | public: 15 | CmdException(const QString& info) : CustomException(info) {} 16 | }; 17 | 18 | class CmdParams 19 | { 20 | public: 21 | CmdParams() {} 22 | virtual ~CmdParams() {} 23 | }; 24 | 25 | class CmdContext 26 | { 27 | public: 28 | CmdContext() : endProcessing(false) {} 29 | virtual ~CmdContext() {} 30 | void stopProcessing() { endProcessing = true; } 31 | bool isEndProcessing() { return endProcessing; } 32 | 33 | protected: 34 | bool endProcessing; 35 | 36 | friend class Commander; 37 | }; 38 | 39 | class Command 40 | { 41 | public: 42 | Command() {} 43 | Command(const std::string& v_desc) : desc(v_desc) {} 44 | virtual ~Command() {} 45 | 46 | virtual std::string getDescription() { return desc; } 47 | 48 | virtual void execute(CmdParams *params, CmdContext *context_ptr) = 0; // throws exceptions 49 | virtual CmdParams* fetchParams(std::string stream)// throws exception 50 | { 51 | return NULL; 52 | } 53 | 54 | protected: 55 | std::string desc; 56 | }; 57 | 58 | class QuitCommand : public Command 59 | { 60 | public: 61 | QuitCommand() : Command("Quit") {} 62 | 63 | virtual void execute(CmdParams *params, CmdContext *context_ptr) 64 | { 65 | if (context_ptr == NULL) { 66 | return; 67 | } 68 | context_ptr->stopProcessing(); 69 | } 70 | 71 | }; 72 | 73 | class Commander 74 | { 75 | public: 76 | Commander(CmdContext *v_context); 77 | virtual ~Commander() { clearCommands(); } 78 | 79 | void printHelp(); 80 | bool addCommand(const std::string& name, Command *cmd, bool overwrite = true); 81 | 82 | virtual void parseCommands(); // main loop 83 | 84 | protected: 85 | Command* getCommand(const std::string& line); 86 | void clearCommands(); 87 | 88 | std::map cmds; 89 | CmdContext *context; 90 | }; 91 | 92 | -------------------------------------------------------------------------------- /commander/PECommander.cpp: -------------------------------------------------------------------------------- 1 | #include "PECommander.h" 2 | #include 3 | 4 | using namespace std; 5 | 6 | PEFile* cmd_util::getPEFromContext(CmdContext *ctx) 7 | { 8 | Executable* exe = cmd_util::getExeFromContext(ctx); 9 | PEFile *pe = dynamic_cast(exe); 10 | if (!pe) { 11 | std::cerr << "It's not a PE file" << std::endl; 12 | } 13 | return pe; 14 | } 15 | 16 | void cmd_util::printSectionMapping(SectionHdrWrapper *sec, Executable::addr_type aType) 17 | { 18 | if (sec == NULL) return; 19 | 20 | offset_t hdrStart = sec->getContentOffset(aType, false); 21 | bufsize_t hdrSize = sec->getContentSize(aType, false); 22 | 23 | offset_t start = sec->getContentOffset(aType, true); 24 | bufsize_t size = sec->getContentSize(aType, true); 25 | 26 | std::string typeStr = cmd_util::addrTypeToStr(aType); 27 | printf("[%s]\n",typeStr.c_str()); 28 | printf(" ------------[In Hdr]------[Mapped]\n"); 29 | printf(" Offset: %10llX \t%10llX\n", 30 | static_cast(hdrStart), 31 | static_cast(start) 32 | ); 33 | printf(" Size: %10lX \t%10lX\n", 34 | static_cast(hdrSize), 35 | static_cast(size) 36 | ); 37 | printf(" Scope: [%10llX - %10llX], size = %lX\n", 38 | static_cast(start), 39 | static_cast(start + size), 40 | static_cast(size) 41 | ); 42 | printf(" \n"); 43 | } 44 | 45 | void cmd_util::printResourceTypes(PEFile *pe) 46 | { 47 | if (pe == NULL || pe->getResourcesAlbum() == NULL) return; 48 | ResourcesAlbum *album = pe->getResourcesAlbum(); 49 | std::vector types = album->getResourceTypes(); 50 | for (size_t i = 0 ; i < types.size(); i++) { 51 | pe::resource_type type = types[i]; 52 | QString info = ResourceContentWrapper::translateType(type); 53 | printf("[%3d]\t%s\n", type, info.toStdString().c_str()); 54 | } 55 | } 56 | 57 | void cmd_util::printStrings(PEFile *pe, size_t limit) 58 | { 59 | ResourcesContainer *allStrings = pe->getResourcesOfType(pe::RESTYPE_STRING); 60 | if (allStrings == NULL) return; 61 | 62 | size_t wrappersCount = allStrings->count(); 63 | if (wrappersCount == 0) { 64 | std::cout <<"No Strings in Resources!\n"; 65 | return; 66 | } 67 | 68 | size_t limCount = 0; 69 | for (size_t i = 0; i < wrappersCount; i++) { 70 | ResourceStringsWrapper* wrapper = dynamic_cast(allStrings->getWrapperAt(i)); 71 | if (wrapper == NULL) { 72 | std::cout << "[ERROR] Null wrapper!\n"; 73 | continue; 74 | } 75 | size_t count = wrapper->getResStringsCount(); 76 | 77 | for (size_t j = 0; j < count; j++) { 78 | if (limit != 0 && limCount >= limit) return; 79 | 80 | ResString *resStr = wrapper->getResStringAt(j); 81 | if (resStr != NULL) { 82 | OUT_PADDED_OFFSET(std::cout, resStr->offset); 83 | std::cout << " [" << std::dec << resStr->getSize() << "]" << std::endl; 84 | std::cout << resStr->getQString().toStdString() << "\n"; 85 | limCount++; 86 | } 87 | } 88 | } 89 | std::cout << std::endl; 90 | } 91 | 92 | void cmd_util::dumpResourcesInfo(PEFile *pe, pe::resource_type type, size_t wrapperId) 93 | { 94 | ResourcesContainer* wrappers = pe->getResourcesOfType(type); 95 | 96 | if (wrappers == NULL || wrappers->count() == 0) { 97 | std::cout << "No such resource type" << std::endl; 98 | return; 99 | } 100 | size_t wrappersCount = wrappers->count(); 101 | if (wrapperId >= wrappersCount) { 102 | return; 103 | } 104 | std::cout << "Found in Resources:" 105 | << std::dec << wrappers->entriesCount() 106 | << std::dec << wrappersCount 107 | << std::endl; 108 | 109 | ResourceContentWrapper* wrapper = wrappers->getWrapperAt(wrapperId); 110 | if (wrapper == NULL) { 111 | return; 112 | } 113 | cmd_util::dumpEntryInfo(wrapper); 114 | cmd_util::dumpNodeInfo(dynamic_cast(wrapper)); 115 | } 116 | 117 | void cmd_util::listDataDirs(PEFile *pe) 118 | { 119 | DataDirWrapper *dDir = dynamic_cast(pe->getWrapper(PEFile::WR_DATADIR)); 120 | const int recordsCount = (dDir) ? dDir->getDirsCount() : 0; 121 | for (size_t i = 0 ; i < recordsCount; i++) { 122 | DataDirEntryWrapper* entry = pe->getDataDirEntry(pe::dir_entry(i)); 123 | if (entry == NULL) { 124 | continue; 125 | } 126 | std::cout << "[" << i << "]" 127 | << entry->getName().toStdString() 128 | << std::endl; 129 | } 130 | } 131 | 132 | //------------------------------------------ 133 | void PECommander::initCommands() 134 | { 135 | this->addCommand("secV", new SectionByAddrCommand(Executable::RVA, "Section by RVA")); 136 | this->addCommand("secR", new SectionByAddrCommand(Executable::RAW, "Section by RAW")); 137 | 138 | this->addCommand("rstrings", new PrintStringsCommand("Print Strings from resources")); 139 | this->addCommand("rsl", new PrintWrapperTypesCommand("List Resource Types")); 140 | this->addCommand("rs", new WrapperInfoCommand("Resource Info")); 141 | 142 | this->addCommand("dir_mv", new MoveDataDirEntryCommand("Move DataDirectory")); 143 | this->addCommand("secinfo", new SectionDumpCommand("Dump chosen Section info")); 144 | this->addCommand("secfdump", new SectionDumpCommand("Dump chosen Section Content into a file", true)); 145 | 146 | this->addCommand("explist", new ExportsListCommand("List all exports")); 147 | this->addCommand("implist", new ImportsListCommand("List all imports")); 148 | } 149 | 150 | -------------------------------------------------------------------------------- /commander/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "PECommander.h" 9 | 10 | #define TITLE "BearCommander" 11 | #define MINBUF 0x200 12 | 13 | using namespace std; 14 | 15 | FileView* tryLoading(QString &fName) 16 | { 17 | FileView *fileView = NULL; 18 | bufsize_t maxMapSize = FILE_MAXSIZE; 19 | do { 20 | if (!QFile::exists(fName)) { 21 | std::cerr << "[ERROR] " << "The file does not exist" << std::endl; 22 | break; 23 | } 24 | try { 25 | fileView = new FileView(fName, maxMapSize); 26 | } catch (BufferException &e1) { 27 | std::cerr << "[ERROR] " << e1.what() << std::endl; 28 | maxMapSize = static_cast(cmd_util::readNumber("Try again with size (hex): ", true)); 29 | if (maxMapSize == 0) break; 30 | } 31 | } while (!fileView); 32 | 33 | return fileView; 34 | } 35 | 36 | int main(int argc, char *argv[]) 37 | { 38 | QCoreApplication app(argc, argv); 39 | 40 | ExeFactory::init(); 41 | ExeCmdContext exeContext; 42 | PECommander commander(&exeContext); 43 | 44 | if (argc < 2) { 45 | std::cout << "Bearparser version: " << BEARPARSER_VERSION << "\n"; 46 | std::cout << "Args: \n"; 47 | commander.printHelp(); 48 | return 0; 49 | } 50 | 51 | int status = 0; 52 | QString fName = QString(argv[1]); 53 | 54 | try { 55 | FileView* fileView = tryLoading(fName); 56 | if (!fileView) return -1; 57 | 58 | ExeFactory::exe_type exeType = ExeFactory::findMatching(fileView); 59 | if (exeType == ExeFactory::NONE) { 60 | std::cerr << "Type not supported\n"; 61 | ExeFactory::destroy(); 62 | return 1; 63 | } 64 | 65 | std::cout << "Type: " << ExeFactory::getTypeName(exeType).toStdString() << std::endl; 66 | bufsize_t readableSize = fileView->getContentSize(); 67 | bufsize_t allocSize = (readableSize < MINBUF) ? MINBUF : readableSize; 68 | 69 | std::cout << "Buffering..." << std::endl; 70 | ByteBuffer *buf = new ByteBuffer(fileView, 0, allocSize); 71 | delete fileView; fileView = NULL; //the view is no longer needed 72 | 73 | std::cout << "Parsing executable..." << std::endl; 74 | Executable *exe = ExeFactory::build(buf, exeType); 75 | 76 | exeContext.setExe(exe); 77 | commander.parseCommands(); 78 | 79 | delete exe; 80 | delete buf; 81 | 82 | std::cout << "Bye!" << std::endl; 83 | 84 | } catch (CustomException &e) { 85 | std::cerr << "[ERROR] " << e.what() << std::endl; 86 | status = -1; 87 | } 88 | ExeFactory::destroy(); 89 | return status; 90 | } 91 | 92 | -------------------------------------------------------------------------------- /parser/ByteBuffer.cpp: -------------------------------------------------------------------------------- 1 | #include "ByteBuffer.h" 2 | #include 3 | #include 4 | 5 | 6 | void ByteBuffer::_init(const bufsize_t& v_size, const bufsize_t& v_padding) 7 | { 8 | if (v_size == 0) throw BufferException("Zero size requested"); 9 | 10 | this->content = allocContent(v_size, v_padding); 11 | if (this->content) { 12 | this->padding = v_padding; 13 | this->contentSize = v_size; 14 | this->originalSize = v_size; 15 | } 16 | } 17 | 18 | ByteBuffer::ByteBuffer(bufsize_t v_size, bufsize_t v_padding) 19 | : content(nullptr), contentSize(0), padding(0), originalSize(0) 20 | { 21 | _init(v_size, v_padding); 22 | } 23 | 24 | ByteBuffer::ByteBuffer(BYTE* v_content, bufsize_t v_size, bufsize_t v_padding) 25 | : content(nullptr), contentSize(0), padding(0), originalSize(0) 26 | { 27 | _init(v_size, v_padding); 28 | if (this->content && v_content) { 29 | ::memcpy(this->content, v_content, v_size); 30 | } 31 | } 32 | 33 | ByteBuffer::ByteBuffer(AbstractByteBuffer *v_parent, offset_t v_offset, bufsize_t v_size, bufsize_t v_padding) 34 | : content(nullptr), contentSize(0), padding(0), originalSize(0) 35 | { 36 | if (!v_parent) throw BufferException("Cannot make subBuffer for NULL buffer!"); 37 | if (!v_size) throw BufferException("Cannot make 0 size buffer!"); 38 | 39 | bufsize_t parentSize = v_parent->getContentSize(); 40 | 41 | bufsize_t copySize = v_size < parentSize ? v_size : parentSize; 42 | bufsize_t allocSize = v_size > parentSize ? v_size : parentSize; 43 | 44 | BYTE *bContent = v_parent->getContentAt(v_offset, copySize); 45 | if (!bContent) throw BufferException("Cannot make Buffer for NULL content!"); 46 | 47 | _init(v_size, v_padding); 48 | if (this->content && bContent) { 49 | ::memcpy(this->content, bContent, v_size); 50 | } 51 | } 52 | 53 | BYTE* ByteBuffer::allocContent(bufsize_t v_size, bufsize_t v_padding) 54 | { 55 | if (!v_size) throw BufferException("Zero size requested"); 56 | if (v_size >= BUFSIZE_MAX || v_size >= LLONG_MAX) throw BufferException("Too big size requested"); 57 | 58 | const bufsize_t allocSize = v_size + v_padding; 59 | const bufsize_t sizeDiff = (allocSize > this->contentSize) ? (allocSize - this->contentSize) : 0; 60 | 61 | BYTE* content = reinterpret_cast(::realloc((void*)this->content, allocSize)); 62 | if (!content) { 63 | throw BufferException("Cannot allocate buffer of size: 0x" + QString::number(allocSize, 16)); 64 | } 65 | if (sizeDiff) { 66 | ::memset(content + this->contentSize, 0, sizeDiff); 67 | } 68 | return content; 69 | } 70 | 71 | bool ByteBuffer::resize(bufsize_t newSize) 72 | { 73 | if (newSize == this->contentSize) { 74 | return true; 75 | } 76 | BYTE *newContent = nullptr; 77 | bool isOk = true; 78 | try { 79 | newContent = allocContent(newSize, this->padding); 80 | if (newContent) { 81 | this->content = newContent; 82 | this->contentSize = newSize; 83 | } 84 | } catch (const BufferException&) { 85 | isOk = false; 86 | } 87 | return isOk; 88 | } 89 | 90 | ByteBuffer::~ByteBuffer() 91 | { 92 | ::free(this->content); 93 | } 94 | -------------------------------------------------------------------------------- /parser/ExeElementWrapper.cpp: -------------------------------------------------------------------------------- 1 | #include "ExeElementWrapper.h" 2 | 3 | ExeElementWrapper::ExeElementWrapper(Executable *v_exe) 4 | : m_Exe(v_exe) 5 | { 6 | if (v_exe == NULL) { 7 | Logger::append(Logger::D_ERROR, "Cannot initialize with Exe == NULL!"); 8 | throw CustomException("Cannot initialize with Exe == NULL!"); 9 | } 10 | } 11 | 12 | bufsize_t ExeElementWrapper::getFieldSize(size_t fieldId, size_t subField) 13 | { 14 | size_t fieldsCount = getFieldsCount(); 15 | if (fieldId >= fieldsCount) return this->getSize(); 16 | 17 | void *ptr = this->getFieldPtr(fieldId, subField); 18 | if (ptr == NULL) return 0; 19 | 20 | void *nextPtr = NULL; 21 | size_t nextFID = fieldId + 1; 22 | 23 | if (nextFID < fieldsCount ) nextPtr = this->getFieldPtr(nextFID, subField); 24 | if (nextPtr != NULL) { 25 | int64_t dif = offset_t (nextPtr) - offset_t (ptr); 26 | if (dif < 0) return 0; 27 | 28 | return (bufsize_t) dif; 29 | } 30 | 31 | offset_t fullSize = this->getSize(); 32 | BYTE *bgnPtr = (BYTE*) getPtr(); 33 | BYTE *endPtr = bgnPtr + fullSize; 34 | offset_t dif = offset_t (endPtr) - offset_t (ptr); 35 | 36 | return (bufsize_t) dif; 37 | } 38 | 39 | offset_t ExeElementWrapper::getOffset() 40 | { 41 | BYTE *ptr = (BYTE*)this->getPtr(); 42 | return getOffset(ptr); 43 | } 44 | 45 | offset_t ExeElementWrapper::getOffset(void *ptr, bool allowExceptions) 46 | { 47 | if (!m_Exe) return INVALID_ADDR; 48 | return m_Exe->getOffset(ptr, allowExceptions); 49 | } 50 | 51 | offset_t ExeElementWrapper::getFieldOffset(size_t fieldId, size_t subField) 52 | { 53 | void* ptr = getFieldPtr(fieldId, subField); 54 | return getOffset(ptr); 55 | } 56 | 57 | WrappedValue ExeElementWrapper::getWrappedValue(size_t fieldId, size_t subFieldId) 58 | { 59 | if (fieldId == -1) return WrappedValue(); //EMPTY 60 | void* ptr = getFieldPtr(fieldId, subFieldId); 61 | if (ptr == NULL) return WrappedValue(); //EMPTY 62 | 63 | bufsize_t fieldSize = getFieldSize(fieldId, subFieldId); 64 | if (fieldSize == BUFSIZE_MAX || fieldSize == 0) return WrappedValue(); //EMPTY 65 | 66 | offset_t offset = this->getOffset(ptr); 67 | if (offset == INVALID_ADDR) return WrappedValue(); //EMPTY 68 | 69 | WrappedValue::data_type dataType = this->containsDataType(fieldId, subFieldId); 70 | return WrappedValue(this->m_Exe, offset, fieldSize, dataType); 71 | } 72 | 73 | uint64_t ExeElementWrapper::getNumValue(size_t fId, size_t subField, bool* isOk) 74 | { 75 | if (isOk) (*isOk) = false; 76 | if (this->m_Exe == NULL) return (-1); 77 | 78 | offset_t offset = this->getFieldOffset(fId, subField); 79 | bufsize_t size = this->getFieldSize(fId, subField); 80 | return this->m_Exe->getNumValue(offset, size, isOk); 81 | } 82 | 83 | bool ExeElementWrapper::setNumValue(size_t fId, size_t subField, uint64_t newVal) 84 | { 85 | if (this->m_Exe == NULL) return false; 86 | 87 | offset_t offset = this->getFieldOffset(fId, subField); 88 | bufsize_t size = this->getFieldSize(fId, subField); 89 | return this->m_Exe->setNumValue(offset, size, newVal); 90 | } 91 | 92 | bool ExeElementWrapper::canCopyToOffset(offset_t rawOffset) 93 | { 94 | if (this->m_Exe == NULL) return false; 95 | 96 | if (this->m_Exe->isAreaEmpty(rawOffset, getSize()) == false) { 97 | return false; 98 | } 99 | return true; 100 | } 101 | 102 | bool ExeElementWrapper::copyToOffset(offset_t rawOffset) 103 | { 104 | if (this->m_Exe == NULL) return false; 105 | 106 | if (canCopyToOffset(rawOffset) == false) { 107 | Logger::append(Logger::D_ERROR,"The area is not empty!"); 108 | return false; 109 | } 110 | if (m_Exe->pasteBuffer(rawOffset, this, false) == false) { 111 | Logger::append(Logger::D_ERROR,"Cannot paste the buffer!"); 112 | return false; 113 | } 114 | return true; 115 | } 116 | -------------------------------------------------------------------------------- /parser/ExeFactory.cpp: -------------------------------------------------------------------------------- 1 | #include "ExeFactory.h" 2 | 3 | #include "pe/DOSExe.h" 4 | #include "pe/PEFile.h" 5 | 6 | std::map ExeFactory::builders; 7 | 8 | void ExeFactory::init() 9 | { 10 | if (builders.size() > 0) { 11 | return; // already initialized 12 | } 13 | builders[MZ] = new DOSExeBuilder(); 14 | builders[PE] = new PEFileBuilder(); 15 | } 16 | 17 | void ExeFactory::destroy() 18 | { 19 | std::map::iterator itr; 20 | for (itr = builders.begin(); itr != builders.end(); ++itr) { 21 | ExeBuilder* builder = itr->second; 22 | delete builder; 23 | } 24 | builders.clear(); 25 | } 26 | 27 | ExeFactory::exe_type ExeFactory::findMatching(AbstractByteBuffer *buf) 28 | { 29 | if (!buf) return NONE; 30 | 31 | ExeFactory::init(); //ensue that the builders are initialized 32 | 33 | std::map::iterator itr; 34 | for (itr = builders.begin(); itr != builders.end(); ++itr) { 35 | 36 | ExeBuilder* builder = itr->second; 37 | if (builder == NULL) continue; 38 | 39 | if (builder->signatureMatches(buf)) { 40 | return itr->first; 41 | } 42 | } 43 | return NONE; 44 | } 45 | 46 | Executable* ExeFactory::build(AbstractByteBuffer *buf, exe_type type) 47 | { 48 | ExeFactory::init(); //ensue that the builders are initialized 49 | 50 | if (builders.find(type) == builders.end()) { 51 | return NULL; 52 | } 53 | ExeBuilder* builder = builders[type]; 54 | if (!builder) return NULL; 55 | 56 | return builder->build(buf); 57 | } 58 | 59 | QString ExeFactory::getTypeName(exe_type type) 60 | { 61 | ExeFactory::init(); //ensue that the builders are initialized 62 | 63 | if (builders.find(type) == builders.end()) return "Not supported"; 64 | 65 | ExeBuilder* builder = builders[type]; 66 | if (builder == NULL) return "Not supported"; 67 | 68 | return builder->typeName(); 69 | } 70 | -------------------------------------------------------------------------------- /parser/ExeNodeWrapper.cpp: -------------------------------------------------------------------------------- 1 | #include "ExeNodeWrapper.h" 2 | 3 | ExeNodeWrapper::ExeNodeWrapper(Executable *exec, ExeNodeWrapper* parent) 4 | : ExeElementWrapper(exec), parentNode(parent), entryNum(0) 5 | { 6 | wrap(); 7 | } 8 | 9 | ExeNodeWrapper::ExeNodeWrapper(Executable *exec, ExeNodeWrapper* parent, size_t entryNumber) 10 | : ExeElementWrapper(exec), parentNode(parent), entryNum(entryNumber) 11 | { 12 | wrap(); 13 | } 14 | 15 | ExeNodeWrapper* ExeNodeWrapper::getEntryAt(size_t fieldId) 16 | { 17 | return this->getEntryAt(this->entries, fieldId); 18 | } 19 | 20 | ExeNodeWrapper* ExeNodeWrapper::getEntryAt(std::vector &_entries, size_t fieldId) 21 | { 22 | return (fieldId < _entries.size()) ? _entries[fieldId] : NULL; 23 | } 24 | 25 | size_t ExeNodeWrapper::getEntriesCount(std::vector &_entries) 26 | { 27 | return _entries.size(); 28 | } 29 | 30 | void ExeNodeWrapper::clear() 31 | { 32 | size_t entriesCount = this->entries.size(); 33 | for (size_t i = 0; i < entriesCount; i++) { 34 | delete this->entries[i]; 35 | } 36 | this->entries.clear(); 37 | } 38 | 39 | void* ExeNodeWrapper::getSubfieldPtr(size_t fieldId, size_t subField) 40 | { 41 | ExeNodeWrapper* entry = this->getEntryAt(fieldId); 42 | if (!entry) return NULL; 43 | //--- 44 | return entry->getFieldPtr(subField); 45 | } 46 | 47 | bufsize_t ExeNodeWrapper::getSubfieldSize(size_t fieldId, size_t subField) 48 | { 49 | ExeNodeWrapper* entry = this->getEntryAt(fieldId); 50 | if (!entry) return 0; 51 | //--- 52 | return entry->getFieldSize(subField); 53 | } 54 | 55 | QString ExeNodeWrapper::getSubfieldName(size_t fieldId, size_t subField) 56 | { 57 | ExeNodeWrapper* entry = this->getEntryAt(fieldId); 58 | if (!entry) return ""; 59 | //--- 60 | return entry->getFieldName(subField); 61 | } 62 | 63 | bool ExeNodeWrapper::canAddEntry() 64 | { 65 | offset_t nextOffset = getNextEntryOffset(); 66 | bufsize_t entrySize = geEntrySize(); 67 | if (entrySize == 0) return false; 68 | 69 | bufsize_t paddedSize = entrySize * 2; 70 | bool haveSpace = this->m_Exe->isAreaEmpty(nextOffset, paddedSize); 71 | Logger::append(Logger::D_INFO, 72 | "NextOffset = %llX size = %lX, canAdd: %u", 73 | static_cast(nextOffset), 74 | static_cast(entrySize), 75 | static_cast(haveSpace) 76 | ); 77 | return haveSpace; 78 | } 79 | 80 | bool ExeNodeWrapper::isMyEntryType(ExeNodeWrapper *entry) 81 | { 82 | if (!entry) return false; 83 | return true; //type cast check in inherited wrappers 84 | } 85 | 86 | ExeNodeWrapper* ExeNodeWrapper::getLastEntry() 87 | { 88 | size_t lastId = this->getEntriesCount() - 1; 89 | return this->getEntryAt(lastId); 90 | } 91 | 92 | offset_t ExeNodeWrapper::getNextEntryOffset() 93 | { 94 | ExeNodeWrapper *lastEntry = getLastEntry(); 95 | if (lastEntry == NULL) return INVALID_ADDR; 96 | 97 | offset_t lastOffset = lastEntry->getOffset(); 98 | if (lastOffset == INVALID_ADDR) return INVALID_ADDR; 99 | 100 | bufsize_t entrySize = lastEntry->getSize(); 101 | offset_t nextOffset = lastOffset + entrySize; 102 | return nextOffset; 103 | } 104 | 105 | bufsize_t ExeNodeWrapper::geEntrySize() 106 | { 107 | ExeNodeWrapper *lastEntry = getLastEntry(); 108 | if (lastEntry == NULL) return 0; 109 | 110 | bufsize_t entrySize = lastEntry->getSize(); 111 | return entrySize; 112 | } 113 | 114 | ExeNodeWrapper* ExeNodeWrapper::addEntryAt(ExeNodeWrapper *entry, offset_t nextOffset) 115 | { 116 | if (canAddEntry() == false) return NULL; 117 | 118 | size_t entryNum = this->getEntriesCount(); 119 | 120 | if (nextOffset == INVALID_ADDR) return NULL; 121 | if (entry == NULL) { 122 | // if no entry supplied, duplicate the last entry... 123 | entry = this->getLastEntry(); 124 | } 125 | 126 | if (isMyEntryType(entry) == false) return NULL; 127 | // if (entrySize != entry->getSize()) return NULL; 128 | if (m_Exe->pasteBuffer(nextOffset, entry, false) == false) { 129 | return NULL; 130 | } 131 | if (loadNextEntry(entryNum) == false) return NULL; 132 | reloadMapping(); 133 | Logger::append(Logger::D_INFO, 134 | "Entries count: %lu", 135 | static_cast(this->getEntriesCount()) 136 | ); 137 | return getLastEntry(); 138 | } 139 | 140 | ExeNodeWrapper* ExeNodeWrapper::addEntry(ExeNodeWrapper *entry) 141 | { 142 | offset_t offset = getNextEntryOffset(); 143 | return addEntryAt(entry, offset); 144 | } 145 | 146 | -------------------------------------------------------------------------------- /parser/FileBuffer.cpp: -------------------------------------------------------------------------------- 1 | #include "FileBuffer.h" 2 | 3 | 4 | FileView::FileView(QString &path, bufsize_t maxSize) 5 | : AbstractFileBuffer(path), fIn (path) 6 | { 7 | if (fIn.open(QIODevice::ReadOnly) == false) { 8 | throw FileBufferException("Cannot open the file: " + path); 9 | } 10 | this->fileSize = fIn.size(); 11 | if (fileSize == 0) { 12 | std::cerr << fIn.errorString().toStdString() << std::endl; 13 | throw FileBufferException("The file is empty"); 14 | } 15 | bufsize_t readableSize = getMappableSize(fIn); 16 | this->mappedSize = (readableSize > maxSize) ? maxSize : readableSize; 17 | 18 | uchar *pData = fIn.map(0, this->mappedSize); 19 | if (!pData) { 20 | throw BufferException("Cannot map the file: " + path + " of size: 0x" + QString::number(this->mappedSize, 16)); 21 | } 22 | this->mappedContent = (BYTE*) pData; 23 | } 24 | 25 | FileView::~FileView() 26 | { 27 | fIn.unmap((uchar*)this->mappedContent); 28 | fIn.close(); 29 | } 30 | 31 | bufsize_t FileView::getMappableSize(QFile &fIn) 32 | { 33 | bufsize_t size = getReadableSize(fIn); 34 | if (size > FILEVIEW_MAXSIZE) { 35 | size = FILEVIEW_MAXSIZE; 36 | } 37 | return size; 38 | } 39 | //---------------------------------------------------------------- 40 | 41 | ByteBuffer* AbstractFileBuffer::read(QString &path, bufsize_t minBufSize, const bool allowTruncate) 42 | { 43 | QFile fIn(path); 44 | if (fIn.open(QIODevice::ReadOnly) == false) { 45 | throw FileBufferException("Cannot open the file: " + path); 46 | } 47 | ByteBuffer *bufferedFile = read(fIn, minBufSize, allowTruncate); 48 | fIn.close(); 49 | return bufferedFile; 50 | } 51 | 52 | ByteBuffer* AbstractFileBuffer::read(QFile &fIn, bufsize_t minBufSize, const bool allowTruncate) //throws exceptions 53 | { 54 | bufsize_t readableSize = getReadableSize(fIn); 55 | bufsize_t allocSize = (readableSize < minBufSize) ? minBufSize : readableSize; 56 | 57 | ByteBuffer *bufferedFile = NULL; 58 | do { 59 | try { 60 | bufferedFile = new ByteBuffer(allocSize); //throws exceptions 61 | } 62 | catch (CustomException) 63 | { 64 | if (!allowTruncate) throw; 65 | allocSize /= 2; 66 | } 67 | } while(!bufferedFile && allocSize); 68 | 69 | char *content = (char*) bufferedFile->getContent(); 70 | bufsize_t contentSize = bufferedFile->getContentSize(); 71 | 72 | if (!content || !contentSize) throw FileBufferException("Cannot allocate buffer"); 73 | //printf("Reading...%lx , BUFSIZE_MAX = %lx\n", allocSize, BUFSIZE_MAX); 74 | 75 | bufsize_t readSize = 0; 76 | offset_t prevOffset = 0; 77 | offset_t maxOffset = contentSize - 1; 78 | 79 | while (offset_t(fIn.pos()) < maxOffset) { 80 | 81 | bufsize_t maxSize = contentSize - readSize; 82 | if (maxSize > FILEVIEW_MAXSIZE) maxSize = FILEVIEW_MAXSIZE; 83 | 84 | readSize += fIn.read(content + readSize, maxSize); 85 | if (prevOffset == fIn.pos()) break; //cannot read more! 86 | prevOffset = fIn.pos(); 87 | } 88 | Logger::append(Logger::D_INFO, 89 | "Read size: %lX", 90 | static_cast(readSize) 91 | ); 92 | return bufferedFile; 93 | } 94 | 95 | bufsize_t AbstractFileBuffer::getReadableSize(QFile &fIn) 96 | { 97 | qint64 fileSize = fIn.size(); 98 | if (!fileSize) return 0; 99 | if (fileSize > qint64(FILE_MAXSIZE)) { 100 | fileSize = qint64(FILE_MAXSIZE); 101 | } 102 | return static_cast(fileSize); 103 | } 104 | 105 | bufsize_t AbstractFileBuffer::getReadableSize(const QString &path) 106 | { 107 | if (!path.length()) return 0; 108 | QFile fIn(path); 109 | if (!fIn.open(QIODevice::ReadOnly)) return 0; 110 | const bufsize_t size = getReadableSize(fIn); 111 | fIn.close(); 112 | return size; 113 | } 114 | 115 | bufsize_t AbstractFileBuffer::dump(const QString &path, AbstractByteBuffer &bBuf, bool allowExceptions) 116 | { 117 | BYTE* buf = bBuf.getContent(); 118 | bufsize_t bufSize = bBuf.getContentSize(); 119 | if (buf == NULL) { 120 | if (allowExceptions) throw FileBufferException("Buffer is empty"); 121 | return 0; 122 | } 123 | QFile fOut(path); 124 | if (fOut.open(QFile::WriteOnly) == false) { 125 | if (allowExceptions) throw FileBufferException("Cannot open the file: " + path + " for writing"); 126 | return 0; 127 | } 128 | bufsize_t wrote = static_cast (fOut.write((char*)buf, bufSize)); 129 | fOut.close(); 130 | return wrote; 131 | } 132 | 133 | -------------------------------------------------------------------------------- /parser/Formatter.cpp: -------------------------------------------------------------------------------- 1 | #include "Formatter.h" 2 | #include "Util.h" 3 | 4 | //---------------- 5 | AbstractFormatter::AbstractFormatter(AbstractByteBuffer *v_buf) 6 | : buf(v_buf) 7 | { 8 | if (v_buf == NULL) throw BufferException("Cannot make HexFilter for NULL buffer!"); 9 | } 10 | 11 | //--------------------------------------------------- 12 | const QString Formatter::operator[](std::size_t idx) const 13 | { 14 | BYTE b = (*buf)[idx]; 15 | if (isHex) { 16 | return QString::number(b, 16).leftJustified(2,'0'); 17 | } 18 | if (pe_util::isPrintable(b) == false) { 19 | if (isSkipNonprintable) { 20 | return ".."; 21 | } 22 | return "\\x"+ QString::number(b, 16).leftJustified(2,'0'); 23 | } 24 | return QChar(b); 25 | } 26 | 27 | /* 28 | 29 | BufferPrinter::BufferPrinter() 30 | { 31 | this->addFormater(int formatterId, AbstractFormatter); 32 | 33 | } 34 | 35 | 36 | bool BufferPrinter::addFormater(int formatterId, AbstractFormatter *formatter) 37 | { 38 | if (this->formatters[formatterId] != NULL) { 39 | return false; //already exist 40 | } 41 | this->formatters[formatterId] = formatter; 42 | return true; 43 | } 44 | 45 | bool BufferPrinter::useFormatter(int formatterId) 46 | { 47 | if (this->formatters[formatterId] == NULL) { 48 | return false; //no such formatter 49 | } 50 | this->strategy = this->formatters[formatterId]; 51 | return true; 52 | } 53 | 54 | void BufferPrinter::clearFormatters() 55 | { 56 | std::map::iterator itr; 57 | for (itr = formatters.begin(); itr != formatters.end(); ++itr) { 58 | AbstractFormatter* f = itr->second; 59 | delete f; 60 | } 61 | formatters.clear(); 62 | } 63 | */ 64 | -------------------------------------------------------------------------------- /parser/MappedExe.cpp: -------------------------------------------------------------------------------- 1 | #include "MappedExe.h" 2 | 3 | void ExeWrappersContainer::clearWrappers() 4 | { 5 | std::map::iterator itr; 6 | for (itr = this->wrappers.begin(); itr != this->wrappers.end(); ++itr){ 7 | ExeElementWrapper* wrapper = itr->second; 8 | delete wrapper; 9 | } 10 | wrappers.clear(); 11 | } 12 | 13 | ExeElementWrapper* ExeWrappersContainer::getWrapper(size_t wrapperId) 14 | { 15 | if (wrappers.find(wrapperId) == wrappers.end()) return NULL; 16 | return wrappers[wrapperId]; 17 | } 18 | 19 | QString ExeWrappersContainer::getWrapperName(size_t id) 20 | { 21 | if (wrappers.find(id) == wrappers.end()) return ""; 22 | return wrappers[id]->getName(); 23 | } 24 | -------------------------------------------------------------------------------- /parser/Util.cpp: -------------------------------------------------------------------------------- 1 | #include "Util.h" 2 | #include 3 | 4 | using namespace pe_util; 5 | 6 | #define MAX_LINE 255 7 | 8 | bool Logger::append(dbg_level lvl, const char* format, ...) 9 | { 10 | if (lvl > DBG_LVL) { 11 | return false; 12 | } 13 | if (format == NULL) { 14 | return false; 15 | } 16 | va_list argptr; 17 | // Initializing arguments to store all values after format 18 | va_start(argptr, format); 19 | 20 | char line[MAX_LINE + 1]; 21 | memset(line, 0, MAX_LINE + 1); 22 | 23 | int printed = vsnprintf(line, MAX_LINE, format, argptr); 24 | 25 | //cleaning up the list: 26 | va_end(argptr); 27 | if (printed <= 0) return false; 28 | 29 | const char *prefixes[D_LVL_COUNT] = { "ERROR", "WARNING", "INFO" }; 30 | if (static_cast(lvl) > static_cast(D_LVL_COUNT)) { 31 | lvl = Logger::D_ERROR; 32 | } 33 | 34 | fprintf(stderr, "[%s] %s\n", prefixes[lvl], line); 35 | return true; 36 | } 37 | 38 | bool pe_util::isStrLonger(const char *inp, size_t maxLen) 39 | { 40 | for (size_t i = 0; i < maxLen; i++ ) { 41 | if (inp[i] == '\0') return false; 42 | } 43 | return true; 44 | } 45 | 46 | size_t pe_util::getAsciiLen(const char *inp, size_t maxInp, bool acceptNotTerminated) 47 | { 48 | size_t i = 0; 49 | for (; i < maxInp; i++) { 50 | const char c = inp[i]; 51 | if (c == '\0') return i; //end of string 52 | if (!IS_PRINTABLE(c) && !IS_ENDLINE(c)) break; 53 | } 54 | if (acceptNotTerminated) return i; 55 | return 0; 56 | } 57 | 58 | size_t pe_util::getAsciiLenW(const WORD *inp, size_t maxInp, bool acceptNotTerminated) 59 | { 60 | size_t i = 0; 61 | for (; i < maxInp; i++) { 62 | const WORD w = inp[i]; 63 | if (w == 0) return i; //end of string 64 | if (!IS_PRINTABLE(w) && !IS_ENDLINE(w)) break; 65 | } 66 | if (acceptNotTerminated) return i; 67 | return 0; 68 | } 69 | 70 | bool pe_util::hasNonPrintable(const char *inp, size_t maxInp) 71 | { 72 | unsigned int i = 0; 73 | for ( i = 0; i < maxInp; i++) { 74 | char c = inp[i]; 75 | if (c == '\0') break; //end of string 76 | if (!IS_PRINTABLE(c)) return true; 77 | } 78 | return false; 79 | } 80 | 81 | bool _isFuncChar(const char c) 82 | { 83 | if ((c >= 'a' && c <= 'z') 84 | || (c >= 'A' && c <= 'Z') 85 | || (c >= '0' && c <= '9') 86 | || (c == '_') 87 | || (c == '.') 88 | || (c== '#') 89 | || (c == '@') 90 | || (c == '?') 91 | || (c == '-') 92 | || (c == '\\') 93 | || (c == '/') 94 | || (c == ':') 95 | ) 96 | { 97 | return true; 98 | } 99 | return false; 100 | } 101 | 102 | bool pe_util::validateFuncName(const char* fPtr, size_t bufSize) 103 | { 104 | if (!fPtr || !bufSize) return false; 105 | 106 | for (char i = 0; i < bufSize; i++) { 107 | const char c = fPtr[i]; 108 | if (c == 0) break; 109 | if (!_isFuncChar(c)) { 110 | return false; 111 | } 112 | } 113 | return true; 114 | } 115 | 116 | size_t pe_util::forwarderNameLen(const char* fPtr, size_t bufSize) 117 | { 118 | if (!fPtr || bufSize == 0) return 0; 119 | 120 | // names can be also mangled, i.e. MSVCRT.??0__non_rtti_object@std@@QAE@ABV01@@Z 121 | bool has_dot = false; 122 | size_t len = 0; 123 | while ((*fPtr == '.') || _isFuncChar(*fPtr)) 124 | { 125 | if (*fPtr == '.') has_dot = true; 126 | len++; 127 | if ((--bufSize) == 0) break; 128 | fPtr++; 129 | } 130 | if (*fPtr == '\0') { 131 | if (!has_dot) { 132 | return 0; //this is not a valid forwarder 133 | } 134 | return len; 135 | } 136 | return 0; 137 | } 138 | 139 | size_t pe_util::noWhiteCount(char *buf, size_t bufSize) { 140 | size_t cntr = 0; 141 | size_t i = 0; 142 | for (i = 0; i < bufSize; i++) { 143 | if (IS_PRINTABLE(buf[i]) && buf[i] != ' ') 144 | cntr++; 145 | } 146 | return cntr; 147 | } 148 | 149 | size_t pe_util::noWhiteCount(std::string s) 150 | { 151 | size_t bufSize = s.length(); 152 | size_t cntr = 0; 153 | size_t i = 0; 154 | for (i = 0; i < bufSize; i++) { 155 | if (IS_PRINTABLE(s[i]) && s[i] != ' ') 156 | cntr++; 157 | } 158 | return cntr; 159 | } 160 | 161 | bool pe_util::isSpaceClear(void* ptr, uint64_t size) 162 | { 163 | BYTE* testblock = (BYTE*) calloc(size, sizeof(BYTE)); 164 | bool isClear = true; 165 | if (memcmp (testblock, ptr, size)) { 166 | isClear = false; 167 | } 168 | free(testblock); 169 | return isClear; 170 | } 171 | 172 | bool pe_util::isHexChar(char c) 173 | { 174 | if (isdigit(c)) return true; 175 | if (c >= 'A' && c <= 'F') return true; 176 | if (c >= 'a' && c <= 'f') return true; 177 | return false; 178 | } 179 | 180 | void pe_util::hexdump(BYTE *buf, size_t bufSize, size_t pad) 181 | { 182 | if (buf == NULL) return; 183 | printf("\n---\n"); 184 | for (size_t i = 0; i < bufSize; i++) { 185 | if (i % pad == 0) printf("\n"); 186 | printf("0x%02X ", buf[i]); 187 | } 188 | printf("\n---\n"); 189 | } 190 | 191 | bool pe_util::endsWith(std::string str, std::string endStr) 192 | { 193 | if (str.length() < endStr.length()) { 194 | return false; 195 | } 196 | size_t pos = str.length() - endStr.length(); 197 | std::string str3 = str.substr(pos); 198 | if ( str3 == endStr ) { 199 | return true; 200 | } 201 | return false; 202 | } 203 | -------------------------------------------------------------------------------- /parser/WrappedValue.cpp: -------------------------------------------------------------------------------- 1 | #include "WrappedValue.h" 2 | 3 | QVariant WrappedValue::getQVariant() 4 | { 5 | if (m_Type == INT) { 6 | bool isOk = false; 7 | 8 | qlonglong num = (qlonglong) m_Owner->getNumValue(m_Offset, m_Size, &isOk); 9 | if (!isOk) return QVariant("INVALID"); 10 | return QVariant(num); 11 | } 12 | if (m_Type == STRING) { 13 | char *strPtr = (char*) this->m_Owner->getContentAt(m_Offset, m_Size); 14 | if (strPtr == NULL) return QVariant(); 15 | return QString(strPtr); 16 | } 17 | if (this->m_Type == WSTRING) { 18 | 19 | bufsize_t wSize = m_Size / bufsize_t(sizeof(WORD)); 20 | WORD *strPtr = (WORD*) this->m_Owner->getContentAt(m_Offset, m_Size); 21 | return QString::fromUtf16(reinterpret_cast(strPtr), static_cast(wSize)); 22 | } 23 | return QVariant("..."); 24 | } 25 | 26 | QString WrappedValue::getIntFormat() 27 | { 28 | QString format = "%0" + QString::number(m_Size * 2) +"llX"; 29 | return format; 30 | } 31 | 32 | QString WrappedValue::toQString() 33 | { 34 | if (this->m_Type == NONE) return ""; 35 | if (this->m_Type == COMPLEX) return "..."; 36 | 37 | QVariant val = getQVariant(); 38 | 39 | if (this->m_Type == STRING || this->m_Type == WSTRING) { 40 | return val.toString(); 41 | } 42 | if (this->m_Type == INT) { 43 | 44 | bufsize_t size = this->m_Size; 45 | if (size > sizeof(uint64_t)) return "..."; 46 | 47 | bool isOk = false; 48 | uint64_t num = m_Owner->getNumValue(m_Offset, m_Size, &isOk); 49 | if (!isOk) return "INVALID"; 50 | QString out; 51 | #if QT_VERSION >= 0x050000 52 | out = QString::asprintf(getIntFormat().toStdString().c_str(), num); 53 | #else 54 | out.sprintf(getIntFormat().toStdString().c_str(), num); 55 | #endif 56 | return out; 57 | } 58 | return getQVariant().toString(); 59 | } 60 | -------------------------------------------------------------------------------- /parser/include/bearparser/AbstractByteBuffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "win_hdrs/win_types.h" 4 | #include "CustomException.h" 5 | #include "Util.h" 6 | 7 | #include 8 | 9 | #include 10 | //------------------------------------------------ 11 | 12 | #define MAX_DWORD 0xffffffff 13 | #define MAX_WORD 0xffff 14 | #define MASK_TO_DWORD(val) ((val < MAX_DWORD) ? (val & MAX_DWORD) : MAX_DWORD) 15 | #define MASK_TO_WORD(val) ((val < MAX_WORD) ? (val & MAX_WORD) : MAX_WORD) 16 | 17 | typedef size_t bufsize_t; 18 | const bufsize_t BUFSIZE_MAX = bufsize_t(-1); 19 | 20 | typedef uint64_t offset_t; 21 | const offset_t INVALID_ADDR = offset_t(-1); 22 | const offset_t OFFSET_MAX = (INVALID_ADDR - 1); 23 | 24 | 25 | class BufferException : public CustomException 26 | { 27 | public: 28 | BufferException(const QString info) : CustomException(info) {} 29 | }; 30 | 31 | namespace buf_util { 32 | bufsize_t roundupToUnit(bufsize_t size, bufsize_t unit); 33 | }; 34 | 35 | class AbstractByteBuffer 36 | { 37 | public: 38 | static bool isValid(AbstractByteBuffer *buf); 39 | 40 | AbstractByteBuffer() { } 41 | virtual ~AbstractByteBuffer() { } 42 | 43 | virtual bufsize_t getContentSize() = 0; 44 | virtual BYTE* getContent() = 0; 45 | virtual bool isTruncated() { return false; } 46 | virtual bool isResized() { return false; } 47 | 48 | BYTE operator[](size_t idx); 49 | 50 | virtual offset_t getOffset(void *ptr, bool allowExceptions = false); // validates 51 | virtual BYTE* getContentAt(offset_t offset, bufsize_t size, bool allowExceptions = false); 52 | virtual BYTE* getContentAtPtr(BYTE *ptr, bufsize_t size, bool allowExceptions = false); 53 | 54 | virtual bool setBufferedValue(BYTE *dstPtr, BYTE *srcPtr, bufsize_t srcSize, bufsize_t paddingSize, bool allowExceptions = false); 55 | bool setStringValue(offset_t rawOffset, QString newText); 56 | 57 | QString getStringValue(offset_t rawOffset, bufsize_t len = BUFSIZE_MAX, bool acceptNonTerminated = false); 58 | QString getWStringValue(offset_t rawOffset, bufsize_t len); 59 | QString getWAsciiStringValue(offset_t rawOffset, bufsize_t len, bool acceptNonTerminated = false); 60 | 61 | bufsize_t getMaxSizeFromOffset(offset_t startOffset); 62 | bufsize_t getMaxSizeFromPtr(BYTE *ptr) { return getMaxSizeFromOffset(getOffset(ptr)); } 63 | 64 | bool isAreaEmpty(offset_t rawOffset, bufsize_t size); 65 | bool fillContent(BYTE filling); 66 | bool pasteBuffer(offset_t rawOffset, AbstractByteBuffer *buf, bool allowTrunc); 67 | 68 | bool containsBlock(offset_t rawOffset, bufsize_t size); 69 | bool intersectsBlock(offset_t rawOffset, bufsize_t size); 70 | 71 | uint64_t getNumValue(offset_t offset, bufsize_t size, bool* isOk); 72 | bool setNumValue(offset_t offset, bufsize_t size, uint64_t newVal); 73 | bool setTextValue(char* textPtr, std::string newText, size_t fieldLimitLen = 0); 74 | 75 | //TODO 76 | virtual bool resize(bufsize_t newSize) { return false; } 77 | offset_t substFragmentByFile(offset_t offset, bufsize_t contentSize, QFile &fIn); 78 | }; 79 | 80 | //-------------------------------------------- 81 | 82 | class BufferView : public AbstractByteBuffer 83 | { 84 | public: 85 | BufferView(AbstractByteBuffer *parent, offset_t offset, bufsize_t size); 86 | virtual ~BufferView() { } 87 | 88 | virtual bufsize_t getContentSize(); 89 | virtual BYTE* getContent(); 90 | 91 | bufsize_t getRequestedSize() const { return size; } 92 | 93 | protected: 94 | AbstractByteBuffer *parent; 95 | offset_t offset; 96 | bufsize_t size; 97 | }; 98 | 99 | -------------------------------------------------------------------------------- /parser/include/bearparser/ByteBuffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "AbstractByteBuffer.h" 3 | 4 | #define DEFAULT_PADDING 2 5 | 6 | class ByteBuffer : public AbstractByteBuffer 7 | { 8 | public: 9 | ByteBuffer(bufsize_t v_size, bufsize_t padding = DEFAULT_PADDING); 10 | ByteBuffer(BYTE *v_content, bufsize_t v_size, bufsize_t padding = DEFAULT_PADDING); 11 | ByteBuffer(AbstractByteBuffer *sourceBuf, offset_t offset, bufsize_t size, bufsize_t padding = DEFAULT_PADDING); 12 | 13 | virtual ~ByteBuffer(); 14 | 15 | virtual bufsize_t getContentSize() { return contentSize; } 16 | virtual BYTE* getContent() { return content; } 17 | virtual bool resize(bufsize_t newSize); 18 | 19 | virtual bool isResized() { return originalSize != contentSize; } 20 | 21 | protected: 22 | BYTE* allocContent(bufsize_t v_size, bufsize_t padding); 23 | 24 | BYTE *content; 25 | bufsize_t contentSize; 26 | bufsize_t padding; 27 | 28 | bufsize_t originalSize; 29 | 30 | private: 31 | void _init(const bufsize_t& v_size, const bufsize_t& v_padding = DEFAULT_PADDING); 32 | }; 33 | -------------------------------------------------------------------------------- /parser/include/bearparser/CustomException.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "win_hdrs/win_types.h" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define UNKNOWN_EXCEPTION (-1) 10 | 11 | class CustomException : public std::exception 12 | { 13 | public: 14 | CustomException(const QString info, const int32_t code = UNKNOWN_EXCEPTION) 15 | : std::exception(), m_info(info), m_code(code) { m_strInfo = info.toStdString(); } 16 | 17 | CustomException(const int32_t code) 18 | : std::exception(), m_info(""), m_code(code) {} 19 | 20 | virtual ~CustomException() throw () {} 21 | 22 | QString getInfo() { return (m_info.length() > 0) ? m_info : codeToString(); } 23 | int getCode() { return m_code; } 24 | virtual const char *what() const throw() { return m_strInfo.c_str(); } 25 | 26 | protected: 27 | virtual QString codeToString() { return ""; } /* for inherited classes */ 28 | QString m_info; 29 | std::string m_strInfo; 30 | const int m_code; 31 | }; 32 | 33 | class ParserException : public CustomException 34 | { 35 | public: 36 | ParserException(const QString info) : CustomException(info) {} 37 | }; 38 | 39 | -------------------------------------------------------------------------------- /parser/include/bearparser/ExeElementWrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "CustomException.h" 5 | #include "win_hdrs/win_types.h" 6 | #include "Executable.h" 7 | #include "WrappedValue.h" 8 | 9 | #define FIELD_NONE (-1) 10 | 11 | class ExeElementWrapper : public AbstractByteBuffer 12 | { 13 | public: 14 | ExeElementWrapper(Executable *exe); 15 | virtual ~ExeElementWrapper() {} 16 | 17 | virtual bool wrap() { return true; } 18 | 19 | /* inherited from: AbstractByteBuffer */ 20 | virtual bufsize_t getContentSize() { return getSize(); } 21 | virtual BYTE* getContent() { return static_cast(getPtr()); } 22 | 23 | /* full structure boundaries */ 24 | virtual void* getPtr() = 0; 25 | virtual bufsize_t getSize() = 0; 26 | virtual QString getName() = 0; 27 | 28 | virtual size_t getFieldsCount() = 0; 29 | virtual size_t getSubFieldsCount() { return 1; } 30 | 31 | virtual offset_t getOffset(); 32 | virtual offset_t getOffset(void *ptr, bool allowExceptions = false); 33 | 34 | /* specific field boundaries */ 35 | virtual void* getFieldPtr(size_t fieldId, size_t subField) = 0; 36 | void* getFieldPtr(size_t fieldId) { return getFieldPtr(fieldId, FIELD_NONE); } 37 | virtual bufsize_t getFieldSize(size_t fieldId, size_t subField = FIELD_NONE); 38 | virtual offset_t getFieldOffset(size_t fieldId, size_t subField = FIELD_NONE); 39 | 40 | virtual QString translateFieldContent(size_t fieldId) { return ""; } 41 | virtual bool hasSubfieldWrapper(size_t parentType) { return false; } 42 | 43 | virtual QString getFieldName(size_t fieldId) = 0; 44 | virtual WrappedValue getWrappedValue(size_t fieldId, size_t subField); 45 | virtual WrappedValue getWrappedValue(size_t fieldId) { return getWrappedValue(fieldId, FIELD_NONE); } 46 | 47 | virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField = FIELD_NONE) { return Executable::NOT_ADDR; } 48 | virtual WrappedValue::data_type containsDataType(size_t fieldId, size_t subField = FIELD_NONE) { return WrappedValue::INT; } 49 | 50 | virtual uint64_t getNumValue(size_t fieldId, size_t subField, bool* isOk); 51 | uint64_t getNumValue(size_t fieldId, bool* isOk) { return getNumValue(fieldId, FIELD_NONE, isOk); } 52 | 53 | virtual bool setNumValue(size_t fieldId, size_t subField, uint64_t val); 54 | bool setNumValue(size_t fieldId, uint64_t val) { return setNumValue(fieldId, FIELD_NONE, val); } 55 | 56 | Executable* getExe() { return m_Exe; } 57 | 58 | inline bool isBit64() { return Executable::isBit64(m_Exe); } 59 | inline bool isBit32() { return Executable::isBit32(m_Exe); } 60 | 61 | protected: 62 | virtual bool canCopyToOffset(offset_t rawOffset); 63 | bool copyToOffset(offset_t rawOffset); 64 | 65 | Executable *m_Exe; 66 | 67 | friend class Executable; 68 | }; 69 | 70 | -------------------------------------------------------------------------------- /parser/include/bearparser/ExeFactory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Executable.h" 4 | 5 | class ExeFactoryException : public CustomException 6 | { 7 | public: 8 | ExeFactoryException(const QString info) : CustomException(info) {} 9 | }; 10 | 11 | class ExeFactory 12 | { 13 | public: 14 | enum exe_type { 15 | NONE = 0, 16 | PE = 1, 17 | MZ, 18 | TYPES_COUNT 19 | }; 20 | 21 | static void init(); 22 | static void destroy(); 23 | 24 | static exe_type findMatching(AbstractByteBuffer *buf); 25 | static Executable* build(AbstractByteBuffer *buf, exe_type type); 26 | static QString getTypeName(exe_type type); 27 | 28 | protected: 29 | static std::map builders; 30 | }; 31 | -------------------------------------------------------------------------------- /parser/include/bearparser/ExeNodeWrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ExeElementWrapper.h" 4 | #include 5 | 6 | const size_t INVALID_ENTRYNUM = (-1); 7 | 8 | class ExeNodeWrapper : public ExeElementWrapper 9 | { 10 | public: 11 | ExeNodeWrapper(Executable *pe, ExeNodeWrapper* parent = NULL); 12 | ExeNodeWrapper(Executable *pe, ExeNodeWrapper* parent, size_t entryNumber); 13 | 14 | virtual ~ExeNodeWrapper() { clear(); } 15 | 16 | virtual bool wrap() { return true; } 17 | virtual void reloadMapping() {} 18 | 19 | virtual ExeNodeWrapper* getEntryAt(size_t fieldId); 20 | virtual size_t getEntriesCount() { return getEntriesCount(this->entries); } 21 | virtual size_t getEntriesNum() { return getEntriesCount(this->entries); } 22 | virtual size_t getSubFieldsCount() { return (this->entries.size() == 0) ? 0 : this->entries[0]->getFieldsCount(); } 23 | 24 | virtual ExeNodeWrapper* getParentNode() { return parentNode; } 25 | size_t getEntryId() { return entryNum; } 26 | 27 | virtual void* getSubfieldPtr(size_t fieldId, size_t subField); 28 | virtual bufsize_t getSubfieldSize(size_t fieldId, size_t subField); 29 | virtual QString getSubfieldName(size_t fieldId, size_t subField); 30 | 31 | virtual QString getFieldName(size_t fieldId) = 0; 32 | //--- 33 | virtual bool canAddEntry(); 34 | 35 | virtual ExeNodeWrapper* addEntry(ExeNodeWrapper *entry); 36 | ExeNodeWrapper* getLastEntry(); 37 | virtual offset_t getNextEntryOffset(); 38 | virtual bufsize_t geEntrySize(); 39 | 40 | virtual bool isValid() { return true; } 41 | 42 | protected: 43 | size_t getEntriesCount(std::vector &_entries); 44 | ExeNodeWrapper* getEntryAt(std::vector &_entries, size_t fieldId); 45 | 46 | virtual void clear(); 47 | virtual void addMapping(ExeNodeWrapper *entry) {} 48 | virtual bool loadNextEntry(size_t entryNum) { return false; } //TODO! 49 | virtual ExeNodeWrapper* addEntryAt(ExeNodeWrapper *entry, offset_t nextOffset); 50 | 51 | virtual bool isMyEntryType(ExeNodeWrapper *entry); // is it an entry of appropriate type 52 | 53 | ExeNodeWrapper* parentNode; 54 | size_t entryNum; 55 | 56 | std::vector entries; // children 57 | }; 58 | 59 | -------------------------------------------------------------------------------- /parser/include/bearparser/Executable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | #include "AbstractByteBuffer.h" 6 | class Executable; 7 | 8 | class ExeException : public CustomException 9 | { 10 | public: 11 | ExeException(const QString info) : CustomException(info) {} 12 | }; 13 | 14 | class ExeBuilder { 15 | public: 16 | ExeBuilder() {} 17 | virtual ~ExeBuilder() {} 18 | 19 | virtual bool signatureMatches(AbstractByteBuffer *buf) = 0; 20 | virtual Executable* build(AbstractByteBuffer *buf) = 0; 21 | virtual QString typeName() = 0; 22 | }; 23 | 24 | //------------------------------------------------------------- 25 | 26 | class Executable : public AbstractByteBuffer { 27 | public: 28 | enum exe_bits { 29 | UNKNOWN = 0, 30 | BITS_16 = 16, 31 | BITS_32 = 32, 32 | BITS_64 = 64, 33 | }; 34 | 35 | enum exe_arch { 36 | ARCH_UNKNOWN = 0, 37 | ARCH_INTEL = 1, 38 | ARCH_ARM = 2 39 | }; 40 | 41 | enum addr_type { 42 | NOT_ADDR = 0, 43 | RAW = 1, 44 | RVA = 2, 45 | VA = 3 46 | }; 47 | 48 | static bool isBit64(Executable *exe) { return (!exe || exe->getBitMode() != Executable::BITS_64) ? false: true; } 49 | static bool isBit32(Executable *exe) { return (!exe || exe->getBitMode() != Executable::BITS_32) ? false: true; } 50 | 51 | bool isBit64() { return isBit64(this); } 52 | bool isBit32() { return isBit32(this); } 53 | 54 | virtual ~Executable(void) { } 55 | 56 | virtual exe_bits getBitMode() { return this->bitMode; } 57 | virtual exe_arch getArch() = 0; 58 | 59 | virtual bufsize_t getContentSize() { return buf->getContentSize(); } 60 | virtual BYTE* getContent() { return buf->getContent(); } 61 | //wrapper: 62 | virtual offset_t getRawSize() const { return static_cast(buf->getContentSize()); } 63 | 64 | BYTE* getContentAtPtr(BYTE* ptr, bufsize_t size, bool allowExceptions = false) { return AbstractByteBuffer::getContentAtPtr(ptr, size, allowExceptions); } 65 | BYTE* getContentAt(offset_t offset, bufsize_t size, bool allowExceptions = false) { return AbstractByteBuffer::getContentAt(offset, size, allowExceptions); } 66 | 67 | virtual BYTE* getContentAt(offset_t offset, Executable::addr_type aType, bufsize_t size, bool allowExceptions = false); 68 | //------------------------------ 69 | virtual bufsize_t getMappedSize(Executable::addr_type aType) = 0; 70 | virtual bufsize_t getAlignment(Executable::addr_type aType) const = 0; 71 | virtual offset_t getImageBase(bool recalculate = false) = 0; 72 | virtual offset_t getEntryPoint(Executable::addr_type aType = Executable::RVA) = 0; 73 | 74 | virtual bufsize_t getImageSize() { return getMappedSize(Executable::VA); } 75 | 76 | /* All Entry Points of the application, including: main EP, Exports, TLS Callbacks */ 77 | virtual size_t getAllEntryPoints(QMap &entrypoints, Executable::addr_type aType = Executable::RVA) 78 | { 79 | offset_t mainEP = getEntryPoint(aType); 80 | entrypoints.insert(mainEP, "_start"); 81 | return 1; 82 | } 83 | 84 | /* conversions */ 85 | virtual bool isValidAddr(offset_t addr, addr_type addrType); 86 | virtual bool isValidVA(offset_t va) { return isValidAddr(va, Executable::VA); } 87 | 88 | virtual offset_t convertAddr(offset_t inAddr, Executable::addr_type inType, Executable::addr_type outType); 89 | 90 | virtual offset_t toRaw(offset_t offset, addr_type addrType, bool allowExceptions = false); //any type of offset to raw 91 | Executable::addr_type detectAddrType(offset_t addr, Executable::addr_type hintType); //TODO 92 | 93 | // returns INVALID_ADDR if failed 94 | // FileAddr <-> RVA 95 | virtual offset_t rawToRva(offset_t raw) = 0; 96 | virtual offset_t rvaToRaw(offset_t rva) = 0; 97 | 98 | // VA <-> RVA 99 | virtual offset_t VaToRva(offset_t va, bool autodetect = false); 100 | 101 | virtual offset_t rvaToVa(offset_t rva) 102 | { 103 | return (rva == INVALID_ADDR) ? INVALID_ADDR : (rva + this->getImageBase()); 104 | } 105 | 106 | // VA -> FileAddr 107 | virtual offset_t vaToRaw(offset_t va) 108 | { 109 | if (va == INVALID_ADDR) return INVALID_ADDR; 110 | 111 | offset_t rva = this->VaToRva(va, true); 112 | return rvaToRaw(rva); 113 | } 114 | 115 | QString getFileName(); 116 | 117 | virtual bool resize(bufsize_t newSize) { return buf->resize(newSize); } 118 | 119 | virtual bool isResized() { return buf ? buf->isResized() : false; } 120 | 121 | virtual bool isTruncated() { return buf ? buf->isTruncated() : false; } 122 | 123 | /* wrappers */ 124 | AbstractByteBuffer* getFileBuffer() const { return buf; } 125 | bufsize_t getFileSize() const; 126 | 127 | virtual bool dumpFragment(offset_t offset, bufsize_t size, QString fileName); 128 | 129 | protected: 130 | Executable(AbstractByteBuffer *v_buf, exe_bits v_bitMode); 131 | 132 | exe_bits bitMode; 133 | AbstractByteBuffer *buf; 134 | }; 135 | 136 | -------------------------------------------------------------------------------- /parser/include/bearparser/FileBuffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "ByteBuffer.h" 5 | 6 | const bufsize_t FILE_MAXSIZE = (LLONG_MAX > BUFSIZE_MAX ? BUFSIZE_MAX : LLONG_MAX); 7 | const bufsize_t FILEVIEW_MAXSIZE = (1024*1024*400); //419mb 8 | 9 | class FileBufferException : public BufferException 10 | { 11 | public: 12 | FileBufferException(const QString info) : BufferException(info) {} 13 | }; 14 | 15 | 16 | class AbstractFileBuffer { 17 | public: 18 | static ByteBuffer* read(QString &file, bufsize_t minBufSize, const bool allowTruncate); //throws exceptions 19 | static bufsize_t getReadableSize(QFile &fIn); 20 | 21 | static bufsize_t getReadableSize(const QString &path); 22 | static bufsize_t dump(const QString &fileName, AbstractByteBuffer &buf, bool allowExceptions = false); 23 | QString getFileName() { return this->fileName; } 24 | 25 | protected: 26 | static ByteBuffer* read(QFile &fIn, bufsize_t minBufSize, const bool allowTruncate); //throws exceptions 27 | 28 | AbstractFileBuffer(QString v_fileName) :fileName(v_fileName), fileSize(0) {} 29 | 30 | QString fileName; 31 | qint64 fileSize; // real size of the file 32 | }; 33 | 34 | 35 | class FileView : public AbstractByteBuffer, public AbstractFileBuffer 36 | { 37 | public: 38 | static bufsize_t getMappableSize(QFile &fIn); 39 | 40 | FileView(QString &fileName, bufsize_t maxSize = FILE_MAXSIZE); //throws exceptions 41 | virtual ~FileView(); 42 | 43 | virtual bufsize_t getContentSize() { return mappedSize; } 44 | virtual BYTE* getContent() { return mappedContent; } 45 | bufsize_t getMappableSize() { return FileView::getMappableSize(fIn); } 46 | virtual bool isTruncated() { return fIn.size() > mappedSize; } 47 | 48 | protected: 49 | BYTE *mappedContent; 50 | bufsize_t mappedSize; 51 | QFile fIn; 52 | }; 53 | 54 | 55 | class FileBuffer : public AbstractByteBuffer, public AbstractFileBuffer 56 | { 57 | public: 58 | FileBuffer(QString &fileName, bufsize_t minSize, bool allowTruncate) //throws exceptions 59 | : AbstractFileBuffer(fileName) 60 | { 61 | QFile fIn(fileName); 62 | if (fIn.open(QFile::ReadOnly) == false) { 63 | throw FileBufferException("Cannot open the file: " + fileName); 64 | } 65 | fileSize = fIn.size(); 66 | this->m_Buf = read(fIn, minSize, allowTruncate);//throws exceptions 67 | fIn.close(); 68 | } 69 | 70 | virtual ~FileBuffer() { delete m_Buf; } 71 | 72 | virtual bufsize_t getContentSize() { return (m_Buf == NULL) ? 0 : m_Buf->getContentSize(); } 73 | virtual BYTE* getContent() { return (m_Buf == NULL) ? NULL : m_Buf->getContent(); } 74 | offset_t getFileSize() { return static_cast(fileSize); } 75 | bool resize(bufsize_t newSize) { return m_Buf->resize(newSize); } 76 | 77 | virtual bool isResized() { return m_Buf ? m_Buf->isResized() : false; } 78 | 79 | virtual bool isTruncated() 80 | { 81 | if (!m_Buf) return false; 82 | return fileSize > this->m_Buf->getContentSize(); 83 | } 84 | 85 | protected: 86 | ByteBuffer* m_Buf; 87 | }; 88 | -------------------------------------------------------------------------------- /parser/include/bearparser/Formatter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "win_hdrs/win_types.h" 4 | #include "AbstractByteBuffer.h" 5 | 6 | class AbstractFormatter 7 | { 8 | public: 9 | AbstractFormatter(AbstractByteBuffer *v_buf); 10 | virtual ~AbstractFormatter() {} 11 | 12 | virtual const QString operator[](std::size_t idx) const = 0; 13 | 14 | protected: 15 | AbstractByteBuffer *buf; 16 | }; 17 | 18 | class Formatter : public AbstractFormatter{ 19 | public: 20 | Formatter(AbstractByteBuffer *buf, bool _isHex = false, bool _isSkipNonprintable = false) 21 | : AbstractFormatter(buf), 22 | isHex(_isHex),isSkipNonprintable(_isSkipNonprintable) 23 | { 24 | } 25 | 26 | void setHex(bool isEnabled) { isHex = isEnabled; } 27 | void setSkipNonPrintable(bool isEnabled) { isSkipNonprintable = isEnabled; } 28 | 29 | const QString operator[](std::size_t idx) const; 30 | 31 | protected: 32 | bool isHex; 33 | bool isSkipNonprintable; 34 | }; 35 | 36 | class HexFormatter : public Formatter 37 | { 38 | public: 39 | HexFormatter(AbstractByteBuffer *buf) : Formatter(buf, true, false) {} 40 | }; 41 | 42 | /* 43 | class BufferPrinter 44 | { 45 | public: 46 | enum FORMATTERS { 47 | F_TEXT = 0, 48 | F_HEX = 1, 49 | COUNT_FORMATTERS 50 | }; 51 | 52 | BufferPrinter(); 53 | ~BufferPrinter() { clearFormatters(); } 54 | 55 | bool addFormater(int formatterId, AbstractFormatter *formatter); 56 | bool useFormatter(int formatterId); 57 | 58 | protected: 59 | void clearFormatters(); 60 | 61 | AbstractFormatter *strategy; 62 | 63 | std::map formatters; 64 | }; 65 | */ 66 | -------------------------------------------------------------------------------- /parser/include/bearparser/MappedExe.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "Executable.h" 5 | #include "ExeElementWrapper.h" 6 | 7 | class ExeWrappersContainer 8 | { 9 | public: 10 | enum WRAPPERS { 11 | WR_NONE = size_t(-1), 12 | COUNT_WRAPPERS = 0 13 | }; 14 | 15 | ExeWrappersContainer() { } 16 | virtual ~ExeWrappersContainer(void) { clearWrappers(); } 17 | 18 | virtual ExeElementWrapper* getWrapper(size_t wrapperId); 19 | 20 | size_t wrappersCount() { return wrappers.size(); } 21 | QString getWrapperName(size_t id); 22 | 23 | protected: 24 | virtual void wrap() = 0; 25 | void clearWrappers(); 26 | 27 | std::map wrappers; 28 | }; 29 | 30 | class MappedExe : public Executable, public ExeWrappersContainer { 31 | public: 32 | virtual bool canResize(bufsize_t newSize) 33 | { 34 | // disabled by default 35 | return false; 36 | } 37 | 38 | virtual bool resize(bufsize_t newSize) 39 | { 40 | if (!canResize(newSize)) return false; 41 | 42 | if (Executable::resize(newSize)) { 43 | wrap(); 44 | return true; 45 | } 46 | return false; 47 | } 48 | 49 | virtual void wrap() = 0; 50 | 51 | protected: 52 | MappedExe(AbstractByteBuffer *v_buf, exe_bits v_bitMode) 53 | : Executable(v_buf, v_bitMode), ExeWrappersContainer() { } 54 | 55 | virtual ~MappedExe(void) { } 56 | }; 57 | -------------------------------------------------------------------------------- /parser/include/bearparser/Util.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "win_hdrs/win_types.h" 9 | 10 | #define DEFAULT_BUFSIZE 0xFF 11 | #define IS_PRINTABLE(c) (c >= 0x20 && c < 0x7f) 12 | #define IS_ENDLINE(c) (c == 0x0A || c == 0xD) 13 | 14 | //---- 15 | #ifdef _DEBUG 16 | #define DBG_LVL 2 17 | #else 18 | #define DBG_LVL 0 19 | #endif 20 | 21 | #define TRACE() if (DBG_LVL) printf(">%s line: %d [%s]\n", __FUNCTION__, __LINE__, __FILE__); 22 | #define LOG(msg) if (DBG_LVL) printf("%s: %s\n", __FUNCTION__,msg); 23 | 24 | namespace Logger { 25 | enum dbg_level{ 26 | D_ERROR = 0, D_WARNING, D_INFO, D_LVL_COUNT 27 | }; 28 | bool append(dbg_level lvl, const char* format, ...); 29 | }; 30 | //---- 31 | namespace pe_util { 32 | inline bool isPrintable(char c) { return IS_PRINTABLE(c); } 33 | 34 | bool isStrLonger(const char *inp, size_t maxLen); 35 | //QString getString(const char *ptr, size_t maxInp, size_t maxBuf = DEFAULT_BUFSIZE); 36 | bool hasNonPrintable(const char *ptr, size_t maxInp); 37 | size_t getAsciiLen(const char *ptr, size_t maxCount, bool acceptNotTerminated = false); 38 | size_t getAsciiLenW(const WORD *ptr, size_t maxCount, bool acceptNotTerminated = false); 39 | 40 | size_t noWhiteCount(char *buf, size_t bufSize); 41 | size_t noWhiteCount(std::string); 42 | bool validateFuncName(const char* fPtr, size_t bufSize); 43 | size_t forwarderNameLen(const char *ptr, size_t max_len); 44 | 45 | void hexdump(BYTE *buf, size_t bufSize, size_t pad); 46 | 47 | inline size_t unitsCount(uint64_t value, uint64_t unit, bool roundup = true) 48 | { 49 | if (unit == 0) return 0; 50 | size_t units = value / unit; 51 | if (roundup) { 52 | if (value % unit) units++; 53 | } 54 | return units; 55 | } 56 | 57 | inline uint64_t roundup(uint64_t value, uint64_t unit) 58 | { 59 | const size_t units = unitsCount(value, unit); 60 | return units * unit; 61 | } 62 | 63 | bool isSpaceClear(void* ptr, uint64_t size); 64 | bool isHexChar(char c); 65 | 66 | bool endsWith(std::string string, std::string endStr); 67 | }; 68 | 69 | -------------------------------------------------------------------------------- /parser/include/bearparser/WatchedLocker.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | 7 | #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 8 | class WatchedLocker : public QMutexLocker { 9 | #else 10 | class WatchedLocker : public QMutexLocker { 11 | #endif 12 | public: 13 | WatchedLocker(QMutex *mutex, bool show = false, const char *func = nullptr) 14 | : QMutexLocker(mutex), showLock(show) 15 | { 16 | if (func) funcName = func; 17 | if (showLock) { 18 | std::cout << __FUNCTION__; 19 | if (funcName.length()) { 20 | std::cout << " : " << funcName; 21 | } 22 | std::cout << std::endl; 23 | } 24 | } 25 | 26 | ~WatchedLocker() 27 | { 28 | if (showLock) { 29 | std::cout << __FUNCTION__; 30 | if (funcName.length()) { 31 | std::cout << " : " << funcName; 32 | } 33 | std::cout << std::endl; 34 | } 35 | } 36 | 37 | protected: 38 | std::string funcName; 39 | bool showLock; 40 | }; 41 | -------------------------------------------------------------------------------- /parser/include/bearparser/WrappedValue.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "win_hdrs/win_types.h" 4 | #include "CustomException.h" 5 | #include "AbstractByteBuffer.h" 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | class WrappedValue { 13 | public: 14 | 15 | enum data_type { 16 | NONE = 0, 17 | INT, 18 | STRING, 19 | WSTRING, 20 | COMPLEX, 21 | DATATYPE_COUNT 22 | }; 23 | 24 | WrappedValue() 25 | : m_Type(NONE), m_Owner(NULL), m_Offset(INVALID_ADDR), m_Size(0) {} 26 | 27 | WrappedValue(AbstractByteBuffer *owner, offset_t offset, bufsize_t size, data_type type) 28 | : m_Type(type), m_Owner(owner), m_Offset(offset), m_Size(size) {} 29 | 30 | data_type getDataType() { return m_Type; } 31 | QVariant getQVariant(); 32 | QString toQString(); 33 | bool isValid() { return (m_Size != 0); } 34 | 35 | protected: 36 | virtual QString getIntFormat(); 37 | 38 | data_type m_Type; 39 | AbstractByteBuffer* m_Owner; 40 | offset_t m_Offset; 41 | bufsize_t m_Size; 42 | }; 43 | -------------------------------------------------------------------------------- /parser/include/bearparser/bearparser.h: -------------------------------------------------------------------------------- 1 | #ifndef BEARPARSER_H 2 | #define BEARPARSER_H 3 | 4 | #define BEARPARSER_VERSION "0.6" 5 | 6 | #include 7 | #include 8 | 9 | #endif //BEARPARSER_H 10 | -------------------------------------------------------------------------------- /parser/include/bearparser/core.h: -------------------------------------------------------------------------------- 1 | #ifndef BEARPARSER_CORE_H 2 | #define BEARPARSER_CORE_H 3 | //core: 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #endif //BEARPARSER_CORE_H 17 | 18 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe.h: -------------------------------------------------------------------------------- 1 | #ifndef BEARPARSER_PEFILE_H 2 | #define BEARPARSER_PEFILE_H 3 | 4 | // win headers: 5 | #include 6 | //supported formats: 7 | #include 8 | #include 9 | 10 | #endif //BEARPARSER_PEFILE_H 11 | 12 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/BoundImpDirWrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "DataDirEntryWrapper.h" 4 | 5 | class BoundImpDirWrapper : public DataDirEntryWrapper 6 | { 7 | public: 8 | BoundImpDirWrapper(PEFile *pe) 9 | : DataDirEntryWrapper(pe, pe::DIR_BOUND_IMPORT), importsCount(0) { wrap(); } 10 | 11 | virtual bool wrap(); 12 | 13 | virtual void* getPtr() { return boundImp(); } 14 | virtual bufsize_t getSize(); 15 | virtual QString getName() { return "BoundImp"; } 16 | virtual size_t getFieldsCount() { return this->entries.size(); } 17 | 18 | virtual void* getFieldPtr(size_t fieldId, size_t subField) { return getSubfieldPtr(fieldId, subField ); } 19 | virtual bufsize_t getFieldSize(size_t fieldId, size_t subField = FIELD_NONE) { return getSubfieldSize(fieldId, subField); } 20 | 21 | virtual QString getFieldName(size_t fieldId, size_t subField) { return getSubfieldName(fieldId, subField ); } 22 | virtual QString getFieldName(size_t fieldId) { return getFieldName(fieldId, FIELD_NONE); } 23 | 24 | protected: 25 | bool loadNextEntry(size_t entryNum); 26 | 27 | IMAGE_BOUND_IMPORT_DESCRIPTOR* boundImp(); 28 | size_t importsCount; 29 | 30 | friend class BoundEntryWrapper; 31 | }; 32 | 33 | class BoundEntryWrapper : public ExeNodeWrapper 34 | { 35 | public: 36 | enum FieldID { 37 | NONE = FIELD_NONE, 38 | TIMESTAMP, 39 | MODULE_NAME_OFFSET, 40 | MODULE_FORWARDERS_NUM, 41 | FIELD_COUNTER 42 | }; 43 | 44 | BoundEntryWrapper(Executable *pe, BoundImpDirWrapper* parent, size_t entryNum) 45 | : ExeNodeWrapper(pe, parent, entryNum ) { } 46 | 47 | bool wrap() { return true; } 48 | 49 | virtual void* getPtr(); 50 | virtual bufsize_t getSize(); 51 | virtual QString getName(); 52 | virtual char* getLibraryName(); 53 | virtual size_t getFieldsCount() { return FIELD_COUNTER; } 54 | virtual size_t getSubFieldsCount() { return 1; } 55 | 56 | virtual void* getFieldPtr(size_t fieldId, size_t subField); 57 | virtual QString getFieldName(size_t fieldId); 58 | }; 59 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/ClrDirWrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "DataDirEntryWrapper.h" 4 | #include 5 | 6 | class ClrDirWrapper : public DataDirEntryWrapper 7 | { 8 | public: 9 | 10 | enum FieldID { 11 | NONE = FIELD_NONE, 12 | CB = 0, 13 | MAJOR_RUNTIME_VER, 14 | MINOR_RUNTIME_VER, 15 | META_DATA_VA, 16 | META_DATA_SIZE, 17 | FLAGS, 18 | ENTRY_POINT, 19 | RESOURCES_VA, 20 | RESOURCES_SIZE, 21 | STRONG_NAME_SIGNATURE_VA, 22 | STRONG_NAME_SIGNATURE_SIZE, 23 | CODE_MANAGER_TABLE_VA, 24 | CODE_MANAGER_TABLE_SIZE, 25 | VTABLE_FIXUPS_VA, 26 | VTABLE_FIXUPS_SIZE, 27 | EXPORT_ADDR_TABLE_JMPS_VA, 28 | EXPORT_ADDR_TABLE_JMPS_SIZE, 29 | MANAGED_NATIVE_HDR_VA, 30 | MANAGED_NATIVE_HDR_SIZE, 31 | FIELD_COUNTER 32 | }; 33 | 34 | static QString translateFlag(DWORD value); 35 | static std::set getFlagsSet(DWORD flags); 36 | //--- 37 | ClrDirWrapper(PEFile *pe) 38 | : DataDirEntryWrapper(pe, pe::DIR_COM_DESCRIPTOR) { wrap(); } 39 | 40 | ~ClrDirWrapper() { clear(); } 41 | 42 | bool wrap(); 43 | 44 | virtual void* getPtr(); 45 | virtual bufsize_t getSize(); 46 | virtual QString getName(); 47 | virtual size_t getFieldsCount(); 48 | virtual size_t getSubFieldsCount() { return 1; } 49 | 50 | virtual void* getFieldPtr(size_t fieldId, size_t subField); 51 | virtual QString getFieldName(size_t fieldId); 52 | virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField = FIELD_NONE); 53 | 54 | QString translateFieldContent(size_t fieldId); 55 | 56 | private: 57 | pe::IMAGE_COR20_HEADER* clrDir(); 58 | 59 | void clear() {} 60 | }; 61 | 62 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/CommonOrdinalsLookup.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "lookup/CommonOrdinalsMap.h" 5 | #include "lookup/CommonOrdinalsWS2_32.h" 6 | #include "lookup/CommonOrdinalsOleaut32.h" 7 | 8 | class CommonOrdinalsLookup 9 | { 10 | public: 11 | CommonOrdinalsLookup() 12 | { 13 | init(); 14 | } 15 | 16 | QString findFuncName(QString dllName, int ordinal) 17 | { 18 | dllName = dllName.toLower(); 19 | 20 | if (!listsMap.contains(dllName)) { 21 | return QString(); 22 | } 23 | 24 | CommonOrdinalsMap* ordinalsMap = listsMap[dllName]; 25 | if (!ordinalsMap || !ordinalsMap->ord_names.contains(ordinal)) { 26 | return QString(); 27 | } 28 | return ordinalsMap->ord_names[ordinal]; 29 | } 30 | 31 | void init() 32 | { 33 | listsMap["wsock32"] = new CommonOrdinalsWS2_32(); 34 | listsMap["ws2_32"] = new CommonOrdinalsWS2_32(); 35 | listsMap["oleaut32"] = new CommonOrdinalsOleaut32(); 36 | } 37 | 38 | void clear() 39 | { 40 | for (auto itr = listsMap.begin(); itr != listsMap.end(); ++itr) { 41 | delete itr.value(); 42 | } 43 | listsMap.clear(); 44 | } 45 | 46 | protected: 47 | QMap listsMap; 48 | }; 49 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/DOSExe.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../MappedExe.h" 4 | #include "DosHdrWrapper.h" 5 | 6 | #define DOS_PARAGRAPH 0x10 7 | 8 | class DOSExeBuilder: public ExeBuilder { 9 | public: 10 | DOSExeBuilder() : ExeBuilder() {} 11 | virtual bool signatureMatches(AbstractByteBuffer *buf); 12 | virtual Executable* build(AbstractByteBuffer *buf); 13 | QString typeName() { return "MZ"; } 14 | }; 15 | 16 | //------------------------------------------------------------- 17 | 18 | class DOSExe : public MappedExe 19 | { 20 | public: 21 | enum WRAPPERS { 22 | WR_NONE = MappedExe::WR_NONE, 23 | WR_DOS_HDR = 0, 24 | COUNT_WRAPPERS 25 | }; 26 | 27 | DOSExe(AbstractByteBuffer *v_buf); 28 | virtual ~DOSExe() { } 29 | 30 | virtual exe_arch getArch() { return exe_arch::ARCH_INTEL; } 31 | 32 | // inherited from Executable: 33 | // 34 | virtual void wrap(); 35 | // FileAddr <-> RVA 36 | virtual offset_t rawToRva(offset_t raw) { return (raw < codeOffset()) ? INVALID_ADDR : raw - codeOffset(); } 37 | virtual offset_t rvaToRaw(offset_t rva) { return rva + codeOffset(); } //TODO 38 | 39 | virtual bufsize_t getMappedSize(Executable::addr_type aType) 40 | { 41 | if (aType == Executable::RAW) 42 | return getContentSize(); 43 | return moduleSize() - codeOffset(); 44 | } 45 | 46 | virtual bufsize_t getAlignment(Executable::addr_type aType) const { return 0; } //TODO 47 | virtual offset_t getImageBase(bool recalculate = false) { return m_dosHdr->e_cs; } 48 | virtual offset_t getEntryPoint(Executable::addr_type aType = Executable::RVA) { return codeOffset() + m_dosHdr->e_ip; } 49 | 50 | //--- 51 | // DOS Exe only: 52 | virtual offset_t dosHeaderOffset() { return 0; } //wrapper's mount point 53 | offset_t peSignatureOffset(); 54 | 55 | protected: 56 | offset_t codeOffset() { return static_cast (m_dosHdr->e_cparhdr) * DOS_PARAGRAPH; } 57 | bufsize_t moduleSize() 58 | { 59 | const size_t unit_size = 0x200; 60 | WORD size = m_dosHdr->e_cp * unit_size; 61 | if (m_dosHdr->e_cblp ) { 62 | WORD trimSize = unit_size - m_dosHdr->e_cblp; 63 | size -= trimSize; 64 | } 65 | return static_cast (size); 66 | } 67 | 68 | 69 | DosHdrWrapper *dosHdrWrapper; 70 | IMAGE_DOS_HEADER* m_dosHdr; 71 | }; 72 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/DataDirEntryWrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PENodeWrapper.h" 4 | 5 | class PEFile; 6 | 7 | 8 | class DataDirEntryWrapper : public PENodeWrapper 9 | { 10 | public: 11 | IMAGE_DATA_DIRECTORY* getDataDirectory(); 12 | 13 | offset_t getDirEntryAddress(); 14 | bufsize_t getDirEntrySize(bool trimToExeSize=false); 15 | int getDirEntryType() { return this->entryType; } 16 | 17 | protected: 18 | DataDirEntryWrapper(PEFile* pe, pe:: dir_entry v_entryType); 19 | 20 | int entryType; 21 | 22 | friend class PEFile; 23 | }; 24 | 25 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/DataDirWrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PENodeWrapper.h" 4 | 5 | class DataDirWrapper : public PEElementWrapper 6 | { 7 | public: 8 | enum DataDirSID { 9 | NONE = FIELD_NONE, 10 | ADDRESS = 0, 11 | SIZE = 1, 12 | COUNTER 13 | }; 14 | 15 | DataDirWrapper(PEFile *pe) : PEElementWrapper(pe) {} 16 | virtual size_t getSubFieldsCount() { return COUNTER; } 17 | 18 | /* full structure boundaries */ 19 | virtual void* getPtr(); 20 | virtual bufsize_t getSize(); 21 | virtual QString getName() { return "Data Directory"; } 22 | virtual size_t getFieldsCount() { return getDirsCount(); } 23 | 24 | /* specific field boundaries */ 25 | virtual void* getFieldPtr(size_t fieldId, size_t subField); 26 | virtual bufsize_t getFieldSize(size_t fieldId, size_t subField); 27 | virtual QString getFieldName(size_t fieldId); 28 | virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField = FIELD_NONE); 29 | 30 | /*specific to this wrapper*/ 31 | size_t getDirsCount(); 32 | }; 33 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/DebugDirWrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "DataDirEntryWrapper.h" 4 | #include "pe_undoc.h" 5 | 6 | 7 | class DebugDirWrapper : public DataDirEntryWrapper 8 | { 9 | public: 10 | DebugDirWrapper(PEFile *pe) 11 | : DataDirEntryWrapper(pe, pe::DIR_DEBUG) { wrap(); } 12 | 13 | virtual void* getPtr() { return getDebugDir(); } 14 | 15 | virtual bufsize_t getSize() 16 | { 17 | return getDirEntrySize(); 18 | } 19 | 20 | virtual QString getName() { return "Debug"; } 21 | 22 | virtual size_t getFieldsCount() 23 | { 24 | return entries.size(); 25 | } 26 | 27 | virtual void* getFieldPtr(size_t fieldId, size_t subField) { return getSubfieldPtr(fieldId, subField ); } 28 | virtual QString getFieldName(size_t fieldId, size_t subField) { return getSubfieldName(fieldId, subField ); } 29 | virtual QString getFieldName(size_t fieldId) { return getFieldName(fieldId, FIELD_NONE); } 30 | virtual bufsize_t getFieldSize(size_t fieldId, size_t subField = FIELD_NONE) { return getSubfieldSize(fieldId, subField); } 31 | 32 | // debug dir only 33 | bool isRepro(); 34 | 35 | protected: 36 | bool wrap() 37 | { 38 | clear(); 39 | if (!getDataDirectory()) { 40 | return false; 41 | } 42 | const size_t LIMIT = (-1); 43 | size_t cntr = 0; 44 | for (cntr = 0; cntr < LIMIT; cntr++) { 45 | if (loadNextEntry(cntr) == false) break; 46 | } 47 | return true; 48 | } 49 | 50 | virtual bool loadNextEntry(size_t cntr); 51 | 52 | IMAGE_DEBUG_DIRECTORY* getDebugDir(size_t index = 0) 53 | { 54 | const offset_t rva = getDirEntryAddress(); 55 | if (rva == INVALID_ADDR || rva == 0) { 56 | return NULL; 57 | } 58 | const size_t offset = index * sizeof(IMAGE_DEBUG_DIRECTORY); 59 | return (IMAGE_DEBUG_DIRECTORY*) m_Exe->getContentAt((rva + offset), Executable::RVA, sizeof(IMAGE_DEBUG_DIRECTORY)); 60 | } 61 | 62 | friend class DebugDirEntryWrapper; 63 | }; 64 | 65 | 66 | class DebugDirEntryWrapper : public PENodeWrapper 67 | { 68 | public: 69 | 70 | enum DebugDirFID { 71 | NONE = FIELD_NONE, 72 | CHARACTERISTIC, 73 | TIMESTAMP, 74 | MAJOR_VER, 75 | MINOR_VER, 76 | TYPE, 77 | DATA_SIZE, 78 | RAW_DATA_ADDR, 79 | RAW_DATA_PTR, 80 | FIELD_COUNTER 81 | }; 82 | 83 | DebugDirEntryWrapper(PEFile *pe, DebugDirWrapper *rootDir, size_t entryNumber) 84 | : PENodeWrapper(pe, rootDir, entryNumber), dbgRootDir(rootDir) 85 | { 86 | wrap(); 87 | } 88 | 89 | ~DebugDirEntryWrapper() { clear(); } 90 | 91 | bool wrap(); 92 | 93 | virtual void* getPtr(); 94 | virtual bufsize_t getSize(); 95 | 96 | virtual QString getName() 97 | { 98 | IMAGE_DEBUG_DIRECTORY* d = debugDir(); 99 | if (!d) return ""; 100 | return translateType(d->Type); 101 | } 102 | 103 | virtual size_t getFieldsCount() { return FIELD_COUNTER; } 104 | virtual size_t getSubFieldsCount() { return 1; } 105 | 106 | virtual void* getFieldPtr(size_t fieldId, size_t subField); 107 | virtual QString getFieldName(size_t fieldId); 108 | virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField = FIELD_NONE); 109 | 110 | QString translateType(int type); 111 | QString translateFieldContent(size_t fieldId); 112 | 113 | protected: 114 | 115 | IMAGE_DEBUG_DIRECTORY* debugDir() 116 | { 117 | if (!dbgRootDir) return NULL; 118 | return this->dbgRootDir->getDebugDir(this->entryNum); 119 | } 120 | 121 | BYTE* getDebugStruct(); 122 | pe::DEBUG_RSDSI* getRDSI(); 123 | pe::DEBUG_NB10* getNB10(); 124 | 125 | DebugDirWrapper* dbgRootDir; 126 | 127 | friend class DebugDirCVEntryWrapper; 128 | }; 129 | 130 | 131 | class DebugDirCVEntryWrapper : public ExeNodeWrapper 132 | { 133 | public: 134 | // fields : 135 | enum FieldID { 136 | NONE = FIELD_NONE, 137 | F_CVDBG_SIGN, 138 | F_CVDBG_GUID, 139 | F_CVDBG_AGE, 140 | F_CVDBG_PDB, 141 | FIELD_COUNTER 142 | }; 143 | 144 | DebugDirCVEntryWrapper(Executable* pe, DebugDirEntryWrapper *_parentDir) 145 | : ExeNodeWrapper(pe, _parentDir, 0) 146 | { 147 | this->parentDir = _parentDir; 148 | } 149 | 150 | // full structure boundaries 151 | virtual void* getPtr(); 152 | virtual bufsize_t getSize(); 153 | 154 | virtual QString getName() { return "CodeView Info"; } 155 | virtual size_t getFieldsCount() { return getPtr() ? FIELD_COUNTER : 0; } 156 | virtual size_t getSubFieldsCount() { return 1; } 157 | 158 | // specific field boundaries 159 | virtual void* getFieldPtr(size_t fieldId, size_t subField = FIELD_NONE); 160 | virtual QString getFieldName(size_t fieldId); 161 | virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField) { return Executable::NOT_ADDR; } 162 | 163 | QString translateFieldContent(size_t fieldId); 164 | 165 | //this wrapper only: 166 | QString getGuidString(); 167 | QString getSignature(); 168 | private: 169 | DebugDirEntryWrapper* parentDir; 170 | }; 171 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/DelayImpDirWrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ImportBaseDirWrapper.h" 4 | #include "pe_formats.h" 5 | 6 | class DelayImpFuncWrapper; 7 | 8 | class DelayImpDirWrapper : public ImportBaseDirWrapper 9 | { 10 | public: 11 | DelayImpDirWrapper(PEFile *pe) 12 | : ImportBaseDirWrapper(pe, pe::DIR_DELAY_IMPORT) { wrap(); } 13 | 14 | virtual void* getPtr(); 15 | virtual bufsize_t getSize(); 16 | virtual QString getName() { return "DelayImports"; } 17 | 18 | protected: 19 | virtual bool loadNextEntry(size_t cntr); 20 | 21 | bool is64(); // autodetect! 64bit PE may use IMAGE_DELAY_LOAD32! 22 | bool is32() { return !is64(); } 23 | 24 | pe::IMAGE_DELAY_LOAD* firstDelayLd() { return (pe::IMAGE_DELAY_LOAD*) firstDelayLd(sizeof(pe::IMAGE_DELAY_LOAD)); } 25 | void* firstDelayLd(bufsize_t size); 26 | bufsize_t getEntrySize(); 27 | 28 | friend class DelayImpEntryWrapper; 29 | }; 30 | 31 | class DelayImpEntryWrapper : public ImportBaseEntryWrapper 32 | { 33 | public: 34 | enum DelayImpDirFID { 35 | NONE = FIELD_NONE, 36 | ATTRS, 37 | NAME, 38 | MOD, 39 | IAT, 40 | INT, 41 | BOUND_IAT, 42 | UNLOAD_IAT, 43 | TIMESTAMP, 44 | FIELD_COUNTER 45 | }; 46 | 47 | DelayImpEntryWrapper(PEFile *pe, DelayImpDirWrapper *importsDir, size_t entryNumber) 48 | : ImportBaseEntryWrapper(pe, importsDir, entryNumber) { wrap(); } 49 | 50 | //bool wrap(); 51 | 52 | virtual void* getPtr(); 53 | virtual bufsize_t getSize(); 54 | virtual QString getName(); 55 | virtual char* getLibraryName(); 56 | virtual size_t getFieldsCount() { return FIELD_COUNTER; } 57 | 58 | virtual void* getFieldPtr(size_t fieldId, size_t subField); 59 | virtual QString getFieldName(size_t fieldId); 60 | virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField = FIELD_NONE); 61 | 62 | protected: 63 | bool loadNextEntry(size_t entryNum); 64 | 65 | virtual IMAGE_IMPORT_BY_NAME* getFirstImpByNamePtr(); 66 | 67 | friend class DelayImpFuncWrapper; 68 | friend class DelayImpDirWrapper; 69 | }; 70 | 71 | class DelayImpFuncWrapper : public ImportBaseFuncWrapper 72 | { 73 | public: 74 | // fields : 75 | enum FieldID { 76 | NONE = FIELD_NONE, 77 | NAMETHUNK_ADDR, 78 | IAT_ADDR, 79 | BOUND_IAT_ADDR, 80 | UNLOAD_IAT_ADDR, 81 | FIELD_COUNTER 82 | }; 83 | 84 | DelayImpFuncWrapper(PEFile *pe, DelayImpEntryWrapper *parentDir, size_t entryNumber) 85 | : ImportBaseFuncWrapper(pe, parentDir, entryNumber) { this->parentDir = parentDir; } 86 | 87 | // full structure boundaries 88 | virtual void* getPtr() { return getFieldPtr(IAT_ADDR); } 89 | virtual bufsize_t getSize() { return sizeof(DWORD); } 90 | 91 | //virtual QString getName(); 92 | virtual size_t getFieldsCount() { return FIELD_COUNTER; } 93 | virtual size_t getSubFieldsCount() { return 1; } 94 | 95 | // specific field boundaries 96 | virtual void* getFieldPtr(size_t fieldId, size_t subField = FIELD_NONE); 97 | virtual bufsize_t getFieldSize(size_t fieldId, size_t subField = FIELD_NONE); 98 | virtual QString getFieldName(size_t fieldId); 99 | virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField); 100 | 101 | char* getFunctionName(); 102 | uint16_t getHint(); 103 | bool isByOrdinal(); 104 | virtual uint64_t getOrdinal(); 105 | offset_t callVia(); 106 | 107 | private: 108 | size_t ptrLen() { return (m_Exe->getBitMode() == Executable::BITS_64) ? sizeof(uint64_t) : sizeof(uint32_t); } 109 | virtual IMAGE_IMPORT_BY_NAME* getImportByNamePtr(); 110 | DelayImpEntryWrapper* parentDir; 111 | }; 112 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/DosHdrWrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../ExeElementWrapper.h" 4 | #include "../Executable.h" 5 | 6 | #include "pe_formats.h" 7 | 8 | class DosHdrWrapper : public ExeElementWrapper 9 | { 10 | public: 11 | /* fields :*/ 12 | enum DosFieldId { 13 | NONE = FIELD_NONE, 14 | MAGIC = 0, 15 | CBLP, 16 | CP, 17 | CRLC, 18 | CPARHDR, 19 | MINALLOC, 20 | MAXALLOC, 21 | SS, 22 | SP, 23 | CSUM, 24 | IP, 25 | CS, 26 | LFARLC, 27 | OVNO, 28 | RES, 29 | OEMID, 30 | OEMINFO, 31 | RES2, 32 | LFNEW, 33 | FIELD_COUNTER 34 | }; 35 | 36 | DosHdrWrapper(Executable *dosExe) : ExeElementWrapper(dosExe) { } 37 | 38 | /* full structure boundaries */ 39 | virtual void* getPtr() { return m_Exe->getContent(); } 40 | virtual bufsize_t getSize() { return sizeof(IMAGE_DOS_HEADER); } 41 | virtual QString getName() { return "DOS Hdr"; } 42 | virtual size_t getFieldsCount() { return FIELD_COUNTER; } 43 | 44 | /* specific field boundaries */ 45 | virtual void* getFieldPtr(size_t fieldId, size_t subField = FIELD_NONE); 46 | virtual QString getFieldName(size_t fieldId); 47 | virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField = FIELD_NONE); 48 | }; 49 | 50 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/ExceptionDirWrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "DataDirEntryWrapper.h" 4 | 5 | class ExceptionEntryWrapper; 6 | class ExceptionDirWrapper; 7 | 8 | class ExceptionDirWrapper : public DataDirEntryWrapper 9 | { 10 | public: 11 | ExceptionDirWrapper(PEFile* pe) 12 | : DataDirEntryWrapper(pe, pe::DIR_EXCEPTION), parsedSize(0) { wrap(); } 13 | 14 | bool wrap(); 15 | 16 | virtual void* getPtr(); 17 | virtual bufsize_t getSize() { return parsedSize; } 18 | 19 | virtual QString getName() { return "Exceptions Dir."; } 20 | virtual size_t getFieldsCount() { return entries.size(); } 21 | 22 | virtual void* getFieldPtr(size_t fieldId, size_t subField) { return getSubfieldPtr(fieldId, subField); } 23 | virtual QString getFieldName(size_t fieldId) { return "Exceptions Block"; } 24 | virtual QString getFieldName(size_t fieldId, size_t subField) { return getSubfieldName(fieldId, subField); } 25 | 26 | private: 27 | bufsize_t parsedSize; 28 | 29 | friend class ExceptionEntryWrapper; 30 | }; 31 | 32 | #define ARM_XDATA_FLAG 0x3 33 | 34 | class ExceptionEntryWrapper : public ExeNodeWrapper 35 | { 36 | public: 37 | // fields : 38 | enum ExceptionBlockFID_Intel { 39 | NONE = FIELD_NONE, 40 | BEGIN_ADDR, 41 | END_ADDR, 42 | UNWIND_INFO_ADDR, 43 | FIELD_COUNTER 44 | }; 45 | 46 | enum ExceptionBlockFID_Arm64 { 47 | ARM_EXCEPT_NONE = FIELD_NONE, 48 | ARM_EXCEPT_START = ExceptionEntryWrapper::BEGIN_ADDR, 49 | ARM_EXCEPT_XDATA = ExceptionEntryWrapper::END_ADDR, 50 | ARM_EXCEPT_FIELD_COUNTER 51 | }; 52 | 53 | ExceptionEntryWrapper(Executable *pe, ExceptionDirWrapper *parentDir, size_t entryNumber) 54 | : ExeNodeWrapper(pe, parentDir, entryNumber), cachedRaw(INVALID_ADDR) { this->parentDir = parentDir;} 55 | 56 | bool wrap() { return true; } 57 | 58 | // full structure boundaries 59 | virtual void* getPtr(); 60 | 61 | virtual bufsize_t getSize(); 62 | virtual QString getName() { return "Exceptions Block"; } 63 | virtual size_t getFieldsCount(); 64 | virtual size_t getSubFieldsCount() { return 1; } 65 | 66 | // specific field boundaries 67 | virtual void* getFieldPtr(size_t fieldId, size_t subField = FIELD_NONE); 68 | virtual QString getFieldName(size_t fieldId); 69 | virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField); 70 | 71 | private: 72 | bufsize_t _getSize(); 73 | offset_t cachedRaw; 74 | ExceptionDirWrapper* parentDir; 75 | }; 76 | 77 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/ExportDirWrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "DataDirEntryWrapper.h" 4 | 5 | class ExportDirWrapper : public DataDirEntryWrapper 6 | { 7 | public: 8 | 9 | enum ExportDirFID { 10 | NONE = FIELD_NONE, 11 | CHARACTERISTIC, 12 | TIMESTAMP, 13 | MAJOR_VER, 14 | MINOR_VER, 15 | NAME_RVA, 16 | BASE, 17 | FUNCTIONS_NUM, 18 | NAMES_NUM, 19 | FUNCTIONS_RVA, 20 | FUNC_NAMES_RVA, 21 | NAMES_ORDINALS_RVA, 22 | FIELD_COUNTER 23 | }; 24 | 25 | ExportDirWrapper(PEFile *pe) 26 | : DataDirEntryWrapper(pe, pe::DIR_EXPORT) { wrap(); } 27 | 28 | bool wrap(); 29 | 30 | virtual void* getPtr() { return exportDir(); } 31 | virtual bufsize_t getSize(); 32 | virtual QString getName(); 33 | virtual size_t getFieldsCount() { return FIELD_COUNTER; } 34 | virtual size_t getSubFieldsCount() { return 1; } 35 | 36 | virtual void* getFieldPtr(size_t fieldId, size_t subField); 37 | virtual QString getFieldName(size_t fieldId); 38 | virtual QString getLibraryName(); 39 | 40 | virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField = FIELD_NONE); 41 | 42 | protected: 43 | char* _getLibraryName(); 44 | void clear(); 45 | size_t mapNames(); 46 | 47 | IMAGE_EXPORT_DIRECTORY* exportDir(); 48 | std::map ordToNameId; 49 | 50 | friend class ExportEntryWrapper; 51 | }; 52 | 53 | 54 | class ExportEntryWrapper : public ExeNodeWrapper 55 | { 56 | public: 57 | // fields : 58 | enum FieldID { 59 | NONE = FIELD_NONE, 60 | FUNCTION_RVA, 61 | NAME_RVA, 62 | FIELD_COUNTER 63 | }; 64 | 65 | ExportEntryWrapper(Executable *pe, ExportDirWrapper *parentDir, size_t entryNumber) 66 | : ExeNodeWrapper(pe, parentDir, entryNumber) { this->parentDir = parentDir; } 67 | 68 | // full structure boundaries 69 | virtual void* getPtr() { return getFuncRvaPtr(); } 70 | virtual bufsize_t getSize(); 71 | virtual QString getName(); 72 | 73 | virtual size_t getFieldsCount() { return FIELD_COUNTER; } 74 | virtual size_t getSubFieldsCount() { return 1; } 75 | 76 | // specific field boundaries 77 | virtual void* getFieldPtr(size_t fieldId, size_t subField = FIELD_NONE);// { return getPtr(); } 78 | virtual bufsize_t getFieldSize(size_t fieldId, size_t subField = FIELD_NONE) { return sizeof(DWORD); } 79 | 80 | virtual QString getFieldName(size_t fieldId); 81 | virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField) { return Executable::RVA; } 82 | 83 | bool isByOrdinal(); 84 | uint32_t getOrdinal(); 85 | 86 | offset_t getFuncRva(); 87 | offset_t getFuncNameRva(); 88 | 89 | char* getFuncName(); 90 | QString getuncNameStr() { char* name = getFuncName(); return name ? name : ""; } 91 | char* getForwarder(); // NULL if not forwarded 92 | QString getForwarderStr() { char* forwarder = getForwarder(); return forwarder ? forwarder : ""; } 93 | 94 | private: 95 | DWORD* getFuncRvaPtr(); 96 | uint32_t getFuncNameId(); 97 | void* getFuncNameRvaPtr(); 98 | 99 | ExportDirWrapper* parentDir; 100 | }; 101 | 102 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/FileHdrWrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PENodeWrapper.h" 4 | 5 | #include "pe_formats.h" 6 | 7 | #include 8 | #include 9 | 10 | class FileHdrWrapper : public PEElementWrapper 11 | { 12 | public: 13 | /* fields :*/ 14 | enum FieldID { 15 | NONE = -1, 16 | MACHINE = 0, 17 | SEC_NUM, 18 | TIMESTAMP, 19 | SYMBOL_PTR, 20 | SYMBOL_NUM, 21 | OPTHDR_SIZE, 22 | CHARACT, 23 | FIELD_COUNTER 24 | }; 25 | 26 | static std::map s_fHdrCharact; 27 | static std::map s_machine; 28 | 29 | static void initCharact(); 30 | static std::vector splitCharact(DWORD characteristics); 31 | static QString translateCharacteristics(DWORD charact); 32 | 33 | static void initMachine(); 34 | static QString translateMachine(DWORD val); 35 | 36 | FileHdrWrapper(PEFile *pe) : PEElementWrapper(pe), hdr(NULL) {} 37 | bool wrap() { hdr = NULL; getPtr(); return true; } 38 | 39 | /* full structure boundaries */ 40 | virtual void* getPtr(); 41 | virtual bufsize_t getSize() { return sizeof(IMAGE_FILE_HEADER); } 42 | virtual QString getName() { return "File Hdr"; } 43 | virtual size_t getFieldsCount() { return FIELD_COUNTER; } 44 | 45 | /* specific field boundaries */ 46 | virtual void* getFieldPtr(size_t fieldId, size_t subField = FIELD_NONE); 47 | virtual QString getFieldName(size_t fieldId); 48 | virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField = FIELD_NONE); 49 | 50 | virtual QString translateFieldContent(size_t fieldId); 51 | private: 52 | IMAGE_FILE_HEADER* hdr; 53 | }; 54 | 55 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/ImportBaseDirWrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "DataDirEntryWrapper.h" 4 | #include "../Util.h" 5 | 6 | class ImportBaseDirWrapper; 7 | class ImportBaseEntryWrapper; 8 | class ImportBaseFuncWrapper; 9 | 10 | namespace imports_util { 11 | // inline uint64_t getUpperLimit(Executable *pe, void* fieldPtr); 12 | inline bool isNameValid(Executable *pe, char* myName); 13 | }; 14 | 15 | class ImportBaseDirWrapper : public DataDirEntryWrapper 16 | { 17 | public: 18 | static bufsize_t thunkSize(Executable::exe_bits bits); 19 | 20 | virtual bool wrap(); 21 | virtual bool isValid(); 22 | 23 | virtual void clearMapping(); 24 | virtual void reloadMapping(); 25 | virtual size_t getFieldsCount() { return this->importsCount; } 26 | 27 | virtual void* getFieldPtr(size_t fieldId, size_t subField) { return getSubfieldPtr(fieldId, subField ); } 28 | virtual QString getFieldName(size_t fieldId, size_t subField) { return getSubfieldName(fieldId, subField ); } 29 | virtual QString getFieldName(size_t fieldId) { return getFieldName(fieldId, FIELD_NONE); } 30 | virtual bufsize_t getFieldSize(size_t fieldId, size_t subField = FIELD_NONE) { return getSubfieldSize(fieldId, subField); } 31 | 32 | QString thunkToFuncName(offset_t thunk, bool shortName=true); 33 | QString thunkToLibName(offset_t thunk); 34 | 35 | QList getThunksList() { return this->thunksList; } 36 | 37 | bool hasThunk(offset_t thunk) { 38 | std::map::iterator libItr = thunkToLibMap.find(thunk); 39 | return (libItr != thunkToLibMap.end()); 40 | } 41 | 42 | ImportBaseFuncWrapper* thunkToFunction(offset_t thunk); 43 | 44 | protected: 45 | ImportBaseDirWrapper(PEFile *pe, pe:: dir_entry v_entryType) 46 | : DataDirEntryWrapper(pe, v_entryType), 47 | importsCount(0), invalidEntries(0) 48 | { 49 | } 50 | 51 | //virtual bool loadNextEntry(size_t entryNum) = 0; 52 | 53 | void addMapping(ExeNodeWrapper *func); 54 | ImportBaseEntryWrapper* thunkToLib(offset_t thunk); 55 | //--- 56 | std::map thunkToLibMap; 57 | QList thunksList; 58 | 59 | size_t importsCount; 60 | size_t invalidEntries; 61 | 62 | friend class ImportBaseEntryWrapper; 63 | }; 64 | 65 | 66 | class ImportBaseEntryWrapper : public PENodeWrapper 67 | { 68 | public: 69 | static bufsize_t NameLenLimit; 70 | 71 | virtual char* getLibraryName() = 0; 72 | virtual size_t getSubFieldsCount() { return 1; } 73 | bool wrap(); 74 | virtual bool isValid(); 75 | 76 | protected: 77 | ImportBaseEntryWrapper(PEFile *pe, ImportBaseDirWrapper *importsDir, size_t entryNumber) 78 | : PENodeWrapper(pe, importsDir, entryNumber), 79 | impDir(importsDir), invalidEntries(0) 80 | { 81 | } 82 | 83 | void addMapping(ExeNodeWrapper *func) { if (impDir) impDir->addMapping(func); } 84 | 85 | std::map thunkToFuncMap; 86 | ImportBaseDirWrapper* impDir; 87 | 88 | size_t invalidEntries; 89 | 90 | friend class ImportBaseDirWrapper; 91 | }; 92 | 93 | class ImportBaseFuncWrapper : public PENodeWrapper 94 | { 95 | public: 96 | ImportBaseFuncWrapper(PEFile *pe, ImportBaseEntryWrapper* parentLib, size_t entryNumber) 97 | : PENodeWrapper(pe, parentLib, entryNumber) { } 98 | 99 | virtual QString getName(); 100 | QString getShortName(); 101 | QString getLibName(); 102 | 103 | virtual bool isValid(); 104 | 105 | virtual bool isByOrdinal() = 0; 106 | virtual uint64_t getOrdinal() = 0; 107 | virtual char* getFunctionName() = 0; 108 | 109 | virtual offset_t callVia() = 0; 110 | 111 | inline bufsize_t getAddrSize() 112 | { 113 | size_t val = (isBit64()) ? sizeof(uint64_t) : sizeof(uint32_t); 114 | return static_cast(val); 115 | } 116 | 117 | inline bufsize_t getThunkValSize() { return getAddrSize(); } 118 | 119 | friend class ImportBaseDirWrapper; 120 | }; 121 | 122 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/ImportDirWrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ImportBaseDirWrapper.h" 4 | #include "pe_formats.h" 5 | 6 | /* 7 | typedef struct _IMAGE_THUNK_DATA32 { 8 | union { 9 | DWORD ForwarderString; // PBYTE 10 | DWORD Function; // PDWORD 11 | DWORD Ordinal; 12 | DWORD AddressOfData; // PIMAGE_IMPORT_BY_NAME 13 | } u1; 14 | } IMAGE_THUNK_DATA32; 15 | 16 | typedef struct _IMAGE_THUNK_DATA64 { 17 | union { 18 | ULONGLONG ForwarderString; // PBYTE 19 | ULONGLONG Function; // PDWORD 20 | ULONGLONG Ordinal; 21 | ULONGLONG AddressOfData; //PIMAGE_IMPORT_BY_NAME 22 | } u1; 23 | } IMAGE_THUNK_DATA64; 24 | */ 25 | 26 | class ImportDirWrapper; 27 | class ImportEntryWrapper; 28 | class ImportedFuncWrapper; 29 | 30 | class ImportDirWrapper : public ImportBaseDirWrapper 31 | { 32 | public: 33 | ImportDirWrapper(PEFile *pe) 34 | : ImportBaseDirWrapper(pe, pe::DIR_IMPORT) { wrap(); } 35 | 36 | virtual void* getPtr() { return firstDescriptor(); } 37 | virtual bufsize_t getSize(); 38 | virtual QString getName() { return "Imports"; } 39 | 40 | protected: 41 | virtual bool loadNextEntry(size_t cntr); 42 | 43 | IMAGE_DATA_DIRECTORY* getDataDirectory(); 44 | IMAGE_IMPORT_DESCRIPTOR *firstDescriptor(); 45 | 46 | friend class ImportEntryWrapper; 47 | }; 48 | 49 | 50 | class ImportEntryWrapper : public ImportBaseEntryWrapper 51 | { 52 | public: 53 | /* fields :*/ 54 | enum FieldID { 55 | NONE = FIELD_NONE, 56 | ORIG_FIRST_THUNK, 57 | TIMESTAMP, 58 | FORWARDER, 59 | NAME, 60 | FIRST_THUNK, 61 | FIELD_COUNTER 62 | }; 63 | 64 | ImportEntryWrapper(PEFile *pe, ImportDirWrapper *importsDir, size_t entryNumber) 65 | : ImportBaseEntryWrapper(pe, importsDir, entryNumber) { wrap(); } 66 | 67 | //virtual bool wrap(); 68 | //bool isValid(); 69 | 70 | /* full structure boundaries */ 71 | virtual void* getPtr(); 72 | 73 | virtual bufsize_t getSize(); 74 | bool isBound(); 75 | virtual QString getName(); 76 | virtual size_t getFieldsCount() { return FIELD_COUNTER; } 77 | 78 | /* specific field boundaries */ 79 | virtual void* getFieldPtr(size_t fieldId, size_t subField = FIELD_NONE); 80 | virtual QString getFieldName(size_t fieldId); 81 | virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField = FIELD_NONE); 82 | 83 | bufsize_t geEntrySize() 84 | { 85 | if (m_Exe == NULL) return 0; 86 | return ImportBaseDirWrapper::thunkSize(m_Exe->getBitMode()); 87 | } 88 | 89 | virtual offset_t getNextEntryOffset() 90 | { 91 | offset_t nextOffset = INVALID_ADDR; 92 | //get after existing entries: 93 | if (this->getEntriesCount() > 0) { 94 | return ExeNodeWrapper::getNextEntryOffset(); 95 | } 96 | //get by thunk: 97 | IMAGE_IMPORT_DESCRIPTOR* desc = (IMAGE_IMPORT_DESCRIPTOR*) this->getPtr(); 98 | if (!desc) return INVALID_ADDR; 99 | 100 | offset_t firstThunk = desc->FirstThunk; 101 | if (firstThunk == 0) { 102 | firstThunk = desc->OriginalFirstThunk; 103 | } 104 | nextOffset = m_Exe->convertAddr(desc->FirstThunk, Executable::RVA, Executable::RAW); 105 | return nextOffset; 106 | } 107 | 108 | char* getLibraryName(); 109 | 110 | protected: 111 | bool loadNextEntry(size_t entryNum); 112 | 113 | friend class ImportDirWrapper; 114 | }; 115 | 116 | class ImportedFuncWrapper : public ImportBaseFuncWrapper 117 | { 118 | public: 119 | /* fields :*/ 120 | enum FieldID { 121 | NONE = FIELD_NONE, 122 | ORIG_THUNK, 123 | THUNK, 124 | FORWARDER, 125 | HINT, 126 | FIELD_COUNTER 127 | }; 128 | 129 | ImportedFuncWrapper(PEFile *pe, ImportEntryWrapper* parentLib, size_t entryNumber) 130 | : ImportBaseFuncWrapper(pe, parentLib, entryNumber) {}// this->parentLib = parentLib; } 131 | 132 | /* full structure boundaries */ 133 | virtual void* getPtr(); 134 | virtual IMAGE_IMPORT_BY_NAME* getImportByNamePtr(); 135 | 136 | virtual bufsize_t getSize(); 137 | //virtual QString getName(); 138 | virtual size_t getFieldsCount() { return FIELD_COUNTER; } 139 | virtual size_t getSubFieldsCount() { return 1; } 140 | 141 | /* specific field boundaries */ 142 | virtual void* getFieldPtr(size_t fieldId, size_t subField = FIELD_NONE); 143 | virtual bufsize_t getFieldSize(size_t fieldId, size_t subField = FIELD_NONE); 144 | virtual QString getFieldName(size_t fieldId); 145 | virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField = FIELD_NONE); 146 | 147 | uint64_t getThunkValue(); 148 | 149 | offset_t getFieldRVA(ImportEntryWrapper::FieldID fId); 150 | void* getValuePtr(ImportEntryWrapper::FieldID fId); 151 | 152 | virtual offset_t callVia() { return getFieldRVA(ImportEntryWrapper::FIRST_THUNK); } 153 | bool isByOrdinal(); 154 | virtual uint64_t getOrdinal() { return getThunkValue(); } 155 | char* getFunctionName(); 156 | 157 | friend class ImportDirWrapper; 158 | }; 159 | 160 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/OptHdrWrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PENodeWrapper.h" 4 | 5 | class OptHdrWrapper : public PEElementWrapper 6 | { 7 | public: 8 | /* fields :*/ 9 | enum OptHdrFID { 10 | NONE = FIELD_NONE, 11 | MAGIC = 0, 12 | LINKER_MAJOR, 13 | LINKER_MINOR, 14 | CODE_SIZE, 15 | INITDATA_SIZE, 16 | UNINITDATA_SIZE, 17 | EP, 18 | CODE_BASE, 19 | DATA_BASE, 20 | 21 | IMAGE_BASE, 22 | SEC_ALIGN, 23 | FILE_ALIGN, 24 | OSVER_MAJOR, 25 | OSVER_MINOR, 26 | IMGVER_MAJOR, 27 | IMGVER_MINOR, 28 | SUBSYSVER_MAJOR, 29 | SUBSYSVER_MINOR, 30 | WIN32_VER, 31 | IMAGE_SIZE, 32 | HDRS_SIZE, 33 | CHECKSUM, 34 | SUBSYS, 35 | DLL_CHARACT, 36 | STACK_RSRV_SIZE, 37 | STACK_COMMIT_SIZE, 38 | HEAP_RSRV_SIZE, 39 | HEAP_COMMIT_SIZE, 40 | LDR_FLAGS, 41 | RVAS_SIZES_NUM, 42 | DATA_DIR, 43 | FIELD_COUNTER 44 | }; 45 | static std::map s_optMagic; 46 | static std::map, QString> s_osVersion; 47 | static std::map s_dllCharact; 48 | static std::map s_subsystem; 49 | 50 | static void initDllCharact(); 51 | static std::vector splitDllCharact(DWORD characteristics); 52 | static QString translateDllCharacteristics(DWORD charact); 53 | 54 | static QString translateOptMagic(DWORD magic); 55 | static QString translateOSVersion(WORD major, WORD minor); 56 | static QString translateSubsystem(DWORD subsystem); 57 | //---- 58 | 59 | OptHdrWrapper(PEFile *pe) : PEElementWrapper(pe), opt32(NULL), opt64(NULL) { wrap(); } 60 | bool wrap(); 61 | 62 | /* full structure boundaries */ 63 | virtual void* getPtr(); 64 | virtual bufsize_t getSize(); 65 | virtual QString getName() { return "Optional Hdr"; } 66 | virtual size_t getFieldsCount() { return FIELD_COUNTER; } 67 | 68 | /* specific field boundaries */ 69 | virtual void* getFieldPtr(size_t fieldId, size_t subField = FIELD_NONE); 70 | virtual bufsize_t getFieldSize(size_t fieldId, size_t subField = FIELD_NONE); 71 | 72 | virtual QString translateFieldContent(size_t fieldId); 73 | 74 | virtual QString getFieldName(size_t fieldId); 75 | virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField = FIELD_NONE); 76 | 77 | Executable::exe_bits getHdrBitMode(); 78 | IMAGE_NT_HEADERS32* nt32(); 79 | IMAGE_NT_HEADERS64* nt64(); 80 | 81 | //DataDirWrapper dataDir; 82 | protected: 83 | IMAGE_OPTIONAL_HEADER32* opt32; 84 | IMAGE_OPTIONAL_HEADER64* opt64; 85 | std::vector dllCharact; 86 | }; 87 | 88 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/PECore.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../Executable.h" 4 | #include "pe_formats.h" 5 | 6 | //class for internal use of PEFile 7 | class PECore 8 | { 9 | public: 10 | 11 | PECore() 12 | : buf(NULL), dos(NULL), fHdr(NULL), opt32(NULL), opt64(NULL) {} 13 | 14 | virtual ~PECore() 15 | { 16 | reset(); 17 | } 18 | 19 | bool wrap(AbstractByteBuffer *v_buf); 20 | 21 | virtual offset_t getRawSize() const { return buf ? static_cast(buf->getContentSize()) : 0; } 22 | 23 | virtual bufsize_t getAlignment(Executable::addr_type aType) const; 24 | virtual offset_t getImageBase(bool recalculate = false); 25 | virtual bufsize_t getImageSize(); 26 | 27 | Executable::exe_bits getHdrBitMode() const; 28 | Executable::exe_arch getHdrArch() const; 29 | offset_t peSignatureOffset() const; 30 | offset_t peFileHdrOffset() const; 31 | offset_t secHdrsOffset() const; 32 | offset_t peOptHdrOffset() const; 33 | bufsize_t peNtHeadersSize() const; 34 | bufsize_t hdrsSize() const; 35 | 36 | void setImageSize(bufsize_t newSize) 37 | { 38 | if (this->opt32) { 39 | this->opt32->SizeOfImage = MASK_TO_DWORD(newSize); 40 | } 41 | else if (this->opt64) { 42 | this->opt64->SizeOfImage = MASK_TO_DWORD(newSize); 43 | } 44 | } 45 | 46 | IMAGE_FILE_HEADER *getFileHeader() const 47 | { 48 | return fHdr; 49 | } 50 | 51 | protected: 52 | void reset(); 53 | AbstractByteBuffer *buf; 54 | 55 | IMAGE_DOS_HEADER *dos; 56 | IMAGE_FILE_HEADER* fHdr; 57 | IMAGE_OPTIONAL_HEADER32* opt32; 58 | IMAGE_OPTIONAL_HEADER64* opt64; 59 | 60 | friend class PEFile; 61 | }; 62 | 63 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/PENodeWrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../ExeNodeWrapper.h" 4 | #include "pe_formats.h" 5 | 6 | class PEFile; 7 | 8 | class PEElementWrapper : public ExeElementWrapper 9 | { 10 | public: 11 | PEElementWrapper(PEFile* pe); 12 | virtual ~PEElementWrapper() {} 13 | 14 | PEFile* getPE() { return m_PE; } 15 | 16 | protected: 17 | PEFile *m_PE; 18 | 19 | friend class PEFile; 20 | }; 21 | 22 | //---- 23 | 24 | class PENodeWrapper : public ExeNodeWrapper 25 | { 26 | public: 27 | PENodeWrapper(PEFile* pe, PENodeWrapper* parent = NULL); 28 | PENodeWrapper(PEFile* pe, PENodeWrapper* parent, size_t entryNumber); 29 | 30 | virtual ~PENodeWrapper() {} 31 | 32 | PEFile* getPE() { return m_PE; } 33 | virtual PENodeWrapper* getParentNode() { return peParentNode; } 34 | 35 | protected: 36 | PEFile *m_PE; 37 | PENodeWrapper *peParentNode; 38 | 39 | friend class PEFile; 40 | }; 41 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/RelocDirWrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "DataDirEntryWrapper.h" 4 | 5 | class RelocEntryWrapper; 6 | class RelocBlockWrapper; 7 | class RelocDirWrapper; 8 | 9 | class RelocDirWrapper : public DataDirEntryWrapper 10 | { 11 | public: 12 | RelocDirWrapper(PEFile *pe) 13 | : DataDirEntryWrapper(pe, pe::DIR_BASERELOC), 14 | parsedSize(0) 15 | { 16 | wrap(); 17 | } 18 | 19 | bool wrap(); 20 | 21 | virtual void* getPtr() { return reloc(); } 22 | 23 | virtual bufsize_t getSize() { return parsedSize; } 24 | virtual QString getName() { return "Relocation Dir."; } 25 | virtual size_t getFieldsCount() { return entries.size(); } 26 | 27 | virtual void* getFieldPtr(size_t fieldId, size_t subField) { return getSubfieldPtr(fieldId, subField ); } 28 | virtual bufsize_t getFieldSize(size_t fieldId, size_t subField) { return getSubfieldSize(fieldId, subField ); } 29 | virtual QString getFieldName(size_t fieldId) { return "Relocation Block"; } 30 | virtual QString getFieldName(size_t fieldId, size_t subField) { return getSubfieldName(fieldId, subField ); } 31 | 32 | protected: 33 | IMAGE_BASE_RELOCATION* reloc(); 34 | 35 | private: 36 | bufsize_t parsedSize; 37 | 38 | friend class RelocBlockWrapper; 39 | }; 40 | 41 | 42 | class RelocBlockWrapper : public ExeNodeWrapper 43 | { 44 | public: 45 | // fields : 46 | enum RelocBlockFID { 47 | NONE = FIELD_NONE, 48 | PAGE_VA, 49 | BLOCK_SIZE, 50 | ENTRIES_PTR, 51 | FIELD_COUNTER 52 | }; 53 | 54 | RelocBlockWrapper(Executable *pe, RelocDirWrapper *parentDir, size_t entryNumber) 55 | : ExeNodeWrapper(pe, parentDir, entryNumber), 56 | cachedRaw(INVALID_ADDR), cachedMaxNum(0), 57 | isValidPage(false) 58 | { 59 | this->parentDir = parentDir; 60 | wrap(); 61 | } 62 | 63 | bool wrap(); 64 | bool isValid(); 65 | // full structure boundaries 66 | virtual void* getPtr(); 67 | virtual bufsize_t getSize(); 68 | virtual QString getName() { return "Relocation Block"; } 69 | virtual size_t getFieldsCount() { return FIELD_COUNTER; } 70 | 71 | // specific field boundaries 72 | virtual void* getFieldPtr(size_t fieldId, size_t subField = FIELD_NONE); 73 | virtual QString getFieldName(size_t fieldId); 74 | virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField); 75 | virtual WrappedValue::data_type containsDataType(size_t fieldId, size_t subField); 76 | 77 | void* getEntriesPtr(); 78 | size_t maxEntriesNumInBlock(); 79 | 80 | IMAGE_BASE_RELOCATION* myReloc() { return (IMAGE_BASE_RELOCATION*) getPtr(); } 81 | 82 | private: 83 | void validatePage(); 84 | bool isValidPage; 85 | 86 | offset_t cachedRaw; 87 | //size_t cachedSize; // TODO 88 | offset_t cachedMaxNum; 89 | 90 | RelocDirWrapper* parentDir; 91 | 92 | size_t parsedSize; 93 | 94 | }; 95 | 96 | class RelocEntryWrapper : public ExeNodeWrapper 97 | { 98 | public: 99 | // fields : 100 | enum FieldID { 101 | NONE = FIELD_NONE, 102 | RELOC_ENTRY_VAL, 103 | FIELD_COUNTER 104 | }; 105 | 106 | RelocEntryWrapper(Executable* pe, RelocBlockWrapper *parentDir, size_t entryNumber) 107 | : ExeNodeWrapper(pe, parentDir, entryNumber) { this->parentDir = parentDir; } 108 | 109 | // full structure boundaries 110 | virtual void* getPtr(); 111 | virtual bufsize_t getSize(); 112 | virtual QString getName() { return "Type-Offset"; } 113 | virtual size_t getFieldsCount() { return FIELD_COUNTER; } 114 | virtual size_t getSubFieldsCount() { return 1; } 115 | 116 | // specific field boundaries 117 | virtual void* getFieldPtr(size_t fieldId, size_t subField = FIELD_NONE) { return getPtr(); } 118 | virtual QString getFieldName(size_t fieldId) { return getName(); } 119 | virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField) { return Executable::NOT_ADDR; } 120 | 121 | offset_t deltaToRVA(WORD delta); 122 | static WORD getType(WORD relocEntryVal); 123 | static WORD getDelta(WORD relocEntryVal); 124 | static QString translateType(WORD type); 125 | 126 | private: 127 | RelocBlockWrapper* parentDir; 128 | }; 129 | 130 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/ResourceDirWrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "DataDirEntryWrapper.h" 4 | #include "ResourceLeafWrapper.h" 5 | 6 | #include "rsrc/ResourcesAlbum.h" 7 | #include "rsrc/ResourceContentFactory.h" 8 | 9 | #include 10 | #include 11 | 12 | 13 | class ResourceDirWrapper : public DataDirEntryWrapper 14 | { 15 | public: 16 | 17 | enum ResourceDirFID { 18 | NONE = FIELD_NONE, 19 | CHARACTERISTIC, 20 | TIMESTAMP, 21 | MAJOR_VER, 22 | MINOR_VER, 23 | NAMED_ENTRIES_NUM, 24 | ID_ENTRIES_NUM, 25 | FIELD_COUNTER 26 | }; 27 | 28 | ResourceDirWrapper(PEFile* pe, ResourcesAlbum *resAlbum = NULL, offset_t rawOffset = 0, long depth = 0, long topEntryId = TOP_ENTRY_ROOT) 29 | : DataDirEntryWrapper(pe, pe::DIR_RESOURCE), 30 | rawOff(rawOffset), dirDepth(depth), album(resAlbum), topEntryID(topEntryId) 31 | { 32 | wrap(); 33 | } 34 | 35 | bool wrap(); 36 | 37 | virtual void* getPtr() { return resourceDir(); } 38 | virtual bufsize_t getSize(); 39 | 40 | virtual QString getName() { return "Resources"; } 41 | virtual size_t getFieldsCount() { return FIELD_COUNTER; } 42 | virtual size_t getSubFieldsCount() { return 1; } 43 | 44 | virtual void* getFieldPtr(size_t fieldId, size_t subField); 45 | virtual bufsize_t getFieldSize(size_t fieldId, size_t subField); 46 | virtual QString getFieldName(size_t fieldId); 47 | 48 | bufsize_t getEntriesAreaSize() 49 | { 50 | return static_cast(this->getEntriesCount()) * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY); 51 | } 52 | 53 | long getDepth() { return this->dirDepth; } 54 | 55 | IMAGE_RESOURCE_DIRECTORY* mainResourceDir(); 56 | ResourcesAlbum* getAlbumPtr() { return album; } 57 | 58 | private: 59 | IMAGE_RESOURCE_DIRECTORY* resourceDir(); 60 | offset_t rawOff; 61 | long dirDepth; 62 | ResourcesAlbum *album; 63 | long topEntryID; 64 | }; 65 | 66 | class ResourceEntryWrapper : public PENodeWrapper 67 | { 68 | public: 69 | // fields : 70 | enum FieldID { 71 | NONE = FIELD_NONE, 72 | NAME_ID_ADDR, 73 | OFFSET_TO_DATA, 74 | FIELD_COUNTER 75 | }; 76 | 77 | static QString translateType(WORD id); 78 | 79 | ResourceEntryWrapper(PEFile *pe, ResourceDirWrapper *parentDir, size_t entryNumber, long topEntryId, ResourcesAlbum *resAlbum) 80 | : PENodeWrapper(pe, parentDir, entryNumber), topEntryID(topEntryId), album(resAlbum), childDir(NULL), childLeaf(NULL) 81 | { 82 | this->parentDir = parentDir; 83 | wrap(); 84 | } 85 | 86 | virtual ~ResourceEntryWrapper() { clear(); } 87 | 88 | bool wrap(); 89 | // full structure boundaries 90 | virtual void* getPtr() { return getEntryPtr(); } 91 | virtual bufsize_t getSize() { return sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY); } 92 | 93 | virtual QString getName() { return "Resource entry: "+ translateType(getID());} 94 | virtual size_t getFieldsCount() { return FIELD_COUNTER; } 95 | virtual size_t getSubFieldsCount() { return 1; } 96 | 97 | // specific field boundaries 98 | virtual void* getFieldPtr(size_t fieldId, size_t subField = FIELD_NONE); 99 | virtual QString getFieldName(size_t fieldId); 100 | virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField) { return Executable::NOT_ADDR; } 101 | 102 | bool isByName(); 103 | bool isDir(); 104 | 105 | WORD getID(); 106 | offset_t getChildOffsetToDirectory(); //relative offset! 107 | offset_t getNameOffset(); 108 | 109 | IMAGE_RESOURCE_DIRECTORY_STRING* getNameStr(); 110 | offset_t getChildAddress(); 111 | 112 | IMAGE_RESOURCE_DIRECTORY_ENTRY *getEntryPtr(); 113 | ResourcesAlbum* getAlbumPtr() { return album; } 114 | long getTopEntryID() { return topEntryID; } 115 | 116 | protected: 117 | virtual void clear(); 118 | 119 | private: 120 | long topEntryID; 121 | ResourcesAlbum *album; 122 | 123 | ResourceDirWrapper* parentDir, *childDir; 124 | ResourceLeafWrapper *childLeaf; 125 | }; 126 | 127 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/ResourceLeafWrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../ExeNodeWrapper.h" 4 | 5 | #include 6 | #include 7 | #include "pe_formats.h" 8 | 9 | class ResourceLeafWrapper : public ExeNodeWrapper 10 | { 11 | public: 12 | // fields : 13 | enum FieldID { 14 | NONE = FIELD_NONE, 15 | OFFSET_TO_DATA, 16 | DATA_SIZE, 17 | CODE_PAGE, 18 | RESERVED, 19 | FIELD_COUNTER 20 | }; 21 | 22 | ResourceLeafWrapper(Executable *pe, offset_t rawOffset, long topEntryId) 23 | : ExeNodeWrapper(pe), offset(rawOffset), topEntryID(topEntryId){ } 24 | 25 | virtual ~ResourceLeafWrapper() { } 26 | 27 | virtual void* getPtr() { return leafEntryPtr(); } 28 | virtual bufsize_t getSize() { return sizeof(IMAGE_RESOURCE_DATA_ENTRY); } 29 | 30 | virtual QString getName() { return "Resource Data"; } 31 | virtual size_t getFieldsCount() { return FIELD_COUNTER; } 32 | 33 | virtual void* getFieldPtr(size_t fieldId, size_t subField); 34 | virtual QString getFieldName(size_t fieldId); 35 | virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField) 36 | { 37 | return (fieldId == OFFSET_TO_DATA) ? Executable::RVA : Executable::NOT_ADDR; 38 | } 39 | 40 | IMAGE_RESOURCE_DATA_ENTRY *leafEntryPtr(); 41 | 42 | Executable* getExe() { return this->m_Exe; } 43 | 44 | protected: 45 | offset_t offset; 46 | long topEntryID; 47 | //ResourceEntryWrapper* parentEntry; 48 | }; 49 | 50 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/RichHdrWrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PENodeWrapper.h" 4 | #include "pe_undoc.h" 5 | 6 | const QString RichHdr_ProdIdToVSversion(WORD prodId); 7 | const QString RichHdr_translateProdId(WORD prodId); 8 | 9 | class RichHdrWrapper : public PEElementWrapper 10 | { 11 | public: 12 | /* fields :*/ 13 | enum FieldID { 14 | NONE = -1, 15 | DANS_ID = 0, 16 | CPAD0, 17 | CPAD1, 18 | CPAD2, 19 | COMP_ID_1, 20 | RICH_ID, 21 | CHECKSUM, 22 | FIELD_COUNTER 23 | }; 24 | 25 | RichHdrWrapper(PEFile *pe) 26 | : PEElementWrapper(pe), richSign(NULL), dansHdr(NULL), compIdCounter(0) { wrap(); } 27 | 28 | size_t compIdCount(); 29 | 30 | virtual bool wrap(); 31 | /* full structure boundaries */ 32 | virtual void* getPtr(); 33 | virtual bufsize_t getSize(); 34 | virtual QString getName() { return "Rich Hdr"; } 35 | virtual size_t getFieldsCount(); 36 | 37 | /* specific field boundaries */ 38 | virtual void* getFieldPtr(size_t fieldId, size_t subField = FIELD_NONE); 39 | virtual bufsize_t getFieldSize(size_t fieldId, size_t subField = FIELD_NONE); 40 | virtual QString translateFieldContent(size_t fieldId); 41 | virtual QString getFieldName(size_t fieldId); 42 | virtual Executable::addr_type containsAddrType(uint32_t fieldId, uint32_t subField = FIELD_NONE); 43 | 44 | /* only for this wrapper type */ 45 | pe::RICH_COMP_ID getCompId(size_t fieldId); 46 | DWORD calcChecksum(); 47 | 48 | protected: 49 | pe::RICH_SIGNATURE* richSign; 50 | pe::RICH_DANS_HEADER* dansHdr; 51 | size_t compIdCounter; 52 | }; 53 | 54 | 55 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/SecurityDirWrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "DataDirEntryWrapper.h" 4 | 5 | /* 6 | typedef struct WIN_CERTIFICATE { 7 | DWORD dwLength; 8 | WORD wRevision; 9 | WORD wCertificateType; 10 | BYTE bCertificate[]; 11 | } WIN_CERTIFICATE, *LPWIN_CERTIFICATE; 12 | */ 13 | 14 | class SecurityDirWrapper : public DataDirEntryWrapper 15 | { 16 | public: 17 | 18 | enum SecurityDirFID { 19 | NONE = FIELD_NONE, 20 | CERT_LEN = 0, 21 | REVISION, 22 | TYPE, 23 | CERT_CONTENT, 24 | FIELD_COUNTER 25 | }; 26 | 27 | SecurityDirWrapper(PEFile * pe) 28 | : DataDirEntryWrapper(pe, pe::DIR_SECURITY), sizeOk(false) 29 | { 30 | wrap(); 31 | } 32 | 33 | ~SecurityDirWrapper() { clear(); } 34 | 35 | bool wrap(); 36 | 37 | virtual void* getPtr(); 38 | 39 | virtual bufsize_t getSize(); 40 | virtual QString getName() { return "Security"; } 41 | virtual size_t getFieldsCount() { return FIELD_COUNTER; } 42 | virtual size_t getSubFieldsCount() { return 1; } 43 | 44 | virtual void* getFieldPtr(size_t fieldId, size_t subField); 45 | virtual QString getFieldName(size_t fieldId); 46 | virtual WrappedValue::data_type containsDataType(size_t fieldId, size_t subField = FIELD_NONE); 47 | 48 | QString translateType(int type); 49 | virtual QString translateFieldContent(size_t fieldId); 50 | 51 | private: 52 | pe::WIN_CERTIFICATE* getCert(); 53 | void clear() {} 54 | 55 | bool sizeOk; 56 | }; 57 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/TlsDirWrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "DataDirEntryWrapper.h" 4 | 5 | class TlsEntryWrapper; 6 | class TlsDirWrapper; 7 | 8 | class TlsDirWrapper : public DataDirEntryWrapper 9 | { 10 | public: 11 | /* fields :*/ 12 | enum TlsDirFID { 13 | NONE = FIELD_NONE, 14 | START_ADDR, 15 | END_ADDR, 16 | INDEX_ADDR, 17 | CALLBACKS_ADDR, 18 | ZEROF_SIZE, 19 | CHARACT, 20 | FIELD_COUNTER 21 | }; 22 | 23 | TlsDirWrapper(PEFile *pe) 24 | : DataDirEntryWrapper(pe, pe::DIR_TLS) { wrap(); } 25 | 26 | bool wrap(); 27 | 28 | virtual void* getPtr(); 29 | virtual bufsize_t getSize(); 30 | 31 | virtual QString getName() { return "TLS"; } 32 | virtual size_t getFieldsCount() { return FIELD_COUNTER; } 33 | virtual size_t getSubFieldsCount() { return 1; } 34 | 35 | virtual void* getFieldPtr(size_t fieldId, size_t subField); 36 | virtual QString getFieldName(size_t fieldId); 37 | virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField = FIELD_NONE); 38 | 39 | private: 40 | inline void* getTlsDirPtr(); 41 | IMAGE_TLS_DIRECTORY64* tls64(); 42 | IMAGE_TLS_DIRECTORY32* tls32(); 43 | }; 44 | 45 | 46 | class TlsEntryWrapper : public ExeNodeWrapper 47 | { 48 | public: 49 | // fields : 50 | enum FieldID { 51 | NONE = FIELD_NONE, 52 | CALLBACK_ADDR, 53 | FIELD_COUNTER 54 | }; 55 | 56 | TlsEntryWrapper(Executable *pe, TlsDirWrapper *parentDir, size_t entryNumber) 57 | : ExeNodeWrapper(pe, parentDir, entryNumber) { this->parentDir = parentDir; } 58 | 59 | // full structure boundaries 60 | virtual void* getPtr(); 61 | virtual bufsize_t getSize(); 62 | 63 | virtual QString getName() { return "TLS Callback"; } 64 | virtual size_t getFieldsCount() { return FIELD_COUNTER; } 65 | virtual size_t getSubFieldsCount() { return 1; } 66 | 67 | // specific field boundaries 68 | virtual void* getFieldPtr(size_t fieldId, size_t subField = FIELD_NONE) { return getPtr(); } 69 | virtual QString getFieldName(size_t fieldId) { return getName(); } 70 | virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField) { return Executable::VA; } 71 | 72 | private: 73 | TlsDirWrapper* parentDir; 74 | 75 | }; 76 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/lookup/CommonOrdinalsMap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class CommonOrdinalsMap 6 | { 7 | public: 8 | CommonOrdinalsMap() 9 | : dllName("") { } 10 | 11 | CommonOrdinalsMap(QString _dllName) 12 | : dllName(_dllName) { } 13 | 14 | QString dllName; 15 | QMap ord_names; 16 | }; 17 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/lookup/CommonOrdinalsWS2_32.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CommonOrdinalsMap.h" 4 | 5 | class CommonOrdinalsWS2_32 : public CommonOrdinalsMap 6 | { 7 | public: 8 | CommonOrdinalsWS2_32() 9 | : CommonOrdinalsMap("ws2_32.dll") 10 | { 11 | ord_names[1] = "accept"; 12 | ord_names[2] = "bind"; 13 | ord_names[3] = "closesocket"; 14 | ord_names[4] = "connect"; 15 | ord_names[5] = "getpeername"; 16 | ord_names[6] = "getsockname"; 17 | ord_names[7] = "getsockopt"; 18 | ord_names[8] = "htonl"; 19 | ord_names[9] = "htons"; 20 | ord_names[10] = "ioctlsocket"; 21 | ord_names[11] = "inet_addr"; 22 | ord_names[12] = "inet_ntoa"; 23 | ord_names[13] = "listen"; 24 | ord_names[14] = "ntohl"; 25 | ord_names[15] = "ntohs"; 26 | ord_names[16] = "recv"; 27 | ord_names[17] = "recvfrom"; 28 | ord_names[18] = "select"; 29 | ord_names[19] = "send"; 30 | ord_names[20] = "sendto"; 31 | ord_names[21] = "setsockopt"; 32 | ord_names[22] = "shutdown"; 33 | ord_names[23] = "socket"; 34 | ord_names[24] = "GetAddrInfoW"; 35 | ord_names[25] = "GetNameInfoW"; 36 | ord_names[26] = "WSApSetPostRoutine"; 37 | ord_names[27] = "FreeAddrInfoW"; 38 | ord_names[28] = "WPUCompleteOverlappedRequest"; 39 | ord_names[29] = "WSAAccept"; 40 | ord_names[30] = "WSAAddressToStringA"; 41 | ord_names[31] = "WSAAddressToStringW"; 42 | ord_names[32] = "WSACloseEvent"; 43 | ord_names[33] = "WSAConnect"; 44 | ord_names[34] = "WSACreateEvent"; 45 | ord_names[35] = "WSADuplicateSocketA"; 46 | ord_names[36] = "WSADuplicateSocketW"; 47 | ord_names[37] = "WSAEnumNameSpaceProvidersA"; 48 | ord_names[38] = "WSAEnumNameSpaceProvidersW"; 49 | ord_names[39] = "WSAEnumNetworkEvents"; 50 | ord_names[40] = "WSAEnumProtocolsA"; 51 | ord_names[41] = "WSAEnumProtocolsW"; 52 | ord_names[42] = "WSAEventSelect"; 53 | ord_names[43] = "WSAGetOverlappedResult"; 54 | ord_names[44] = "WSAGetQOSByName"; 55 | ord_names[45] = "WSAGetServiceClassInfoA"; 56 | ord_names[46] = "WSAGetServiceClassInfoW"; 57 | ord_names[47] = "WSAGetServiceClassNameByClassIdA"; 58 | ord_names[48] = "WSAGetServiceClassNameByClassIdW"; 59 | ord_names[49] = "WSAHtonl"; 60 | ord_names[50] = "WSAHtons"; 61 | ord_names[51] = "gethostbyaddr"; 62 | ord_names[52] = "gethostbyname"; 63 | ord_names[53] = "getprotobyname"; 64 | ord_names[54] = "getprotobynumber"; 65 | ord_names[55] = "getservbyname"; 66 | ord_names[56] = "getservbyport"; 67 | ord_names[57] = "gethostname"; 68 | ord_names[58] = "WSAInstallServiceClassA"; 69 | ord_names[59] = "WSAInstallServiceClassW"; 70 | ord_names[60] = "WSAIoctl"; 71 | ord_names[61] = "WSAJoinLeaf"; 72 | ord_names[62] = "WSALookupServiceBeginA"; 73 | ord_names[63] = "WSALookupServiceBeginW"; 74 | ord_names[64] = "WSALookupServiceEnd"; 75 | ord_names[65] = "WSALookupServiceNextA"; 76 | ord_names[66] = "WSALookupServiceNextW"; 77 | ord_names[67] = "WSANSPIoctl"; 78 | ord_names[68] = "WSANtohl"; 79 | ord_names[69] = "WSANtohs"; 80 | ord_names[70] = "WSAProviderConfigChange"; 81 | ord_names[71] = "WSARecv"; 82 | ord_names[72] = "WSARecvDisconnect"; 83 | ord_names[73] = "WSARecvFrom"; 84 | ord_names[74] = "WSARemoveServiceClass"; 85 | ord_names[75] = "WSAResetEvent"; 86 | ord_names[76] = "WSASend"; 87 | ord_names[77] = "WSASendDisconnect"; 88 | ord_names[78] = "WSASendTo"; 89 | ord_names[79] = "WSASetEvent"; 90 | ord_names[80] = "WSASetServiceA"; 91 | ord_names[81] = "WSASetServiceW"; 92 | ord_names[82] = "WSASocketA"; 93 | ord_names[83] = "WSASocketW"; 94 | ord_names[84] = "WSAStringToAddressA"; 95 | ord_names[85] = "WSAStringToAddressW"; 96 | ord_names[86] = "WSAWaitForMultipleEvents"; 97 | ord_names[87] = "WSCDeinstallProvider"; 98 | ord_names[88] = "WSCEnableNSProvider"; 99 | ord_names[89] = "WSCEnumProtocols"; 100 | ord_names[90] = "WSCGetProviderPath"; 101 | ord_names[91] = "WSCInstallNameSpace"; 102 | ord_names[92] = "WSCInstallProvider"; 103 | ord_names[93] = "WSCUnInstallNameSpace"; 104 | ord_names[94] = "WSCUpdateProvider"; 105 | ord_names[95] = "WSCWriteNameSpaceOrder"; 106 | ord_names[96] = "WSCWriteProviderOrder"; 107 | ord_names[97] = "freeaddrinfo"; 108 | ord_names[98] = "getaddrinfo"; 109 | ord_names[99] = "getnameinfo"; 110 | ord_names[101] = "WSAAsyncSelect"; 111 | ord_names[102] = "WSAAsyncGetHostByAddr"; 112 | ord_names[103] = "WSAAsyncGetHostByName"; 113 | ord_names[104] = "WSAAsyncGetProtoByNumber"; 114 | ord_names[105] = "WSAAsyncGetProtoByName"; 115 | ord_names[106] = "WSAAsyncGetServByPort"; 116 | ord_names[107] = "WSAAsyncGetServByName"; 117 | ord_names[108] = "WSACancelAsyncRequest"; 118 | ord_names[109] = "WSASetBlockingHook"; 119 | ord_names[110] = "WSAUnhookBlockingHook"; 120 | ord_names[111] = "WSAGetLastError"; 121 | ord_names[112] = "WSASetLastError"; 122 | ord_names[113] = "WSACancelBlockingCall"; 123 | ord_names[114] = "WSAIsBlocking"; 124 | ord_names[115] = "WSAStartup"; 125 | ord_names[116] = "WSACleanup"; 126 | ord_names[151] = "__WSAFDIsSet"; 127 | ord_names[500] = "WEP"; 128 | } 129 | }; 130 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/pe_undoc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../win_hdrs/win_types.h" 4 | 5 | #include "../win_hdrs/pshpack4.h" // ensure that 4 byte packing (the default) is used 6 | 7 | namespace pe { 8 | 9 | /* 10 | * Rich header format. 11 | */ 12 | 13 | const DWORD RICH_HDR_MAGIC = 0x68636952; //"Rich" 14 | const DWORD DANS_HDR_MAGIC = 0x536E6144; //"DanS" 15 | 16 | typedef struct _RICH_COMP_ID { 17 | WORD CV; 18 | WORD prodId; 19 | DWORD count; 20 | } RICH_COMP_ID, *PRICH_COMP_ID; 21 | 22 | typedef struct _RICH_SIGNATURE { 23 | DWORD richId; 24 | DWORD checksum; 25 | } RICH_SIGNATURE, *PRICH_SIGNATURE; 26 | 27 | typedef struct _RICH_DANS_HEADER { 28 | DWORD dansId; 29 | DWORD cPad[3]; 30 | RICH_COMP_ID compId[1]; //several instances possible 31 | } RICH_DANS_HEADER, *PRICH_DANS_HEADER; 32 | 33 | typedef struct _IMAGE_RICH_HEADER { 34 | RICH_DANS_HEADER dansHdr; 35 | RICH_SIGNATURE richSign; 36 | } IMAGE_RICH_HEADER, *PIMAGE_RICH_HEADER; 37 | 38 | 39 | ///--- 40 | 41 | //Debug Directory type: CodeView 42 | #pragma pack (1) 43 | 44 | #ifndef MAX_PATH 45 | #define MAX_PATH 260 46 | #endif 47 | 48 | #define CV_SIGNATURE_RSDS 0x53445352 49 | #define CV_SIGNATURE_NB10 0x3031424E 50 | 51 | typedef struct _RSDSI_GUID { 52 | DWORD Data1; 53 | WORD Data2; 54 | WORD Data3; 55 | BYTE Data4[2]; 56 | BYTE Data5[6]; 57 | } RSDSI_GUID; 58 | 59 | 60 | // CodeView header 61 | struct CV_HEADER 62 | { 63 | DWORD CvSignature; // NBxx 64 | LONG Offset; // Always 0 for NB10 65 | }; 66 | 67 | typedef struct _DEBUG_NB10 68 | { 69 | CV_HEADER cvHdr; 70 | DWORD Signature; // seconds since 01.01.1970 71 | DWORD Age; // an always-incrementing value 72 | BYTE PdbFileName[1]; // zero terminated string with the name of the PDB file 73 | } DEBUG_NB10, *PDEBUG_NB10; 74 | 75 | typedef struct _DEBUG_RSDSI 76 | { 77 | /*000*/ DWORD dwSig; 78 | /*004*/ RSDSI_GUID guidSig; 79 | /*014*/ DWORD age; 80 | /*018*/ BYTE szPdb[1]; 81 | /*324*/ 82 | } DEBUG_RSDSI, *PDEBUG_RSDSI; 83 | 84 | #define RSDSI_SIZE sizeof (RSDSI) 85 | 86 | #pragma pack () //#pragma pack (1) 87 | 88 | 89 | }; //namespace pe 90 | 91 | #include "../win_hdrs/poppack.h" 92 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/rsrc/ResourceContentFactory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ResourceContentWrapper.h" 4 | 5 | class ResourceContentFactory 6 | { 7 | public: 8 | static ResourceContentWrapper *makeResContentWrapper(pe::resource_type typeId, ResourceLeafWrapper* leaf); 9 | }; 10 | 11 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/rsrc/ResourceContentWrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../ExeElementWrapper.h" 4 | #include "../ResourceLeafWrapper.h" 5 | #include "../pe_formats.h" 6 | 7 | class ResourceContentFactory; 8 | 9 | class ResourceContentWrapper : public ExeNodeWrapper 10 | { 11 | public: 12 | static QString translateType(pe::resource_type type); 13 | 14 | virtual ~ResourceContentWrapper() {} 15 | 16 | void* getResContentPtr(); 17 | bufsize_t getResContentSize(); 18 | offset_t getContentRaw(); 19 | 20 | pe::resource_type getType() { return typeId; } 21 | 22 | virtual void* getPtr() { return getResContentPtr(); } 23 | virtual bufsize_t getSize() { return getResContentSize(); } 24 | 25 | virtual QString getName() { return translateType(this->typeId); } 26 | virtual size_t getFieldsCount() { return 1; } 27 | virtual size_t getSubFieldsCount() { return 1; } 28 | 29 | /* specific field boundatries */ 30 | virtual void* getFieldPtr(size_t fieldId, size_t subField) { return getPtr(); } 31 | virtual QString getFieldName(size_t fieldId) { return getName(); } 32 | virtual WrappedValue::data_type containsDataType(size_t fieldId, size_t subField = FIELD_NONE) { return WrappedValue::COMPLEX; } 33 | 34 | protected: 35 | ResourceContentWrapper(Executable *pe, ResourceLeafWrapper* v_leaf, pe::resource_type v_typeId) 36 | : ExeNodeWrapper(pe), myLeaf(v_leaf), typeId(v_typeId) {} 37 | 38 | BYTE* getContentAt(offset_t dataAddr, Executable::addr_type aT, bufsize_t dataSize); 39 | 40 | ResourceLeafWrapper* myLeaf; 41 | pe::resource_type typeId; 42 | 43 | friend class ResourceContentFactory; 44 | }; 45 | 46 | 47 | class ReourceManifestWrapper : public ResourceContentWrapper 48 | { 49 | public: 50 | virtual WrappedValue::data_type containsDataType(size_t fieldId, size_t subField = FIELD_NONE) { return WrappedValue::STRING; } 51 | 52 | protected: 53 | ReourceManifestWrapper(Executable *pe, ResourceLeafWrapper* v_leaf) 54 | : ResourceContentWrapper(pe, v_leaf, pe::RESTYPE_MANIFEST) {} 55 | 56 | friend class ResourceContentFactory; 57 | }; 58 | 59 | class ReourceHTMLWrapper : public ResourceContentWrapper 60 | { 61 | public: 62 | virtual WrappedValue::data_type containsDataType(size_t fieldId, size_t subField = FIELD_NONE) { return WrappedValue::STRING; } 63 | 64 | protected: 65 | ReourceHTMLWrapper(Executable *pe, ResourceLeafWrapper* v_leaf) 66 | : ResourceContentWrapper(pe, v_leaf, pe::RESTYPE_HTML 67 | ) {} 68 | 69 | friend class ResourceContentFactory; 70 | }; -------------------------------------------------------------------------------- /parser/include/bearparser/pe/rsrc/ResourceStringsWrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../ResourceLeafWrapper.h" 3 | #include "ResourceContentWrapper.h" 4 | 5 | #include 6 | 7 | class ResString : public ExeNodeWrapper { 8 | public: 9 | enum ResourceFID { 10 | NONE = FIELD_NONE, 11 | STR_LEN, 12 | WSTRING, 13 | FIELD_COUNTER 14 | }; 15 | 16 | ResString(WORD *v_ptr, WORD *v_sizePtr, offset_t v_offset, Executable* v_exe) 17 | : ExeNodeWrapper(v_exe), ptr(v_ptr), sizePtr(v_sizePtr), offset(v_offset) { } 18 | 19 | /* full structure boundatries */ 20 | virtual void* getPtr(); 21 | virtual bufsize_t getSize(); 22 | virtual QString getName(); 23 | virtual size_t getFieldsCount() { return FIELD_COUNTER; } 24 | virtual size_t getSubFieldsCount() { return 1; } 25 | 26 | /* specific field boundatries */ 27 | virtual void* getFieldPtr(size_t fieldId, size_t subField); 28 | virtual QString getFieldName(size_t fieldId); 29 | virtual bufsize_t getFieldSize(size_t fId, size_t subField); 30 | 31 | QString getQString() 32 | { 33 | if (this->m_Exe == NULL) return ""; //ERROR 34 | WORD* entries = ptr; 35 | int size = *(sizePtr); 36 | WORD *content = (WORD*) this->m_Exe->getContentAt(offset,Executable::RAW, size); 37 | if (content == NULL) return ""; 38 | 39 | return QString::fromUtf16(reinterpret_cast(content), size); 40 | } 41 | 42 | virtual size_t getStrLen() { return (sizePtr == NULL) ? 0 : static_cast(*sizePtr); } 43 | virtual WrappedValue::data_type containsDataType(size_t fieldId, size_t subField) 44 | { 45 | if (fieldId == WSTRING) { 46 | return WrappedValue::WSTRING; 47 | } 48 | return WrappedValue::INT; 49 | } 50 | WORD *ptr; 51 | WORD *sizePtr; 52 | offset_t offset; 53 | }; 54 | 55 | class ResourceStringsWrapper : public ResourceContentWrapper 56 | { 57 | public: 58 | enum ResourceFID { 59 | NONE = FIELD_NONE, 60 | STR_LEN, 61 | WSTRING, 62 | FIELD_COUNTER 63 | }; 64 | 65 | /* specific field boundatries */ 66 | virtual QString getFieldName(size_t fieldId); 67 | virtual void* getFieldPtr(size_t fieldId, size_t subField); 68 | virtual bufsize_t getFieldSize(size_t fieldId, size_t subField = FIELD_NONE); 69 | 70 | virtual size_t getFieldsCount() { return entries.size(); } 71 | 72 | ResString* getResStringAt(size_t index) 73 | { 74 | if (index > entries.size()) return NULL; 75 | ResString* str = dynamic_cast(entries[index]); 76 | return str; 77 | } 78 | 79 | QString getQStringAt(size_t index) 80 | { 81 | ResString* str = getResStringAt(index); 82 | return str->getQString(); 83 | } 84 | 85 | size_t getResStringsCount() { return entries.size(); } 86 | 87 | virtual WrappedValue::data_type containsDataType(size_t fieldId, size_t subField) 88 | { 89 | if (fieldId == WSTRING) { 90 | return WrappedValue::WSTRING; 91 | } 92 | return WrappedValue::INT; 93 | } 94 | 95 | protected: 96 | ResourceStringsWrapper(Executable *pe, ResourceLeafWrapper* v_leaf) 97 | : ResourceContentWrapper(pe, v_leaf, pe::RESTYPE_STRING) { wrap(); } 98 | 99 | bool wrap(); 100 | 101 | size_t parsedSize; 102 | 103 | friend class ResourceContentFactory; 104 | friend class ResourcesAlbum; 105 | }; 106 | 107 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/rsrc/ResourceVersionWrapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../ResourceLeafWrapper.h" 4 | #include "ResourceContentWrapper.h" 5 | #include "../pe_formats.h" 6 | 7 | class ResourceVersionWrapper : public ResourceContentWrapper 8 | { 9 | public: 10 | enum ResourceFID { 11 | NONE = FIELD_NONE, 12 | STRUCT_LEN, 13 | VAL_LEN, 14 | STRUCT_TYPE, 15 | INFO, 16 | SIGNATURE, 17 | STRUCT_VER, 18 | FILE_VER_0, 19 | FILE_VER_1, 20 | PRODUCT_VER_0, 21 | PRODUCT_VER_1, 22 | FLAGS_MASK, 23 | FLAGS, 24 | OS, 25 | TYPE, 26 | SUBTYPE, 27 | TIMESTAMP_0, 28 | TIMESTAMP_1, 29 | CHILDREN, 30 | FIELD_COUNTER 31 | }; 32 | 33 | ResourceVersionWrapper(Executable *pe, ResourceLeafWrapper* v_leaf); 34 | 35 | /* full structure boundatries */ 36 | virtual void* getPtr() { return getVersionInfo(); } 37 | virtual bufsize_t getSize() { return (getVersionInfo() == NULL) ? 0 :sizeof(pe::version_info); } 38 | virtual QString getName() { return "Version"; } 39 | virtual size_t getFieldsCount() { return FIELD_COUNTER; } 40 | virtual size_t getSubFieldsCount() { return 1; } //TODO: children 41 | 42 | /* specific field boundatries */ 43 | virtual void* getFieldPtr(size_t fieldId, size_t subField); 44 | virtual QString getFieldName(size_t fieldId); 45 | 46 | virtual WrappedValue::data_type containsDataType(size_t fieldId, size_t subField = FIELD_NONE); 47 | 48 | pe::version_info *getVersionInfo(); 49 | 50 | QString getVersionText() 51 | { 52 | pe::version_info *info = getVersionInfo(); 53 | if (!info) return ""; //ERROR 54 | 55 | int size = INFOTEXT_LEN; 56 | const WORD *content = info->key; 57 | if (!content) return ""; 58 | 59 | return QString::fromUtf16(reinterpret_cast(content), size); 60 | } 61 | 62 | friend class ResourceContentFactory; 63 | }; 64 | 65 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/rsrc/ResourcesAlbum.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define TOP_ENTRY_ROOT long(-1) 4 | 5 | #include "../../ExeNodeWrapper.h" 6 | #include "../ResourceLeafWrapper.h" 7 | #include "ResourceContentFactory.h" 8 | 9 | #include 10 | #include 11 | 12 | class ResourcesContainer { 13 | public: 14 | ResourcesContainer() {} 15 | virtual ~ResourcesContainer() {} //TODO 16 | 17 | void putWrapper(ResourceContentWrapper* wrapper); 18 | ResourceContentWrapper* getWrapperAt(size_t index); 19 | 20 | size_t count() { return wrappers.size(); } 21 | size_t entriesCount(); 22 | 23 | protected: 24 | std::vector wrappers; 25 | }; 26 | 27 | class ResourcesAlbum { 28 | public: 29 | 30 | ResourcesAlbum(Executable *pe) {} 31 | 32 | virtual ~ResourcesAlbum() { clear(); } 33 | 34 | void putLeaf(ResourceLeafWrapper* leaf, long topEntryId); 35 | void clear(); 36 | 37 | size_t dirsCount() { return allLeafs.size(); } 38 | size_t entriesCountAt(long topEntryId); 39 | std::vector* entriesAt(long topEntryId); 40 | 41 | //TODO: create ResourceContentWrapper 42 | void mapIdToLeafType(long topId, pe::resource_type leafType) { idToLeafType[topId] = leafType; } 43 | void wrapLeafsContent(); // TODO: wrap content on demand - lazy mode 44 | ResourceContentWrapper* getContentWrapper(ResourceLeafWrapper* leaf) { return this->leafToContentWrapper[leaf]; } 45 | 46 | bool hasType(pe::resource_type typeId) { return (allWrappers.find(typeId) == allWrappers.end()) ? false : true; } 47 | ResourcesContainer* getResourcesOfType(pe::resource_type typeId); 48 | std::vector getResourceTypes() const { return allTypes; } 49 | 50 | protected: 51 | void clearLeafsContent(); 52 | 53 | void initResourceTypes(); 54 | bool hasTopEntry(long topEntryId) { return (allLeafs.find(topEntryId) == allLeafs.end()) ? false : true; } 55 | 56 | std::vector allTypes; 57 | std::map allWrappers; 58 | std::map > allLeafs; 59 | 60 | std::map idToLeafType; // map topEntryId to leafDataType: i. e. RT_HTML, case RT_MANIFEST 61 | std::map leafToContentWrapper; 62 | 63 | }; 64 | 65 | -------------------------------------------------------------------------------- /parser/include/bearparser/pe/rsrc/pe_rsrc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ResourcesAlbum.h" 4 | #include "ResourceStringsWrapper.h" 5 | #include "ResourceVersionWrapper.h" 6 | 7 | -------------------------------------------------------------------------------- /parser/include/bearparser/win_hdrs/poppack.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright 1990 - 1998 Microsoft Corporation 4 | 5 | Module Name: 6 | 7 | poppack.h 8 | 9 | Abstract: 10 | 11 | This file turns packing of structures off. (That is, it enables 12 | automatic alignment of structure fields.) An include file is needed 13 | because various compilers do this in different ways. 14 | 15 | poppack.h is the complement to pshpack?.h. An inclusion of poppack.h 16 | MUST ALWAYS be preceded by an inclusion of one of pshpack?.h, in one-to-one 17 | correspondence. 18 | 19 | For Microsoft compatible compilers, this file uses the pop option 20 | to the pack pragma so that it can restore the previous saved by the 21 | pshpack?.h include file. 22 | 23 | --*/ 24 | 25 | #if ! (defined(lint) || defined(_lint) || defined(RC_INVOKED)) 26 | #if ( _MSC_VER >= 800 ) || defined(_PUSHPOP_SUPPORTED) 27 | #pragma warning(disable:4103) 28 | #if !(defined( MIDL_PASS )) || defined( __midl ) 29 | #pragma pack(pop) 30 | #else 31 | #pragma pack() 32 | #endif 33 | #else 34 | #pragma pack() 35 | #endif 36 | #endif // ! (defined(lint) || defined(_lint) || defined(RC_INVOKED)) 37 | -------------------------------------------------------------------------------- /parser/include/bearparser/win_hdrs/pshpack1.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright 1995 - 1998 Microsoft Corporation 4 | 5 | Module Name: 6 | 7 | pshpack1.h 8 | 9 | Abstract: 10 | 11 | This file turns 1 byte packing of structures on. (That is, it disables 12 | automatic alignment of structure fields.) An include file is needed 13 | because various compilers do this in different ways. For Microsoft 14 | compatible compilers, this files uses the push option to the pack pragma 15 | so that the poppack.h include file can restore the previous packing 16 | reliably. 17 | 18 | The file poppack.h is the complement to this file. 19 | 20 | --*/ 21 | 22 | #if ! (defined(lint) || defined(_lint) || defined(RC_INVOKED)) 23 | #if ( _MSC_VER >= 800 ) || defined(_PUSHPOP_SUPPORTED) 24 | #pragma warning(disable:4103) 25 | #if !(defined( MIDL_PASS )) || defined( __midl ) 26 | #pragma pack(push) 27 | #endif 28 | #pragma pack(1) 29 | #else 30 | #pragma pack(1) 31 | #endif 32 | #endif // ! (defined(lint) || defined(_lint) || defined(RC_INVOKED)) 33 | -------------------------------------------------------------------------------- /parser/include/bearparser/win_hdrs/pshpack2.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright 1995 - 1998 Microsoft Corporation 4 | 5 | Module Name: 6 | 7 | pshpack2.h 8 | 9 | Abstract: 10 | 11 | This file turns 2 byte packing of structures on. (That is, it disables 12 | automatic alignment of structure fields.) An include file is needed 13 | because various compilers do this in different ways. For Microsoft 14 | compatible compilers, this files uses the push option to the pack pragma 15 | so that the poppack.h include file can restore the previous packing 16 | reliably. 17 | 18 | The file poppack.h is the complement to this file. 19 | 20 | --*/ 21 | 22 | #if ! (defined(lint) || defined(_lint) || defined(RC_INVOKED)) 23 | #if ( _MSC_VER >= 800 ) || defined(_PUSHPOP_SUPPORTED) 24 | #pragma warning(disable:4103) 25 | #if !(defined( MIDL_PASS )) || defined( __midl ) 26 | #pragma pack(push) 27 | #endif 28 | #pragma pack(2) 29 | #else 30 | #pragma pack(2) 31 | #endif 32 | #endif // ! (defined(lint) || defined(_lint) || defined(RC_INVOKED)) 33 | -------------------------------------------------------------------------------- /parser/include/bearparser/win_hdrs/pshpack4.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright 1995 - 1998 Microsoft Corporation 4 | 5 | Module Name: 6 | 7 | pshpack4.h 8 | 9 | Abstract: 10 | 11 | This file turns 4 byte packing of structures on. (That is, it disables 12 | automatic alignment of structure fields.) An include file is needed 13 | because various compilers do this in different ways. For Microsoft 14 | compatible compilers, this files uses the push option to the pack pragma 15 | so that the poppack.h include file can restore the previous packing 16 | reliably. 17 | 18 | The file poppack.h is the complement to this file. 19 | 20 | --*/ 21 | 22 | #if ! (defined(lint) || defined(_lint) || defined(RC_INVOKED)) 23 | #if ( _MSC_VER >= 800 ) || defined(_PUSHPOP_SUPPORTED) 24 | #pragma warning(disable:4103) 25 | #if !(defined( MIDL_PASS )) || defined( __midl ) 26 | #pragma pack(push) 27 | #endif 28 | #pragma pack(4) 29 | #else 30 | #pragma pack(4) 31 | #endif 32 | #endif // ! (defined(lint) || defined(_lint) || defined(RC_INVOKED)) 33 | -------------------------------------------------------------------------------- /parser/include/bearparser/win_hdrs/pshpack8.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright 1995 - 1998 Microsoft Corporation 4 | 5 | Module Name: 6 | 7 | pshpack8.h 8 | 9 | Abstract: 10 | 11 | This file turns 8 byte packing of structures on. (That is, it disables 12 | automatic alignment of structure fields.) An include file is needed 13 | because various compilers do this in different ways. For Microsoft 14 | compatible compilers, this files uses the push option to the pack pragma 15 | so that the poppack.h include file can restore the previous packing 16 | reliably. 17 | 18 | The file poppack.h is the complement to this file. 19 | 20 | --*/ 21 | 22 | #if ! (defined(lint) || defined(_lint) || defined(RC_INVOKED)) 23 | #if ( _MSC_VER >= 800 ) || defined(_PUSHPOP_SUPPORTED) 24 | #pragma warning(disable:4103) 25 | #if !(defined( MIDL_PASS )) || defined( __midl ) 26 | #pragma pack(push) 27 | #endif 28 | #pragma pack(8) 29 | #else 30 | #pragma pack(8) 31 | #endif 32 | #endif // ! (defined(lint) || defined(_lint) || defined(RC_INVOKED)) 33 | -------------------------------------------------------------------------------- /parser/include/bearparser/win_hdrs/win_types.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef _MSC_VER 4 | #include 5 | #else 6 | #include 7 | #endif 8 | 9 | #if _WIN32 10 | #include 11 | #else 12 | #ifndef __WIN_TYPES 13 | #define __WIN_TYPES__ 14 | 15 | #ifndef BYTE 16 | typedef unsigned char BYTE; 17 | #endif 18 | 19 | #ifndef BOOLEAN 20 | typedef BYTE BOOLEAN; 21 | #endif 22 | 23 | #ifndef BOOL 24 | typedef BYTE BOOL; 25 | #endif 26 | 27 | #ifndef WORD 28 | typedef uint16_t WORD; 29 | #endif 30 | 31 | #ifndef DWORD 32 | typedef uint32_t DWORD; 33 | #endif 34 | 35 | #ifndef ULONGLONG 36 | typedef uint64_t ULONGLONG; 37 | #endif 38 | 39 | #ifndef CHAR 40 | typedef char CHAR; 41 | #endif 42 | 43 | #ifndef WCHAR 44 | typedef wchar_t WCHAR; 45 | #endif 46 | 47 | #ifndef VOID 48 | #define VOID void 49 | typedef char CHAR; 50 | typedef uint16_t SHORT; 51 | typedef uint32_t LONG; 52 | 53 | #if !defined(MIDL_PASS) 54 | typedef int INT; 55 | #endif 56 | #endif //VOID 57 | 58 | #endif // __WIN_TYPES__ 59 | 60 | 61 | #endif // #if _MSC_VER 62 | -------------------------------------------------------------------------------- /parser/pe/BoundImpDirWrapper.cpp: -------------------------------------------------------------------------------- 1 | #include "pe/BoundImpDirWrapper.h" 2 | #include "pe/PEFile.h" 3 | 4 | /* 5 | typedef struct _IMAGE_BOUND_IMPORT_DESCRIPTOR { 6 | DWORD TimeDateStamp; 7 | WORD OffsetModuleName; 8 | WORD NumberOfModuleForwarderRefs; 9 | // Array of zero or more IMAGE_BOUND_FORWARDER_REF follows 10 | } IMAGE_BOUND_IMPORT_DESCRIPTOR, *PIMAGE_BOUND_IMPORT_DESCRIPTOR; 11 | 12 | typedef struct _IMAGE_BOUND_FORWARDER_REF { 13 | DWORD TimeDateStamp; 14 | WORD OffsetModuleName; 15 | WORD Reserved; 16 | } IMAGE_BOUND_FORWARDER_REF, *PIMAGE_BOUND_FORWARDER_REF; 17 | 18 | */ 19 | 20 | IMAGE_BOUND_IMPORT_DESCRIPTOR* BoundImpDirWrapper::boundImp() 21 | { 22 | offset_t rva = getDirEntryAddress(); 23 | 24 | BYTE *ptr = m_Exe->getContentAt(rva, Executable::RVA, sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR)); 25 | if (ptr == NULL) return NULL; 26 | return (IMAGE_BOUND_IMPORT_DESCRIPTOR*) ptr; 27 | } 28 | 29 | bool BoundImpDirWrapper::loadNextEntry(size_t entryNum) 30 | { 31 | BoundEntryWrapper* imp = new BoundEntryWrapper(m_Exe, this, entryNum); 32 | if (!imp || !imp->getPtr()) { 33 | delete imp; 34 | return false; 35 | } 36 | // TODO! do it in proper way! 37 | bool isOk = false; 38 | uint64_t offset = imp->getNumValue(BoundEntryWrapper::MODULE_NAME_OFFSET, &isOk); 39 | if (!isOk || offset == 0) { 40 | delete imp; 41 | return false; 42 | } 43 | entries.push_back(imp); 44 | return true; 45 | } 46 | 47 | bool BoundImpDirWrapper::wrap() 48 | { 49 | clear(); 50 | size_t oldCount = this->importsCount; 51 | this->importsCount = 0; 52 | 53 | if (!getDataDirectory()) { 54 | return (oldCount != this->importsCount); //has count changed 55 | } 56 | 57 | size_t cntr = 0; 58 | while (loadNextEntry(cntr)) { 59 | cntr++; 60 | } 61 | 62 | this->importsCount = cntr; 63 | return (oldCount != this->importsCount); //has count changed 64 | } 65 | 66 | bufsize_t BoundImpDirWrapper::getSize() 67 | { 68 | if (getPtr() == NULL) return 0; 69 | bufsize_t entrySize = static_cast(sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR)); 70 | return entrySize * static_cast(this->entries.size()); 71 | } 72 | 73 | //------------------------------------------------------------- 74 | 75 | void* BoundEntryWrapper::getPtr() 76 | { 77 | BoundImpDirWrapper* parent = dynamic_cast (this->getParentNode()); 78 | if (!parent) return NULL; 79 | 80 | IMAGE_BOUND_IMPORT_DESCRIPTOR* firstEntry = parent->boundImp(); 81 | if (firstEntry == NULL) return NULL; 82 | 83 | uint64_t descAddr = parent->getOffset(firstEntry); 84 | if (descAddr == INVALID_ADDR) return NULL; 85 | 86 | uint64_t entryOffset = descAddr + (this->entryNum * sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR)); 87 | if (entryOffset == INVALID_ADDR) return NULL; 88 | 89 | BYTE *content = this->m_Exe->getContentAt(entryOffset, Executable::RAW, sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR)); 90 | if (!content) return NULL; 91 | 92 | return content; 93 | } 94 | 95 | 96 | bufsize_t BoundEntryWrapper::getSize() 97 | { 98 | if (getPtr() == NULL) return 0; 99 | return sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR); 100 | } 101 | 102 | QString BoundEntryWrapper::getName() 103 | { 104 | char* name = getLibraryName(); 105 | if (!name) return ""; 106 | return QString(name); 107 | } 108 | 109 | char* BoundEntryWrapper::getLibraryName() 110 | { 111 | //---- 112 | BoundImpDirWrapper* parent = dynamic_cast (this->getParentNode()); 113 | if (!parent) return NULL; 114 | 115 | IMAGE_BOUND_IMPORT_DESCRIPTOR* firstEntry = parent->boundImp(); 116 | if (firstEntry == NULL) return NULL; 117 | 118 | uint64_t offset = this->getOffset(firstEntry); 119 | if (offset == INVALID_ADDR) return NULL; 120 | //---- 121 | IMAGE_BOUND_IMPORT_DESCRIPTOR* bImp = (IMAGE_BOUND_IMPORT_DESCRIPTOR*) this->getPtr(); 122 | if (bImp == NULL) return NULL; 123 | 124 | WORD mnOff = bImp->OffsetModuleName; 125 | 126 | offset += mnOff; 127 | 128 | char *ptr = (char*) m_Exe->getContentAt(offset, Executable::RAW, 1); 129 | return ptr; 130 | } 131 | 132 | void* BoundEntryWrapper::getFieldPtr(size_t fId, size_t subField) 133 | { 134 | BoundImpDirWrapper* parent = dynamic_cast (this->getParentNode()); 135 | if (!parent) return NULL; 136 | 137 | IMAGE_BOUND_IMPORT_DESCRIPTOR* bImp = (IMAGE_BOUND_IMPORT_DESCRIPTOR*) this->getPtr(); 138 | if (bImp == NULL) return NULL; 139 | 140 | switch (fId) { 141 | case TIMESTAMP : return &bImp->TimeDateStamp; 142 | case MODULE_NAME_OFFSET : return &bImp->OffsetModuleName; 143 | case MODULE_FORWARDERS_NUM : return &bImp->NumberOfModuleForwarderRefs; 144 | } 145 | return this->getPtr(); 146 | } 147 | 148 | QString BoundEntryWrapper::getFieldName(size_t fieldId) 149 | { 150 | switch (fieldId) { 151 | case TIMESTAMP : return "TimeDateStamp"; 152 | case MODULE_NAME_OFFSET : return "OffsetModuleName"; 153 | case MODULE_FORWARDERS_NUM : return "NumberOfModuleForwarderRefs"; 154 | } 155 | return getName(); 156 | } 157 | 158 | -------------------------------------------------------------------------------- /parser/pe/DOSExe.cpp: -------------------------------------------------------------------------------- 1 | #include "pe/DOSExe.h" 2 | 3 | 4 | bool DOSExeBuilder::signatureMatches(AbstractByteBuffer *buf) 5 | { 6 | if (buf == NULL) return false; 7 | 8 | WORD *magic = (WORD*) buf->getContentAt(0, sizeof(WORD)); 9 | if (magic == NULL) return false; 10 | 11 | if ((*magic) == pe::S_DOS || (*magic) == pe::S_DOS2) { 12 | return true; 13 | } 14 | 15 | return false; 16 | } 17 | 18 | Executable* DOSExeBuilder::build(AbstractByteBuffer *buf) 19 | { 20 | Executable *exe = NULL; 21 | if (signatureMatches(buf) == false) return NULL; 22 | 23 | try { 24 | exe = new DOSExe(buf); 25 | } catch (ExeException) { 26 | // 27 | } 28 | 29 | return exe; 30 | } 31 | 32 | //------------------------------------------------------------- 33 | 34 | DOSExe::DOSExe(AbstractByteBuffer *v_buf) 35 | : MappedExe(v_buf, Executable::BITS_16), dosHdrWrapper(NULL) 36 | { 37 | wrap(); 38 | } 39 | 40 | void DOSExe::wrap() 41 | { 42 | this->dosHdrWrapper = new DosHdrWrapper(this); 43 | 44 | m_dosHdr = (IMAGE_DOS_HEADER*) getContentAt(0, sizeof(IMAGE_DOS_HEADER)); 45 | if (m_dosHdr == NULL) throw ExeException("Could not Wrap!"); 46 | 47 | WORD* magic = (WORD*) this->dosHdrWrapper->getFieldPtr(DosHdrWrapper::MAGIC); 48 | 49 | if (this->dosHdrWrapper->getPtr() == NULL || magic == NULL) { 50 | throw ExeException("Could not Wrap!"); 51 | } 52 | 53 | if ((*magic) != pe::S_DOS && (*magic) != pe::S_DOS2) { 54 | Logger::append(Logger::D_WARNING, "It is not a DOS file!\n"); 55 | throw ExeException("It is not a DOS file!"); 56 | } 57 | this->wrappers[WR_DOS_HDR] = this->dosHdrWrapper; 58 | } 59 | 60 | offset_t DOSExe::peSignatureOffset() 61 | { 62 | LONG* lfnew = (LONG*) this->dosHdrWrapper->getFieldPtr(DosHdrWrapper::LFNEW); 63 | if (lfnew == NULL) return 0; 64 | 65 | return static_cast(*lfnew); 66 | } 67 | 68 | -------------------------------------------------------------------------------- /parser/pe/DataDirEntryWrapper.cpp: -------------------------------------------------------------------------------- 1 | #include "pe/DataDirEntryWrapper.h" 2 | #include "pe/PEFile.h" 3 | 4 | DataDirEntryWrapper::DataDirEntryWrapper(PEFile* pe, pe:: dir_entry v_entryType) 5 | : PENodeWrapper(pe), entryType(v_entryType) 6 | { 7 | wrap(); 8 | } 9 | 10 | IMAGE_DATA_DIRECTORY* DataDirEntryWrapper::getDataDirectory() 11 | { 12 | 13 | if (m_PE == NULL) return NULL; 14 | 15 | IMAGE_DATA_DIRECTORY *d = m_PE->getDataDirectory(); 16 | return d; 17 | } 18 | 19 | offset_t DataDirEntryWrapper::getDirEntryAddress() 20 | { 21 | DataDirWrapper *dDir = dynamic_cast(m_PE->getWrapper(PEFile::WR_DATADIR)); 22 | const size_t recordsCount = dDir ? dDir->getDirsCount() : 0; 23 | if (this->entryType >= recordsCount) return INVALID_ADDR; 24 | 25 | IMAGE_DATA_DIRECTORY *d = getDataDirectory(); 26 | if (!d) return INVALID_ADDR; 27 | 28 | offset_t rva = static_cast(d[this->entryType].VirtualAddress); 29 | if (rva == 0) return INVALID_ADDR; 30 | return rva; 31 | } 32 | 33 | bufsize_t DataDirEntryWrapper::getDirEntrySize(bool trimToExeSize) 34 | { 35 | DataDirWrapper *dDir = dynamic_cast(m_PE->getWrapper(PEFile::WR_DATADIR)); 36 | const size_t recordsCount = dDir ? dDir->getDirsCount() : 0; 37 | if (this->entryType >= recordsCount) return 0; 38 | 39 | IMAGE_DATA_DIRECTORY *d = getDataDirectory(); 40 | if (!d) return 0; 41 | 42 | bufsize_t dirSize = static_cast(d[this->entryType].Size); 43 | if (!trimToExeSize) { 44 | return dirSize; 45 | } 46 | 47 | if (!this->m_Exe) return 0; // should never happen 48 | 49 | offset_t dirRva = d[this->entryType].VirtualAddress; 50 | offset_t dirRaw = this->m_Exe->rvaToRaw(dirRva); 51 | if (dirRaw == INVALID_ADDR) { 52 | return 0; 53 | } 54 | bufsize_t fullSize = this->m_Exe->getContentSize(); 55 | bufsize_t remainingSize = bufsize_t(fullSize - dirRaw); 56 | 57 | return (dirSize < remainingSize) ? dirSize : remainingSize; 58 | } 59 | -------------------------------------------------------------------------------- /parser/pe/DataDirWrapper.cpp: -------------------------------------------------------------------------------- 1 | #include "pe/DataDirWrapper.h" 2 | #include "pe/PEFile.h" 3 | 4 | void* DataDirWrapper::getPtr() 5 | { 6 | if (m_PE == NULL) return NULL; 7 | 8 | const offset_t myOff = m_PE->peDataDirOffset(); 9 | IMAGE_DATA_DIRECTORY* ptr = (IMAGE_DATA_DIRECTORY*) m_Exe->getContentAt(myOff, getSize()); 10 | return ptr; 11 | } 12 | 13 | bufsize_t DataDirWrapper::getSize() 14 | { 15 | if (m_PE == NULL) return 0; 16 | const size_t count = getDirsCount(); 17 | const bufsize_t size = sizeof(IMAGE_DATA_DIRECTORY) * count; 18 | return size; 19 | } 20 | 21 | size_t DataDirWrapper::getDirsCount() 22 | { 23 | if (m_PE == NULL) return 0; 24 | OptHdrWrapper* optHdr = dynamic_cast(m_PE->getWrapper(PEFile::WR_OPTIONAL_HDR)); 25 | if (!optHdr) return 0; 26 | bool isOk = false; 27 | size_t count = optHdr->getNumValue(OptHdrWrapper::RVAS_SIZES_NUM, &isOk); 28 | if (!isOk) return 0; 29 | if (count > pe::DIR_ENTRIES_COUNT) { 30 | count = pe::DIR_ENTRIES_COUNT; 31 | } 32 | return count; 33 | } 34 | 35 | void* DataDirWrapper::getFieldPtr(size_t fieldId, size_t subField) 36 | { 37 | if (fieldId >= getDirsCount()) { 38 | return getPtr(); // invalid fieldID, give default 39 | } 40 | 41 | IMAGE_DATA_DIRECTORY* dataDir = (IMAGE_DATA_DIRECTORY*) getPtr(); 42 | if (dataDir == NULL) return NULL; 43 | 44 | switch (subField) { 45 | case ADDRESS : 46 | return (void*)(&dataDir[fieldId].VirtualAddress); 47 | case SIZE : 48 | return (void*)(&dataDir[fieldId].Size); 49 | } 50 | return (void*)(&dataDir[fieldId].VirtualAddress); 51 | } 52 | 53 | bufsize_t DataDirWrapper::getFieldSize(size_t fieldId, size_t subField) 54 | { 55 | if (fieldId >= getDirsCount()) return getSize(); 56 | 57 | IMAGE_DATA_DIRECTORY* dir = (IMAGE_DATA_DIRECTORY*) getPtr(); 58 | if (dir == NULL) return 0; 59 | 60 | IMAGE_DATA_DIRECTORY record = dir[fieldId]; 61 | 62 | switch (subField) { 63 | case ADDRESS : 64 | return sizeof(record.VirtualAddress); 65 | case SIZE : 66 | return sizeof(record.Size); 67 | } 68 | return sizeof(record.VirtualAddress) + sizeof(record.Size); 69 | } 70 | 71 | QString DataDirWrapper::getFieldName(size_t fieldId) 72 | { 73 | switch (fieldId) { 74 | case pe::DIR_EXPORT: return "Export Directory"; 75 | case pe::DIR_IMPORT: return "Import Directory"; 76 | case pe::DIR_RESOURCE : return "Resource Directory"; 77 | case pe::DIR_EXCEPTION: return "Exception Directory"; 78 | case pe::DIR_SECURITY: return "Security Directory"; 79 | case pe::DIR_BASERELOC: return "Base Relocation Table"; 80 | case pe::DIR_DEBUG : return "Debug Directory"; 81 | case pe::DIR_ARCHITECTURE: return "Architecture Specific Data"; 82 | case pe::DIR_GLOBALPTR : return "RVA of GlobalPtr"; 83 | case pe::DIR_TLS: return "TLS Directory"; 84 | case pe::DIR_LOAD_CONFIG: return "Load Configuration Directory"; 85 | case pe::DIR_BOUND_IMPORT: return "Bound Import Directory"; 86 | case pe::DIR_IAT: return "Import Address Table"; 87 | case pe::DIR_DELAY_IMPORT: return "Delay Load Import Descriptors"; 88 | case pe::DIR_COM_DESCRIPTOR : return ".NET header"; 89 | } 90 | return ""; 91 | } 92 | 93 | Executable::addr_type DataDirWrapper::containsAddrType(size_t fieldId, size_t subField) 94 | { 95 | if (subField != ADDRESS) return Executable::NOT_ADDR; 96 | 97 | if (fieldId == pe::DIR_SECURITY) return Executable::RAW; 98 | return Executable::RVA; 99 | } 100 | -------------------------------------------------------------------------------- /parser/pe/DosHdrWrapper.cpp: -------------------------------------------------------------------------------- 1 | #include "pe/DosHdrWrapper.h" 2 | #include "pe/DOSExe.h" 3 | 4 | void* DosHdrWrapper::getFieldPtr(size_t fieldId, size_t subField) 5 | { 6 | /* 7 | DOSExe *dosExe = dynamic_cast (m_Exe); 8 | if (dosExe == NULL) return NULL; 9 | */ 10 | offset_t myOff = 0;//dosExe->dosHeaderOffset(); 11 | IMAGE_DOS_HEADER* dosHdr = (IMAGE_DOS_HEADER*) m_Exe->getContentAt(myOff, sizeof(IMAGE_DOS_HEADER)); 12 | if (dosHdr == NULL) return NULL; //error 13 | 14 | switch (fieldId) { 15 | case MAGIC: return (void*) &dosHdr->e_magic; 16 | case CBLP: return (void*) &dosHdr->e_cblp; 17 | case CP: return (void*) &dosHdr->e_cp; 18 | case CRLC: return (void*) &dosHdr->e_crlc; 19 | case CPARHDR: return (void*) &dosHdr->e_cparhdr; 20 | case MINALLOC: return (void*) &dosHdr->e_minalloc; 21 | case MAXALLOC: return (void*) &dosHdr->e_maxalloc; 22 | case SS: return (void*) &dosHdr->e_ss; 23 | case SP: return (void*) &dosHdr->e_sp; 24 | case CSUM: return (void*) &dosHdr->e_csum; 25 | case IP: return (void*) &dosHdr->e_ip; 26 | case CS: return (void*) &dosHdr->e_cs; 27 | case LFARLC: return (void*) &dosHdr->e_lfarlc; 28 | case OVNO: return (void*) &dosHdr->e_ovno; 29 | case RES: return (void*) &dosHdr->e_res[0]; 30 | case OEMID: return (void*) &dosHdr->e_oemid; 31 | case OEMINFO: return (void*) &dosHdr->e_oeminfo; 32 | case RES2: return (void*) &dosHdr->e_res2[0]; 33 | case LFNEW: return (void*) &dosHdr->e_lfanew; 34 | case FIELD_COUNTER: return (void*) (&dosHdr->e_lfanew + 1); 35 | } 36 | return (void*)dosHdr; 37 | } 38 | 39 | QString DosHdrWrapper::getFieldName(size_t fieldId) 40 | { 41 | switch (fieldId) { 42 | case MAGIC: return "Magic number"; 43 | case CBLP: return "Bytes on last page of file"; 44 | case CP: return "Pages in file"; 45 | case CRLC: return "Relocations"; 46 | case CPARHDR: return "Size of header in paragraphs"; 47 | case MINALLOC: return "Minimum extra paragraphs needed"; 48 | case MAXALLOC: return "Maximum extra paragraphs needed"; 49 | case SS: return "Initial (relative) SS value"; 50 | case SP: return "Initial SP value"; 51 | case CSUM: return "Checksum"; 52 | case IP: return "Initial IP value"; 53 | case CS: return "Initial (relative) CS value"; 54 | case LFARLC: return "File address of relocation table"; 55 | case OVNO: return "Overlay number"; 56 | case RES: return "Reserved words[4]"; 57 | case OEMID: return "OEM identifier (for OEM information)"; 58 | case OEMINFO: return "OEM information; OEM identifier specific"; 59 | case RES2: return "Reserved words[10]"; 60 | case LFNEW: return "File address of new exe header"; 61 | } 62 | return ""; 63 | } 64 | 65 | Executable::addr_type DosHdrWrapper::containsAddrType(size_t fieldId, size_t subField) 66 | { 67 | switch (fieldId) { 68 | case LFARLC: return Executable::RAW; 69 | case LFNEW: return Executable::RAW; 70 | } 71 | return Executable::NOT_ADDR; 72 | } 73 | 74 | -------------------------------------------------------------------------------- /parser/pe/PECore.cpp: -------------------------------------------------------------------------------- 1 | #include "pe/PECore.h" 2 | 3 | #define DEFAULT_IMGBASE 0x10000 4 | 5 | void PECore::reset() 6 | { 7 | dos = NULL; 8 | fHdr = NULL; 9 | opt32 = NULL; 10 | opt64 = NULL; 11 | } 12 | 13 | bool PECore::wrap(AbstractByteBuffer *v_buf) 14 | { 15 | buf = v_buf; 16 | const bool allowExceptionsFromBuffer = false; 17 | 18 | // reset all: 19 | reset(); 20 | 21 | offset_t offset = 0; 22 | this->dos = (IMAGE_DOS_HEADER*) buf->getContentAt(offset, sizeof(IMAGE_DOS_HEADER), allowExceptionsFromBuffer); 23 | if (!dos) throw ExeException("Could not wrap PECore: invalid DOS Header!"); 24 | 25 | offset = dos->e_lfanew + sizeof(DWORD); //skip 'PE' signature 26 | this->fHdr = (IMAGE_FILE_HEADER*) buf->getContentAt(offset, sizeof(IMAGE_FILE_HEADER), allowExceptionsFromBuffer); 27 | if (!fHdr) throw ExeException("Could not wrap PECore!"); 28 | 29 | offset = offset + sizeof(IMAGE_FILE_HEADER); 30 | WORD *magic = (WORD*) buf->getContentAt(offset, sizeof(WORD), allowExceptionsFromBuffer); 31 | if (!magic) throw ExeException("Could not wrap PECore: invalid FileHeader"); 32 | 33 | const Executable::exe_bits mode = ((*magic) == pe::OH_NT64) ? Executable::BITS_64 : Executable::BITS_32; 34 | const size_t ntHdrSize = (mode == Executable::BITS_32) ? sizeof(IMAGE_OPTIONAL_HEADER32) : sizeof(IMAGE_OPTIONAL_HEADER64); 35 | BYTE *ntHdrPtr = buf->getContentAt(offset, ntHdrSize, allowExceptionsFromBuffer); 36 | 37 | if (ntHdrPtr) { 38 | if (mode == Executable::BITS_32) { 39 | this->opt32 = (IMAGE_OPTIONAL_HEADER32*)ntHdrPtr; 40 | } 41 | else if (mode == Executable::BITS_64) { 42 | this->opt64 = (IMAGE_OPTIONAL_HEADER64*)ntHdrPtr; 43 | } 44 | } 45 | if (!this->opt32 && !this->opt64) { 46 | throw ExeException("Could not wrap PECore: invalid OptionalHeader"); 47 | } 48 | return true; 49 | } 50 | 51 | Executable::exe_bits PECore::getHdrBitMode() const 52 | { 53 | if (opt32) return Executable::BITS_32; 54 | if (opt64) return Executable::BITS_64; 55 | 56 | return Executable::BITS_32; // DEFAULT 57 | } 58 | 59 | Executable::exe_arch PECore::getHdrArch() const 60 | { 61 | if (!this->fHdr) { 62 | return Executable::ARCH_UNKNOWN; 63 | } 64 | if (this->fHdr->Machine == M_I386 || this->fHdr->Machine == M_AMD64) { 65 | return Executable::ARCH_INTEL; 66 | } 67 | if (this->fHdr->Machine == M_ARM || this->fHdr->Machine == M_ARM64LE) { 68 | return Executable::ARCH_ARM; 69 | } 70 | return Executable::ARCH_UNKNOWN; 71 | } 72 | 73 | offset_t PECore::peSignatureOffset() const 74 | { 75 | if (!dos) return INVALID_ADDR; 76 | return static_cast (dos->e_lfanew); 77 | } 78 | 79 | offset_t PECore::peFileHdrOffset() const 80 | { 81 | const offset_t offset = peSignatureOffset(); 82 | if (offset == INVALID_ADDR) { 83 | return INVALID_ADDR; 84 | } 85 | const offset_t signSize = sizeof(DWORD); 86 | return offset + signSize; 87 | } 88 | 89 | offset_t PECore::peOptHdrOffset() const 90 | { 91 | const offset_t offset = peFileHdrOffset(); 92 | if (offset == INVALID_ADDR) { 93 | return INVALID_ADDR; 94 | } 95 | return offset + sizeof(IMAGE_FILE_HEADER); 96 | } 97 | 98 | bufsize_t PECore::peNtHeadersSize() const 99 | { 100 | if (this->getHdrBitMode() == Executable::BITS_64) 101 | return sizeof(IMAGE_NT_HEADERS64); 102 | 103 | return sizeof(IMAGE_NT_HEADERS32); 104 | } 105 | 106 | offset_t PECore::secHdrsOffset() const 107 | { 108 | const offset_t offset = peOptHdrOffset(); 109 | if (offset == INVALID_ADDR) { 110 | return INVALID_ADDR; 111 | } 112 | if (!fHdr) { 113 | return INVALID_ADDR; 114 | } 115 | const offset_t size = static_cast(this->fHdr->SizeOfOptionalHeader); 116 | return offset + size; 117 | } 118 | 119 | bufsize_t PECore::getAlignment(Executable::addr_type aType) const 120 | { 121 | if (this->opt32) { 122 | if (aType == Executable::RAW) return opt32->FileAlignment; 123 | return opt32->SectionAlignment; 124 | } 125 | if (this->opt64) { 126 | if (aType == Executable::RAW) return opt64->FileAlignment; 127 | return opt64->SectionAlignment; 128 | } 129 | return 0; 130 | } 131 | 132 | bufsize_t PECore::getImageSize() 133 | { 134 | bufsize_t imgSize = 0; 135 | if (this->opt32) { 136 | imgSize = opt32->SizeOfImage; 137 | } 138 | if (this->opt64) { 139 | imgSize = opt64->SizeOfImage; 140 | } 141 | return imgSize; 142 | } 143 | 144 | bufsize_t PECore::hdrsSize() const 145 | { 146 | bufsize_t hdrsSize = 0; 147 | if (this->opt32) { 148 | hdrsSize = opt32->SizeOfHeaders; 149 | } 150 | if (this->opt64) { 151 | hdrsSize = opt64->SizeOfHeaders; 152 | } 153 | return hdrsSize; 154 | } 155 | 156 | offset_t PECore::getImageBase(bool recalculate) 157 | { 158 | offset_t imgBase = 0; 159 | if (this->opt32) { 160 | imgBase = opt32->ImageBase; 161 | } 162 | if (this->opt64) { 163 | imgBase = opt64->ImageBase; 164 | } 165 | //can be null, under XP. In this case, the binary will be relocated to 10000h 166 | //(quote: http://code.google.com/p/corkami/wiki/PE) 167 | if (imgBase == 0 && recalculate) { 168 | imgBase = DEFAULT_IMGBASE; 169 | } 170 | //in 32 bit PEs: it can be any value as long as ImageBase + 'SizeOfImage' < 80000000h 171 | //if the ImageBase is bigger than that, the binary will be relocated to 10000h 172 | if (this->opt32) { 173 | offset_t maxOffset = this->getImageSize() + imgBase; 174 | if (maxOffset >= 0x80000000 && recalculate) { 175 | imgBase = DEFAULT_IMGBASE; 176 | } 177 | } 178 | return imgBase; 179 | } 180 | 181 | -------------------------------------------------------------------------------- /parser/pe/PENodeWrapper.cpp: -------------------------------------------------------------------------------- 1 | #include "pe/PENodeWrapper.h" 2 | #include "pe/PEFile.h" 3 | 4 | PEElementWrapper::PEElementWrapper(PEFile* pe) 5 | : ExeElementWrapper(pe), m_PE(pe) 6 | { 7 | } 8 | 9 | //-------------------------------------------------------------------- 10 | 11 | PENodeWrapper::PENodeWrapper(PEFile *exe, PENodeWrapper* parent) 12 | : ExeNodeWrapper(exe, parent, 0), m_PE(exe), peParentNode(parent) 13 | { 14 | wrap(); 15 | } 16 | 17 | PENodeWrapper::PENodeWrapper(PEFile *exe, PENodeWrapper* parent, size_t entryNumber) 18 | : ExeNodeWrapper(exe, parent, entryNumber), m_PE(exe), peParentNode(parent) 19 | { 20 | wrap(); 21 | } 22 | -------------------------------------------------------------------------------- /parser/pe/SecurityDirWrapper.cpp: -------------------------------------------------------------------------------- 1 | #include "pe/SecurityDirWrapper.h" 2 | #include "pe/PEFile.h" 3 | 4 | pe::WIN_CERTIFICATE* SecurityDirWrapper::getCert() 5 | { 6 | offset_t rva = getDirEntryAddress(); 7 | 8 | BYTE *ptr = m_Exe->getContentAt(rva, Executable::RAW, sizeof(pe::WIN_CERTIFICATE)); 9 | if (ptr == NULL) return NULL; 10 | 11 | return (pe::WIN_CERTIFICATE*) ptr; 12 | } 13 | 14 | bool SecurityDirWrapper::wrap() 15 | { 16 | this->sizeOk = false; 17 | 18 | pe::WIN_CERTIFICATE* cert = getCert(); 19 | if (cert == NULL) return false; 20 | 21 | offset_t offset = this->getFieldOffset(SecurityDirWrapper::CERT_CONTENT); 22 | if (offset == INVALID_ADDR) return false; 23 | BYTE *ptr = NULL; 24 | 25 | size_t fieldsSize = sizeof(cert->dwLength) + sizeof(cert->wRevision) + sizeof(cert->dwLength); 26 | size_t certSize = cert->dwLength - fieldsSize; 27 | ptr = m_Exe->getContentAt(offset, Executable::RAW, static_cast(certSize)); 28 | 29 | if (ptr == NULL) return false; 30 | 31 | this->sizeOk = true; 32 | return true; 33 | } 34 | 35 | void* SecurityDirWrapper::getPtr() 36 | { 37 | return getCert(); 38 | } 39 | 40 | bufsize_t SecurityDirWrapper::getSize() 41 | { 42 | pe::WIN_CERTIFICATE* cert = getCert(); 43 | if (cert == NULL) return 0; 44 | 45 | bufsize_t fullSize = static_cast(sizeof(pe::WIN_CERTIFICATE)); // TODO: check it 46 | if (this->sizeOk) { 47 | fullSize = static_cast(cert->dwLength); 48 | } 49 | return fullSize; 50 | } 51 | 52 | 53 | void* SecurityDirWrapper::getFieldPtr(size_t fId, size_t subField) 54 | { 55 | pe::WIN_CERTIFICATE* cert = getCert(); 56 | if (cert == NULL) return 0; 57 | 58 | switch (fId) { 59 | case CERT_LEN : return &cert->dwLength; 60 | case REVISION : return &cert->wRevision; 61 | case TYPE : return &cert->wCertificateType; 62 | case CERT_CONTENT : return &cert->bCertificate; 63 | } 64 | return this->getPtr(); 65 | } 66 | 67 | QString SecurityDirWrapper::getFieldName(size_t fieldId) 68 | { 69 | switch (fieldId) { 70 | case CERT_LEN : return "Length"; 71 | case REVISION : return "Revision"; 72 | case TYPE : return "Type"; 73 | case CERT_CONTENT : return "Cert. Content"; 74 | } 75 | return getName(); 76 | } 77 | 78 | WrappedValue::data_type SecurityDirWrapper::containsDataType(size_t fieldId, size_t subField) 79 | { 80 | if (fieldId == CERT_CONTENT){ 81 | return WrappedValue::COMPLEX; 82 | } 83 | return WrappedValue::INT; 84 | } 85 | 86 | QString SecurityDirWrapper::translateType(int type) 87 | { 88 | switch (type) { 89 | case pe::WIN_CERT_TYPE_X509 : return "X.509 certificate"; 90 | case pe::WIN_CERT_TYPE_PKCS_SIGNED_DATA : return "PKCS Signed Data"; 91 | case pe::WIN_CERT_TYPE_RESERVED_1 : return "Reserved"; 92 | case pe::WIN_CERT_TYPE_PKCS1_SIGN : return "PKCS1 Module Sign Fields"; 93 | } 94 | return ""; 95 | } 96 | 97 | QString SecurityDirWrapper::translateFieldContent(size_t fieldId) 98 | { 99 | if (fieldId != TYPE) return ""; 100 | 101 | pe::WIN_CERTIFICATE* cert = getCert(); 102 | if (cert == NULL) return ""; 103 | 104 | return translateType(cert->wCertificateType); 105 | } 106 | -------------------------------------------------------------------------------- /parser/pe/TlsDirWrapper.cpp: -------------------------------------------------------------------------------- 1 | #include "pe/TlsDirWrapper.h" 2 | #include "pe/PEFile.h" 3 | 4 | bool TlsDirWrapper::wrap() 5 | { 6 | clear(); 7 | size_t entryId = 0; 8 | while (true) { 9 | TlsEntryWrapper* entry = new TlsEntryWrapper(this->m_Exe, this, entryId++); 10 | if (!entry->getPtr()) { 11 | delete entry; 12 | break; 13 | } 14 | 15 | bool isOk = false; 16 | uint64_t val = entry->getNumValue(TlsEntryWrapper::CALLBACK_ADDR, &isOk); 17 | if (!isOk || val == 0) { 18 | delete entry; 19 | break; 20 | } 21 | this->entries.push_back(entry); 22 | } 23 | return true; 24 | } 25 | 26 | void* TlsDirWrapper::getPtr() 27 | { 28 | if (m_Exe->getBitMode() == Executable::BITS_32) { 29 | return tls32(); 30 | } 31 | return tls64(); 32 | } 33 | 34 | bufsize_t TlsDirWrapper::getSize() 35 | { 36 | if (!getPtr()) return 0; 37 | if (m_Exe->getBitMode() == Executable::BITS_32) { 38 | return sizeof(IMAGE_TLS_DIRECTORY32); 39 | } 40 | return sizeof(IMAGE_TLS_DIRECTORY64); 41 | } 42 | 43 | void* TlsDirWrapper::getTlsDirPtr() 44 | { 45 | bufsize_t dirSize = 0; 46 | 47 | if (m_Exe->getBitMode() == Executable::BITS_32) { 48 | dirSize = sizeof(IMAGE_TLS_DIRECTORY32); 49 | } else if (m_Exe->getBitMode() == Executable::BITS_64) { 50 | dirSize = sizeof(IMAGE_TLS_DIRECTORY64); 51 | } 52 | 53 | offset_t rva = getDirEntryAddress(); 54 | BYTE *ptr = m_Exe->getContentAt(rva, Executable::RVA, dirSize); 55 | return ptr; 56 | } 57 | 58 | IMAGE_TLS_DIRECTORY32* TlsDirWrapper::tls32() 59 | { 60 | if (m_Exe->getBitMode() != Executable::BITS_32) return NULL; 61 | return (IMAGE_TLS_DIRECTORY32*) getTlsDirPtr(); 62 | } 63 | 64 | IMAGE_TLS_DIRECTORY64* TlsDirWrapper::tls64() 65 | { 66 | if (m_Exe->getBitMode() != Executable::BITS_64) return NULL; 67 | return (IMAGE_TLS_DIRECTORY64*) getTlsDirPtr(); 68 | } 69 | 70 | void* TlsDirWrapper::getFieldPtr(size_t fId, size_t subField) 71 | { 72 | IMAGE_TLS_DIRECTORY32* t32 = tls32(); 73 | IMAGE_TLS_DIRECTORY64* t64 = tls64(); 74 | 75 | if (!t32 && !t64) return NULL; 76 | 77 | switch (fId) { 78 | case START_ADDR : return t32 ? (void*) &t32->StartAddressOfRawData : (void*) &t64->StartAddressOfRawData; 79 | case END_ADDR : return t32 ? (void*) &t32->EndAddressOfRawData : (void*) &t64->EndAddressOfRawData; 80 | case INDEX_ADDR : return t32 ? (void*) &t32->AddressOfIndex : (void*) &t64->AddressOfIndex; 81 | case CALLBACKS_ADDR : return t32 ? (void*) &t32->AddressOfCallBacks : (void*) &t64->AddressOfCallBacks; 82 | case ZEROF_SIZE : return t32 ? (void*) &t32->SizeOfZeroFill : (void*) &t64->SizeOfZeroFill; 83 | case CHARACT : return t32 ? (void*) &t32->Characteristics : (void*) &t64->Characteristics; 84 | } 85 | return this->getPtr(); 86 | } 87 | 88 | QString TlsDirWrapper::getFieldName(size_t fieldId) 89 | { 90 | switch (fieldId) { 91 | case START_ADDR : return "StartAddressOfRawData"; 92 | case END_ADDR : return "EndAddressOfRawData"; 93 | case INDEX_ADDR : return "AddressOfIndex"; 94 | case CALLBACKS_ADDR : return "AddressOfCallBacks"; 95 | case ZEROF_SIZE : return "SizeOfZeroFill"; 96 | case CHARACT : return "Characteristics"; 97 | } 98 | return getName(); 99 | } 100 | 101 | Executable::addr_type TlsDirWrapper::containsAddrType(size_t fieldId, size_t subField) 102 | { 103 | switch (fieldId) { 104 | case START_ADDR : 105 | case END_ADDR : 106 | case INDEX_ADDR : 107 | case CALLBACKS_ADDR : 108 | return Executable::VA; 109 | } 110 | return Executable::NOT_ADDR; 111 | } 112 | 113 | //---------------- 114 | void* TlsEntryWrapper::getPtr() 115 | { 116 | if (!this->parentDir) return nullptr; 117 | 118 | bool isOk = false; 119 | const offset_t firstVA = static_cast(this->parentDir->getNumValue(TlsDirWrapper::CALLBACKS_ADDR, &isOk)); 120 | if (!isOk || (firstVA == 0)) return nullptr; 121 | 122 | const offset_t firstRaw = m_Exe->toRaw(firstVA, Executable::VA); 123 | if (firstRaw == INVALID_ADDR) { 124 | return nullptr; 125 | } 126 | 127 | const bufsize_t addrSize = this->parentDir->getFieldSize(TlsDirWrapper::CALLBACKS_ADDR); 128 | const offset_t myRaw = firstRaw + (addrSize * this->entryNum); 129 | BYTE *ptr = m_Exe->getContentAt(myRaw, Executable::RAW, addrSize); 130 | return ptr; 131 | } 132 | 133 | bufsize_t TlsEntryWrapper::getSize() 134 | { 135 | if (!this->parentDir) return 0; 136 | const bufsize_t addrSize = this->parentDir->getFieldSize(TlsDirWrapper::CALLBACKS_ADDR); 137 | return addrSize; 138 | } 139 | -------------------------------------------------------------------------------- /parser/pe/rsrc/ResourceContentFactory.cpp: -------------------------------------------------------------------------------- 1 | #include "pe/rsrc/ResourceContentFactory.h" 2 | #include "pe/rsrc/ResourceStringsWrapper.h" 3 | #include "pe/rsrc/ResourceVersionWrapper.h" 4 | 5 | ResourceContentWrapper* ResourceContentFactory::makeResContentWrapper(pe::resource_type typeId, ResourceLeafWrapper* leaf) 6 | { 7 | if (leaf == NULL) return NULL; 8 | 9 | Executable *pe = leaf->getExe(); 10 | if (pe == NULL) return NULL; 11 | 12 | ResourceContentWrapper* cw = NULL; 13 | 14 | switch (typeId) { 15 | case pe::RESTYPE_STRING: 16 | return new ResourceStringsWrapper(pe, leaf); 17 | 18 | case pe::RESTYPE_VERSION: 19 | return new ResourceVersionWrapper(pe, leaf); 20 | 21 | case pe::RESTYPE_MANIFEST: 22 | return new ReourceManifestWrapper(pe, leaf); 23 | 24 | case pe::RESTYPE_HTML: 25 | return new ReourceHTMLWrapper(pe, leaf); 26 | 27 | default: 28 | cw = new ResourceContentWrapper(pe, leaf, typeId); 29 | } 30 | //printf("Making ResourceContentWrapper of type: %d\n", typeId); 31 | //if (!isSupportedType(typeId)) 32 | return cw; 33 | } 34 | -------------------------------------------------------------------------------- /parser/pe/rsrc/ResourceContentWrapper.cpp: -------------------------------------------------------------------------------- 1 | #include "pe/rsrc/ResourceContentWrapper.h" 2 | 3 | QString ResourceContentWrapper::translateType(pe::resource_type type) 4 | { 5 | switch (type) { 6 | case pe::RESTYPE_CURSOR : return "Cursor"; 7 | case pe::RESTYPE_FONT : return "Font"; 8 | case pe::RESTYPE_BITMAP : return "Bitmap"; 9 | case pe::RESTYPE_ICON : return "Icon"; 10 | case pe::RESTYPE_MENU : return "Menu"; 11 | case pe::RESTYPE_DIALOG : return "Dialog"; 12 | case pe::RESTYPE_STRING : return "Strings"; 13 | case pe::RESTYPE_FONTDIR : return "Font Dir."; 14 | case pe::RESTYPE_ACCELERATOR : return "Accelerator"; 15 | case pe::RESTYPE_RCDATA : return "RC Data"; 16 | case pe::RESTYPE_MESSAGETABLE : return "Message Table"; 17 | 18 | case pe::RESTYPE_GROUP_CURSOR : return "Cursors Group"; 19 | case pe::RESTYPE_GROUP_ICON : return "Icons Group"; 20 | case pe::RESTYPE_VERSION : return "Version"; 21 | case pe::RESTYPE_DLGINCLUDE : return "Dialog Include"; 22 | case pe::RESTYPE_PLUGPLAY : return "Plug-n-Play"; 23 | case pe::RESTYPE_VXD : return "VXD"; 24 | case pe::RESTYPE_ANICURSOR : return "Animated Cursor"; 25 | case pe::RESTYPE_ANIICON : return "Animated Icon"; 26 | case pe::RESTYPE_HTML : return "HTML"; 27 | case pe::RESTYPE_MANIFEST : return "Manifest"; 28 | } 29 | return "UNKN"; 30 | } 31 | 32 | //------------------------------------------------------- 33 | 34 | void* ResourceContentWrapper::getResContentPtr() 35 | { 36 | if (myLeaf == NULL) return NULL; 37 | 38 | IMAGE_RESOURCE_DATA_ENTRY* entry = this->myLeaf->leafEntryPtr(); 39 | if (entry == NULL) return NULL; 40 | 41 | offset_t dataRva = static_cast(entry->OffsetToData); 42 | bufsize_t dataSize = static_cast(entry->Size); 43 | 44 | Executable* m_Exe = myLeaf->getExe(); 45 | Executable::addr_type aT = m_Exe->detectAddrType(dataRva, Executable::RVA); 46 | offset_t dataOffset = m_Exe->toRaw(dataRva, aT); 47 | if (dataOffset == INVALID_ADDR) return NULL; 48 | 49 | BYTE* b = m_Exe->getContentAt(dataRva, aT, dataSize); 50 | return b; 51 | } 52 | 53 | bufsize_t ResourceContentWrapper::getResContentSize() 54 | { 55 | if (myLeaf == NULL) { 56 | printf("[ERR] MyLeaf is NULL\n"); 57 | return 0; 58 | } 59 | IMAGE_RESOURCE_DATA_ENTRY* entry = this->myLeaf->leafEntryPtr(); 60 | if (entry == NULL) { 61 | printf("[ERR] Leaf ERR\n"); 62 | return 0; 63 | } 64 | DWORD size = entry->Size; 65 | return size; 66 | } 67 | 68 | offset_t ResourceContentWrapper::getContentRaw() 69 | { 70 | if (myLeaf == NULL) return 0; 71 | 72 | IMAGE_RESOURCE_DATA_ENTRY* entry = this->myLeaf->leafEntryPtr(); 73 | if (entry == NULL) return 0; 74 | 75 | uint64_t dataRva = entry->OffsetToData; 76 | Executable* m_Exe = myLeaf->getExe(); 77 | Executable::addr_type aT = m_Exe->detectAddrType(dataRva, Executable::RVA); 78 | return m_Exe->toRaw(dataRva, aT); 79 | } 80 | 81 | BYTE* ResourceContentWrapper::getContentAt(offset_t dataAddr, Executable::addr_type aT, bufsize_t dataSize) 82 | { 83 | if (myLeaf == NULL) return NULL; 84 | 85 | Executable* m_Exe = myLeaf->getExe(); 86 | BYTE* b = m_Exe->getContentAt(dataAddr, aT, dataSize); 87 | return b; 88 | } 89 | 90 | -------------------------------------------------------------------------------- /parser/pe/rsrc/ResourceStringsWrapper.cpp: -------------------------------------------------------------------------------- 1 | #include "pe/rsrc/ResourceStringsWrapper.h" 2 | 3 | void* ResString::getPtr() 4 | { 5 | return this->sizePtr; 6 | } 7 | 8 | bufsize_t ResString::getSize() { 9 | WORD* len = this->sizePtr; 10 | if (len == NULL) return 0; 11 | return (*len) * sizeof(WORD) + sizeof(WORD); 12 | } 13 | 14 | QString ResString::getName() 15 | { 16 | return getQString(); 17 | } 18 | 19 | /* specific field boundatries */ 20 | void* ResString::getFieldPtr(size_t fId, size_t subField) 21 | { 22 | switch (fId) { 23 | case STR_LEN: return this->sizePtr; 24 | case WSTRING: 25 | { 26 | bufsize_t size = (sizePtr == NULL) ? 0 : static_cast(*sizePtr); 27 | WORD *content = (WORD*) this->m_Exe->getContentAt(offset,Executable::RAW, size); 28 | return content; 29 | } 30 | } 31 | return this->getPtr(); 32 | } 33 | 34 | QString ResString::getFieldName(size_t fId) 35 | { 36 | switch (fId) { 37 | case STR_LEN: return "Length"; 38 | case WSTRING: return "WString"; 39 | } 40 | return ""; 41 | } 42 | 43 | bufsize_t ResString::getFieldSize(size_t fId, size_t subField) 44 | { 45 | switch (fId) { 46 | case STR_LEN: return sizeof(WORD); 47 | case WSTRING: 48 | { 49 | WORD* len = this->sizePtr; 50 | if (len == NULL) return 0; 51 | return (*len) * sizeof(WORD); 52 | } 53 | } 54 | return 0; 55 | } 56 | //------------------------------------------------------ 57 | 58 | bool ResourceStringsWrapper::wrap() 59 | { 60 | clear(); 61 | this->parsedSize = 0; 62 | 63 | BYTE *c = static_cast(this->getPtr()); 64 | if (!c) { 65 | return false; 66 | } 67 | size_t maxSize = this->getSize(); 68 | //printf("maxSize = %x\n", maxSize); 69 | offset_t startRaw = getContentRaw(); 70 | offset_t cRaw = startRaw; 71 | 72 | while (parsedSize < maxSize) { 73 | 74 | WORD* stringSize = (WORD*) this->getContentAt(cRaw, Executable::RAW, sizeof(WORD)); 75 | if (stringSize == NULL){ 76 | printf("Cannot fetch the string size!\n"); 77 | break; 78 | } 79 | this->parsedSize += sizeof(WORD); 80 | cRaw += sizeof(WORD); 81 | 82 | size_t wStrSize = (*stringSize); 83 | if (wStrSize == 0) { 84 | continue; 85 | } 86 | bufsize_t totalStrSize = wStrSize * sizeof(WORD); 87 | 88 | WORD* uStringPtr = (WORD*) this->getContentAt(cRaw, Executable::RAW, totalStrSize); 89 | if (uStringPtr == NULL) break; 90 | 91 | Executable *exe = this->myLeaf->getExe(); 92 | ResString *rStr = new ResString(uStringPtr, stringSize, cRaw, exe); 93 | this->entries.push_back(rStr); 94 | 95 | this->parsedSize += totalStrSize; 96 | cRaw += totalStrSize; 97 | } 98 | return true; 99 | } 100 | 101 | QString ResourceStringsWrapper::getFieldName(size_t fId) 102 | { 103 | return "ResourceString"; 104 | } 105 | 106 | void* ResourceStringsWrapper::getFieldPtr(size_t fId, size_t subField) 107 | { 108 | if (fId >= this->entries.size()) return NULL; 109 | return this->entries[fId]->getFieldPtr(subField); 110 | } 111 | 112 | bufsize_t ResourceStringsWrapper::getFieldSize(size_t fId, size_t subField) 113 | { 114 | if (fId >= this->entries.size()) return 0; 115 | return this->entries[fId]->getFieldSize(subField); 116 | } 117 | 118 | -------------------------------------------------------------------------------- /parser/pe/rsrc/ResourceVersionWrapper.cpp: -------------------------------------------------------------------------------- 1 | #include "pe/rsrc/ResourceVersionWrapper.h" 2 | 3 | ResourceVersionWrapper::ResourceVersionWrapper(Executable *pe, ResourceLeafWrapper* v_leaf) 4 | : ResourceContentWrapper(pe, v_leaf, pe::RESTYPE_VERSION) 5 | { 6 | //TEST 7 | /* printf("Version: %s\n", getVersionText().toStdString().c_str()); 8 | 9 | pe::version_info *info = getVersionInfo(); 10 | if (info == NULL) return; 11 | 12 | if (info->children == 0) { 13 | printf("No children!"); 14 | return; 15 | } 16 | BYTE *childEntry = (BYTE*) &info->children; 17 | pe::version_child* child = (pe::version_child*) m_Exe->getContentAtPtr(childEntry, sizeof(pe::version_child)); 18 | if (child == NULL) { 19 | printf("[ERR] Cannot fetch a child\n"); 20 | } else { 21 | printf("Got child of type: [%d]\n", child->wType); 22 | printf("len = %x\nValLen = %x\ntype = %x\nkey[0] = %c\n", child->wLength, child->wValueLength, child->wType, child->szKey[0]); 23 | 24 | int size = INFOTEXT_LEN; 25 | WORD *content = (WORD*) child->szKey; 26 | if (content == NULL) return; 27 | 28 | QString str = QString::fromUtf16(content, size); 29 | std::string verStr = str.toStdString(); 30 | printf("key = [%s] len = %d\n", verStr.c_str(), verStr.length()); 31 | } 32 | */ 33 | //!TEST 34 | } 35 | 36 | pe::version_info* ResourceVersionWrapper::getVersionInfo() 37 | { 38 | void *ptr = this->getResContentPtr(); 39 | if (ptr == NULL) return NULL; 40 | 41 | size_t size = this->getResContentSize(); 42 | if (size < sizeof(pe::version_info)) return NULL; 43 | 44 | pe::version_info* info = (pe::version_info*) ptr; 45 | return info; 46 | } 47 | 48 | QString ResourceVersionWrapper::getFieldName(size_t fId) 49 | { 50 | switch (fId) { 51 | case STRUCT_LEN: return "Length of Structure"; 52 | case VAL_LEN: return "Length of Value"; 53 | case STRUCT_TYPE: return "Type of Structure"; 54 | case INFO: return "Info"; 55 | //case PADDING1: return "Padding1"; 56 | case SIGNATURE: return "Signature"; 57 | case STRUCT_VER: return "Struct. Version"; 58 | 59 | case FILE_VER_0: 60 | case FILE_VER_1: return "File Version"; 61 | 62 | case PRODUCT_VER_0: 63 | case PRODUCT_VER_1: return "Product Version"; 64 | 65 | case FLAGS_MASK: return "File Flags mask"; 66 | case FLAGS: return "Flags"; 67 | case OS: return "File OS"; 68 | case TYPE: return "File Type"; 69 | case SUBTYPE: return "File SubType"; 70 | case TIMESTAMP_0: case TIMESTAMP_1: return "File Timestamp"; 71 | //case PADDING2: return "Padding2"; 72 | case CHILDREN: return "Children"; 73 | } 74 | return ""; 75 | } 76 | 77 | void* ResourceVersionWrapper::getFieldPtr(size_t fId, size_t subField) 78 | { 79 | pe::version_info* ptr = getVersionInfo(); 80 | 81 | if (ptr == NULL) return NULL; 82 | 83 | switch (fId) { 84 | case STRUCT_LEN: return &(ptr->length); 85 | case VAL_LEN: return &(ptr->valueLength); 86 | case STRUCT_TYPE: return &(ptr->type); 87 | case INFO: return &(ptr->key); 88 | 89 | case SIGNATURE: return &(ptr->Value.dwSignature); 90 | case STRUCT_VER: return &(ptr->Value.dwStrucVersion); 91 | case FILE_VER_0: return &(ptr->Value.dwFileVersionMS); 92 | case FILE_VER_1: return &(ptr->Value.dwFileVersionLS); 93 | 94 | case PRODUCT_VER_0: return &(ptr->Value.dwProductVersionMS); 95 | case PRODUCT_VER_1: return &(ptr->Value.dwProductVersionLS); 96 | 97 | case FLAGS_MASK: return &(ptr->Value.dwFileFlagsMask); 98 | case FLAGS: return &(ptr->Value.dwFileFlags); 99 | case OS: return &(ptr->Value.dwFileOS); 100 | case TYPE: return &(ptr->Value.dwFileType); 101 | case SUBTYPE: return &(ptr->Value.dwFileSubtype); 102 | case TIMESTAMP_0: return &(ptr->Value.dwFileDateMS); 103 | case TIMESTAMP_1: return &(ptr->Value.dwFileDateLS); 104 | 105 | //case PADDING2: return &(ptr->padding2); 106 | case CHILDREN: return &(ptr->children); 107 | } 108 | return ptr; 109 | } 110 | 111 | WrappedValue::data_type ResourceVersionWrapper::containsDataType(size_t fieldId, size_t subField) 112 | { 113 | if (fieldId == INFO) { 114 | return WrappedValue::WSTRING; 115 | } 116 | return WrappedValue::INT; 117 | } -------------------------------------------------------------------------------- /parser/pe/rsrc/ResourcesAlbum.cpp: -------------------------------------------------------------------------------- 1 | #include "pe/rsrc/ResourcesAlbum.h" 2 | #include "pe/rsrc/ResourceStringsWrapper.h" 3 | 4 | 5 | void ResourcesContainer::putWrapper(ResourceContentWrapper* wrapper) 6 | { 7 | if (wrapper == NULL) return; 8 | //TODO: check if already exist... 9 | wrappers.push_back(wrapper); 10 | } 11 | 12 | ResourceContentWrapper* ResourcesContainer::getWrapperAt(size_t index) 13 | { 14 | if (index >= wrappers.size()) return NULL; 15 | return wrappers.at(index); 16 | } 17 | 18 | size_t ResourcesContainer::entriesCount() 19 | { 20 | size_t totalCount = 0; 21 | size_t wrappersCount = this->count(); 22 | 23 | for (size_t i = 0; i < wrappersCount; i++) { 24 | ResourceContentWrapper* wrapper = this->getWrapperAt(i); 25 | if (wrapper == NULL) { 26 | continue; 27 | } 28 | size_t count = wrapper->getFieldsCount(); 29 | totalCount += count; 30 | } 31 | return totalCount; 32 | } 33 | 34 | //---------------------------------------------------------------------- 35 | void ResourcesAlbum::clearLeafsContent() 36 | { 37 | std::map::iterator itr; 38 | for (itr = leafToContentWrapper.begin(); itr != leafToContentWrapper.end(); ++itr) { 39 | ResourceContentWrapper* cw = itr->second; 40 | delete cw; 41 | } 42 | leafToContentWrapper.clear(); 43 | } 44 | 45 | void ResourcesAlbum::clear() 46 | { 47 | clearLeafsContent(); 48 | //--- 49 | std::map::iterator cntItr; 50 | for (cntItr = leafToContentWrapper.begin(); cntItr != leafToContentWrapper.end(); ++cntItr) { 51 | ResourceContentWrapper* cntWr = cntItr->second; 52 | delete cntWr; 53 | } 54 | leafToContentWrapper.clear(); 55 | //--- 56 | allLeafs.clear(); 57 | allTypes.clear(); 58 | } 59 | 60 | void ResourcesAlbum::putLeaf(ResourceLeafWrapper* leaf, long topEntryId) 61 | { 62 | if (!leaf) return; 63 | allLeafs[topEntryId].push_back(leaf); 64 | } 65 | 66 | void ResourcesAlbum::wrapLeafsContent() 67 | { 68 | std::map >::iterator itr; 69 | for (itr = allLeafs.begin(); itr != allLeafs.end(); ++itr) { 70 | 71 | std::vector &leafVec = itr->second; 72 | long topEntryId = itr->first; 73 | 74 | for (size_t i = 0; i < leafVec.size(); i++) { 75 | ResourceLeafWrapper* leaf = leafVec.at(i); 76 | pe::resource_type type = idToLeafType[topEntryId]; 77 | //printf("topEntryId %d type: %d\n", topEntryId, type); 78 | //TODO: finish it! 79 | ResourceContentWrapper* cw = ResourceContentFactory::makeResContentWrapper(type, leaf); 80 | if (cw) { 81 | leafToContentWrapper[leaf] = cw; 82 | this->allWrappers[type].putWrapper(cw); 83 | } 84 | } 85 | } 86 | initResourceTypes(); 87 | } 88 | 89 | size_t ResourcesAlbum::entriesCountAt(long topEntryId) 90 | { 91 | if (hasTopEntry(topEntryId) == false) { 92 | return 0; 93 | } 94 | return allLeafs[topEntryId].size(); 95 | } 96 | 97 | std::vector* ResourcesAlbum::entriesAt(long topEntryId) 98 | { 99 | if (hasTopEntry(topEntryId) == false) { 100 | return NULL; 101 | } 102 | return &(allLeafs[topEntryId]); 103 | } 104 | 105 | ResourcesContainer* ResourcesAlbum::getResourcesOfType(pe::resource_type typeId) 106 | { 107 | if (hasType(typeId) == false) { 108 | return NULL; 109 | } 110 | return &(allWrappers[typeId]); 111 | } 112 | 113 | void ResourcesAlbum::initResourceTypes() 114 | { 115 | this->allTypes.clear(); 116 | std::map::iterator itr; 117 | 118 | for ( itr = this->allWrappers.begin(); itr != this->allWrappers.end(); ++itr ) { 119 | pe::resource_type type = itr->first; 120 | this->allTypes.push_back(type); 121 | } 122 | } 123 | /* 124 | std::vector ResourcesAlbum::getResourceTypes() 125 | { 126 | std::vector typesVec; 127 | std::map::iterator itr; 128 | 129 | for ( itr = allWrappers.begin(); itr != allWrappers.end(); ++itr ) { 130 | pe::resource_type type = itr->first; 131 | typesVec.push_back(type); 132 | } 133 | return typesVec; 134 | } 135 | */ -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | START_DIR=$(pwd) 3 | SOURCE_DIR=$1 4 | BUILD_DIR=$2 5 | TESTS_DIR="test_cases" 6 | 7 | if [[ "$SOURCE_DIR" == "" ]]; then 8 | SOURCE_DIR=$(pwd) 9 | fi 10 | 11 | echo "Source Dir: ""$SOURCE_DIR" 12 | cd "$SOURCE_DIR" 13 | 14 | if [ -d $TESTS_DIR ]; then 15 | echo "Test directory already exits" 16 | else 17 | git clone https://github.com/hasherezade/bearparser_tests.git 18 | mv bearparser_tests $TESTS_DIR 19 | fi 20 | 21 | if [[ "$BUILD_DIR" == "" ]]; then 22 | BUILD_DIR=build 23 | fi 24 | echo "Build Dir: ""$BUILD_DIR" 25 | 26 | BCMD_DIR=$(pwd)/$BUILD_DIR/ 27 | FAILED=0 28 | 29 | tests_list=$SOURCE_DIR/"tests_list.txt" 30 | 31 | cd $TESTS_DIR 32 | chmod +x test1.sh 33 | 34 | while IFS=' ' read -r p1 p2 35 | do 36 | if [[ "$p2" == "" || "$p1" == "" ]]; then 37 | continue; 38 | fi 39 | if [[ "$p1" == "#" ]]; then # allow for commenting out lines 40 | continue; 41 | fi 42 | 43 | ./test1.sh "$BCMD_DIR" "$p2" "$p1" 44 | if [[ "$?" != 0 ]]; then 45 | FAILED=$FAILED+1 46 | fi 47 | done < "$tests_list" 48 | 49 | if [[ "$FAILED" == 0 ]]; then 50 | echo "All passed" 51 | fi 52 | 53 | cd "$START_DIR" 54 | 55 | -------------------------------------------------------------------------------- /test_qt4.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ./test.sh $(pwd) build_qt4 3 | 4 | -------------------------------------------------------------------------------- /tests_list.txt: -------------------------------------------------------------------------------- 1 | x64/QtGui4 info 2 | x64/QtGui4 winfo0 3 | x64/QtGui4 winfo1 4 | x64/QtGui4 secinfo 5 | x64/QtGui4 implist 6 | x64/QtGui4 explist 7 | 8 | x86/overlapping_sec secinfo 9 | x86/overlapping_sec implist 10 | 11 | tinype/tiny.128/tiny info 12 | tinype/tiny.128/tiny winfo3 13 | tinype/tiny.128/tiny secinfo 14 | tinype/tiny.168/tiny secinfo 15 | tinype/tiny.97/tiny implist 16 | tinype/tiny.import.209/tiny implist 17 | 18 | x86/ghost_crackme winfo7 19 | x86/ghost_crackme rstrings 20 | 21 | x86/kernel32 implist 22 | x86/kernel32 explist 23 | 24 | x86/cm_level2_32 tls 25 | x64/cm_level2_64 tls 26 | 27 | x64/test_case5_dll winfo6 28 | x64/hdr_test1 conv 29 | 30 | x86/bfsvc boundimp 31 | x86/bfsvc conv 32 | 33 | x86/srpapi ldconfig 34 | x86/srpapi delayimp 35 | 36 | x86/manyimportsW7 info 37 | 38 | --------------------------------------------------------------------------------