pax_global_header00006660000000000000000000000064141532064420014513gustar00rootroot0000000000000052 comment=871c2bf9a5694e694abeeeceb034a687fd29b243 unshield-1.5.1/000077500000000000000000000000001415320644200133325ustar00rootroot00000000000000unshield-1.5.1/.appveyor-linux.yml000066400000000000000000000022001415320644200171270ustar00rootroot00000000000000image: Ubuntu environment: matrix: - CC: clang CXX: clang++ - CC: gcc CXX: g++ configuration: - Debug - Release for: - matrix: only: - configuration: Debug CC: clang environment: CFLAGS: -Og -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic CXXFLAGS: -Og -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic - matrix: only: - configuration: Release CC: clang environment: CFLAGS: -O2 CXXFLAGS: -O2 - matrix: only: - configuration: Debug CC: gcc environment: CFLAGS: -Og -g -Wall -Wextra CXXFLAGS: -Og -g -Wall -Wextra - matrix: only: - configuration: Release CC: gcc environment: CFLAGS: -O2 CXXFLAGS: -O2 init: - $CC --version - $CXX --version - cmake --version before_build: - cd $APPVEYOR_BUILD_FOLDER - mkdir build - cd build build_script: - cmake .. -DCMAKE_BUILD_TYPE=$configuration -DCMAKE_INSTALL_PREFIX=/var/tmp/unshield - cmake --build . - cmake --install . test_script: - ../run-tests.sh unshield-1.5.1/.appveyor-windows.yml000066400000000000000000000156101415320644200174730ustar00rootroot00000000000000image: Visual Studio 2019 cache: C:\Tools\vcpkg\installed\ environment: APPVEYOR_SAVE_CACHE_ON_ERROR: true matrix: - compiler: clang - compiler: msvc - compiler: gcc platform: - x86-windows - x64-windows configuration: - Debug - Release for: - matrix: only: - configuration: Debug platform: x86-windows compiler: clang environment: CC: clang-cl CXX: clang-cl CFLAGS: -Og -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -m32 CXXFLAGS: -Og -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -m32 build_script: - call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvars32.bat" - cmake .. -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Debug -GNinja - cmake --build . - matrix: only: - configuration: Release platform: x86-windows compiler: clang environment: CC: clang-cl CXX: clang-cl CFLAGS: -O2 -m32 CXXFLAGS: -O2 -m32 build_script: - call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvars32.bat" - cmake .. -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Release -GNinja - cmake --build . - matrix: only: - configuration: Debug platform: x86-windows compiler: msvc build_script: - call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvars32.bat" - cmake .. -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake -AWin32 - cmake --build . --config Debug - matrix: only: - configuration: Release platform: x86-windows compiler: msvc build_script: - call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvars32.bat" - cmake .. -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake -AWin32 - cmake --build . --config Release - matrix: only: - configuration: Debug platform: x86-windows compiler: gcc environment: CC: gcc CXX: g++ CFLAGS: -Og -g -Wall -Wextra CXXFLAGS: -Og -g -Wall -Wextra build_script: - SET PATH=C:\\mingw-w64\\i686-8.1.0-posix-dwarf-rt_v6-rev0\\mingw32\\bin;%PATH% - call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvars32.bat" - cmake .. -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Debug -G"MinGW Makefiles" - cmake --build . - matrix: only: - configuration: Release platform: x86-windows compiler: gcc environment: CC: gcc CXX: g++ CFLAGS: -O2 CXXFLAGS: -O2 build_script: - SET PATH=C:\\mingw-w64\\i686-8.1.0-posix-dwarf-rt_v6-rev0\\mingw32\\bin;%PATH% - call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvars32.bat" - cmake .. -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Release -G"MinGW Makefiles" - cmake --build . - matrix: only: - configuration: Debug platform: x64-windows compiler: clang environment: CC: clang-cl CXX: clang-cl CFLAGS: -Og -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic CXXFLAGS: -Og -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic build_script: - call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvars64.bat" - cmake .. -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Debug -GNinja - cmake --build . - matrix: only: - configuration: Release platform: x64-windows compiler: clang environment: CC: clang-cl CXX: clang-cl CFLAGS: -O2 CXXFLAGS: -O2 build_script: - call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvars64.bat" - cmake .. -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Release -GNinja - cmake --build . - matrix: only: - configuration: Debug platform: x64-windows compiler: msvc build_script: - call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvars64.bat" - cmake .. -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake -Ax64 - cmake --build . --config Debug - matrix: only: - configuration: Release platform: x64-windows compiler: msvc build_script: - call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvars64.bat" - cmake .. -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake -Ax64 - cmake --build . --config Release - matrix: only: - configuration: Debug platform: x64-windows compiler: gcc environment: CC: gcc CXX: g++ CFLAGS: -Og -g -Wall -Wextra CXXFLAGS: -Og -g -Wall -Wextra build_script: - SET PATH=C:\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin;%PATH% - call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvars64.bat" - cmake .. -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Debug -G"MinGW Makefiles" - cmake --build . - matrix: only: - configuration: Release platform: x64-windows compiler: gcc environment: CC: gcc CXX: g++ CFLAGS: -O2 CXXFLAGS: -O2 build_script: - SET PATH=C:\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin;%PATH% - call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvars64.bat" - cmake .. -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Release -G"MinGW Makefiles" - cmake --build . before_build: - cd %APPVEYOR_BUILD_FOLDER% - mkdir build - cd build install: - cd C:\Tools\vcpkg #msys repos are temporary down, downloading two dependencies manuallly from a mirror repo - if not exist downloads mkdir downloads - cd downloads - curl -O https://mirrors.ustc.edu.cn/msys2/mingw/i686/mingw-w64-i686-pkg-config-0.29.2-1-any.pkg.tar.xz - curl -O https://mirrors.ustc.edu.cn/msys2/mingw/i686/mingw-w64-i686-libwinpthread-git-8.0.0.5906.c9a21571-1-any.pkg.tar.zst - cd .. #end of the hotfix - vcpkg install zlib:%platform% openssl:%platform% - cd %APPVEYOR_BUILD_FOLDER% unshield-1.5.1/.editorconfig000066400000000000000000000004521415320644200160100ustar00rootroot00000000000000# top-most EditorConfig file root = true # Unix-style newlines with a newline ending every file [*] charset = utf-8 trim_trailing_whitespace = true end_of_line = lf insert_final_newline = true # Tab indentation (no size specified) [Makefile] indent_style = tab [*.{c,h,cpp,hpp}] indent_size = 2 unshield-1.5.1/.github/000077500000000000000000000000001415320644200146725ustar00rootroot00000000000000unshield-1.5.1/.github/workflows/000077500000000000000000000000001415320644200167275ustar00rootroot00000000000000unshield-1.5.1/.github/workflows/cmake.yml000066400000000000000000000026431415320644200205370ustar00rootroot00000000000000name: CMake on: push: branches: [ main ] pull_request: branches: [ main ] env: # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) BUILD_TYPE: Release jobs: build: # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. # You can convert this to a matrix build if you need cross-platform coverage. # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Configure CMake # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} - name: Build # Build your program with the given configuration run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} - name: Test working-directory: ${{github.workspace}}/build # Execute tests defined by the CMake configuration. # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail run: ctest -C ${{env.BUILD_TYPE}} # FIXME continue-on-error: true unshield-1.5.1/.github/workflows/codeql-analysis.yml000066400000000000000000000050261415320644200225450ustar00rootroot00000000000000# For most projects, this workflow file will not need changing; you simply need # to commit it to your repository. # # You may wish to alter this file to override the set of languages analyzed, # or to provide custom queries or build logic. name: "CodeQL" on: push: branches: [master] pull_request: # The branches below must be a subset of the branches above branches: [master] schedule: - cron: '0 1 * * 3' jobs: analyze: name: Analyze runs-on: ubuntu-latest strategy: fail-fast: false matrix: # Override automatic language detection by changing the below list # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python'] language: ['cpp'] # Learn more... # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection steps: - name: Checkout repository uses: actions/checkout@v2 with: # We must fetch at least the immediate parents so that if this is # a pull request then we can checkout the head. fetch-depth: 2 # If this run was triggered by a pull request event, then checkout # the head of the pull request instead of the merge commit. - run: git checkout HEAD^2 if: ${{ github.event_name == 'pull_request' }} # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@v1 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. # By default, queries listed here will override any specified in a config file. # Prefix the list here with "+" to use these queries and those in the config file. # queries: ./path/to/local/query, your-org/your-repo/queries@main # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild uses: github/codeql-action/autobuild@v1 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines # and modify them (or add more) to build your code if your project # uses a compiled language #- run: | # make bootstrap # make release - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v1 unshield-1.5.1/.gitignore000066400000000000000000000004141415320644200153210ustar00rootroot00000000000000*.a **/CMakeCache.txt **/CMakeFiles/ *cmake_install.cmake **/CMakeScripts/ *.core .gdb_history *.la lib/libunshield.so* .libs lib/unshield_config.h libunshield.pc *.lo ltmain.sh Makefile *.o src/unshield src/unshield-deobfuscate .*.swp .idea build /cmake-build-debug/ unshield-1.5.1/.travis.yml000066400000000000000000000025351415320644200154500ustar00rootroot00000000000000os: - linux - osx osx_image: xcode12u dist: bionic language: c compiler: - gcc - clang env: global: - CFLAGS="-Wall -Werror -ggdb3" matrix: - USE_OUR_OWN_MD5=0 BUILD_STATIC=0 - USE_OUR_OWN_MD5=1 BUILD_STATIC=0 - USE_OUR_OWN_MD5=0 BUILD_STATIC=1 - USE_OUR_OWN_MD5=1 BUILD_STATIC=1 - STATIC_ANALYZER=scan-build CMAKE_OPTS="-DCMAKE_BUILD_TYPE=Debug" addons: apt: packages: - clang homebrew: packages: - openssl - gcc@10 matrix: exclude: - os: osx env: STATIC_ANALYZER=scan-build CMAKE_OPTS="-DCMAKE_BUILD_TYPE=Debug" allow_failures: - env: USE_OUR_OWN_MD5=1 BUILD_STATIC=0 - env: STATIC_ANALYZER=scan-build CMAKE_OPTS="-DCMAKE_BUILD_TYPE=Debug" install: # Help CMake find OpenSSL - if [ "$TRAVIS_OS_NAME" = "osx" ]; then export CMAKE_OPTS="-DOPENSSL_ROOT_DIR=/usr/local/opt/openssl"; fi # Use the real gcc, not clang - if [ "$TRAVIS_OS_NAME" = "osx" ] && [ "$CC" = "gcc" ]; then CC=gcc-10; $CC --version; fi # cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH=/var/tmp/unshield . && make && make install script: - mkdir build - cd build - $STATIC_ANALYZER cmake -DCMAKE_INSTALL_PREFIX:PATH=/var/tmp/unshield -DUSE_OUR_OWN_MD5=$USE_OUR_OWN_MD5 -DBUILD_STATIC=$BUILD_STATIC ${CMAKE_OPTS:-} .. - $STATIC_ANALYZER make - make install - ../run-tests.sh unshield-1.5.1/CMakeLists.txt000066400000000000000000000065141415320644200161000ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.8.7) project(unshield C) # Mimic CMP0048 which is avaliable only for cmake 3.0 and later set(PROJECT_VERSION_MAJOR 1) set(PROJECT_VERSION_MINOR 5) set(PROJECT_VERSION_PATCH 1) set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") option(BUILD_STATIC "Build static version of libunshield" OFF) include(CheckIncludeFiles) include(CheckSymbolExists) include(CheckCSourceCompiles) include(GNUInstallDirs) check_include_files(byteswap.h HAVE_BYTESWAP_H) check_include_files(dlfcn.h HAVE_DLFCN_H) check_include_files(inttypes.h HAVE_INTTYPES_H) check_include_files(memory.h HAVE_MEMORY_H) check_include_files(stdbool.h HAVE_STDBOOL_H) check_include_files(stdint.h HAVE_STDINT_H) check_include_files(stdlib.h HAVE_STDLIB_H) check_include_files(strings.h HAVE_STRINGS_H) check_include_files(string.h HAVE_STRING_H) check_include_files(sys/byteswap.h HAVE_SYS_BYTESWAP_H) check_include_files(sys/stat.h HAVE_SYS_STAT_H) check_include_files(sys/types.h HAVE_SYS_TYPES_H) check_include_files(unistd.h HAVE_UNISTD_H) check_symbol_exists(fnmatch fnmatch.h HAVE_FNMATCH) check_symbol_exists(iconv iconv.h HAVE_ICONV) set(SIZE_FORMAT "zi") check_c_source_compiles("#include \nint main(int argc, char **argv) { size_t value = 0; printf(\"%${SIZE_FORMAT}\", value); return 0; }" SIZE_FORMAT_ZI) if(NOT SIZE_FORMAT_ZI) set(SIZE_FORMAT "i") check_c_source_compiles("#include \nint main(int argc, char **argv) { size_t value = 0; printf(\"%${SIZE_FORMAT}\", value); return 0; }" SIZE_FORMAT_I) if(NOT SIZE_FORMAT_I) set(SIZE_FORMAT "li") check_c_source_compiles("#include \nint main(int argc, char **argv) { size_t value = 0; printf(\"%${SIZE_FORMAT}\", value); return 0; }" SIZE_FORMAT_LI) if(NOT SIZE_FORMAT_LI) message(FATAL_ERROR "You must be using a really weird platform!") endif() endif() endif() find_package(ZLIB REQUIRED) find_package(OpenSSL) if (${OPENSSL_FOUND}) option(USE_OUR_OWN_MD5 "Build using own md5 implementation" OFF) else() option(USE_OUR_OWN_MD5 "Build using own md5 implementation" ON) endif() message(STATUS "OPENSSL_FOUND: ${OPENSSL_FOUND}") message(STATUS "USE_OUR_OWN_MD5: ${USE_OUR_OWN_MD5}") message(STATUS "BUILD_STATIC: ${BUILD_STATIC}") add_definitions(-DHAVE_CONFIG_H) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/lib/unshield_config.h.in ${CMAKE_CURRENT_BINARY_DIR}/lib/unshield_config.h) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libunshield.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libunshield.pc @ONLY) include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR}/lib) # Function to change MSVC runtime linkage to static function(set_msvc_runtime_static) foreach(flag_var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) if(${flag_var} MATCHES "/MD") string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") endif() endforeach() endfunction() if (MSVC) add_definitions(-D_CRT_SECURE_NO_WARNINGS) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/win32_msvc) endif () add_subdirectory(lib) add_subdirectory(src) install(FILES man/unshield.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libunshield.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) unshield-1.5.1/ChangeLog000066400000000000000000000013311415320644200151020ustar00rootroot000000000000002009-07-16 Mark Ellis * 0.6 release 2009-06-18 Mark Ellis * src/unshield.c - fix use of -L (lowercase) option with -d 2008-05-06 Jonny Lamb * .cvsignore: * cvsclean: * lib/.cvsignore: * lib/md5/.cvsignore: * src/.cvsignore: Removed useless CVS ignore and clean files. * bootstrap: * unshield.spec.in: Removed spec file. 2008-05-06 Jonny Lamb * VERSION: Upped version number to 0.5.1. 2008-02-15 Mark Ellis * added man page for unshield 2008-01-09 Mark Ellis * started changelog * added LICENSE to EXTRA_DIST * added cabfile.h to libunshield_la_SOURCES unshield-1.5.1/LICENSE000066400000000000000000000021031415320644200143330ustar00rootroot00000000000000Copyright (c) 2003 David Eriksson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. unshield-1.5.1/README.md000066400000000000000000000066571415320644200146270ustar00rootroot00000000000000Unshield ======== [![Build Status](https://travis-ci.org/twogood/unshield.png?branch=master)](https://travis-ci.org/twogood/unshield) [![Packaging status](https://repology.org/badge/tiny-repos/unshield.svg)](https://repology.org/project/unshield/versions) [![Homebrew package](https://repology.org/badge/version-for-repo/homebrew/unshield.svg)](https://repology.org/project/unshield/versions) #### Microsoft Windows build [![Appveyor Build status](https://ci.appveyor.com/api/projects/status/rnjlecanres5au3q?svg=true)](https://ci.appveyor.com/project/twogood/unshield) [Download page](https://ci.appveyor.com/project/twogood/unshield/build/artifacts) Note: The Microsoft Windows build is currently broken even if Appveyor doesn't notice, sorry about that! A PR to fix this is welcome! Support Unshield development ---------------------------- - [PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=SQ7PEFMJK36AU) Dictionary ---------- InstallShield (IS): see www.installshield.com InstallShield Cabinet File (ISCF): A .cab file used by IS. Microsoft Cabinet File (MSCF): A .cab file used by Microsoft. About Unshield -------------- To install a Pocket PC application remotely, an installable Microsoft Cabinet File is copied to the /Windows/AppMgr/Install directory on the PDA and then the wceload.exe is executed to perform the actual install. That is a very simple procedure. Unfortunately, many applications for Pocket PC are distributed as InstallShield installers for Microsoft Windows, and not as individual Microsoft Cabinet Files. That is very impractical for users of other operating systems, such as Linux or FreeBSD. An installer created by the InstallShield software stores the files it will install inside of InstallShield Cabinet Files. It would thus be desirable to be able to extract the Microsoft Cabinet Files from the InstallShield Cabinet Files in order to be able to install the applications without access to Microsoft Windows. The format of InstallShield Cabinet Files is not officially documented but there are two tools available for Microsoft Windows that extracts files from InstallShield installers, and they are distributed with source code included. These tools are named "i5comp" and "i6comp" and can be downloaded from the Internet. One major drawback with these tools are that for the actual decompression of the files stored in the InstallShield Cabinet Files they require the use of code written by InstallShield that is not available as source code. Luckily, by examining this code with the 'strings' tool, I discovered that they were using the open source zlib library (www.gzip.org/zlib) for decompression. I could have modified i5comp and i6comp to run on other operating systems than Microsoft Windows, but I preferred to use them as a reference for this implementation. The goals of this implementation are: - Use a well known open source license (MIT) - Work on both little-endian and big-endian systems - Separate the implementation in a tool and a library - Support InstallShield versions 5 and later - Be able to list contents of InstallShield Cabinet Files - Be able to extract files from InstallShield Cabinet Files License ------- Unshield uses the MIT license. The short version is "do as you like, but don't blame me if anything goes wrong". See the file LICENSE for details. Build From Source ----------------- Just use the standard CMake build process: ``` sh cmake . make make install ``` unshield-1.5.1/lib/000077500000000000000000000000001415320644200141005ustar00rootroot00000000000000unshield-1.5.1/lib/CMakeLists.txt000066400000000000000000000023671415320644200166500ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.6) project(libunshield C) add_subdirectory(convert_utf) if(USE_OUR_OWN_MD5) add_subdirectory(md5) endif() set(LIBUNSHIELD_HEADES "internal.h" "libunshield.h" "log.h" "cabfile.h" ) set(LIBUNSHIELD_SOURCES "bswap.c" "component.c" "directory.c" "file.c" "file_group.c" "helper.c" "libunshield.c" "log.c" ) if(BUILD_STATIC) add_library(${PROJECT_NAME} STATIC ${LIBUNSHIELD_HEADES} ${LIBUNSHIELD_SOURCES}) else() add_library(${PROJECT_NAME} SHARED ${LIBUNSHIELD_HEADES} ${LIBUNSHIELD_SOURCES}) endif() target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(${PROJECT_NAME} PUBLIC ZLIB::ZLIB convert_utf) set_target_properties(libunshield PROPERTIES OUTPUT_NAME unshield) set_target_properties(libunshield PROPERTIES VERSION 0.0.0 SOVERSION 0) if(USE_OUR_OWN_MD5) target_link_libraries(${PROJECT_NAME} PUBLIC md5) else() target_link_libraries(${PROJECT_NAME} PUBLIC OpenSSL::Crypto) endif() install(TARGETS libunshield RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(FILES libunshield.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) unshield-1.5.1/lib/bswap.c000066400000000000000000000006041415320644200153600ustar00rootroot00000000000000/* $Id$ */ #include "internal.h" #if IMPLEMENT_BSWAP_XX /* * Written by Manuel Bouyer . * Public domain. */ uint16_t bswap_16(uint16_t x) { return ((x << 8) & 0xff00) | ((x >> 8) & 0x00ff); } uint32_t bswap_32(uint32_t x) { return ((x << 24) & 0xff000000 ) | ((x << 8) & 0x00ff0000 ) | ((x >> 8) & 0x0000ff00 ) | ((x >> 24) & 0x000000ff ); } #endif unshield-1.5.1/lib/cabfile.h000066400000000000000000000042151415320644200156400ustar00rootroot00000000000000/* $Id$ */ #ifndef __cabfile_h__ #define __cabfile_h__ #define OFFSET_COUNT 0x47 #define CAB_SIGNATURE 0x28635349 #define MSCF_SIGNATURE 0x4643534d #define COMMON_HEADER_SIZE 20 #define VOLUME_HEADER_SIZE_V5 40 #define VOLUME_HEADER_SIZE_V6 64 #define MAX_FILE_GROUP_COUNT 71 #define MAX_COMPONENT_COUNT 71 typedef struct { uint32_t signature; /* 00 */ uint32_t version; uint32_t volume_info; uint32_t cab_descriptor_offset; uint32_t cab_descriptor_size; /* 10 */ } CommonHeader; typedef struct { uint32_t data_offset; uint32_t data_offset_high; uint32_t first_file_index; uint32_t last_file_index; uint32_t first_file_offset; uint32_t first_file_offset_high; uint32_t first_file_size_expanded; uint32_t first_file_size_expanded_high; uint32_t first_file_size_compressed; uint32_t first_file_size_compressed_high; uint32_t last_file_offset; uint32_t last_file_offset_high; uint32_t last_file_size_expanded; uint32_t last_file_size_expanded_high; uint32_t last_file_size_compressed; uint32_t last_file_size_compressed_high; } VolumeHeader; typedef struct { uint32_t file_table_offset; /* c */ uint32_t file_table_size; /* 14 */ uint32_t file_table_size2; /* 18 */ uint32_t directory_count; /* 1c */ uint32_t file_count; /* 28 */ uint32_t file_table_offset2; /* 2c */ uint32_t file_group_offsets[MAX_FILE_GROUP_COUNT]; /* 0x3e */ uint32_t component_offsets [MAX_COMPONENT_COUNT]; /* 0x15a */ } CabDescriptor; #define FILE_SPLIT 1U #define FILE_OBFUSCATED 2U #define FILE_COMPRESSED 4U #define FILE_INVALID 8U #define LINK_NONE 0 #define LINK_PREV 1 #define LINK_NEXT 2 #define LINK_BOTH 3 typedef struct { uint32_t name_offset; uint32_t directory_index; uint16_t flags; uint64_t expanded_size; uint64_t compressed_size; uint64_t data_offset; uint8_t md5[16]; uint16_t volume; uint32_t link_previous; uint32_t link_next; uint8_t link_flags; } FileDescriptor; typedef struct { uint32_t name_offset; uint32_t descriptor_offset; uint32_t next_offset; } OffsetList; #endif unshield-1.5.1/lib/component.c000066400000000000000000000031321415320644200162450ustar00rootroot00000000000000/* $Id$ */ #include "internal.h" #include "log.h" #include #include int unshield_component_count(Unshield* unshield) { Header* header = unshield->header_list; return header->component_count; } const char* unshield_component_name(Unshield* unshield, int index) { Header* header = unshield->header_list; if (index >= 0 && index < header->component_count) return header->components[index]->name; else return NULL; } UnshieldComponent* unshield_component_new(Header* header, uint32_t offset) { UnshieldComponent* self = NEW1(UnshieldComponent); uint8_t* p = unshield_header_get_buffer(header, offset); uint32_t file_group_table_offset; unsigned i; self->name = unshield_header_get_string(header, READ_UINT32(p)); p += 4; switch (header->major_version) { case 0: case 5: p += 0x6c; break; case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: default: p += 0x6b; break; } self->file_group_count = READ_UINT16(p); p += 2; if (self->file_group_count > MAX_FILE_GROUP_COUNT) abort(); self->file_group_names = NEW(const char*, self->file_group_count); file_group_table_offset = READ_UINT32(p); p += 4; p = unshield_header_get_buffer(header, file_group_table_offset); for (i = 0; i < self->file_group_count; i++) { self->file_group_names[i] = unshield_header_get_string(header, READ_UINT32(p)); p += 4; } return self; } void unshield_component_destroy(UnshieldComponent* self) { if (self) { FREE(self->file_group_names); free(self); } } unshield-1.5.1/lib/convert_utf/000077500000000000000000000000001415320644200164365ustar00rootroot00000000000000unshield-1.5.1/lib/convert_utf/CMakeLists.txt000066400000000000000000000010221415320644200211710ustar00rootroot00000000000000set(LIBCONVERT_UTF_HEADES "ConvertUTF.h" ) set(LIBCONVERT_UTF_SOURCES "ConvertUTF.c" ) if(BUILD_STATIC AND MSVC) set_msvc_runtime_static() endif() add_library(convert_utf STATIC ${LIBCONVERT_UTF_HEADES} ${LIBCONVERT_UTF_SOURCES}) # Linux/Clang-7 # relocation R_X86_64_32S against `.rodata' can not be used when making a shared object; # recompile with -fPIC include(CheckCCompilerFlag) CHECK_C_COMPILER_FLAG("-fPIC" COMPILER_HAS_FPIC) if (COMPILER_HAS_FPIC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") endif() unshield-1.5.1/lib/convert_utf/ConvertUTF.c000066400000000000000000000451731415320644200206130ustar00rootroot00000000000000/* * Copyright 2001-2004 Unicode, Inc. * * Disclaimer * * This source code is provided as is by Unicode, Inc. No claims are * made as to fitness for any particular purpose. No warranties of any * kind are expressed or implied. The recipient agrees to determine * applicability of information provided. If this file has been * purchased on magnetic or optical media from Unicode, Inc., the * sole remedy for any claim will be exchange of defective media * within 90 days of receipt. * * Limitations on Rights to Redistribute This Code * * Unicode, Inc. hereby grants the right to freely use the information * supplied in this file in the creation of products supporting the * Unicode Standard, and to make copies of this file in any form * for internal or external distribution as long as this notice * remains attached. */ /* --------------------------------------------------------------------- Conversions between UTF32, UTF-16, and UTF-8. Source code file. Author: Mark E. Davis, 1994. Rev History: Rick McGowan, fixes & updates May 2001. Sept 2001: fixed const & error conditions per mods suggested by S. Parent & A. Lillich. June 2002: Tim Dodd added detection and handling of incomplete source sequences, enhanced error detection, added casts to eliminate compiler warnings. July 2003: slight mods to back out aggressive FFFE detection. Jan 2004: updated switches in from-UTF8 conversions. Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions. See the header file "ConvertUTF.h" for complete documentation. ------------------------------------------------------------------------ */ #include "ConvertUTF.h" #ifdef CVTUTF_DEBUG #include #endif static const int halfShift = 10; /* used for shifting by 10 bits */ static const UTF32 halfBase = 0x0010000UL; static const UTF32 halfMask = 0x3FFUL; #define UNI_SUR_HIGH_START (UTF32)0xD800 #define UNI_SUR_HIGH_END (UTF32)0xDBFF #define UNI_SUR_LOW_START (UTF32)0xDC00 #define UNI_SUR_LOW_END (UTF32)0xDFFF #define false 0 #define true 1 /* --------------------------------------------------------------------- */ ConversionResult ConvertUTF32toUTF16 ( const UTF32** sourceStart, const UTF32* sourceEnd, UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) { ConversionResult result = conversionOK; const UTF32* source = *sourceStart; UTF16* target = *targetStart; while (source < sourceEnd) { UTF32 ch; if (target >= targetEnd) { result = targetExhausted; break; } ch = *source++; if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { if (flags == strictConversion) { --source; /* return to the illegal value itself */ result = sourceIllegal; break; } else { *target++ = UNI_REPLACEMENT_CHAR; } } else { *target++ = (UTF16)ch; /* normal case */ } } else if (ch > UNI_MAX_LEGAL_UTF32) { if (flags == strictConversion) { result = sourceIllegal; } else { *target++ = UNI_REPLACEMENT_CHAR; } } else { /* target is a character in range 0xFFFF - 0x10FFFF. */ if (target + 1 >= targetEnd) { --source; /* Back up source pointer! */ result = targetExhausted; break; } ch -= halfBase; *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START); } } *sourceStart = source; *targetStart = target; return result; } /* --------------------------------------------------------------------- */ ConversionResult ConvertUTF16toUTF32 ( const UTF16** sourceStart, const UTF16* sourceEnd, UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) { ConversionResult result = conversionOK; const UTF16* source = *sourceStart; UTF32* target = *targetStart; UTF32 ch, ch2; while (source < sourceEnd) { const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */ ch = *source++; /* If we have a surrogate pair, convert to UTF32 first. */ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) { /* If the 16 bits following the high surrogate are in the source buffer... */ if (source < sourceEnd) { ch2 = *source; /* If it's a low surrogate, convert to UTF32. */ if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { ch = ((ch - UNI_SUR_HIGH_START) << halfShift) + (ch2 - UNI_SUR_LOW_START) + halfBase; ++source; } else if (flags == strictConversion) { /* it's an unpaired high surrogate */ --source; /* return to the illegal value itself */ result = sourceIllegal; break; } } else { /* We don't have the 16 bits following the high surrogate. */ --source; /* return to the high surrogate */ result = sourceExhausted; break; } } else if (flags == strictConversion) { /* UTF-16 surrogate values are illegal in UTF-32 */ if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) { --source; /* return to the illegal value itself */ result = sourceIllegal; break; } } if (target >= targetEnd) { source = oldSource; /* Back up source pointer! */ result = targetExhausted; break; } *target++ = ch; } *sourceStart = source; *targetStart = target; #ifdef CVTUTF_DEBUG if (result == sourceIllegal) { fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2); fflush(stderr); } #endif return result; } /* --------------------------------------------------------------------- */ /* * Index into the table below with the first byte of a UTF-8 sequence to * get the number of trailing bytes that are supposed to follow it. * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is * left as-is for anyone who may want to do such conversion, which was * allowed in earlier algorithms. */ static const char trailingBytesForUTF8[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 }; /* * Magic values subtracted from a buffer value during UTF8 conversion. * This table contains as many values as there might be trailing bytes * in a UTF-8 sequence. */ static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, 0x03C82080UL, 0xFA082080UL, 0x82082080UL }; /* * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed * into the first byte, depending on how many bytes follow. There are * as many entries in this table as there are UTF-8 sequence types. * (I.e., one byte sequence, two byte... etc.). Remember that sequencs * for *legal* UTF-8 will be 4 or fewer bytes total. */ static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; /* --------------------------------------------------------------------- */ /* The interface converts a whole buffer to avoid function-call overhead. * Constants have been gathered. Loops & conditionals have been removed as * much as possible for efficiency, in favor of drop-through switches. * (See "Note A" at the bottom of the file for equivalent code.) * If your compiler supports it, the "isLegalUTF8" call can be turned * into an inline function. */ /* --------------------------------------------------------------------- */ ConversionResult ConvertUTF16toUTF8 ( const UTF16** sourceStart, const UTF16* sourceEnd, UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) { ConversionResult result = conversionOK; const UTF16* source = *sourceStart; UTF8* target = *targetStart; while (source < sourceEnd) { UTF32 ch; unsigned short bytesToWrite = 0; const UTF32 byteMask = 0xBF; const UTF32 byteMark = 0x80; const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */ ch = *source++; /* If we have a surrogate pair, convert to UTF32 first. */ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) { /* If the 16 bits following the high surrogate are in the source buffer... */ if (source < sourceEnd) { UTF32 ch2 = *source; /* If it's a low surrogate, convert to UTF32. */ if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { ch = ((ch - UNI_SUR_HIGH_START) << halfShift) + (ch2 - UNI_SUR_LOW_START) + halfBase; ++source; } else if (flags == strictConversion) { /* it's an unpaired high surrogate */ --source; /* return to the illegal value itself */ result = sourceIllegal; break; } } else { /* We don't have the 16 bits following the high surrogate. */ --source; /* return to the high surrogate */ result = sourceExhausted; break; } } else if (flags == strictConversion) { /* UTF-16 surrogate values are illegal in UTF-32 */ if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) { --source; /* return to the illegal value itself */ result = sourceIllegal; break; } } /* Figure out how many bytes the result will require */ if (ch < (UTF32)0x80) { bytesToWrite = 1; } else if (ch < (UTF32)0x800) { bytesToWrite = 2; } else if (ch < (UTF32)0x10000) { bytesToWrite = 3; } else if (ch < (UTF32)0x110000) { bytesToWrite = 4; } else { bytesToWrite = 3; ch = UNI_REPLACEMENT_CHAR; } target += bytesToWrite; if (target > targetEnd) { source = oldSource; /* Back up source pointer! */ target -= bytesToWrite; result = targetExhausted; break; } switch (bytesToWrite) { /* note: everything falls through. */ case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; case 1: *--target = (UTF8)(ch | firstByteMark[bytesToWrite]); } target += bytesToWrite; } *sourceStart = source; *targetStart = target; return result; } /* --------------------------------------------------------------------- */ /* * Utility routine to tell whether a sequence of bytes is legal UTF-8. * This must be called with the length pre-determined by the first byte. * If not calling this from ConvertUTF8to*, then the length can be set by: * length = trailingBytesForUTF8[*source]+1; * and the sequence is illegal right away if there aren't that many bytes * available. * If presented with a length > 4, this returns false. The Unicode * definition of UTF-8 goes up to 4-byte sequences. */ static Boolean isLegalUTF8(const UTF8 *source, int length) { UTF8 a; const UTF8 *srcptr = source+length; switch (length) { default: return false; /* Everything else falls through when "true"... */ case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; case 2: if ((a = (*--srcptr)) > 0xBF) return false; switch (*source) { /* no fall-through in this inner switch */ case 0xE0: if (a < 0xA0) return false; break; case 0xED: if (a > 0x9F) return false; break; case 0xF0: if (a < 0x90) return false; break; case 0xF4: if (a > 0x8F) return false; break; default: if (a < 0x80) return false; } case 1: if (*source >= 0x80 && *source < 0xC2) return false; } if (*source > 0xF4) return false; return true; } /* --------------------------------------------------------------------- */ /* * Exported function to return whether a UTF-8 sequence is legal or not. * This is not used here; it's just exported. */ Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) { int length = trailingBytesForUTF8[*source]+1; if (source+length > sourceEnd) { return false; } return isLegalUTF8(source, length); } /* --------------------------------------------------------------------- */ ConversionResult ConvertUTF8toUTF16 ( const UTF8** sourceStart, const UTF8* sourceEnd, UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) { ConversionResult result = conversionOK; const UTF8* source = *sourceStart; UTF16* target = *targetStart; while (source < sourceEnd) { UTF32 ch = 0; unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; if (source + extraBytesToRead >= sourceEnd) { result = sourceExhausted; break; } /* Do this check whether lenient or strict */ if (! isLegalUTF8(source, extraBytesToRead+1)) { result = sourceIllegal; break; } /* * The cases all fall through. See "Note A" below. */ switch (extraBytesToRead) { case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ case 3: ch += *source++; ch <<= 6; case 2: ch += *source++; ch <<= 6; case 1: ch += *source++; ch <<= 6; case 0: ch += *source++; } ch -= offsetsFromUTF8[extraBytesToRead]; if (target >= targetEnd) { source -= (extraBytesToRead+1); /* Back up source pointer! */ result = targetExhausted; break; } if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ /* UTF-16 surrogate values are illegal in UTF-32 */ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { if (flags == strictConversion) { source -= (extraBytesToRead+1); /* return to the illegal value itself */ result = sourceIllegal; break; } else { *target++ = UNI_REPLACEMENT_CHAR; } } else { *target++ = (UTF16)ch; /* normal case */ } } else if (ch > UNI_MAX_UTF16) { if (flags == strictConversion) { result = sourceIllegal; source -= (extraBytesToRead+1); /* return to the start */ break; /* Bail out; shouldn't continue */ } else { *target++ = UNI_REPLACEMENT_CHAR; } } else { /* target is a character in range 0xFFFF - 0x10FFFF. */ if (target + 1 >= targetEnd) { source -= (extraBytesToRead+1); /* Back up source pointer! */ result = targetExhausted; break; } ch -= halfBase; *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START); } } *sourceStart = source; *targetStart = target; return result; } /* --------------------------------------------------------------------- */ ConversionResult ConvertUTF32toUTF8 ( const UTF32** sourceStart, const UTF32* sourceEnd, UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) { ConversionResult result = conversionOK; const UTF32* source = *sourceStart; UTF8* target = *targetStart; while (source < sourceEnd) { UTF32 ch; unsigned short bytesToWrite = 0; const UTF32 byteMask = 0xBF; const UTF32 byteMark = 0x80; ch = *source++; if (flags == strictConversion ) { /* UTF-16 surrogate values are illegal in UTF-32 */ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { --source; /* return to the illegal value itself */ result = sourceIllegal; break; } } /* * Figure out how many bytes the result will require. Turn any * illegally large UTF32 things (> Plane 17) into replacement chars. */ if (ch < (UTF32)0x80) { bytesToWrite = 1; } else if (ch < (UTF32)0x800) { bytesToWrite = 2; } else if (ch < (UTF32)0x10000) { bytesToWrite = 3; } else if (ch <= UNI_MAX_LEGAL_UTF32) { bytesToWrite = 4; } else { bytesToWrite = 3; ch = UNI_REPLACEMENT_CHAR; result = sourceIllegal; } target += bytesToWrite; if (target > targetEnd) { --source; /* Back up source pointer! */ target -= bytesToWrite; result = targetExhausted; break; } switch (bytesToWrite) { /* note: everything falls through. */ case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]); } target += bytesToWrite; } *sourceStart = source; *targetStart = target; return result; } /* --------------------------------------------------------------------- */ ConversionResult ConvertUTF8toUTF32 ( const UTF8** sourceStart, const UTF8* sourceEnd, UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) { ConversionResult result = conversionOK; const UTF8* source = *sourceStart; UTF32* target = *targetStart; while (source < sourceEnd) { UTF32 ch = 0; unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; if (source + extraBytesToRead >= sourceEnd) { result = sourceExhausted; break; } /* Do this check whether lenient or strict */ if (! isLegalUTF8(source, extraBytesToRead+1)) { result = sourceIllegal; break; } /* * The cases all fall through. See "Note A" below. */ switch (extraBytesToRead) { case 5: ch += *source++; ch <<= 6; case 4: ch += *source++; ch <<= 6; case 3: ch += *source++; ch <<= 6; case 2: ch += *source++; ch <<= 6; case 1: ch += *source++; ch <<= 6; case 0: ch += *source++; } ch -= offsetsFromUTF8[extraBytesToRead]; if (target >= targetEnd) { source -= (extraBytesToRead+1); /* Back up the source pointer! */ result = targetExhausted; break; } if (ch <= UNI_MAX_LEGAL_UTF32) { /* * UTF-16 surrogate values are illegal in UTF-32, and anything * over Plane 17 (> 0x10FFFF) is illegal. */ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { if (flags == strictConversion) { source -= (extraBytesToRead+1); /* return to the illegal value itself */ result = sourceIllegal; break; } else { *target++ = UNI_REPLACEMENT_CHAR; } } else { *target++ = ch; } } else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */ result = sourceIllegal; *target++ = UNI_REPLACEMENT_CHAR; } } *sourceStart = source; *targetStart = target; return result; } /* --------------------------------------------------------------------- Note A. The fall-through switches in UTF-8 reading code save a temp variable, some decrements & conditionals. The switches are equivalent to the following loop: { int tmpBytesToRead = extraBytesToRead+1; do { ch += *source++; --tmpBytesToRead; if (tmpBytesToRead) ch <<= 6; } while (tmpBytesToRead > 0); } In UTF-8 writing code, the switches on "bytesToWrite" are similarly unrolled loops. --------------------------------------------------------------------- */ unshield-1.5.1/lib/convert_utf/ConvertUTF.h000066400000000000000000000134651415320644200206170ustar00rootroot00000000000000/* * Copyright 2001-2004 Unicode, Inc. * * Disclaimer * * This source code is provided as is by Unicode, Inc. No claims are * made as to fitness for any particular purpose. No warranties of any * kind are expressed or implied. The recipient agrees to determine * applicability of information provided. If this file has been * purchased on magnetic or optical media from Unicode, Inc., the * sole remedy for any claim will be exchange of defective media * within 90 days of receipt. * * Limitations on Rights to Redistribute This Code * * Unicode, Inc. hereby grants the right to freely use the information * supplied in this file in the creation of products supporting the * Unicode Standard, and to make copies of this file in any form * for internal or external distribution as long as this notice * remains attached. */ /* --------------------------------------------------------------------- Conversions between UTF32, UTF-16, and UTF-8. Header file. Several funtions are included here, forming a complete set of conversions between the three formats. UTF-7 is not included here, but is handled in a separate source file. Each of these routines takes pointers to input buffers and output buffers. The input buffers are const. Each routine converts the text between *sourceStart and sourceEnd, putting the result into the buffer between *targetStart and targetEnd. Note: the end pointers are *after* the last item: e.g. *(sourceEnd - 1) is the last item. The return result indicates whether the conversion was successful, and if not, whether the problem was in the source or target buffers. (Only the first encountered problem is indicated.) After the conversion, *sourceStart and *targetStart are both updated to point to the end of last text successfully converted in the respective buffers. Input parameters: sourceStart - pointer to a pointer to the source buffer. The contents of this are modified on return so that it points at the next thing to be converted. targetStart - similarly, pointer to pointer to the target buffer. sourceEnd, targetEnd - respectively pointers to the ends of the two buffers, for overflow checking only. These conversion functions take a ConversionFlags argument. When this flag is set to strict, both irregular sequences and isolated surrogates will cause an error. When the flag is set to lenient, both irregular sequences and isolated surrogates are converted. Whether the flag is strict or lenient, all illegal sequences will cause an error return. This includes sequences such as: , , or in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code must check for illegal sequences. When the flag is set to lenient, characters over 0x10FFFF are converted to the replacement character; otherwise (when the flag is set to strict) they constitute an error. Output parameters: The value "sourceIllegal" is returned from some routines if the input sequence is malformed. When "sourceIllegal" is returned, the source value will point to the illegal value that caused the problem. E.g., in UTF-8 when a sequence is malformed, it points to the start of the malformed sequence. Author: Mark E. Davis, 1994. Rev History: Rick McGowan, fixes & updates May 2001. Fixes & updates, Sept 2001. ------------------------------------------------------------------------ */ /* --------------------------------------------------------------------- The following 4 definitions are compiler-specific. The C standard does not guarantee that wchar_t has at least 16 bits, so wchar_t is no less portable than unsigned short! All should be unsigned values to avoid sign extension during bit mask & shift operations. ------------------------------------------------------------------------ */ typedef unsigned long UTF32; /* at least 32 bits */ typedef unsigned short UTF16; /* at least 16 bits */ typedef unsigned char UTF8; /* typically 8 bits */ typedef unsigned char Boolean; /* 0 or 1 */ /* Some fundamental constants */ #define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD #define UNI_MAX_BMP (UTF32)0x0000FFFF #define UNI_MAX_UTF16 (UTF32)0x0010FFFF #define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF #define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF typedef enum { conversionOK, /* conversion successful */ sourceExhausted, /* partial character in source, but hit end */ targetExhausted, /* insuff. room in target for conversion */ sourceIllegal /* source sequence is illegal/malformed */ } ConversionResult; typedef enum { strictConversion = 0, lenientConversion } ConversionFlags; /* This is for C++ and does no harm in C */ #ifdef __cplusplus extern "C" { #endif ConversionResult ConvertUTF8toUTF16 ( const UTF8** sourceStart, const UTF8* sourceEnd, UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags); ConversionResult ConvertUTF16toUTF8 ( const UTF16** sourceStart, const UTF16* sourceEnd, UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); ConversionResult ConvertUTF8toUTF32 ( const UTF8** sourceStart, const UTF8* sourceEnd, UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags); ConversionResult ConvertUTF32toUTF8 ( const UTF32** sourceStart, const UTF32* sourceEnd, UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); ConversionResult ConvertUTF16toUTF32 ( const UTF16** sourceStart, const UTF16* sourceEnd, UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags); ConversionResult ConvertUTF32toUTF16 ( const UTF32** sourceStart, const UTF32* sourceEnd, UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags); Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd); #ifdef __cplusplus } #endif /* --------------------------------------------------------------------- */ unshield-1.5.1/lib/convert_utf/README.google000066400000000000000000000004611415320644200205720ustar00rootroot00000000000000This is a utf8/16/32 conversion functions downloaded from unicode.org website from url: ftp://www.unicode.org/Public/PROGRAMS/CVTUTF/ Only ConvertUTF.h and ConvertUTF.c files were downloaded. The rest of files related to UTF7 and testing harness were not downloaded. No modifications have been done. unshield-1.5.1/lib/convert_utf/README.unshield000066400000000000000000000001571415320644200211330ustar00rootroot00000000000000These files were downloaded from http://gears.googlecode.com/svn/trunk/third_party/convert_utf/ on 2013-02-15. unshield-1.5.1/lib/convert_utf/readme.txt000066400000000000000000000027241415320644200204410ustar00rootroot00000000000000 The accompanying C source code file "ConvertUTF.c" and the associated header file "ConvertUTF.h" provide for conversion between various transformation formats of Unicode characters. The following conversions are supported: UTF-32 to UTF-16 UTF-32 to UTF-8 UTF-16 to UTF-32 UTF-16 to UTF-8 UTF-8 to UTF-16 UTF-8 to UTF-32 In addition, there is a test harness which runs various tests. The files "CVTUTF7.C" and "CVTUTF7.H" are for archival and historical purposes only. They have not been updated to Unicode 3.0 or later and should be considered obsolescent. "CVTUTF7.C" contains two functions that can convert between UCS2 (i.e., the BMP characters only) and UTF-7. Surrogates are not supported, the code has not been tested, and should be considered unsuitable for general purpose use. Please submit any bug reports about these programs here: http://www.unicode.org/unicode/reporting.html Version 1.0: initial version. Version 1.1: corrected some minor problems; added stricter checks. Version 1.2: corrected switch statements associated with "extraBytesToRead" in 4 & 5 byte cases, in functions for conversion from UTF8. Note: formally, the 4 & 5 byte cases are illegal in the latest UTF8, but the table and this code has always catered for those, cases since at one time they were legal. Version 1.3: Updated UTF-8 legality check; updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions Updated UTF-8 legality tests in harness.c Last update: October 19, 2004 unshield-1.5.1/lib/directory.c000066400000000000000000000014361415320644200162540ustar00rootroot00000000000000/* $Id$ */ #include "internal.h" #include "log.h" int unshield_directory_count(Unshield* unshield) { if (unshield) { /* XXX: multi-volume support... */ Header* header = unshield->header_list; return header->cab.directory_count; } else return -1; } const char* unshield_directory_name(Unshield* unshield, int index) { if (unshield && index >= 0) { /* XXX: multi-volume support... */ Header* header = unshield->header_list; if (index < (int)header->cab.directory_count) return unshield_get_utf8_string(header, header->data + header->common.cab_descriptor_offset + header->cab.file_table_offset + header->file_table[index]); } unshield_warning("Failed to get directory name %i", index); return NULL; } unshield-1.5.1/lib/file.c000066400000000000000000001064301415320644200151670ustar00rootroot00000000000000/* $Id$ */ #include "internal.h" #if USE_OUR_OWN_MD5 #include "md5/global.h" #include "md5/md5.h" #else #include #define MD5Init MD5_Init #define MD5Update MD5_Update #define MD5Final MD5_Final #endif #include "cabfile.h" #include "log.h" #include #include #include #if !defined(_MSC_VER) #include /* for MIN(a,b) */ #endif #ifdef _WIN32 #define fseek _fseeki64 #define ftell _ftelli64 #endif #ifndef MIN /* missing in some platforms */ #define MIN(a,b) (((a)<(b))?(a):(b)) #endif #include #define VERBOSE 3 #define ror8(x,n) (((x) >> ((int)(n))) | ((x) << (8 - (int)(n)))) #define rol8(x,n) (((x) << ((int)(n))) | ((x) >> (8 - (int)(n)))) static const uint8_t END_OF_CHUNK[4] = { 0x00, 0x00, 0xff, 0xff }; static FileDescriptor* unshield_read_file_descriptor(Unshield* unshield, int index) { /* XXX: multi-volume support... */ Header* header = unshield->header_list; uint8_t* p = NULL; uint8_t* saved_p = NULL; FileDescriptor* fd = NEW1(FileDescriptor); switch (header->major_version) { case 0: case 5: saved_p = p = header->data + header->common.cab_descriptor_offset + header->cab.file_table_offset + header->file_table[header->cab.directory_count + index]; #if VERBOSE unshield_trace("File descriptor offset %i: %08x", index, p - header->data); #endif fd->volume = header->index; fd->name_offset = READ_UINT32(p); p += 4; fd->directory_index = READ_UINT32(p); p += 4; fd->flags = READ_UINT16(p); p += 2; fd->expanded_size = READ_UINT32(p); p += 4; fd->compressed_size = READ_UINT32(p); p += 4; p += 0x14; fd->data_offset = READ_UINT32(p); p += 4; #if VERBOSE >= 2 unshield_trace("Name offset: %08x", fd->name_offset); unshield_trace("Directory index: %08x", fd->directory_index); unshield_trace("Flags: %04x", fd->flags); unshield_trace("Expanded size: %08x", fd->expanded_size); unshield_trace("Compressed size: %08x", fd->compressed_size); unshield_trace("Data offset: %08x", fd->data_offset); #endif if (header->major_version == 5) { memcpy(fd->md5, p, 0x10); p += 0x10; assert((p - saved_p) == 0x3a); } break; case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: default: saved_p = p = header->data + header->common.cab_descriptor_offset + header->cab.file_table_offset + header->cab.file_table_offset2 + index * 0x57; #if VERBOSE unshield_trace("File descriptor offset: %08x", p - header->data); #endif fd->flags = READ_UINT16(p); p += 2; fd->expanded_size = READ_UINT64(p); p += 8; fd->compressed_size = READ_UINT64(p); p += 8; fd->data_offset = READ_UINT64(p); p += 8; memcpy(fd->md5, p, 0x10); p += 0x10; p += 0x10; fd->name_offset = READ_UINT32(p); p += 4; fd->directory_index = READ_UINT16(p); p += 2; assert((p - saved_p) == 0x40); p += 0xc; fd->link_previous = READ_UINT32(p); p += 4; fd->link_next = READ_UINT32(p); p += 4; fd->link_flags = *p; p ++; #if VERBOSE if (fd->link_flags != LINK_NONE) { unshield_trace("Link: previous=%i, next=%i, flags=%i", fd->link_previous, fd->link_next, fd->link_flags); } #endif fd->volume = READ_UINT16(p); p += 2; assert((p - saved_p) == 0x57); break; } if (!(fd->flags & FILE_COMPRESSED) && fd->compressed_size != fd->expanded_size) { unshield_warning("File is not compressed but compressed size is %08x and expanded size is %08x", fd->compressed_size, fd->expanded_size); } return fd; } static FileDescriptor* unshield_get_file_descriptor(Unshield* unshield, int index) { /* XXX: multi-volume support... */ Header* header = unshield->header_list; if (index < 0 || index >= (int)header->cab.file_count) { unshield_error("Invalid index"); return NULL; } if (!header->file_descriptors) header->file_descriptors = calloc(header->cab.file_count, sizeof(FileDescriptor*)); if (!header->file_descriptors[index]) header->file_descriptors[index] = unshield_read_file_descriptor(unshield, index); return header->file_descriptors[index]; } int unshield_file_count (Unshield* unshield)/*{{{*/ { if (unshield) { /* XXX: multi-volume support... */ Header* header = unshield->header_list; return header->cab.file_count; } else return -1; }/*}}}*/ const char* unshield_file_name (Unshield* unshield, int index)/*{{{*/ { FileDescriptor* fd = unshield_get_file_descriptor(unshield, index); if (fd) { /* XXX: multi-volume support... */ Header* header = unshield->header_list; return unshield_get_utf8_string(header, header->data + header->common.cab_descriptor_offset + header->cab.file_table_offset + fd->name_offset); } unshield_warning("Failed to get file descriptor %i", index); return NULL; }/*}}}*/ bool unshield_file_is_valid(Unshield* unshield, int index) { bool is_valid = false; FileDescriptor* fd; if (index < 0 || index >= unshield_file_count(unshield)) goto exit; if (!(fd = unshield_get_file_descriptor(unshield, index))) goto exit; if (fd->flags & FILE_INVALID) goto exit; if (!fd->name_offset) goto exit; if (!fd->data_offset) goto exit; is_valid = true; exit: return is_valid; } static int unshield_uncompress (Byte *dest, uLong* destLen, Byte *source, uLong *sourceLen)/*{{{*/ { z_stream stream; int err; stream.next_in = source; stream.avail_in = (uInt)*sourceLen; stream.next_out = dest; stream.avail_out = (uInt)*destLen; stream.zalloc = (alloc_func)0; stream.zfree = (free_func)0; /* make second parameter negative to disable checksum verification */ err = inflateInit2(&stream, -MAX_WBITS); if (err != Z_OK) return err; err = inflate(&stream, Z_FINISH); if (err != Z_STREAM_END) { inflateEnd(&stream); return err; } *destLen = stream.total_out; *sourceLen = stream.total_in; err = inflateEnd(&stream); return err; }/*}}}*/ static int unshield_uncompress_old(Byte *dest, uLong *destLen, Byte *source, uLong *sourceLen)/*{{{*/ { z_stream stream; int err; stream.next_in = source; stream.avail_in = (uInt)*sourceLen; stream.next_out = dest; stream.avail_out = (uInt)*destLen; stream.zalloc = (alloc_func)0; stream.zfree = (free_func)0; *destLen = 0; *sourceLen = 0; /* make second parameter negative to disable checksum verification */ err = inflateInit2(&stream, -MAX_WBITS); if (err != Z_OK) return err; while (stream.avail_in > 1) { err = inflate(&stream, Z_BLOCK); if (err != Z_OK) { inflateEnd(&stream); return err; } } *destLen = stream.total_out; *sourceLen = stream.total_in; err = inflateEnd(&stream); return err; }/*}}}*/ typedef struct { Unshield* unshield; unsigned index; FileDescriptor* file_descriptor; int volume; FILE* volume_file; VolumeHeader volume_header; unsigned volume_bytes_left; unsigned obfuscation_offset; } UnshieldReader; static bool unshield_reader_open_volume(UnshieldReader* reader, int volume)/*{{{*/ { bool success = false; uint64_t data_offset = 0; uint64_t volume_bytes_left_compressed; uint64_t volume_bytes_left_expanded; CommonHeader common_header; #if VERBOSE >= 2 unshield_trace("Open volume %i", volume); #endif FCLOSE(reader->volume_file); reader->volume_file = unshield_fopen_for_reading(reader->unshield, volume, CABINET_SUFFIX); if (!reader->volume_file) { unshield_error("Failed to open input cabinet file %i", volume); goto exit; } { uint8_t tmp[COMMON_HEADER_SIZE]; uint8_t* p = tmp; if (COMMON_HEADER_SIZE != fread(&tmp, 1, COMMON_HEADER_SIZE, reader->volume_file)) goto exit; if (!unshield_read_common_header(&p, &common_header)) goto exit; } memset(&reader->volume_header, 0, sizeof(VolumeHeader)); switch (reader->unshield->header_list->major_version) { case 0: case 5: { uint8_t five_header[VOLUME_HEADER_SIZE_V5]; uint8_t* p = five_header; if (VOLUME_HEADER_SIZE_V5 != fread(&five_header, 1, VOLUME_HEADER_SIZE_V5, reader->volume_file)) goto exit; reader->volume_header.data_offset = READ_UINT32(p); p += 4; #if VERBOSE if (READ_UINT32(p)) unshield_trace("Unknown = %08x", READ_UINT32(p)); #endif /* unknown */ p += 4; reader->volume_header.first_file_index = READ_UINT32(p); p += 4; reader->volume_header.last_file_index = READ_UINT32(p); p += 4; reader->volume_header.first_file_offset = READ_UINT32(p); p += 4; reader->volume_header.first_file_size_expanded = READ_UINT32(p); p += 4; reader->volume_header.first_file_size_compressed = READ_UINT32(p); p += 4; reader->volume_header.last_file_offset = READ_UINT32(p); p += 4; reader->volume_header.last_file_size_expanded = READ_UINT32(p); p += 4; reader->volume_header.last_file_size_compressed = READ_UINT32(p); p += 4; if (reader->volume_header.last_file_offset == 0) reader->volume_header.last_file_offset = INT32_MAX; } break; case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: default: { uint8_t six_header[VOLUME_HEADER_SIZE_V6]; uint8_t* p = six_header; if (VOLUME_HEADER_SIZE_V6 != fread(&six_header, 1, VOLUME_HEADER_SIZE_V6, reader->volume_file)) goto exit; reader->volume_header.data_offset = READ_UINT32(p); p += 4; reader->volume_header.data_offset_high = READ_UINT32(p); p += 4; reader->volume_header.first_file_index = READ_UINT32(p); p += 4; reader->volume_header.last_file_index = READ_UINT32(p); p += 4; reader->volume_header.first_file_offset = READ_UINT32(p); p += 4; reader->volume_header.first_file_offset_high = READ_UINT32(p); p += 4; reader->volume_header.first_file_size_expanded = READ_UINT32(p); p += 4; reader->volume_header.first_file_size_expanded_high = READ_UINT32(p); p += 4; reader->volume_header.first_file_size_compressed = READ_UINT32(p); p += 4; reader->volume_header.first_file_size_compressed_high = READ_UINT32(p); p += 4; reader->volume_header.last_file_offset = READ_UINT32(p); p += 4; reader->volume_header.last_file_offset_high = READ_UINT32(p); p += 4; reader->volume_header.last_file_size_expanded = READ_UINT32(p); p += 4; reader->volume_header.last_file_size_expanded_high = READ_UINT32(p); p += 4; reader->volume_header.last_file_size_compressed = READ_UINT32(p); p += 4; reader->volume_header.last_file_size_compressed_high = READ_UINT32(p); p += 4; } break; } #if VERBOSE >= 2 unshield_trace("First file index = %i, last file index = %i", reader->volume_header.first_file_index, reader->volume_header.last_file_index); unshield_trace("First file offset = %08x, last file offset = %08x", reader->volume_header.first_file_offset, reader->volume_header.last_file_offset); #endif /* enable support for split archives for IS5 */ if (reader->unshield->header_list->major_version == 5) { if (reader->index < (reader->unshield->header_list->cab.file_count - 1) && reader->index == reader->volume_header.last_file_index && reader->volume_header.last_file_size_compressed != reader->file_descriptor->compressed_size) { unshield_trace("IS5 split file last in volume"); reader->file_descriptor->flags |= FILE_SPLIT; } else if (reader->index > 0 && reader->index == reader->volume_header.first_file_index && reader->volume_header.first_file_size_compressed != reader->file_descriptor->compressed_size) { unshield_trace("IS5 split file first in volume"); reader->file_descriptor->flags |= FILE_SPLIT; } } if (reader->file_descriptor->flags & FILE_SPLIT) { #if VERBOSE unshield_trace(/*"Total bytes left = 0x08%x, "*/"previous data offset = 0x08%x", /*total_bytes_left, */data_offset); #endif if (reader->index == reader->volume_header.last_file_index && reader->volume_header.last_file_offset != 0x7FFFFFFF) { /* can be first file too... */ #if VERBOSE unshield_trace("Index %i is last file in cabinet file %i", reader->index, volume); #endif data_offset = reader->volume_header.last_file_offset; volume_bytes_left_expanded = reader->volume_header.last_file_size_expanded; volume_bytes_left_compressed = reader->volume_header.last_file_size_compressed; } else if (reader->index == reader->volume_header.first_file_index) { #if VERBOSE unshield_trace("Index %i is first file in cabinet file %i", reader->index, volume); #endif data_offset = reader->volume_header.first_file_offset; volume_bytes_left_expanded = reader->volume_header.first_file_size_expanded; volume_bytes_left_compressed = reader->volume_header.first_file_size_compressed; } else { success = true; goto exit; } #if VERBOSE unshield_trace("Will read 0x%08x bytes from offset 0x%08x", volume_bytes_left_compressed, data_offset); #endif } else { data_offset = reader->file_descriptor->data_offset; volume_bytes_left_expanded = reader->file_descriptor->expanded_size; volume_bytes_left_compressed = reader->file_descriptor->compressed_size; } if (reader->file_descriptor->flags & FILE_COMPRESSED) reader->volume_bytes_left = volume_bytes_left_compressed; else reader->volume_bytes_left = volume_bytes_left_expanded; fseek(reader->volume_file, data_offset, SEEK_SET); reader->volume = volume; success = true; exit: return success; }/*}}}*/ void unshield_deobfuscate(unsigned char* buffer, size_t size, unsigned* seed) { unsigned tmp_seed = *seed; for (; size > 0; size--, buffer++, tmp_seed++) { *buffer = ror8(*buffer ^ 0xd5, 2) - (tmp_seed % 0x47); } *seed = tmp_seed; } static void unshield_reader_deobfuscate(UnshieldReader* reader, uint8_t* buffer, size_t size) { unshield_deobfuscate(buffer, size, &reader->obfuscation_offset); } static bool unshield_reader_read(UnshieldReader* reader, void* buffer, size_t size)/*{{{*/ { bool success = false; uint8_t* p = buffer; size_t bytes_left = size; #if VERBOSE >= 3 unshield_trace("unshield_reader_read start: bytes_left = 0x%x, volume_bytes_left = 0x%x", bytes_left, reader->volume_bytes_left); #endif for (;;) { /* Read as much as possible from this volume */ size_t bytes_to_read = MIN(bytes_left, reader->volume_bytes_left); #if VERBOSE >= 3 unshield_trace("Trying to read 0x%x bytes from offset %08x in volume %i", bytes_to_read, ftell(reader->volume_file), reader->volume); #endif if (bytes_to_read == 0) { unshield_error("bytes_to_read can't be zero"); goto exit; } if (bytes_to_read != fread(p, 1, bytes_to_read, reader->volume_file)) { unshield_error("Failed to read 0x%08x bytes of file %i (%s) from volume %i. Current offset = 0x%08x", bytes_to_read, reader->index, unshield_file_name(reader->unshield, reader->index), reader->volume, ftell(reader->volume_file)); goto exit; } bytes_left -= bytes_to_read; reader->volume_bytes_left -= bytes_to_read; #if VERBOSE >= 3 unshield_trace("bytes_left = %i, volume_bytes_left = %i", bytes_left, reader->volume_bytes_left); #endif if (!bytes_left) break; p += bytes_to_read; /* Open next volume */ if (!unshield_reader_open_volume(reader, reader->volume + 1)) { unshield_error("Failed to open volume %i to read %i more bytes", reader->volume + 1, bytes_to_read); goto exit; } } if (reader->file_descriptor->flags & FILE_OBFUSCATED) unshield_reader_deobfuscate(reader, buffer, size); success = true; exit: return success; }/*}}}*/ int copy_file(FILE* infile, FILE* outfile) { #define SIZE (1024*1024) char buffer[SIZE]; size_t bytes; while (0 < (bytes = fread(buffer, 1, sizeof(buffer), infile))) fwrite(buffer, 1, bytes, outfile); return 0; } static UnshieldReader* unshield_reader_create_external(/*{{{*/ Unshield* unshield, int index, FileDescriptor* file_descriptor) { bool success = false; const char* file_name = unshield_file_name(unshield, index); const char* directory_name = unshield_directory_name(unshield, file_descriptor->directory_index); char* base_directory_name = unshield_get_base_directory_name(unshield); long int path_max = unshield_get_path_max(unshield); char* directory_and_filename = malloc(path_max); UnshieldReader* reader = NEW1(UnshieldReader); if (!reader) goto exit; reader->unshield = unshield; reader->index = index; reader->file_descriptor = file_descriptor; snprintf(directory_and_filename, path_max, "%s/%s/%s", base_directory_name, directory_name, file_name); reader->volume_file = fopen(directory_and_filename, "rb"); if (!reader->volume_file) { unshield_error("Failed to open input file %s", directory_and_filename); goto exit; } if (file_descriptor->flags & FILE_COMPRESSED) { long file_size = FSIZE(reader->volume_file); FILE *temporary_file = NULL; /* * Normally the compressed data is nicely terminated with end of chunk marker 00 00 ff ff but not always * This seem to happen for small files where the compressed size and expanded size are almost the same. * Workaround: Create a temporary file with the correct end of chunk. */ long diff = file_descriptor->compressed_size - file_size; if (diff > 0) { diff = MIN(sizeof(END_OF_CHUNK), diff); temporary_file = tmpfile(); copy_file(reader->volume_file, temporary_file); fwrite(END_OF_CHUNK + sizeof(END_OF_CHUNK) - diff, 1, diff, temporary_file); fseek(temporary_file, 0, SEEK_SET); fclose(reader->volume_file); reader->volume_file = temporary_file; reader->volume_bytes_left = file_size + diff; } else { reader->volume_bytes_left = file_descriptor->compressed_size; } } else { reader->volume_bytes_left = file_descriptor->expanded_size; } success = true; exit: FREE(base_directory_name); FREE(directory_and_filename); if (success) return reader; FREE(reader); return NULL; } static UnshieldReader* unshield_reader_create(/*{{{*/ Unshield* unshield, int index, FileDescriptor* file_descriptor) { bool success = false; UnshieldReader* reader = NEW1(UnshieldReader); if (!reader) return NULL; reader->unshield = unshield; reader->index = index; reader->file_descriptor = file_descriptor; for (;;) { if (!unshield_reader_open_volume(reader, file_descriptor->volume)) { unshield_error("Failed to open volume %i", file_descriptor->volume); goto exit; } /* Start with the correct volume for IS5 cabinets */ if (reader->unshield->header_list->major_version <= 5 && index > (int)reader->volume_header.last_file_index) { unshield_trace("Trying next volume..."); file_descriptor->volume++; continue; } break; }; success = true; exit: if (success) return reader; FREE(reader); return NULL; }/*}}}*/ static void unshield_reader_destroy(UnshieldReader* reader)/*{{{*/ { if (reader) { FCLOSE(reader->volume_file); free(reader); } }/*}}}*/ #define BUFFER_SIZE (64*1024) /* * If filename is NULL, just throw away the result */ bool unshield_file_save (Unshield* unshield, int index, const char* filename)/*{{{*/ { bool success = false; FILE* output = NULL; unsigned char* input_buffer = (unsigned char*)malloc(BUFFER_SIZE+1); unsigned char* output_buffer = (unsigned char*)malloc(BUFFER_SIZE); unsigned int bytes_left; uLong total_written = 0; UnshieldReader* reader = NULL; FileDescriptor* file_descriptor; MD5_CTX md5; MD5Init(&md5); if (!unshield) goto exit; if (!(file_descriptor = unshield_get_file_descriptor(unshield, index))) { unshield_error("Failed to get file descriptor for file %i", index); goto exit; } if ((file_descriptor->flags & FILE_INVALID) || 0 == file_descriptor->data_offset) { /* invalid file */ goto exit; } if (file_descriptor->link_flags & LINK_PREV) { success = unshield_file_save(unshield, file_descriptor->link_previous, filename); goto exit; } reader = unshield_reader_create(unshield, index, file_descriptor); if (!reader) { unshield_error("Failed to create data reader for file %i", index); goto exit; } if (unshield_fsize(reader->volume_file) == (long)file_descriptor->data_offset) { unshield_error("File %i is not inside the cabinet.", index); goto exit; } if (filename) { output = fopen(filename, "wb"); if (!output) { unshield_error("Failed to open output file '%s'", filename); goto exit; } } if (file_descriptor->flags & FILE_COMPRESSED) bytes_left = file_descriptor->compressed_size; else bytes_left = file_descriptor->expanded_size; /*unshield_trace("Bytes to read: %i", bytes_left);*/ while (bytes_left > 0) { uLong bytes_to_write = BUFFER_SIZE; int result; if (file_descriptor->flags & FILE_COMPRESSED) { uLong read_bytes; uint16_t bytes_to_read = 0; if (!unshield_reader_read(reader, &bytes_to_read, sizeof(bytes_to_read))) { unshield_error("Failed to read %i bytes of file %i (%s) from input cabinet file %i", sizeof(bytes_to_read), index, unshield_file_name(unshield, index), file_descriptor->volume); goto exit; } bytes_to_read = letoh16(bytes_to_read); if (bytes_to_read == 0) { unshield_error("bytes_to_read can't be zero"); unshield_error("HINT: Try unshield_file_save_old() or -O command line parameter!"); goto exit; } if (!unshield_reader_read(reader, input_buffer, bytes_to_read)) { #if VERBOSE unshield_error("Failed to read %i bytes of file %i (%s) from input cabinet file %i", bytes_to_read, index, unshield_file_name(unshield, index), file_descriptor->volume); #endif goto exit; } /* add a null byte to make inflate happy */ input_buffer[bytes_to_read] = 0; read_bytes = bytes_to_read+1; result = unshield_uncompress(output_buffer, &bytes_to_write, input_buffer, &read_bytes); if (Z_OK != result) { unshield_error("Decompression failed with code %i. bytes_to_read=%i, volume_bytes_left=%i, volume=%i, read_bytes=%i", result, bytes_to_read, reader->volume_bytes_left, file_descriptor->volume, read_bytes); if (result == Z_DATA_ERROR) { unshield_error("HINT: Try unshield_file_save_old() or -O command line parameter!"); } goto exit; } #if VERBOSE >= 3 unshield_trace("read_bytes = %i", read_bytes); #endif bytes_left -= 2; bytes_left -= bytes_to_read; } else { bytes_to_write = MIN(bytes_left, BUFFER_SIZE); if (!unshield_reader_read(reader, output_buffer, bytes_to_write)) { #if VERBOSE unshield_error("Failed to read %i bytes from input cabinet file %i", bytes_to_write, file_descriptor->volume); #endif goto exit; } bytes_left -= bytes_to_write; } MD5Update(&md5, output_buffer, bytes_to_write); if (output) { if (bytes_to_write != fwrite(output_buffer, 1, bytes_to_write, output)) { unshield_error("Failed to write %i bytes to file '%s'", bytes_to_write, filename); goto exit; } } total_written += bytes_to_write; } if (file_descriptor->expanded_size != total_written) { unshield_error("Expanded size expected to be %i, but was %i", file_descriptor->expanded_size, total_written); goto exit; } if (unshield->header_list->major_version >= 6) { unsigned char md5result[16]; MD5Final(md5result, &md5); if (0 != memcmp(md5result, file_descriptor->md5, 16)) { unshield_error("MD5 checksum failure for file %i (%s)", index, unshield_file_name(unshield, index)); goto exit; } } success = true; exit: unshield_reader_destroy(reader); FCLOSE(output); FREE(input_buffer); FREE(output_buffer); return success; }/*}}}*/ int unshield_file_directory(Unshield* unshield, int index)/*{{{*/ { FileDescriptor* fd = unshield_get_file_descriptor(unshield, index); if (fd) { return fd->directory_index; } else return -1; }/*}}}*/ size_t unshield_file_size(Unshield* unshield, int index)/*{{{*/ { FileDescriptor* fd = unshield_get_file_descriptor(unshield, index); if (fd) { return fd->expanded_size; } else return 0; }/*}}}*/ bool unshield_file_save_raw(Unshield* unshield, int index, const char* filename) { /* XXX: Thou Shalt Not Cut & Paste... */ bool success = false; FILE* output = NULL; unsigned char* input_buffer = (unsigned char*)malloc(BUFFER_SIZE); unsigned char* output_buffer = (unsigned char*)malloc(BUFFER_SIZE); unsigned int bytes_left; UnshieldReader* reader = NULL; FileDescriptor* file_descriptor; if (!unshield) goto exit; if (!(file_descriptor = unshield_get_file_descriptor(unshield, index))) { unshield_error("Failed to get file descriptor for file %i", index); goto exit; } if ((file_descriptor->flags & FILE_INVALID) || 0 == file_descriptor->data_offset) { /* invalid file */ goto exit; } if (file_descriptor->link_flags & LINK_PREV) { success = unshield_file_save_raw(unshield, file_descriptor->link_previous, filename); goto exit; } reader = unshield_reader_create(unshield, index, file_descriptor); if (!reader) { unshield_error("Failed to create data reader for file %i", index); goto exit; } if (unshield_fsize(reader->volume_file) == (long)file_descriptor->data_offset) { unshield_error("File %i is not inside the cabinet.", index); goto exit; } if (filename) { output = fopen(filename, "wb"); if (!output) { unshield_error("Failed to open output file '%s'", filename); goto exit; } } if (file_descriptor->flags & FILE_COMPRESSED) bytes_left = file_descriptor->compressed_size; else bytes_left = file_descriptor->expanded_size; /*unshield_trace("Bytes to read: %i", bytes_left);*/ while (bytes_left > 0) { uLong bytes_to_write = MIN(bytes_left, BUFFER_SIZE); if (!unshield_reader_read(reader, output_buffer, bytes_to_write)) { #if VERBOSE unshield_error("Failed to read %i bytes from input cabinet file %i", bytes_to_write, file_descriptor->volume); #endif goto exit; } bytes_left -= bytes_to_write; if (output) { if (bytes_to_write != fwrite(output_buffer, 1, bytes_to_write, output)) { unshield_error("Failed to write %i bytes to file '%s'", bytes_to_write, filename); goto exit; } } } success = true; exit: unshield_reader_destroy(reader); FCLOSE(output); FREE(input_buffer); FREE(output_buffer); return success; } static uint8_t* find_bytes( const uint8_t* buffer, size_t bufferSize, const uint8_t* pattern, size_t patternSize) { const unsigned char *p = buffer; size_t buffer_left = bufferSize; while ((p = memchr(p, pattern[0], buffer_left)) != NULL) { if (patternSize > buffer_left) break; if (memcmp(p, pattern, patternSize) == 0) return (uint8_t*)p; ++p; --buffer_left; } return NULL; } bool unshield_file_save_old(Unshield* unshield, int index, const char* filename)/*{{{*/ { /* XXX: Thou Shalt Not Cut & Paste... */ bool success = false; FILE* output = NULL; size_t input_buffer_size = BUFFER_SIZE; unsigned char* input_buffer = (unsigned char*)malloc(BUFFER_SIZE); unsigned char* output_buffer = (unsigned char*)malloc(BUFFER_SIZE); unsigned int bytes_left; uLong total_written = 0; UnshieldReader* reader = NULL; FileDescriptor* file_descriptor; if (!unshield) goto exit; if (!(file_descriptor = unshield_get_file_descriptor(unshield, index))) { unshield_error("Failed to get file descriptor for file %i", index); goto exit; } if ((file_descriptor->flags & FILE_INVALID) || 0 == file_descriptor->data_offset) { /* invalid file */ goto exit; } if (file_descriptor->link_flags & LINK_PREV) { success = unshield_file_save(unshield, file_descriptor->link_previous, filename); goto exit; } reader = unshield_reader_create(unshield, index, file_descriptor); if (!reader) { unshield_error("Failed to create data reader for file %i", index); goto exit; } if (unshield_fsize(reader->volume_file) == (long)file_descriptor->data_offset) { unshield_error("File %i is not inside the cabinet. Trying external file!", index); unshield_reader_destroy(reader); reader = unshield_reader_create_external(unshield, index, file_descriptor); if (!reader) { unshield_error("Failed to create data reader for file %i", index); goto exit; } } if (filename) { output = fopen(filename, "wb"); if (!output) { unshield_error("Failed to open output file '%s'", filename); goto exit; } } bytes_left = file_descriptor->expanded_size; #if VERBOSE >= 4 unshield_trace("Bytes to write: %i", bytes_left); #endif while (bytes_left > 0) { uLong bytes_to_write = 0; int result; if (reader->volume_bytes_left == 0 && !unshield_reader_open_volume(reader, reader->volume + 1)) { unshield_error("Failed to open volume %i to read %i more bytes", reader->volume + 1, bytes_left); goto exit; } if (file_descriptor->flags & FILE_COMPRESSED) { uLong read_bytes; size_t input_size = reader->volume_bytes_left; uint8_t* chunk_buffer; while (input_size > input_buffer_size) { input_buffer_size *= 2; #if VERBOSE >= 3 unshield_trace("increased input_buffer_size to 0x%x", input_buffer_size); #endif input_buffer = realloc(input_buffer, input_buffer_size); assert(input_buffer); } if (!unshield_reader_read(reader, input_buffer, input_size)) { #if VERBOSE unshield_error("Failed to read 0x%x bytes of file %i (%s) from input cabinet file %i", input_size, index, unshield_file_name(unshield, index), file_descriptor->volume); #endif goto exit; } for (chunk_buffer = input_buffer; input_size && bytes_left; ) { size_t chunk_size; uint8_t* match = find_bytes(chunk_buffer, input_size, END_OF_CHUNK, sizeof(END_OF_CHUNK)); if (!match) { unshield_error("Could not find end of chunk for file %i (%s) from input cabinet file %i", index, unshield_file_name(unshield, index), file_descriptor->volume); goto exit; } chunk_size = match - chunk_buffer; /* Detect when the chunk actually contains the end of chunk marker. Needed by Qtime.smk from "The Feeble Files - spanish version". The first bit of a compressed block is always zero, so we apply this workaround if it's a one. A possibly more proper fix for this would be to have unshield_uncompress_old eat compressed data and discard chunk markers inbetween. */ while ((chunk_size + sizeof(END_OF_CHUNK)) < input_size && chunk_buffer[chunk_size + sizeof(END_OF_CHUNK)] & 1) { unshield_warning("It seems like we have an end of chunk marker inside of a chunk."); chunk_size += sizeof(END_OF_CHUNK); match = find_bytes(chunk_buffer + chunk_size, input_size - chunk_size, END_OF_CHUNK, sizeof(END_OF_CHUNK)); if (!match) { unshield_error("Could not find end of chunk for file %i (%s) from input cabinet file %i", index, unshield_file_name(unshield, index), file_descriptor->volume); goto exit; } chunk_size = match - chunk_buffer; } #if VERBOSE >= 3 unshield_trace("chunk_size = 0x%x", chunk_size); #endif /* add a null byte to make inflate happy */ chunk_buffer[chunk_size] = 0; bytes_to_write = BUFFER_SIZE; read_bytes = chunk_size; result = unshield_uncompress_old(output_buffer, &bytes_to_write, chunk_buffer, &read_bytes); if (Z_OK != result) { unshield_error("Decompression failed with code %i. input_size=%i, volume_bytes_left=%i, volume=%i, read_bytes=%i", result, input_size, reader->volume_bytes_left, file_descriptor->volume, read_bytes); goto exit; } #if VERBOSE >= 3 unshield_trace("read_bytes = 0x%x", read_bytes); #endif chunk_buffer += chunk_size; chunk_buffer += sizeof(END_OF_CHUNK); input_size -= chunk_size; input_size -= sizeof(END_OF_CHUNK); bytes_left -= bytes_to_write; if (output) { if (bytes_to_write != fwrite(output_buffer, 1, bytes_to_write, output)) { unshield_error("Failed to write %i bytes to file '%s'", bytes_to_write, filename); goto exit; } } total_written += bytes_to_write; } } else { bytes_to_write = MIN(bytes_left, BUFFER_SIZE); if (!unshield_reader_read(reader, output_buffer, bytes_to_write)) { #if VERBOSE unshield_error("Failed to read %i bytes from input cabinet file %i", bytes_to_write, file_descriptor->volume); #endif goto exit; } bytes_left -= bytes_to_write; if (output) { if (bytes_to_write != fwrite(output_buffer, 1, bytes_to_write, output)) { unshield_error("Failed to write %i bytes to file '%s'", bytes_to_write, filename); goto exit; } } total_written += bytes_to_write; } } if (file_descriptor->expanded_size != total_written) { unshield_error("Expanded size expected to be %i, but was %i", file_descriptor->expanded_size, total_written); goto exit; } success = true; exit: unshield_reader_destroy(reader); FCLOSE(output); FREE(input_buffer); FREE(output_buffer); return success; }/*}}}*/ unshield-1.5.1/lib/file_group.c000066400000000000000000000034401415320644200164000ustar00rootroot00000000000000/* $Id$ */ #include "internal.h" #include "log.h" #include #include #define VERBOSE 1 UnshieldFileGroup* unshield_file_group_new(Header* header, uint32_t offset)/*{{{*/ { UnshieldFileGroup* self = NEW1(UnshieldFileGroup); uint8_t* p = unshield_header_get_buffer(header, offset); #if VERBOSE unshield_trace("File group descriptor offset: %08x", offset); #endif self->name = unshield_header_get_string(header, READ_UINT32(p)); p += 4; if (header->major_version <= 5) p += 0x48; else p += 0x12; self->first_file = READ_UINT32(p); p += 4; self->last_file = READ_UINT32(p); p += 4; #if VERBOSE unshield_trace("File group %08x first file = %i, last file = %i", offset, self->first_file, self->last_file); #endif return self; }/*}}}*/ void unshield_file_group_destroy(UnshieldFileGroup* self)/*{{{*/ { FREE(self); }/*}}}*/ int unshield_file_group_count(Unshield* unshield)/*{{{*/ { Header* header = unshield->header_list; return header->file_group_count; }/*}}}*/ UnshieldFileGroup* unshield_file_group_get(Unshield* unshield, int index) { Header* header = unshield->header_list; if (index >= 0 && index < header->file_group_count) return header->file_groups[index]; else return NULL; } UnshieldFileGroup* unshield_file_group_find(Unshield* unshield, const char* name) { Header* header = unshield->header_list; int i; for (i = 0; i < header->file_group_count; i++) { if (STREQ(header->file_groups[i]->name, name)) return header->file_groups[i]; } return NULL; } const char* unshield_file_group_name(Unshield* unshield, int index)/*{{{*/ { Header* header = unshield->header_list; if (index >= 0 && index < header->file_group_count) return header->file_groups[index]->name; else return NULL; }/*}}}*/ unshield-1.5.1/lib/helper.c000066400000000000000000000143371415320644200155330ustar00rootroot00000000000000#define _BSD_SOURCE 1 #define _DEFAULT_SOURCE 1 #include "internal.h" #include "log.h" #include "convert_utf/ConvertUTF.h" #include #include #include #include #include #include #ifdef _WIN32 #define fseek _fseeki64 #define ftell _ftelli64 #define realpath(N,R) _fullpath((R),(N),_MAX_PATH) #include #ifndef PATH_MAX #define PATH_MAX _MAX_PATH #endif #else #include #endif #define VERBOSE 0 #if defined(_MSC_VER) #define snprintf _snprintf #define vsnprintf _vsnprintf #define strcasecmp _stricmp #define strncasecmp _strnicmp #endif long int unshield_get_path_max(Unshield* unshield) { #ifdef PATH_MAX return PATH_MAX; #else long int path_max = pathconf(unshield->filename_pattern, _PC_PATH_MAX); if (path_max <= 0) path_max = 4096; return path_max; #endif } char *unshield_get_base_directory_name(Unshield *unshield) { long int path_max = unshield_get_path_max(unshield); char *p = strrchr(unshield->filename_pattern, '/'); char *dirname = malloc(path_max); if (p) { strncpy(dirname, unshield->filename_pattern, path_max); if ((unsigned int) (p - unshield->filename_pattern) > path_max) { dirname[path_max - 1] = 0; } else dirname[(p - unshield->filename_pattern)] = 0; } else strcpy(dirname, "."); return dirname; } static char* get_filename(Unshield* unshield, int index, const char* suffix) { if (unshield && unshield->filename_pattern) { long path_max = unshield_get_path_max(unshield); char* filename = malloc(path_max); if (filename == NULL) { unshield_error("Unable to allocate memory.\n"); goto exit; } if (snprintf(filename, path_max, unshield->filename_pattern, index, suffix) >= path_max) { unshield_error("Pathname exceeds system limits.\n"); goto exit; } exit: return filename; } return NULL; } FILE* unshield_fopen_for_reading(Unshield* unshield, int index, const char* suffix) { if (unshield && unshield->filename_pattern) { FILE* result = NULL; char* filename = get_filename(unshield, index, suffix); char* dirname = unshield_get_base_directory_name(unshield); const char *q; struct dirent *dent = NULL; DIR *sourcedir = NULL; long int path_max = unshield_get_path_max(unshield); q=strrchr(filename,'/'); if (q) q++; else q=filename; sourcedir = opendir(dirname); /* Search for the File case independent */ if (sourcedir) { for (dent=readdir(sourcedir);dent;dent=readdir(sourcedir)) { if (!(strcasecmp(q, dent->d_name))) { /*unshield_trace("Found match %s\n",dent->d_name);*/ break; } } if (dent == NULL) { unshield_trace("File %s not found even case insensitive\n",filename); goto exit; } else if(snprintf(filename, path_max, "%s/%s", dirname, dent->d_name)>=path_max) { unshield_error("Pathname exceeds system limits.\n"); goto exit; } } else unshield_trace("Could not open directory %s error %s\n", dirname, strerror(errno)); #if VERBOSE unshield_trace("Opening file '%s'", filename); #endif result = fopen(filename, "rb"); exit: if (sourcedir) closedir(sourcedir); free(filename); free(dirname); return result; } return NULL; } long long unshield_fsize(FILE* file) { long long result; long long previous = ftell(file); fseek(file, 0L, SEEK_END); result = ftell(file); fseek(file, previous, SEEK_SET); return result; } bool unshield_read_common_header(uint8_t** buffer, CommonHeader* common) { uint8_t* p = *buffer; common->signature = READ_UINT32(p); p += 4; if (CAB_SIGNATURE != common->signature) { unshield_error("Invalid file signature"); if (MSCF_SIGNATURE == common->signature) unshield_warning("Found Microsoft Cabinet header. Use cabextract (https://www.cabextract.org.uk/) to unpack this file."); return false; } common->version = READ_UINT32(p); p += 4; common->volume_info = READ_UINT32(p); p += 4; common->cab_descriptor_offset = READ_UINT32(p); p += 4; common->cab_descriptor_size = READ_UINT32(p); p += 4; #if VERBOSE unshield_trace("Common header: %08x %08x %08x %08x", common->version, common->volume_info, common->cab_descriptor_offset, common->cab_descriptor_size); #endif *buffer = p; return true; } /** Get pointer at cab descriptor + offset */ uint8_t* unshield_header_get_buffer(Header* header, uint32_t offset) { if (offset) return header->data + header->common.cab_descriptor_offset + offset; else return NULL; } static int unshield_strlen_utf16(const uint16_t* utf16) { const uint16_t* current = utf16; while (*current++) ; return current - utf16; } static StringBuffer* unshield_add_string_buffer(Header* header) { StringBuffer* result = NEW1(StringBuffer); result->next = header->string_buffer; return header->string_buffer = result; } static const char* unshield_utf16_to_utf8(Header* header, const uint16_t* utf16) { StringBuffer* string_buffer = unshield_add_string_buffer(header); int length = unshield_strlen_utf16(utf16); int buffer_size = 3 * length + 1; char* target = string_buffer->string = NEW(char, buffer_size); ConversionResult result = ConvertUTF16toUTF8( (const UTF16**)&utf16, utf16 + length + 1, (UTF8**)&target, (UTF8*)(target + buffer_size), lenientConversion); if (result != conversionOK) { /* fail fast */ abort(); } return string_buffer->string; } const char* unshield_get_utf8_string(Header* header, const void* buffer) { if (header->major_version >= 17 && buffer != NULL) { return unshield_utf16_to_utf8(header, (const uint16_t*)buffer); } else { return (const char*)buffer; } } /** Get string at cab descriptor offset + string offset */ const char* unshield_header_get_string(Header* header, uint32_t offset) { return unshield_get_utf8_string(header, unshield_header_get_buffer(header, offset)); } unshield-1.5.1/lib/internal.h000066400000000000000000000065161415320644200160750ustar00rootroot00000000000000/* $Id$ */ #ifndef __internal_h__ #define __internal_h__ #include "libunshield.h" #include "lib/unshield_config.h" #if HAVE_STDINT_H #include #elif HAVE_INTTYPES_H #include #endif #include #include /* for FILE */ #include "cabfile.h" typedef struct _StringBuffer StringBuffer; struct _StringBuffer { StringBuffer* next; char* string; }; typedef struct _Header Header; struct _Header { Header* next; int index; uint8_t* data; size_t size; int major_version; /* shortcuts */ CommonHeader common; CabDescriptor cab; uint32_t* file_table; FileDescriptor** file_descriptors; int component_count; UnshieldComponent** components; int file_group_count; UnshieldFileGroup** file_groups; StringBuffer* string_buffer; }; struct _Unshield { Header* header_list; char* filename_pattern; }; /* Internal component functions */ UnshieldComponent* unshield_component_new(Header* header, uint32_t offset); void unshield_component_destroy(UnshieldComponent* self); /* Internal file group functions */ UnshieldFileGroup* unshield_file_group_new(Header* header, uint32_t offset); void unshield_file_group_destroy(UnshieldFileGroup* self); /* Helpers */ char *unshield_get_base_directory_name(Unshield *unshield); long int unshield_get_path_max(Unshield* unshield); FILE* unshield_fopen_for_reading(Unshield* unshield, int index, const char* suffix); long long unshield_fsize(FILE* file); bool unshield_read_common_header(uint8_t** buffer, CommonHeader* common); const char* unshield_get_utf8_string(Header* header, const void* buffer); const char* unshield_header_get_string(Header* header, uint32_t offset); uint8_t* unshield_header_get_buffer(Header* header, uint32_t offset); /* Constants */ #define HEADER_SUFFIX "hdr" #define CABINET_SUFFIX "cab" /* Macros for safer development */ #define FREE(ptr) { if (ptr) { free(ptr); (ptr) = NULL; } } #define STRDUP(str) ((str) ? strdup(str) : NULL) #define NEW(type, count) ((type*)calloc(count, sizeof(type))) #define NEW1(type) ((type*)calloc(1, sizeof(type))) #define FCLOSE(file) if (file) { fclose(file); (file) = NULL; } #define FSIZE(file) ((file) ? unshield_fsize(file) : 0) #define STREQ(s1,s2) (0 == strcmp(s1,s2)) #if WORDS_BIGENDIAN #if HAVE_BYTESWAP_H #include #elif HAVE_SYS_BYTESWAP_H #include #else /* use our own functions */ #define IMPLEMENT_BSWAP_XX 1 #define bswap_16 unshield_bswap_16 #define bswap_32 unshield_bswap_32 uint16_t bswap_16(uint16_t x); uint32_t bswap_32(uint32_t x); #endif #define letoh16(x) bswap_16(x) #define letoh32(x) bswap_32(x) #else #define letoh32(x) (x) #define letoh16(x) (x) #endif static inline uint16_t get_unaligned_le16(const uint8_t *p) { return p[0] | p[1] << 8; } static inline uint32_t get_unaligned_le32(const uint8_t *p) { return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24; } static inline uint64_t get_unaligned_le64(const uint8_t *p) { return (uint64_t)get_unaligned_le32(p + 4) << 32 | get_unaligned_le32(p); } #define READ_UINT16(p) get_unaligned_le16(p) #define READ_UINT32(p) get_unaligned_le32(p) #define READ_UINT64(p) get_unaligned_le64(p) #define READ_INT16(p) ((int16_t)READ_UINT16(p)) #define READ_INT32(p) ((int32_t)READ_UINT32(p)) #endif unshield-1.5.1/lib/libunshield.c000066400000000000000000000243751415320644200165610ustar00rootroot00000000000000/* $Id$ */ #define _BSD_SOURCE 1 #define _DEFAULT_SOURCE 1 #include "internal.h" #include "log.h" #include #include #include #include /** Create filename pattern used by unshield_fopen_for_reading() */ static bool unshield_create_filename_pattern(Unshield* unshield, const char* filename)/*{{{*/ { /* TODO Correct his function so that it handles filenames with more than one dot ('.')! */ if (unshield && filename) { char pattern[256]; char* prefix = strdup(filename); char* p = strrchr(prefix, '/'); if (!p) p = prefix; for (; *p != '\0'; p++) { if ('.' == *p || isdigit(*p)) { *p = '\0'; break; } } snprintf(pattern, sizeof(pattern), "%s%%i.%%s", prefix); free(prefix); FREE(unshield->filename_pattern); unshield->filename_pattern = strdup(pattern); return true; } else return false; }/*}}}*/ static bool unshield_get_common_header(Header* header) { uint8_t* p = header->data; return unshield_read_common_header(&p, &header->common); } static bool unshield_get_cab_descriptor(Header* header) { if (header->common.cab_descriptor_size) { uint8_t* p = header->data + header->common.cab_descriptor_offset; int i; p += 0xc; header->cab.file_table_offset = READ_UINT32(p); p += 4; p += 4; header->cab.file_table_size = READ_UINT32(p); p += 4; header->cab.file_table_size2 = READ_UINT32(p); p += 4; header->cab.directory_count = READ_UINT32(p); p += 4; p += 8; header->cab.file_count = READ_UINT32(p); p += 4; header->cab.file_table_offset2 = READ_UINT32(p); p += 4; assert((p - (header->data + header->common.cab_descriptor_offset)) == 0x30); if (header->cab.file_table_size != header->cab.file_table_size2) unshield_warning("File table sizes do not match"); unshield_trace("Cabinet descriptor: %08x %08x %08x %08x", header->cab.file_table_offset, header->cab.file_table_size, header->cab.file_table_size2, header->cab.file_table_offset2 ); unshield_trace("Directory count: %i", header->cab.directory_count); unshield_trace("File count: %i", header->cab.file_count); p += 0xe; for (i = 0; i < MAX_FILE_GROUP_COUNT; i++) { header->cab.file_group_offsets[i] = READ_UINT32(p); p += 4; } for (i = 0; i < MAX_COMPONENT_COUNT; i++) { header->cab.component_offsets[i] = READ_UINT32(p); p += 4; } return true; } else { unshield_error("No CAB descriptor available!"); return false; } } static bool unshield_get_file_table(Header* header) { uint8_t* p = header->data + header->common.cab_descriptor_offset + header->cab.file_table_offset; int count = header->cab.directory_count + header->cab.file_count; int i; header->file_table = calloc(count, sizeof(uint32_t)); for (i = 0; i < count; i++) { header->file_table[i] = READ_UINT32(p); p += 4; } return true; } static bool unshield_header_get_components(Header* header)/*{{{*/ { int count = 0; int i; int available = 16; header->components = malloc(available * sizeof(UnshieldComponent*)); for (i = 0; i < MAX_COMPONENT_COUNT; i++) { if (header->cab.component_offsets[i]) { OffsetList list; list.next_offset = header->cab.component_offsets[i]; while (list.next_offset) { uint8_t* p = unshield_header_get_buffer(header, list.next_offset); list.name_offset = READ_UINT32(p); p += 4; list.descriptor_offset = READ_UINT32(p); p += 4; list.next_offset = READ_UINT32(p); p += 4; if (count == available) { available <<= 1; header->components = realloc(header->components, available * sizeof(UnshieldComponent*)); } header->components[count++] = unshield_component_new(header, list.descriptor_offset); } } } header->component_count = count; return true; } /*}}}*/ static bool unshield_header_get_file_groups(Header* header)/*{{{*/ { int count = 0; int i; int available = 16; header->file_groups = malloc(available * sizeof(UnshieldFileGroup*)); for (i = 0; i < MAX_FILE_GROUP_COUNT; i++) { if (header->cab.file_group_offsets[i]) { OffsetList list; list.next_offset = header->cab.file_group_offsets[i]; while (list.next_offset) { uint8_t* p = unshield_header_get_buffer(header, list.next_offset); list.name_offset = READ_UINT32(p); p += 4; list.descriptor_offset = READ_UINT32(p); p += 4; list.next_offset = READ_UINT32(p); p += 4; if (count == available) { available <<= 1; header->file_groups = realloc(header->file_groups, available * sizeof(UnshieldFileGroup*)); } header->file_groups[count++] = unshield_file_group_new(header, list.descriptor_offset); } } } header->file_group_count = count; return true; } /*}}}*/ /** Read all header files */ static bool unshield_read_headers(Unshield* unshield, int version)/*{{{*/ { int i; bool iterate = true; Header* previous = NULL; if (unshield->header_list) { unshield_warning("Already have a header list"); return true; } for (i = 1; iterate; i++) { FILE* file = unshield_fopen_for_reading(unshield, i, HEADER_SUFFIX); if (file) { unshield_trace("Reading header from .hdr file %i.", i); iterate = false; } else { unshield_trace("Could not open .hdr file %i. Reading header from .cab file %i instead.", i, i); file = unshield_fopen_for_reading(unshield, i, CABINET_SUFFIX); } if (file) { size_t bytes_read; Header* header = NEW1(Header); header->index = i; header->size = FSIZE(file); if (header->size < 4) { unshield_error("Header file %i too small", i); goto error; } header->data = malloc(header->size); if (!header->data) { unshield_error("Failed to allocate memory for header file %i", i); goto error; } bytes_read = fread(header->data, 1, header->size, file); FCLOSE(file); if (bytes_read != header->size) { unshield_error("Failed to read from header file %i. Expected = %i, read = %i", i, header->size, bytes_read); goto error; } if (!unshield_get_common_header(header)) { unshield_error("Failed to read common header from header file %i", i); goto error; } if (version != -1) { header->major_version = version; } else if (header->common.version >> 24 == 1) { header->major_version = (header->common.version >> 12) & 0xf; } else if (header->common.version >> 24 == 2 || header->common.version >> 24 == 4) { header->major_version = (header->common.version & 0xffff); if (header->major_version != 0) header->major_version = header->major_version / 100; } #if 0 if (header->major_version < 5) header->major_version = 5; #endif unshield_trace("Version 0x%08x handled as major version %i", header->common.version, header->major_version); if (!unshield_get_cab_descriptor(header)) { unshield_error("Failed to read CAB descriptor from header file %i", i); goto error; } if (!unshield_get_file_table(header)) { unshield_error("Failed to read file table from header file %i", i); goto error; } if (!unshield_header_get_components(header)) { unshield_error("Failed to read components from header file %i", i); goto error; } if (!unshield_header_get_file_groups(header)) { unshield_error("Failed to read file groups from header file %i", i); goto error; } if (previous) previous->next = header; else previous = unshield->header_list = header; continue; error: if (header) FREE(header->data); FREE(header); iterate = false; } else iterate = false; } return (unshield->header_list != NULL); }/*}}}*/ Unshield* unshield_open(const char* filename)/*{{{*/ { return unshield_open_force_version(filename, -1); }/*}}}*/ Unshield* unshield_open_force_version(const char* filename, int version)/*{{{*/ { Unshield* unshield = NEW1(Unshield); if (!unshield) { unshield_error("Failed to allocate memory for Unshield structure"); goto error; } if (!unshield_create_filename_pattern(unshield, filename)) { unshield_error("Failed to create filename pattern"); goto error; } if (!unshield_read_headers(unshield, version)) { unshield_error("Failed to read header files"); goto error; } return unshield; error: unshield_close(unshield); return NULL; }/*}}}*/ static void unshield_free_string_buffers(Header* header) { StringBuffer* current = header->string_buffer; header->string_buffer = NULL; while (current != NULL) { StringBuffer* next = current->next; FREE(current->string); FREE(current); current = next; } } void unshield_close(Unshield* unshield)/*{{{*/ { if (unshield) { Header* header; for(header = unshield->header_list; header; ) { Header* next = header->next; int i; unshield_free_string_buffers(header); if (header->components) { for (i = 0; i < header->component_count; i++) unshield_component_destroy(header->components[i]); free(header->components); } if (header->file_groups) { for (i = 0; i < header->file_group_count; i++) unshield_file_group_destroy(header->file_groups[i]); free(header->file_groups); } if (header->file_descriptors) { for (i = 0; i < (int)header->cab.file_count; i++) FREE(header->file_descriptors[i]); free(header->file_descriptors); } FREE(header->file_table); FREE(header->data); FREE(header); header = next; } FREE(unshield->filename_pattern); free(unshield); } }/*}}}*/ bool unshield_is_unicode(Unshield* unshield) { if (unshield) { Header* header = unshield->header_list; return header->major_version >= 17; } else return false; } unshield-1.5.1/lib/libunshield.h000066400000000000000000000047341415320644200165630ustar00rootroot00000000000000/* $Id$ */ #ifndef __unshield_h__ #define __unshield_h__ #include #include #define UNSHIELD_LOG_LEVEL_LOWEST 0 #define UNSHIELD_LOG_LEVEL_ERROR 1 #define UNSHIELD_LOG_LEVEL_WARNING 2 #define UNSHIELD_LOG_LEVEL_TRACE 3 #define UNSHIELD_LOG_LEVEL_HIGHEST 4 #ifdef __cplusplus extern "C" { #endif typedef struct _Unshield Unshield; /* Logging */ void unshield_set_log_level(int level); /* Open/close functions */ Unshield* unshield_open(const char* filename); Unshield* unshield_open_force_version(const char* filename, int version); void unshield_close(Unshield* unshield); /* Component functions */ typedef struct { const char* name; unsigned file_group_count; const char** file_group_names; } UnshieldComponent; int unshield_component_count (Unshield* unshield); const char* unshield_component_name (Unshield* unshield, int index); /* File group functions */ typedef struct { const char* name; unsigned first_file; unsigned last_file; } UnshieldFileGroup; int unshield_file_group_count (Unshield* unshield); UnshieldFileGroup* unshield_file_group_get (Unshield* unshield, int index); UnshieldFileGroup* unshield_file_group_find (Unshield* unshield, const char* name); const char* unshield_file_group_name (Unshield* unshield, int index); /* Directory functions */ int unshield_directory_count (Unshield* unshield); const char* unshield_directory_name (Unshield* unshield, int index); /* File functions */ int unshield_file_count (Unshield* unshield); const char* unshield_file_name (Unshield* unshield, int index); bool unshield_file_is_valid (Unshield* unshield, int index); bool unshield_file_save (Unshield* unshield, int index, const char* filename); int unshield_file_directory (Unshield* unshield, int index); size_t unshield_file_size (Unshield* unshield, int index); /** For investigation of compressed data */ bool unshield_file_save_raw(Unshield* unshield, int index, const char* filename); /** Maybe it's just gzip without size? */ bool unshield_file_save_old(Unshield* unshield, int index, const char* filename); /** Deobfuscate a buffer. Seed is 0 at file start */ void unshield_deobfuscate(unsigned char* buffer, size_t size, unsigned* seed); /** Is the archive Unicode-capable? */ bool unshield_is_unicode(Unshield* unshield); #ifdef __cplusplus } #endif #endif unshield-1.5.1/lib/log.c000066400000000000000000000007701415320644200150310ustar00rootroot00000000000000/* $Id */ #include "log.h" #include #include /* evil static data */ static int current_log_level = UNSHIELD_LOG_LEVEL_HIGHEST; void unshield_set_log_level(int level) { current_log_level = level; } void _unshield_log(int level, const char* file, int line, const char* format, ...) { va_list ap; if (level > current_log_level) return; fprintf(stderr, "[%s:%i] ", file, line); va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap); fprintf(stderr, "\n"); } unshield-1.5.1/lib/log.h000066400000000000000000000014561415320644200150400ustar00rootroot00000000000000/* $Id$ */ #ifndef __log_h__ #define __log_h__ #include "internal.h" #define UNSHIELD_LOG_LEVEL_LOWEST 0 #define UNSHIELD_LOG_LEVEL_ERROR 1 #define UNSHIELD_LOG_LEVEL_WARNING 2 #define UNSHIELD_LOG_LEVEL_TRACE 3 #define UNSHIELD_LOG_LEVEL_HIGHEST 4 #ifdef __cplusplus extern "C" { #endif void _unshield_log(int level, const char* file, int line, const char* format, ...); #define unshield_trace(format, ...) \ _unshield_log(UNSHIELD_LOG_LEVEL_TRACE,__FUNCTION__, __LINE__, format, ##__VA_ARGS__) #define unshield_warning(format, ...) \ _unshield_log(UNSHIELD_LOG_LEVEL_WARNING,__FUNCTION__, __LINE__, format, ##__VA_ARGS__) #define unshield_error(format, ...) \ _unshield_log(UNSHIELD_LOG_LEVEL_ERROR,__FUNCTION__, __LINE__, format, ##__VA_ARGS__) #ifdef __cplusplus } #endif #endif unshield-1.5.1/lib/md5/000077500000000000000000000000001415320644200145655ustar00rootroot00000000000000unshield-1.5.1/lib/md5/CMakeLists.txt000066400000000000000000000003341415320644200173250ustar00rootroot00000000000000set(LIBMD5_UTF_HEADES "global.h" "md5.h" ) set(LIBMD5_UTF_SOURCES "md5c.c" ) if(BUILD_STATIC AND MSVC) set_msvc_runtime_static() endif() add_library(md5 STATIC ${LIBMD5_UTF_HEADES} ${LIBMD5_UTF_SOURCES}) unshield-1.5.1/lib/md5/global.h000066400000000000000000000014101415320644200161720ustar00rootroot00000000000000/* GLOBAL.H - RSAREF types and constants */ /* PROTOTYPES should be set to one if and only if the compiler supports function argument prototyping. The following makes PROTOTYPES default to 0 if it has not already been defined with C compiler flags. */ #ifndef PROTOTYPES #define PROTOTYPES 0 #endif /* POINTER defines a generic pointer type */ typedef unsigned char *POINTER; /* UINT2 defines a two byte word */ typedef unsigned short int UINT2; /* UINT4 defines a four byte word */ typedef unsigned int UINT4; /* PROTO_LIST is defined depending on how PROTOTYPES is defined above. If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it returns an empty list. */ #if PROTOTYPES #define PROTO_LIST(list) list #else #define PROTO_LIST(list) () #endif unshield-1.5.1/lib/md5/md5.h000066400000000000000000000025061415320644200154260ustar00rootroot00000000000000/* MD5.H - header file for MD5C.C */ /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved. License to copy and use this software is granted provided that it is identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing this software or this function. License is also granted to make and use derivative works provided that such works are identified as "derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing the derived work. RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided "as is" without express or implied warranty of any kind. These notices must be retained in any copies of any part of this documentation and/or software. */ /* MD5 context. */ typedef struct { UINT4 state[4]; /* state (ABCD) */ UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ unsigned char buffer[64]; /* input buffer */ } MD5_CTX; void MD5Init PROTO_LIST ((MD5_CTX *)); void MD5Update PROTO_LIST ((MD5_CTX *, unsigned char *, unsigned int)); void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *)); unshield-1.5.1/lib/md5/md5c.c000066400000000000000000000243071415320644200155670ustar00rootroot00000000000000/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm */ /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved. License to copy and use this software is granted provided that it is identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing this software or this function. License is also granted to make and use derivative works provided that such works are identified as "derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing the derived work. RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided "as is" without express or implied warranty of any kind. These notices must be retained in any copies of any part of this documentation and/or software. */ #include "global.h" #include "md5.h" /* Constants for MD5Transform routine. */ #define S11 7 #define S12 12 #define S13 17 #define S14 22 #define S21 5 #define S22 9 #define S23 14 #define S24 20 #define S31 4 #define S32 11 #define S33 16 #define S34 23 #define S41 6 #define S42 10 #define S43 15 #define S44 21 static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64])); static void Encode PROTO_LIST ((unsigned char *, UINT4 *, unsigned int)); static void Decode PROTO_LIST ((UINT4 *, unsigned char *, unsigned int)); static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int)); static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int)); static unsigned char PADDING[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* F, G, H and I are basic MD5 functions. */ #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) #define H(x, y, z) ((x) ^ (y) ^ (z)) #define I(x, y, z) ((y) ^ ((x) | (~z))) /* ROTATE_LEFT rotates x left n bits. */ #define ROTATE_LEFT(x, n) ((((x) << (n)) & 0xffffffffU) | ((x) >> (32-(n)))) /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. Rotation is separate from addition to prevent recomputation. */ #define FF(a, b, c, d, x, s, ac) { \ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define GG(a, b, c, d, x, s, ac) { \ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define HH(a, b, c, d, x, s, ac) { \ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define II(a, b, c, d, x, s, ac) { \ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } /* MD5 initialization. Begins an MD5 operation, writing a new context. */ void MD5Init (context) MD5_CTX *context; /* context */ { context->count[0] = context->count[1] = 0; /* Load magic initialization constants. */ context->state[0] = 0x67452301; context->state[1] = 0xefcdab89; context->state[2] = 0x98badcfe; context->state[3] = 0x10325476; } /* MD5 block update operation. Continues an MD5 message-digest operation, processing another message block, and updating the context. */ void MD5Update (context, input, inputLen) MD5_CTX *context; /* context */ unsigned char *input; /* input block */ unsigned int inputLen; /* length of input block */ { unsigned int i, index, partLen; /* Compute number of bytes mod 64 */ index = (unsigned int)((context->count[0] >> 3) & 0x3F); /* Update number of bits */ if ((context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3)) context->count[1]++; context->count[1] += ((UINT4)inputLen >> 29); partLen = 64 - index; /* Transform as many times as possible. */ if (inputLen >= partLen) { MD5_memcpy ((POINTER)&context->buffer[index], (POINTER)input, partLen); MD5Transform (context->state, context->buffer); for (i = partLen; i + 63 < inputLen; i += 64) MD5Transform (context->state, &input[i]); index = 0; } else i = 0; /* Buffer remaining input */ MD5_memcpy ((POINTER)&context->buffer[index], (POINTER)&input[i], inputLen-i); } /* MD5 finalization. Ends an MD5 message-digest operation, writing the the message digest and zeroizing the context. */ void MD5Final (digest, context) unsigned char digest[16]; /* message digest */ MD5_CTX *context; /* context */ { unsigned char bits[8]; unsigned int index, padLen; /* Save number of bits */ Encode (bits, context->count, 8); /* Pad out to 56 mod 64. */ index = (unsigned int)((context->count[0] >> 3) & 0x3f); padLen = (index < 56) ? (56 - index) : (120 - index); MD5Update (context, PADDING, padLen); /* Append length (before padding) */ MD5Update (context, bits, 8); /* Store state in digest */ Encode (digest, context->state, 16); /* Zeroize sensitive information. */ MD5_memset ((POINTER)context, 0, sizeof (*context)); } /* MD5 basic transformation. Transforms state based on block. */ static void MD5Transform (state, block) UINT4 state[4]; unsigned char block[64]; { UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; Decode (x, block, 64); /* Round 1 */ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ /* Round 2 */ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ /* Round 3 */ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ /* Round 4 */ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ state[0] += a; state[1] += b; state[2] += c; state[3] += d; /* Zeroize sensitive information. */ MD5_memset ((POINTER)x, 0, sizeof (x)); } /* Encodes input (UINT4) into output (unsigned char). Assumes len is a multiple of 4. */ static void Encode (output, input, len) unsigned char *output; UINT4 *input; unsigned int len; { unsigned int i, j; for (i = 0, j = 0; j < len; i++, j += 4) { output[j] = (unsigned char)(input[i] & 0xff); output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); } } /* Decodes input (unsigned char) into output (UINT4). Assumes len is a multiple of 4. */ static void Decode (output, input, len) UINT4 *output; unsigned char *input; unsigned int len; { unsigned int i, j; for (i = 0, j = 0; j < len; i++, j += 4) output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); } /* Note: Replace "for loop" with standard memcpy if possible. */ static void MD5_memcpy (output, input, len) POINTER output; POINTER input; unsigned int len; { unsigned int i; for (i = 0; i < len; i++) output[i] = input[i]; } /* Note: Replace "for loop" with standard memset if possible. */ static void MD5_memset (output, value, len) POINTER output; int value; unsigned int len; { unsigned int i; for (i = 0; i < len; i++) ((char *)output)[i] = (char)value; } unshield-1.5.1/lib/unshield_config.h.in000066400000000000000000000044301415320644200200170ustar00rootroot00000000000000/* Define to 1 if you have the header file. */ #cmakedefine HAVE_BYTESWAP_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_DLFCN_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_INTTYPES_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_MEMORY_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STDBOOL_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STDLIB_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STRING_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_BYTESWAP_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_UNISTD_H 1 /* Name of package */ #define PACKAGE "@PROJECT_NAME@" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "" /* Define to the full name of this package. */ #define PACKAGE_NAME "@PROJECT_NAME@" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "@PROJECT_NAME@ @PROJECT_VERSION@" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "@PROJECT_NAME@" /* Define to the home page for this package. */ #define PACKAGE_URL "" /* Define to the version of this package. */ #define PACKAGE_VERSION "@PROJECT_VERSION@" /* printf format that works with size_t values */ #cmakedefine SIZE_FORMAT "@SIZE_FORMAT@" /* Define to 1 if your system has a working POSIX `fnmatch' function. */ #cmakedefine HAVE_FNMATCH 1 /* Define to 1 if your system has a working POSIX `iconv' function. */ #cmakedefine HAVE_ICONV 1 /* Defined if we should use our own MD5 routines. */ #cmakedefine01 USE_OUR_OWN_MD5 /* Version number of package */ #define VERSION "@PROJECT_VERSION@" /* Enable GNU style printf formatters */ #define __USE_MINGW_ANSI_STDIO 1 unshield-1.5.1/libunshield.pc.in000066400000000000000000000004771415320644200165750ustar00rootroot00000000000000prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=@CMAKE_INSTALL_FULL_BINDIR@ libdir=@CMAKE_INSTALL_FULL_LIBDIR@ includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ Name: libunshield Description: Library to extract CAB files from InstallShield installers Version: @PROJECT_VERSION@ Libs: -L${libdir} -lunshield Cflags: -I${includedir} unshield-1.5.1/man/000077500000000000000000000000001415320644200141055ustar00rootroot00000000000000unshield-1.5.1/man/unshield.1000066400000000000000000000032741415320644200160100ustar00rootroot00000000000000.TH UNSHIELD "1" "July 2004" "The SynCE project" "http://www.synce.org" .SH NAME unshield \- extract CAB files from an InstallShield installer archive .SH SYNOPSIS unshield [\-c COMPONENT] [\-d DIRECTORY] [\-D LEVEL] [\-g GROUP] [\-h] [\-i VERSION] [\-j] [\-L] [\-n] [\-o] [\-O] [\-r] [\-v] [\-V] c|g|l|t|x CABFILE .SH DESCRIPTION Unshield extracts CAB files from InstallShield installers, used to install software on Microsoft Windows based machines. .SH OPTIONS .TP \fB\-c\fR COMPONENT Only list/extract this component .TP \fB\-d\fR DIRECTORY Extract files to DIRECTORY .TP \fB\-D\fR LEVEL Set debug log level 0 \- No logging (default) 1 \- Errors only 2 \- Errors and warnings 3 \- Errors, warnings and debug messages .TP \fB\-g\fR GROUP Only list/extract this file group .TP \fB\-h\fR Show help message .TP \fB\-i\fR VERSION Force InstallShield version number (don't autodetect)\n .br Use this option if you have a very old archive (generated with InstallShield <= 4) and / or the automatic detection fails .TP \fB\-j\fR Junk paths (do not make directories) .TP \fB\-L\fR Make file and directory names lowercase .TP \fB\-n\fR Never overwrite files .TP \fB\-o\fR Always overwrite files .TP \fB\-O\fR Use old compression .TP \fB\-r\fR Save raw data (do not decompress) .TP \fB\-R\fR Don't do any conversion to file and directory names when extracting. .TP \fB\-v\fR Be verbose .TP \fB\-V\fR Print version information .SS "Commands:" .TP c List components .TP g List file groups .TP l List files .TP t Test files .TP x Extract files .SS "Other:" .TP CABFILE The InstallShield installer file to act upon .SH "AUTHOR" This manual page was adapted by Mark Ellis , from the skeleton generated by help2man unshield-1.5.1/rebuild.sh000077500000000000000000000002641415320644200153210ustar00rootroot00000000000000#!/bin/sh set -e set -x export CFLAGS="-Wall -Werror -ggdb3" cd `dirname $0` mkdir -p build cd build cmake -DCMAKE_INSTALL_PREFIX:PATH=/var/tmp/unshield .. && make && make install unshield-1.5.1/run-tests.sh000077500000000000000000000004371415320644200156410ustar00rootroot00000000000000#!/bin/bash ALL_RET=0 for SCRIPT in $(find $(dirname $0)/test/v* -name '*.sh'); do echo -n "Running test $SCRIPT..." bash ${SCRIPT} TEST_RET=$? if [ "$TEST_RET" = "0" ]; then echo "succeeded" else echo "FAILED with code $TEST_RET" ALL_RET=1 fi done exit $ALL_RET unshield-1.5.1/src/000077500000000000000000000000001415320644200141215ustar00rootroot00000000000000unshield-1.5.1/src/CMakeLists.txt000066400000000000000000000015471415320644200166700ustar00rootroot00000000000000LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir) IF("${isSystemDir}" STREQUAL "-1") SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}") endif() add_executable(unshield "unshield.c") target_link_libraries(unshield libunshield) if(WIN32) if(HAVE_ICONV) target_link_libraries(unshield iconv) endif() target_link_libraries(unshield ${ZLIB_LIBRARIES}) endif() add_executable(unshield-deobfuscate "unshield-deobfuscate.c") target_link_libraries(unshield-deobfuscate libunshield) if(WIN32) target_link_libraries(unshield-deobfuscate ${ZLIB_LIBRARIES}) endif() if(BUILD_STATIC AND MSVC) set_msvc_runtime_static() endif() install(TARGETS unshield RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) unshield-1.5.1/src/unshield-deobfuscate.c000066400000000000000000000017721415320644200203710ustar00rootroot00000000000000#include #include #include "../lib/libunshield.h" int main(int argc, char** argv) { unsigned seed = 0; FILE* input = NULL; FILE* output = NULL; size_t size; unsigned char buffer[16384]; if (argc != 3) { fprintf(stderr, "Syntax:\n" " %s INPUT-FILE OUTPUT-FILE\n", argv[0]); exit(1); } input = fopen(argv[1], "rb"); if (!input) { fprintf(stderr, "Failed to open %s for reading\n", argv[1]); exit(2); } output = fopen(argv[2], "wb"); if (!output) { fprintf(stderr, "Failed to open %s for writing\n", argv[2]); exit(3); } while ((size = fread(buffer, 1, sizeof(buffer), input)) != 0) { unshield_deobfuscate(buffer, size, &seed); if (fwrite(buffer, 1, size, output) != size) { fprintf(stderr, "Failed to write %lu bytes to %s\n", (unsigned long)size, argv[2]); exit(4); } } fclose(input); fclose(output); return 0; } unshield-1.5.1/src/unshield.c000066400000000000000000000450051415320644200161040ustar00rootroot00000000000000/* $Id$ */ #ifdef __linux__ #define _BSD_SOURCE 1 #define _DEFAULT_SOURCE 1 #define _POSIX_C_SOURCE 2 #endif #include #include #include #include #include #include #include #include #include #include "../lib/libunshield.h" #ifdef HAVE_CONFIG_H #include "lib/unshield_config.h" #endif #if HAVE_FNMATCH #include #endif #ifdef HAVE_ICONV #include #include #endif #ifndef VERSION #define VERSION "Unknown" #endif #define FREE(ptr) { if (ptr) { free(ptr); ptr = NULL; } } #ifdef _WIN32 #define realpath(N,R) _fullpath((R),(N),_MAX_PATH) #include #ifndef PATH_MAX #define PATH_MAX _MAX_PATH #endif #else #include #endif #ifndef NAME_MAX #define NAME_MAX FILENAME_MAX #endif typedef enum { OVERWRITE_ASK, OVERWRITE_NEVER, OVERWRITE_ALWAYS, } OVERWRITE; typedef enum { ACTION_EXTRACT, ACTION_LIST_COMPONENTS, ACTION_LIST_FILE_GROUPS, ACTION_LIST_FILES, ACTION_TEST } ACTION; typedef enum { FORMAT_NEW, FORMAT_OLD, FORMAT_RAW } FORMAT; #define DEFAULT_OUTPUT_DIRECTORY "." static const char* output_directory = DEFAULT_OUTPUT_DIRECTORY; static const char* file_group_name = NULL; static const char* component_name = NULL; static bool junk_paths = false; static bool make_lowercase = false; static bool raw_filename = false; static bool verbose = false; static ACTION action = ACTION_EXTRACT; static OVERWRITE overwrite = OVERWRITE_ASK; static int log_level = UNSHIELD_LOG_LEVEL_LOWEST; static int exit_status = 0; static FORMAT format = FORMAT_NEW; static int is_version = -1; static const char* cab_file_name = NULL; static char* const* path_names = NULL; static int path_name_count = 0; #ifdef HAVE_ICONV static const char* encoding = NULL; iconv_t encoding_descriptor = (iconv_t)-1; #endif static bool make_sure_directory_exists(const char* directory)/*{{{*/ { struct stat dir_stat; const char* p = directory; bool success = false; char* current = NULL; while (p && *p) { if ('/' == *p) p++; else if (0 == strncmp(p, "./", 2)) p+=2; else if (0 == strncmp(p, "../", 3)) p+=3; else { const char* slash = strchr(p, '/'); current = strdup(directory); if (slash) current[slash-directory] = '\0'; if (stat(current, &dir_stat) < 0) { #if defined (__MINGW32__) || defined (_WIN32) if (_mkdir(current) < 0) #else if (mkdir(current, 0700) < 0) #endif { fprintf(stderr, "Failed to create directory %s\n", directory); if(strlen(directory)>NAME_MAX) fprintf(stderr, "Directory name must be less than %i characters\n", NAME_MAX+1); goto exit; } } p = slash; FREE(current); } } success = true; exit: FREE(current); return success; }/*}}}*/ #ifdef HAVE_ICONV static bool convert_encoding(char *buffer, size_t size) { bool success = false; char *newbuf, *inbuf, *outbuf; size_t inbytesleft, outbytesleft, newsize; if (encoding_descriptor == (iconv_t)-1) return true; inbuf = buffer; inbytesleft = strlen(buffer); newbuf = outbuf = malloc(size); outbytesleft = size - 1; if (iconv(encoding_descriptor, &inbuf, &inbytesleft, &outbuf, &outbytesleft) == (size_t)-1) { fprintf(stderr, "Could not encode text to '%s' error %s\n", encoding, strerror(errno)); goto exit; } newsize = (size_t)(outbuf - newbuf); memcpy(buffer, newbuf, newsize); buffer[newsize] = '\0'; success = true; exit: free(newbuf); return success; } #endif static void show_usage(const char* name) { fprintf(stderr, "Syntax:\n" "\n" "\t%s [-c COMPONENT] [-d DIRECTORY] [-D LEVEL] [-g GROUP] [-i VERSION] [-e ENCODING] [-GhlOrV] c|g|l|t|x CABFILE [FILENAME...]\n" "\n" "Options:\n" "\t-c COMPONENT Only list/extract this component\n" "\t-d DIRECTORY Extract files to DIRECTORY\n" "\t-D LEVEL Set debug log level\n" "\t 0 - No logging (default)\n" "\t 1 - Errors only\n" "\t 2 - Errors and warnings\n" "\t 3 - Errors, warnings and debug messages\n" "\t-g GROUP Only list/extract this file group\n" "\t-h Show this help message\n" "\t-i VERSION Force InstallShield version number (don't autodetect)\n" "\t-e ENCODING Convert filename character encoding to local codepage from ENCODING (implicitly sets -R)\n" "\t-j Junk paths (do not make directories)\n" "\t-L Make file and directory names lowercase\n" "\t-O Use old compression\n" "\t-r Save raw data (do not decompress)\n" "\t-R Don't do any conversion to file and directory names when extracting.\n" "\t-V --version Print copyright and version information\n" "\n" "Commands:\n" "\tc List components\n" "\tg List file groups\n" "\tl List files\n" "\tt Test files\n" "\tx Extract files\n" "\n" "Other:\n" "\tCABFILE The file to list or extract contents of\n" "\tFILENAME... Optionally specify names of specific files to extract" #if HAVE_FNMATCH " (wildcards are supported)" #endif "\n" , name); #if 0 "\t-n Never overwrite files\n" "\t-o Overwrite files WITHOUT prompting\n" "\t-v Verbose output\n" #endif } static bool handle_parameters( int argc, char* const argv[]) { int c; static struct option long_options[] = { { "version", no_argument, NULL, 'V' }, { NULL, 0, NULL, 0 } }; while ((c = getopt_long(argc, argv, "c:d:D:g:hi:e:jLnoOrRV", long_options, NULL)) != -1) { switch (c) { case 'c': component_name = optarg; break; case 'd': output_directory = optarg; break; case 'D': log_level = atoi(optarg); break; case 'g': file_group_name = optarg; break; case 'i': is_version = atoi(optarg); break; case 'e': #ifdef HAVE_ICONV encoding = optarg; raw_filename = true; #else fprintf(stderr, "This version of Unshield is not built with encoding support.\n"); return false; #endif break; case 'j': junk_paths = true; break; case 'L': make_lowercase = true; break; case 'R': raw_filename = true; break; case 'n': overwrite = OVERWRITE_NEVER; break; case 'o': overwrite = OVERWRITE_ALWAYS; break; case 'O': format = FORMAT_OLD; break; case 'r': format = FORMAT_RAW; break; case 'v': verbose = true; break; case 'V': printf("Unshield version " VERSION ". MIT License. (C) 2003-2021 David Eriksson.\n"); exit(0); break; case 'h': default: show_usage(argv[0]); return false; } } unshield_set_log_level(log_level); if (optind == argc || !argv[optind]) { fprintf(stderr, "No action provided on command line.\n\n"); show_usage(argv[0]); return false; } char action_char = argv[optind++][0]; switch (action_char) { case 'c': action = ACTION_LIST_COMPONENTS; break; case 'g': action = ACTION_LIST_FILE_GROUPS; break; case 'l': action = ACTION_LIST_FILES; break; case 't': action = ACTION_TEST; break; case 'x': action = ACTION_EXTRACT; break; default: fprintf(stderr, "Unknown action '%c' on command line.\n\n", action_char); show_usage(argv[0]); return false; } cab_file_name = argv[optind++]; if (cab_file_name == NULL) { fprintf(stderr, "No InstallShield Cabinet File name provided on command line.\n\n"); show_usage(argv[0]); return false; } path_name_count = argc - optind; path_names = &argv[optind]; return true; } static bool extract_file(Unshield* unshield, const char* prefix, int index) { bool success; char* dirname; char* filename; char* p; int directory = unshield_file_directory(unshield, index); long int path_max; char* real_output_directory; char* real_filename; #ifdef PATH_MAX path_max = PATH_MAX; #else path_max = pathconf(prefix, _PC_PATH_MAX); if (path_max <= 0) path_max = 4096; #endif real_output_directory = malloc(path_max); real_filename = malloc(path_max); dirname = malloc(path_max); filename = malloc(path_max); if (real_output_directory == NULL || real_filename == NULL) { fprintf(stderr,"Unable to allocate memory."); success=false; goto exit; } if(strlen(output_directory) < path_max-1) { strncpy(dirname, output_directory,path_max-1); if (path_max > 0) dirname[path_max - 1]= '\0'; strcat(dirname, "/"); } else { fprintf(stderr, "\nOutput directory exceeds maximum path length.\n"); success = false; goto exit; } if (prefix && prefix[0]) { if(strlen(dirname)+strlen(prefix) < path_max-1) { strcat(dirname, prefix); strcat(dirname, "/"); } else { fprintf(stderr, "\nOutput directory exceeds maximum path length.\n"); success = false; goto exit; } } if (!junk_paths && directory >= 0) { const char* tmp = unshield_directory_name(unshield, directory); if (tmp && tmp[0]) { if(strlen(dirname)+strlen(tmp) < path_max-1) { strcat(dirname, tmp); strcat(dirname, "/"); } else { fprintf(stderr, "\nOutput directory exceeds maximum path length.\n"); success = false; goto exit; } } } for (p = dirname + strlen(output_directory); *p != '\0'; p++) { switch (*p) { case '\\': *p = '/'; break; case ' ': case '<': case '>': case '[': case ']': *p = '_'; break; default: if (!raw_filename) { if (!isprint(*p)) *p = '_'; else if (make_lowercase) *p = tolower(*p); } break;; } } #ifdef HAVE_ICONV if (!convert_encoding(dirname, path_max)) { success = false; goto exit; } #endif #if 0 if (dirname[strlen(dirname)-1] != '/') strcat(dirname, "/"); #endif make_sure_directory_exists(dirname); snprintf(filename, path_max, "%s%s", dirname, unshield_file_name(unshield, index)); for (p = filename + strlen(dirname); *p != '\0'; p++) { if (!raw_filename) { if (!isprint(*p)) *p = '_'; else if (make_lowercase) *p = tolower(*p); } } #ifdef HAVE_ICONV if (!convert_encoding(filename + strlen(dirname), path_max - strlen(dirname))) { success = false; goto exit; } #endif #ifdef __GLIBC__ /* use GNU extension to return non-existing files to real_output_directory */ realpath(output_directory, real_output_directory); realpath(filename, real_filename); if (real_filename == NULL || strncmp(real_filename, real_output_directory, strlen(real_output_directory)) != 0) { fprintf(stderr, "\n\nExtraction failed.\n"); fprintf(stderr, "Error: %s (%d).\n", strerror(errno), errno); fprintf(stderr, "Possible directory traversal attack for: %s\n", filename); fprintf(stderr, "To be placed at: %s\n\n", real_filename); success = false; goto exit; } #endif printf(" extracting: %s\n", filename); switch (format) { case FORMAT_NEW: success = unshield_file_save(unshield, index, filename); break; case FORMAT_OLD: success = unshield_file_save_old(unshield, index, filename); break; case FORMAT_RAW: success = unshield_file_save_raw(unshield, index, filename); break; } exit: if (!success) { fprintf(stderr, "Failed to extract file '%s'.%s\n", unshield_file_name(unshield, index), (log_level < 3) ? "Run unshield again with -D 3 for more information." : ""); unlink(filename); exit_status = 1; } free(real_filename); free(real_output_directory); free(dirname); free(filename); return success; } static bool should_process_file(Unshield* unshield, int index) { int i; if (path_name_count == 0) return true; for (i = 0; i < path_name_count; i++) { #if HAVE_FNMATCH if (fnmatch(path_names[i], unshield_file_name(unshield, index), 0) == 0) return true; #else if (strcmp(path_names[i], unshield_file_name(unshield, index)) == 0) return true; #endif } return false; } static int extract_helper(Unshield* unshield, const char* prefix, int first, int last)/*{{{*/ { int i; int count = 0; for (i = first; i <= last; i++) { if (unshield_file_is_valid(unshield, i) && should_process_file(unshield, i) && extract_file(unshield, prefix, i)) count++; } return count; }/*}}}*/ static bool test_file(Unshield* unshield, int index) { bool success; printf(" testing: %s\n", unshield_file_name(unshield, index)); switch (format) { case FORMAT_NEW: success = unshield_file_save(unshield, index, NULL); break; case FORMAT_OLD: success = unshield_file_save_old(unshield, index, NULL); break; case FORMAT_RAW: success = unshield_file_save_raw(unshield, index, NULL); break; } if (!success) { fprintf(stderr, "Failed to extract file '%s'.%s\n", unshield_file_name(unshield, index), (log_level < 3) ? "Run unshield again with -D 3 for more information." : ""); exit_status = 1; } return success; } static int test_helper(Unshield* unshield, const char* prefix, int first, int last)/*{{{*/ { int i; int count = 0; for (i = first; i <= last; i++) { if (unshield_file_is_valid(unshield, i) && test_file(unshield, i)) count++; } return count; }/*}}}*/ static bool list_components(Unshield* unshield) { int i; int count = unshield_component_count(unshield); if (count < 0) return false; for (i = 0; i < count; i++) { printf("%s\n", unshield_component_name(unshield, i)); } printf("-------\n%i components\n", count); return true; } static bool list_file_groups(Unshield* unshield) { int i; int count = unshield_file_group_count(unshield); if (count < 0) return false; for (i = 0; i < count; i++) { printf("%s\n", unshield_file_group_name(unshield, i)); } printf("-------\n%i file groups\n", count); return true; } static int list_files_helper(Unshield* unshield, const char* prefix, int first, int last)/*{{{*/ { int i; int valid_count = 0; for (i = first; i <= last; i++) { char dirname[4096]; if (unshield_file_is_valid(unshield, i) && should_process_file(unshield, i)) { valid_count++; if (prefix && prefix[0]) { strcpy(dirname, prefix); strcat(dirname, "\\"); } else dirname[0] = '\0'; strcat(dirname, unshield_directory_name(unshield, unshield_file_directory(unshield, i))); #if 0 for (p = dirname + strlen(output_directory); *p != '\0'; p++) if ('\\' == *p) *p = '/'; #endif if (dirname[strlen(dirname)-1] != '\\') strcat(dirname, "\\"); printf(" %8" SIZE_FORMAT " %s%s\n", unshield_file_size(unshield, i), dirname, unshield_file_name(unshield, i)); } } return valid_count; }/*}}}*/ typedef int (*ActionHelper)(Unshield* unshield, const char* prefix, int first, int last); static bool do_action(Unshield* unshield, ActionHelper helper) { int count = 0; if (component_name) { fprintf(stderr, "This action is not implemented for components, sorry! Patch welcome!\n"); return false; } else if (file_group_name) { UnshieldFileGroup* file_group = unshield_file_group_find(unshield, file_group_name); printf("File group: %s\n", file_group_name); if (file_group) count = helper(unshield, file_group_name, file_group->first_file, file_group->last_file); } else { int i; for (i = 0; i < unshield_file_group_count(unshield); i++) { UnshieldFileGroup* file_group = unshield_file_group_get(unshield, i); if (file_group) count += helper(unshield, file_group->name, file_group->first_file, file_group->last_file); } } printf(" -------- -------\n %i files\n", count); return true; } int main(int argc, char* const argv[]) { bool success = false; Unshield* unshield = NULL; setlocale(LC_ALL, ""); if (!handle_parameters(argc, argv)) goto exit; unshield = unshield_open_force_version(cab_file_name, is_version); if (!unshield) { fprintf(stderr, "Failed to open %s as an InstallShield Cabinet File\n", cab_file_name); goto exit; } #ifdef HAVE_ICONV if (!unshield_is_unicode(unshield) && encoding != NULL) { if ((encoding_descriptor = iconv_open("", encoding)) == (iconv_t)-1) { fprintf(stderr, "Cannot use encoding '%s' error %s\n", encoding, strerror(errno)); goto exit; } } #endif printf("Cabinet: %s\n", cab_file_name); switch (action) { case ACTION_EXTRACT: success = do_action(unshield, extract_helper); break; case ACTION_LIST_COMPONENTS: success = list_components(unshield); break; case ACTION_LIST_FILE_GROUPS: success = list_file_groups(unshield); break; case ACTION_LIST_FILES: success = do_action(unshield, list_files_helper); break; case ACTION_TEST: if (strcmp(output_directory, DEFAULT_OUTPUT_DIRECTORY) != 0) fprintf(stderr, "Output directory (-d) option has no effect with test (t) command.\n"); if (make_lowercase) fprintf(stderr, "Make lowercase (-L) option has no effect with test (t) command.\n"); success = do_action(unshield, test_helper); break; } exit: unshield_close(unshield); #ifdef HAVE_ICONV if (encoding_descriptor != (iconv_t)-1) iconv_close(encoding_descriptor); #endif if (!success) exit_status = 1; return exit_status; } unshield-1.5.1/test/000077500000000000000000000000001415320644200143115ustar00rootroot00000000000000unshield-1.5.1/test/v0/000077500000000000000000000000001415320644200146365ustar00rootroot00000000000000unshield-1.5.1/test/v0/avigomanager.md5000066400000000000000000000056651415320644200177210ustar00rootroot00000000000000a943ad8f40479fa5cd68afba5787be4f ./AVIGO/Avigo100.pgm 48c56d5db36b20d0f8644a85d1c33dac ./AVIGO/AvigoMgr.exe 618341f3e7654c8d5d7e13f17bf433f8 ./AVIGO/AvigoToPc.avi 0be37395a851b1d7aaa7039605ec12c9 ./AVIGO/Deu100.alb 72960b3faf8c1845f37d1aac23996e6c ./AVIGO/Download.exe cb4848abcb77130f48b8f9e9cf6d8977 ./AVIGO/Eng100.alb 0e206fc4ef4a922c1de3199465ee5955 ./AVIGO/English/AvigoMan.cnt 9095276ff7bdda4dd35b79d76397410c ./AVIGO/English/Avigoman.hlp 2b212e81224f2bdd608d98fe579c8c4c ./AVIGO/Esp100.alb abc3474a2219fe49c2a2bf2f3e764a64 ./AVIGO/Financial100.app 1f17ba903bc00e2694e6338c0e9bd8c3 ./AVIGO/Fra100.alb 7265699e1bbae3022376e4f18f2e52b7 ./AVIGO/French/AVIGOMAN.HLP df1c526338995596901bcc95ed637f33 ./AVIGO/French/AvigoMan.cnt 64889479798be3d1a682ebd2e1b50452 ./AVIGO/German/AvigoMan.cnt ec267fd5abb90d373e3b9fe6a5762315 ./AVIGO/German/Avigoman.hlp e21adacb76cfff3350a3e82c4f883a44 ./AVIGO/Ita100.alb 048fa624c7f7f9ddf76898f1dd5a5418 ./AVIGO/Italian/AVIGOMAN.HLP 85cf12ce9899c7242233a340dcb10de4 ./AVIGO/Italian/AvigoMan.cnt 54e9447a8133042ba0fa293a2440527b ./AVIGO/PcToAvigo.avi 351f02281421554f722cd7ff749b8576 ./AVIGO/Readme.txt cd8818345ab13e0bf7627035c8a746ad ./AVIGO/Spanish/AVIGOMAN.HLP 676dd602591dceb83799e58c032071f1 ./AVIGO/Spanish/AvigoMan.cnt 77abaeafbb2340ec06bd83da4b3c0418 ./AVIGO/SyncMovie.avi 4aec6b69fd4237a2a0562974e55537ef ./AVIGO/language.lng 9cb48c7068f6d9389493b0f1035ab204 ./AVIGO/translat.lng 5f854403d1e201a397151610fb9c80dd ./AVIGO_DLL's/DLGDLL.dll 54584845c6f232a18e4c8f7c59aeca09 ./AVIGO_DLL's/cw3220.dll 15f24a05040bb34765c852942480dc0d ./AVIGO_DLL's/io_common.dll 5beb2e7cb566e103480f3f4c3b99f006 ./AVIGO_DLL's/io_error.dll b83f81c70983c28252c452fcdce906de ./AVIGO_DLL's/io_ircomm.dll 955db4b34095dc7340c82a8e328c4aa3 ./AVIGO_DLL's/io_obex.dll 989c75747c7b24caacf2e4df0330f45c ./AVIGO_DLL's/io_tiobex.dll 149f277034310ea0e204a5ded4502c26 ./AVIGO_DLL's/tops.dll 41b7178b258b97248a2e31d6771cf6f3 ./AVIGO_DLL's/update.dll 0aba3f8d3a59754306d75c157e1d2b0a ./DAO_Reg/dao350.dll 87a2adf125be51cdd5d8d3843e0f0b7e ./DAO_UnReg/Dao2535.tlb 5caa91bc875bfdfd4066b1abdfcd6831 ./English/Readme.txt 441e965db51513b8e3c22477832641c3 ./OLE_Reg/Olepro32.dll 81a267f80035cb3a7559be4179700931 ./OLE_Unreg/Ole32.dll b9d04a19150d6799c95045719e6e6913 ./OLE_Unreg/Oleaut32.dll 8a7871c9b80a678813ca668338432456 ./System_Reg/msexcl35.dll e8a31571e9b0f79bc30ad7b8afa75c08 ./System_Reg/msjet35.dll 6252deb3dab5e502fcab24183c642563 ./System_Reg/msltus35.dll d74cc7953be48ec1f3deff4741977887 ./System_Reg/msrd2x35.dll 17291135b3146b3c3c9d201b5d65c168 ./System_Reg/mstext35.dll c3f50ecf458c55ac1157b98f74e6ad0f ./System_UnReg/Comctl32.dll 9ba25eab9b071b8ef0799f7b785c4722 ./System_UnReg/Msvcrt40.dll 8472c0e32802199891d76d57879bd9d9 ./System_UnReg/msjint35.dll 5773425a2bb778684b57d042a0cd5247 ./System_UnReg/msjter35.dll 9f8c2ac5719be020bd5fe898fa01f90f ./System_UnReg/vbajet32.dll 9d1864ae5f6ff8bbde86a3f5a448110d ./System_UnReg/vbar332.dll unshield-1.5.1/test/v0/avigomanager.sh000077500000000000000000000020401415320644200176310ustar00rootroot00000000000000#!/bin/bash set -e cd `dirname $0` MD5_FILE=`pwd`/`basename $0 .sh`.md5 UNSHIELD=${UNSHIELD:-/var/tmp/unshield/bin/unshield} if [ \! -x ${UNSHIELD} ]; then echo "unshield executable not found at $UNSHIELD" >&2 exit 1 fi DIR=`mktemp -d` trap 'rm -rf ${DIR}' TERM INT EXIT cd ${DIR} #URL=https://www.ti.com/organizers/avigo/docs/avigomanager11b22.zip URL="https://www.dropbox.com/s/8r4b6752swe3nhu/unshield-avigomanager11b22.zip?dl=1" curl -sSL -o test.zip ${URL} unzip -q test.zip 'data*' set +e timeout 10 ${UNSHIELD} -d extract1 x data1.cab > log1 2>&1 CODE=$? if [ ${CODE} -ne 1 ]; then cat log1 >&2 echo "unshield should have failed with error 1 but was $CODE" >&2 exit 2 fi timeout 10 ${UNSHIELD} -O -d extract2 x data1.cab > log2 2>&1 CODE=$? if [ ${CODE} -ne 0 ]; then cat log2 >&2 echo "unshield failed with error $CODE" >&2 exit 3 fi cd extract2 find . -type f -print0 | LC_ALL=C sort -z | xargs -0 md5sum > ../md5 if ! diff -wu ${MD5_FILE} ../md5 >&2 ; then echo "MD5 sums diff" >&2 exit 4 fi exit 0 unshield-1.5.1/test/v0/baldurs_gate_patch_v1_1_4315_international.md5000066400000000000000000000233461415320644200253210ustar00rootroot00000000000000f44ad46b463b80395ab1d385c81134b7 ./English/dialog.tlk 078f0e7f20f588f64541c75fa5213b16 ./French/dialog.tlk 73b29706c2e3975807347ae56b1baef3 ./French/dialogF.tlk e47065f6607ce2b60b4b47b50e44418e ./German/dialog.tlk d1907ebe55191062a47638c55604fb24 ./German/dialogF.tlk 296d5436b35871c776a0eea17b0d55ab ./Italian/dialog.tlk d0150855642cd5df9c6c6e9e97fd91d5 ./Italian/dialogF.tlk 9cbfa197ac49bea7b44cff3105a31cec ./Language_Independant/BGMain.exe bf31b604845049664a1e71b9832c4ff9 ./Language_Independant/Override/ACTFLAM.bcs d41d8cd98f00b204e9800998ecf8427e ./Language_Independant/Override/AR2100.bcs 5736f7f134173fbc7f928e17825eaf17 ./Language_Independant/Override/AR3300.bcs 0df6f2e721bc839a89fcd02edde1a5f4 ./Language_Independant/Override/Ar0109.ARE 2ad128852e9785ddbadd8f3fe90a7b58 ./Language_Independant/Override/Ar0111.ARE f5a5fccc6df7d21259981ff113058797 ./Language_Independant/Override/Ar0145.ARE c864b455d4566212a5315338a7f28048 ./Language_Independant/Override/Ar0146.ARE c23530ef38b54ad4261c4024540f3337 ./Language_Independant/Override/Ar2300.ARE 9a7bfc5fcbe99792b464189e32607834 ./Language_Independant/Override/Ar2600.ARE bb2ca8bd9fce65af090f7d076bb5cdd8 ./Language_Independant/Override/Ar2608.ARE 5e7fd56e606543b56a6cf8b388440aea ./Language_Independant/Override/Ar2609.ARE a3352f73e9c7323cb97833e1f8fedce2 ./Language_Independant/Override/Ar2610.ARE 9b7010ef7eed7bfd323bc7e242a089ae ./Language_Independant/Override/Ar2611.ARE 2f73eb6c030e2fc818a392af1e95948e ./Language_Independant/Override/Ar2612.ARE d44097f753e3c3bc7632c0ca25f974bf ./Language_Independant/Override/Ar2614.ARE 0bb9921e9cda60f750a1f8e93a48e19e ./Language_Independant/Override/Bendal.dlg efd712d144b8dd63630b652d58905721 ./Language_Independant/Override/Cadder.dlg 00b778d8d99b5a4f19f94541a47b9a0d ./Language_Independant/Override/Caedmo.dlg a4cb1c738ece8b00c3b0f91942f88ea5 ./Language_Independant/Override/Drizzt.bcs 2572ffb826e37f22c3848d0dfbeba7a8 ./Language_Independant/Override/LEAT08.itm ca179d10729d01df68d3c731f696a155 ./Language_Independant/Override/RING09.itm a4adf7fbfda3b1d21a6ff5612338999d ./Language_Independant/Override/Skelwa.CRE ca05124ba6cd3c4faa8682a89053aaca ./Language_Independant/Override/Skelwa02.CRE 2b06acba186f30847a7abb1c1aa3b9aa ./Language_Independant/Override/SpPr403.spl 760bcf9a9706b5e284a3b2041830b905 ./Language_Independant/Override/SpWi107.spl 401500c3c3faf3a631abf0166cb6b58e ./Language_Independant/Override/SpWi116.spl 6f337ee0e7ebe04055fc659be06bab32 ./Language_Independant/Override/Voleta.dlg 0491a372f751668cbd63b1c0a8cd4e89 ./Language_Independant/Override/albert.CRE fe64a508802a4669a2eefc8636943ce3 ./Language_Independant/Override/albert.dlg f6065227952e197037f4a664ef656a04 ./Language_Independant/Override/amnise.dlg 30960cf425e47e89e8f1f4dc2917c7d5 ./Language_Independant/Override/ar0700n.WED 0195dffeb01b85f6bd45e3a821edfdb2 ./Language_Independant/Override/ar1900.bcs 8f9a936979600c240f1e29632aee0874 ./Language_Independant/Override/ar3352.bcs afdc5ac03dce7340c3455647f1db32e9 ./Language_Independant/Override/ar5406.MOS b3ef2dd5547fe36dd6a369d3c42ec65d ./Language_Independant/Override/belt.CRE 5bf45a95bfc33851b5d38748b7529b1f ./Language_Independant/Override/benjy.CRE a0127b3b87addf9d53a2cd899caf743a ./Language_Independant/Override/bjorni.CRE 0fdd621c4bf752b63d88b5ec632ce163 ./Language_Independant/Override/bolt02.itm 65a0412b1bae0c0afa0af4c1fe0558b6 ./Language_Independant/Override/bolt03.itm 492f176e9b115a8bd62739492786219b ./Language_Independant/Override/bolt04.itm 8eeb446b0f02c118d477a9e77768cdd4 ./Language_Independant/Override/bolt05.itm 6ef2de15ee29e51ed88f9e8a0679ae93 ./Language_Independant/Override/bolt06.itm 408e1f21c97a4ddeee02c6f98ccf35d6 ./Language_Independant/Override/boot02.itm 3b67d3bb38e7cb0859b831de73e2a920 ./Language_Independant/Override/bow01.itm da427230ff40667488e8da123bc858e4 ./Language_Independant/Override/bow02.itm 56ccef981ba1c3778a17eee9cb60d49f ./Language_Independant/Override/brage2.CRE 13ef5bd132873f9296eb4d4635e62338 ./Language_Independant/Override/branwe.CRE 655e75b123d88c168e7d19c278a1eb46 ./Language_Independant/Override/calaha.dlg fa50aca69104b6578a8df6cadc220446 ./Language_Independant/Override/chan06.itm 22167d0e6d74356d411f42124370f27f ./Language_Independant/Override/childulg.dlg a1d3a31b9e598ea45a5d45fc4cbb53dc ./Language_Independant/Override/davaeo.CRE deee772fc7fb3e5a849bbb664bca9f41 ./Language_Independant/Override/dink.dlg 0db446157a7d034c1c896a50eb327af7 ./Language_Independant/Override/divine.dlg b64e887c706335f42a300f7935348dd8 ./Language_Independant/Override/dradee.dlg a60c708166b6adb5c6c4c11c0d4fd78b ./Language_Independant/Override/drizzt.CRE d696f9accc2f86f54df842516013808b ./Language_Independant/Override/evalt.dlg 3d84d85860613c6092412ae6b4953669 ./Language_Independant/Override/farthi.dlg 4475aae986b6cc0bd4a0e384efe2ac07 ./Language_Independant/Override/fenrus.dlg 27dc860406637f616c9396bf334528ae ./Language_Independant/Override/fenten.dlg a4dc2c28612f3b6892a3f23b20502c90 ./Language_Independant/Override/firebe.CRE 680781e9ccf32fab8994618c7f865afd ./Language_Independant/Override/flam13.CRE f1e9f431db953e7cc45697adcf4680f0 ./Language_Independant/Override/flam2.dlg bd81430094ae1c047a6ef69ebc558076 ./Language_Independant/Override/ftowbez.dlg bd5c387a4613afb6ee1bcb3d70b51554 ./Language_Independant/Override/ftown2.dlg 0cf1b83d35e21e54f9c1000d22e7b3b3 ./Language_Independant/Override/gandol.dlg 9796cc9316a92b77a35c532e3ec8b74e ./Language_Independant/Override/gatewa2.dlg 163d1d07a68acf1d1118b0d840860722 ./Language_Independant/Override/gatewere.dlg 1e9cb82c54b77174f133765455465021 ./Language_Independant/Override/gnarl.dlg a3c68400b10091a9a68cd130ef55570a ./Language_Independant/Override/gnoll5.bcs 7a407fd1b6b860537771417c2db21276 ./Language_Independant/Override/gnoll5.dlg 1a1be4486488392c982dff51af9ccdc8 ./Language_Independant/Override/gnolldr.bcs d1204551cd327c4d9ea051bd2c56536e ./Language_Independant/Override/husam.dlg 6f1b7a1821c4c55533c2b905f43d4115 ./Language_Independant/Override/islsir.dlg 3fec0eb719f037472c0f93d212a0aaf0 ./Language_Independant/Override/jaheir6.CRE b5db08dd4aa6423b1c714be04b51dfbc ./Language_Independant/Override/jorin.dlg 4231a7055dbf282d49bc3cb4483ec797 ./Language_Independant/Override/kryla.dlg 58d654666cc52b8fc240655e09fec3ea ./Language_Independant/Override/lahl.dlg 7240ae40425fdba71a3d5b4ea6ca1495 ./Language_Independant/Override/liia.CRE 4e9e1acf62d7a42e0829a3500560e816 ./Language_Independant/Override/lothan.dlg 0cc09ec3fed6a0573290203f113eb716 ./Language_Independant/Override/maltz.dlg 8cae66fe89641b4862f509ddf3c0c8fd ./Language_Independant/Override/marale.dlg 6e120e8f604a6fb138b444c6daef7df9 ./Language_Independant/Override/memnis.dlg a13cb3e24b3a1ce88bf6aaf8c30c18a1 ./Language_Independant/Override/misc72.itm 2992b58f9bca3919e5545d2b9db33e00 ./Language_Independant/Override/misc89.itm 2a073fca4785ffe64261608b376584ef ./Language_Independant/Override/mtowbez.dlg 485b5d06cbdcd0d9d58d5397d183e2bf ./Language_Independant/Override/mulahe.CRE d2b720feadcf2ffa27bc5726903c2e95 ./Language_Independant/Override/nadin.dlg dcfe8b78790df6d65ef14a240145b231 ./Language_Independant/Override/nalin.CRE dc854e9da3bb3739fe501017c764c509 ./Language_Independant/Override/narlen.dlg 9189a9a8216a58628e7e1713f88adb7d ./Language_Independant/Override/nikola.CRE 35c08e8869e4c62ef55f22c880961f82 ./Language_Independant/Override/ogrelead.dlg 21d7243f053a64ceb267394822fe7ac5 ./Language_Independant/Override/oublek.dlg 405531ccf46cac6574e093324e5f996b ./Language_Independant/Override/palin.dlg 3721269a403a5ad7970fb113aa4c36a7 ./Language_Independant/Override/potn40.itm 56c493ca7aab27dc1aa94a1649047777 ./Language_Independant/Override/ragefa.CRE 25dc632981540c49aa6d8cf129b1bcc6 ./Language_Independant/Override/ragefa.dlg 4f8adfd0e59f3047615c1392ac64861b ./Language_Independant/Override/ramazi.CRE dc17a97ddfa215d0c7da0afac28e642a ./Language_Independant/Override/ramazi.dlg 3e9f4d5f5261c864e77e2a8175c4f48e ./Language_Independant/Override/sarevo.dlg 7be6d7f2bf5734b4c0dbe93f2ceef6f6 ./Language_Independant/Override/sarevok.bcs 1465c6d411a8f32546a26a189c09dc95 ./Language_Independant/Override/schlum.CRE d772e8dea7973c3a95d341c45552421c ./Language_Independant/Override/schlum1.itm eaeb861e9470bacddd5f9cb39f1c8149 ./Language_Independant/Override/shoal.dlg 459bd037be0ae24ebb6cc10a002a0dcd ./Language_Independant/Override/silenc.dlg 44859c480791275bb8acd6929a862edf ./Language_Independant/Override/skelwa03.CRE 432040033cdd060d28bd5810edb87dac ./Language_Independant/Override/spwi313.spl a8f88138ed6beb1df1e34085c5a9c4a1 ./Language_Independant/Override/sw2h06.itm fae46d1893f8bdab8fe2b8c37d4e7e38 ./Language_Independant/Override/taloun.dlg 97659d8a158ff9d465600470981dd8bc ./Language_Independant/Override/tem2304.STO 529b1a213a4f37915fab7e389d675224 ./Language_Independant/Override/tem4802.STO ee55ee4e14ff258ac04e2567f1372f46 ./Language_Independant/Override/tethto2.dlg 16f10e640d0420c4a6a0b064c11b4a1c ./Language_Independant/Override/thalan.dlg 5b6b091576f7fde26c96505c9be3a927 ./Language_Independant/Override/therel.dlg 885b5e2a5cf200ab2d15974872a0518d ./Language_Independant/Override/tick.dlg 1defb39a2f307a6ed027c04f052b8e83 ./Language_Independant/Override/tremai.dlg 9cab96c801bc2ee5598f28a04db41a86 ./Language_Independant/Override/ulcast.dlg 9449663f07b5cdf1bc5b8704dd258beb ./Language_Independant/Override/ulraun.dlg a08081bec7dbe2465a7524a756dfd0c4 ./Language_Independant/Override/unshey.dlg 18ca62661ff16cb69c2a06781ce5a408 ./Language_Independant/Override/viconi.dlg 24db078462d81aeebe007e8f7aaf1506 ./Language_Independant/Override/voltin.CRE cfd5b84d34910a486e648d82d0d7b37c ./Language_Independant/Override/xan6.CRE 14d20a1c15087b551e4d08ae56a643c2 ./Language_Independant/Override/yeslick.bcs afd8570cf7b78630c002464b31790645 ./Spanish/dialog.tlk 7f7826a38750b3aba1da421f1100cbc6 ./Spanish/dialogF.tlk unshield-1.5.1/test/v0/baldurs_gate_patch_v1_1_4315_international.sh000077500000000000000000000016431415320644200252450ustar00rootroot00000000000000#!/bin/bash set -e cd `dirname $0` MD5_FILE=`pwd`/`basename $0 .sh`.md5 UNSHIELD=${UNSHIELD:-/var/tmp/unshield/bin/unshield} if [ \! -x ${UNSHIELD} ]; then echo "unshield executable not found at $UNSHIELD" >&2 exit 1 fi DIR=`mktemp -d` trap 'rm -rf ${DIR}' TERM INT EXIT cd ${DIR} URL="https://www.dropbox.com/s/9ruil8oi6amjbbk/unshield-baldurs_gate_patch_v1_1_4315_international.zip?dl=1" curl -fsSL -o test.zip ${URL} unzip -q test.zip 'data*' set +e timeout 10 ${UNSHIELD} -d extract1 x data1.cab > log2 2>&1 CODE=$? if [ ${CODE} -ne 0 ]; then cat log2 >&2 echo "unshield failed with error $CODE" >&2 echo "See https://github.com/twogood/unshield/issues/70" >&2 exit 2 fi cd extract1 find . -type f | LC_ALL=C sort | xargs md5sum > ../md5 if ! diff -wu ${MD5_FILE} ../md5 >&2 ; then echo "MD5 sums diff" >&2 echo "See https://github.com/twogood/unshield/issues/70" >&2 exit 3 fi exit 0 unshield-1.5.1/test/v0/the-feeble-files-spanish.md5000066400000000000000000000511331415320644200220130ustar00rootroot00000000000000f77a2f7632408752c29e0beab0ee3d66 ./Essential_Game_Files/0011.VGA d92b95f8b41cadd2daa8fe98b0e66607 ./Essential_Game_Files/0012.VGA 702b790944582ddbb9755b7228e8f147 ./Essential_Game_Files/0021.VGA 95e08584433213bbbe7715d03ed057d5 ./Essential_Game_Files/0022.VGA de4f46b96872f50ed9a9bc86e3f3b74f ./Essential_Game_Files/0071.VGA c9984357a5534e05b9d3f7da36856730 ./Essential_Game_Files/0072.VGA a884cd4b8597f40e9557ef4a7ca80031 ./Essential_Game_Files/0081.VGA e465c315cbe92ba02821c8e9ff927777 ./Essential_Game_Files/0082.VGA a1af4636fe0d3286d17d0aa6ca89fda4 ./Essential_Game_Files/0091.VGA a1af4636fe0d3286d17d0aa6ca89fda4 ./Essential_Game_Files/0091.fst 1f8c398703d331547b1b0c33de176eed ./Essential_Game_Files/0091.slw 34f3dd6e1b6978a0b05ef8b0c33557f4 ./Essential_Game_Files/0092.VGA b089d0826fcd31f4cee07821c421f8b8 ./Essential_Game_Files/0111.VGA 81a2356eaa10b64e96c1df514c613ad7 ./Essential_Game_Files/0112.VGA 1127cc5ca705e233c8d5ce16f6661ab3 ./Essential_Game_Files/0121.VGA e00a8980b4e908bad7649ded80ac90ad ./Essential_Game_Files/0122.VGA dc11c5123a5abf5ec80fd83df3ddf127 ./Essential_Game_Files/0131.VGA 15ab7ba9d8fb87e2f81ded0948718eba ./Essential_Game_Files/0132.VGA 424c1aa5ba80d8fff10c297a7b25a311 ./Essential_Game_Files/0141.VGA 77b7feaee792dd2cb0e0259d0738307d ./Essential_Game_Files/0142.VGA 4e7c1545d3d9380775f6050793a08cae ./Essential_Game_Files/0151.VGA d2591384e041476a671a67a3939ee3ce ./Essential_Game_Files/0152.VGA 3c8b32725559422b302c4bffe97e8ad4 ./Essential_Game_Files/0161.VGA 9c9e47ec2a14b345db3f7bfc9b17fddd ./Essential_Game_Files/0162.VGA f0b876165c7947fce2e3fde53fdc3ffb ./Essential_Game_Files/0163.vga db9f832c74ad1ad8a095de4e5edaf340 ./Essential_Game_Files/0171.VGA 913766b7aee2242cf48d6cee6f16c7f7 ./Essential_Game_Files/0172.VGA a3f245749e396ed70acfcf175b125b45 ./Essential_Game_Files/0181.VGA f9be2faebc1be752d9013e1dd8c8a53c ./Essential_Game_Files/0182.VGA b6454c471d265ae06ad56dfb20c0eff9 ./Essential_Game_Files/0191.VGA 06bd665e453690dbd798cf43f0879b63 ./Essential_Game_Files/0192.VGA f0b876165c7947fce2e3fde53fdc3ffb ./Essential_Game_Files/0193.vga 62d294bc4a70ef39e44c82db15e1dc47 ./Essential_Game_Files/1101.VGA 9e436e2f74476ed57f81bfb46baff8c5 ./Essential_Game_Files/1102.VGA 8c5e9afbdafff2145195262760d8d51d ./Essential_Game_Files/1111.VGA 0cd1408697a4454b0690a92723654546 ./Essential_Game_Files/1112.VGA d6bc66bbf805cfad874dda37d54caf84 ./Essential_Game_Files/1121.VGA b6c6259af57589a6315a516a09dc07a8 ./Essential_Game_Files/1122.VGA 0d30177c9075d5e2d40de5b1a1281a5b ./Essential_Game_Files/1131.VGA d68b6015a7d7bd7c1f755a8af008fc8b ./Essential_Game_Files/1132.VGA a1a36bac72c805ad3b247f5dce4e9f6b ./Essential_Game_Files/1141.VGA b6fd933333588eb55a2b100af503466e ./Essential_Game_Files/1142.VGA cedc3894f34e896da3cd6922412fb60f ./Essential_Game_Files/1151.VGA ee4925c01ba2ee625b54388d61097ffa ./Essential_Game_Files/1152.VGA ac06944d7925d141c01238f6a0fe8ca0 ./Essential_Game_Files/1161.VGA 51252981e969ad1d9f92cd9921199eb6 ./Essential_Game_Files/1162.VGA b05ab0b03954ff829ff6945059963c2f ./Essential_Game_Files/1171.VGA 69dd06969d3b64c9b1759fd0b792fedb ./Essential_Game_Files/1172.VGA 89f7e8e830e63cd91a2741041062c01a ./Essential_Game_Files/1181.VGA 0fdea1a722181204786346ebfab323c5 ./Essential_Game_Files/1182.VGA b3985bfd0448c0876eb3814576e47a86 ./Essential_Game_Files/1191.VGA 737f977e11c16b3ad8e9d83e3532a27d ./Essential_Game_Files/1192.VGA 898ebfe7fc3006c286245d6058c09e35 ./Essential_Game_Files/1201.VGA 2f8b8f89c6779b1239a933e257528db4 ./Essential_Game_Files/1202.VGA b3809b1968fcae950682df407003883b ./Essential_Game_Files/1211.VGA 4024f6a7dae0edb52a378db169e77b32 ./Essential_Game_Files/1212.VGA 7364747aac14421f05a843fa1136e65b ./Essential_Game_Files/1221.VGA 8d6daa45a034f77bac1d1c53503d658b ./Essential_Game_Files/1222.VGA bb9454789fa0350b079caeeff2991d5b ./Essential_Game_Files/1231.VGA ed32aa7e3f3141bbb007706ec3468162 ./Essential_Game_Files/1232.VGA 34ce97569163bd476d69eb4b073aa107 ./Essential_Game_Files/1241.VGA e1d4c78d2628cc925741f0168b4cf50d ./Essential_Game_Files/1242.VGA 698087f497a600946a00708e89ea6213 ./Essential_Game_Files/1251.VGA b1af97c56743e30d61b1bd73d716e2e8 ./Essential_Game_Files/1252.VGA 5ccaca4a804080c7046fd093ceb3c58c ./Essential_Game_Files/1261.VGA e20e77a408fdba0ee805d4b984cb81e1 ./Essential_Game_Files/1262.VGA f976644048d7b8ce7067e2f47728981f ./Essential_Game_Files/1271.VGA 4fd983abc568d148a756a6e0f9e3fccc ./Essential_Game_Files/1272.VGA 6fb3bd85891960cbd03e5bede83a5164 ./Essential_Game_Files/1281.VGA 7d6743c36079e05e0b8e742dbc6c6674 ./Essential_Game_Files/1282.VGA 90a663c8049219064fc225f666eec273 ./Essential_Game_Files/1291.VGA ac93dc37767c306db799554f7696adff ./Essential_Game_Files/1292.VGA 9b6a75c089e2d4b9bef591dab165392c ./Essential_Game_Files/1301.VGA 6fc4f5bf9e22542492769559b65c3ec0 ./Essential_Game_Files/1302.VGA 2305d4bb44b3d03cc301d71ea1dd00e4 ./Essential_Game_Files/1311.VGA 7a9b929200fbfbc57e16773eabd72349 ./Essential_Game_Files/1312.VGA 3741748a98403c8734a965f0f4ab639e ./Essential_Game_Files/1331.VGA ac7d0d37ecdb10e50d14ed612e8cbf79 ./Essential_Game_Files/1332.VGA 338b8621806b622bf34aa88928591de5 ./Essential_Game_Files/1481.VGA 8a84e75f9cb6137e21c299cd5aa5823e ./Essential_Game_Files/1482.VGA f0f39c94ef7ab9e66cad3b5c360a9717 ./Essential_Game_Files/1491.VGA b069ffaeca03749260cc55c65ebfa722 ./Essential_Game_Files/1492.VGA e5ff3ada2e94d682a56905beb8382a67 ./Essential_Game_Files/1501.VGA 3d73e76419585936e141fa6866fd4c21 ./Essential_Game_Files/1502.VGA d1e21c85cc5a400638526d1878112091 ./Essential_Game_Files/1511.VGA 786aa1579ee2dea9771ac0b61eb1d88e ./Essential_Game_Files/1512.VGA 1efce191b367fd655a7e8e6d586a223a ./Essential_Game_Files/1521.VGA 121c98babd5afd30e91f6807b2543f7d ./Essential_Game_Files/1522.VGA bc2939dd554564a65407b7be01ab0a8c ./Essential_Game_Files/1531.VGA 11ce4c6499631d2e460607b18a90183d ./Essential_Game_Files/1532.VGA 8f35ac30a7f0c025ddad8bf32a1e1a73 ./Essential_Game_Files/1541.VGA a82c33dae03b5089d5a60a5bd8c0ac09 ./Essential_Game_Files/1542.VGA 726e491cec0d18880d8b78cdbd50d19b ./Essential_Game_Files/1551.VGA 32077dd343f45329bc4d3112c56e87ff ./Essential_Game_Files/1552.VGA a4cf19056b228a02c2bf32b31082326e ./Essential_Game_Files/1561.VGA 782da97fb7e703da8fd990c152a78012 ./Essential_Game_Files/1562.VGA 80885bd0f3734f989653c4782c56e5d4 ./Essential_Game_Files/1571.VGA 903aebe1ab59863cd5f70344fe3317c9 ./Essential_Game_Files/1572.VGA 82c306723db9d3389654f78c58b0de23 ./Essential_Game_Files/1581.VGA 600154f723f0b76a0fb6f341f2941caa ./Essential_Game_Files/1582.VGA f45b09c0b1eb3ce58f1f48497b14ba3d ./Essential_Game_Files/1591.VGA e7b21fdd3017e4c40696789799ae5a9c ./Essential_Game_Files/1592.VGA c8cbc1f3c11db6149275fa318478dee5 ./Essential_Game_Files/1601.VGA 9faf19c66b4c3da420ee854676f562d0 ./Essential_Game_Files/1602.VGA 2c279669bf94928727ee218f371b1793 ./Essential_Game_Files/1611.VGA 038846d32d0819380fca2fa028c17304 ./Essential_Game_Files/1612.VGA 342c5835e2bb1b1d78769940c83b02a0 ./Essential_Game_Files/1621.VGA 274fdffadc4f4b8cde034fe849d70b6a ./Essential_Game_Files/1622.VGA c30500ebd8262fc184b4fd9563e60bce ./Essential_Game_Files/1631.VGA 0d8c3c62a2ea4a71a9cdfbc6a4386cd8 ./Essential_Game_Files/1632.VGA 378b2b079f4ad4dd1fe864521973e0b9 ./Essential_Game_Files/1641.VGA 7893ef7fdd5299dd703d1a7f18d4e448 ./Essential_Game_Files/1642.VGA ddf4c52413f1d42cea807b8bdacaf5e7 ./Essential_Game_Files/1651.VGA b3b5f63503b1510eb18ae4d15f787ab9 ./Essential_Game_Files/1652.VGA 506c6eb8c776e1dd1f5557cf155f5641 ./Essential_Game_Files/1661.VGA f2fc995fa47a7b0a6eee94e79c83efc0 ./Essential_Game_Files/1662.VGA 670310ad34d3dad9c48c622aa3db8fcf ./Essential_Game_Files/1671.VGA 4e4d504e1c0cc998c365eecfb7e122c7 ./Essential_Game_Files/1672.VGA a64dc64018ab021002b2958f7c2b255c ./Essential_Game_Files/1681.VGA c88f26d2037af9cc6231a09ed36efbcc ./Essential_Game_Files/1682.VGA 307006e98381d7707c871e7c6d6402fa ./Essential_Game_Files/1691.VGA cfc3f1f01b43d5c7a72451250c57f6f2 ./Essential_Game_Files/1692.VGA 788dd8e2cd6140a7bd94785fe36930dd ./Essential_Game_Files/1701.VGA 4ff08bbebe92c6c8592a3fe454b1b095 ./Essential_Game_Files/1702.VGA 5f11f1d6b9eeb2e7a3957e3faae5a3e3 ./Essential_Game_Files/1711.VGA 68a729ae1d001d35db99e930db7de219 ./Essential_Game_Files/1712.VGA 98c044a423bbb7bd7274072960a2e9f6 ./Essential_Game_Files/1731.VGA 88daa0b4de221496dedf63d9d3367ef2 ./Essential_Game_Files/1732.VGA c53745039b6466033b6647462aff4945 ./Essential_Game_Files/1781.VGA c836cc779f4a2482a625ffbfca2619dc ./Essential_Game_Files/1782.VGA e9a4e093d54136845d584bda2a7f5e38 ./Essential_Game_Files/1791.VGA ac820b2784043ef4c352adba4965c1c2 ./Essential_Game_Files/1792.VGA a3f9a3a4c8b5943288465f9a4bf66ec1 ./Essential_Game_Files/1801.VGA 630a8a296ed0943289c5cd52441e9151 ./Essential_Game_Files/1802.VGA 0bac8878919f5ec3c282f120521bb50b ./Essential_Game_Files/1811.VGA 87a1da2123cd63d649c64a7bcefafde7 ./Essential_Game_Files/1812.VGA 05e4381ab638fae633480ffadf73915b ./Essential_Game_Files/1821.VGA 9fe8aa1a06a82b4ff94b8185ba848dd0 ./Essential_Game_Files/1822.VGA 456c7e4df8dda20fc4191a2ab451a23a ./Essential_Game_Files/1831.VGA 197cb37e6920ee2d62094d822d9e29b8 ./Essential_Game_Files/1832.VGA 4d1e8a2c6c61493c1d531ba17ec46e06 ./Essential_Game_Files/1841.VGA 9b8bf064d6c967c6ac713dfaa84d9501 ./Essential_Game_Files/1842.VGA b24e6f1b5ab2a917c0ab3a1494fd0659 ./Essential_Game_Files/1851.VGA 8529e139e90d3b76bda87c0b3a0bc427 ./Essential_Game_Files/1852.VGA b51e9317ff2fb65971820e306cbf0a73 ./Essential_Game_Files/1861.VGA 8a385b653e0deb0483967193b11bae4e ./Essential_Game_Files/1862.VGA f8d5f44fca5d761d1f00b7713e02988e ./Essential_Game_Files/1871.VGA c4f7ec874c7165ad245d4178179669f1 ./Essential_Game_Files/1872.VGA 7481e4db932e6c1114acc52991183813 ./Essential_Game_Files/1881.VGA b1b359f5a913fbac6bbb9b4d19c61f2d ./Essential_Game_Files/1882.VGA b2ff7049dcf6b38912a3649120d5cc6c ./Essential_Game_Files/1891.VGA 56a6d12448b383c9cf4f966131e9fd48 ./Essential_Game_Files/1892.VGA 91bdbcc4559138f5a21457deb7f70a03 ./Essential_Game_Files/1901.VGA a284ac4e9e8a4df4e830a8dbec247739 ./Essential_Game_Files/1902.VGA 74c17cbafa309194732fb0c00dd95375 ./Essential_Game_Files/1911.VGA b6026825655bea901d1e7deea46106cb ./Essential_Game_Files/1912.VGA 59665be5b0899223b77e70dfaf55ac69 ./Essential_Game_Files/1921.VGA 4534fa783f9a2f9f2b2d00e28d1df42c ./Essential_Game_Files/1922.VGA a0e3de5f40aa459ef10a295f405e16e6 ./Essential_Game_Files/1931.VGA edfbcbdb2af8d24c8bfcd39de6b2980e ./Essential_Game_Files/1932.VGA 3ef8366f6ada98ca4228fa6e9ac5231a ./Essential_Game_Files/1941.VGA bafc7bde7289261c822522bc886d7b99 ./Essential_Game_Files/1942.VGA 72e4fc26559a8a8f385dfc90385c8552 ./Essential_Game_Files/1951.VGA 4bb17129b4811fc70380e3f4c0b61943 ./Essential_Game_Files/1952.VGA 37dc35fd7eba04d0df200152e39d88b1 ./Essential_Game_Files/1961.VGA 0ac6854bac184b9e0869bd7477cf312e ./Essential_Game_Files/1962.VGA 910a7c58b33d8ef3d125f1fef552c387 ./Essential_Game_Files/1971.VGA ffba66f7b272cf0741c038608b075c67 ./Essential_Game_Files/1972.VGA 4c074f4f6802a87b3b3a40ea48204fba ./Essential_Game_Files/1981.VGA 599f81669d4985b0539916191b3933f9 ./Essential_Game_Files/1982.VGA f8f758023dc5acc97c734efd1dc38289 ./Essential_Game_Files/1991.VGA fb2725ca20a497c88e3e906b6b6e11d0 ./Essential_Game_Files/1992.VGA 76207006986c448e87f4b2b722e27ccd ./Essential_Game_Files/2001.VGA 8388bc06ce0949dbab302a8dd61aac89 ./Essential_Game_Files/2002.VGA c7da916b388d56179dc7f123a80ee100 ./Essential_Game_Files/2011.VGA 1782f9682ca097688f2cc1817b841788 ./Essential_Game_Files/2012.VGA 7d858a740d615b45543775716cc5809b ./Essential_Game_Files/2031.VGA f5c453b0dd535585504b3a84299d9c73 ./Essential_Game_Files/2032.VGA c372995d226110ccd998bc32be528ab7 ./Essential_Game_Files/2081.VGA 8eb186cb31972c79ef218329e7b41229 ./Essential_Game_Files/2082.VGA a002752971d770831970e9dac980d73c ./Essential_Game_Files/2091.VGA 6ad24fb52539de2f5dae6ba68211811f ./Essential_Game_Files/2092.VGA b05ca02618030684246893c84531d4da ./Essential_Game_Files/2101.VGA 4988325e603c726a35f94ac8216421bd ./Essential_Game_Files/2102.VGA 6e2af23932f5e31c1d28415686985cba ./Essential_Game_Files/2111.VGA 6d413abed1e45de7b001d4ee5cafca7c ./Essential_Game_Files/2112.VGA 3d993e487b20a548d2111d51e93abe96 ./Essential_Game_Files/2121.VGA 92533aba54fb5dbd8bb3185a26f617f8 ./Essential_Game_Files/2122.VGA 014b9aa02c536d9c63caeaba00868eba ./Essential_Game_Files/2131.VGA 1f5a1d19324b5076c6d46240e3b1b41b ./Essential_Game_Files/2132.VGA ad288a6147b1961501408a28ad6ec09d ./Essential_Game_Files/2141.VGA 06bf52a316b0583b4119db39ab99402e ./Essential_Game_Files/2142.VGA f03bb4b2b1febd48941392d930b6b628 ./Essential_Game_Files/2151.VGA 3598ce89ac8683338792bb1f09e23660 ./Essential_Game_Files/2152.VGA 999bc48efb6ab23533349f51f7f633e1 ./Essential_Game_Files/2161.VGA 3c0356bfb35f3d1bbff6fa9f1b1f03d7 ./Essential_Game_Files/2162.VGA 8651a075902cbd628874c05cca5f5ecc ./Essential_Game_Files/2171.VGA 7f1979d31c9f0434c788d663c63a2619 ./Essential_Game_Files/2172.VGA 7e2e8b971f297be6f590074cb10aeb85 ./Essential_Game_Files/2181.VGA b5f1db3aa2b9d6d11fe646c7f6bd0207 ./Essential_Game_Files/2182.VGA 44735dcd64a24f528bc0f6661d83acb4 ./Essential_Game_Files/2191.VGA 36868fca049e24924d372dfbc9c9508a ./Essential_Game_Files/2192.VGA 8c7787ac2e33cd80cc9c762aa20b9a60 ./Essential_Game_Files/2201.VGA 36c7e4b15dd6d65b85a3413431d5e572 ./Essential_Game_Files/2202.VGA 98b38d95e2e84e4a7716fcf929d01845 ./Essential_Game_Files/2211.VGA fa5a040398498ed4f9abac267fd6f46c ./Essential_Game_Files/2212.VGA 954b5e5046713f2e6647dc713c90795a ./Essential_Game_Files/2221.VGA acfc543fe2830bad6abc4f5803fd5afb ./Essential_Game_Files/2222.VGA b1677301a1c83baddb98f538e1e7e905 ./Essential_Game_Files/2231.VGA b00f7c4b9ad4e1b02cced028a1ee1316 ./Essential_Game_Files/2232.VGA 192418ff6dbe40f847a2c57abda1379f ./Essential_Game_Files/2241.VGA f49acbd2a28a1ba3abff4243beb10169 ./Essential_Game_Files/2242.VGA b81f4715ed83e27da66c3bd6ae41990d ./Essential_Game_Files/2251.VGA 11e8d550a5c900b32e6549b7606c6454 ./Essential_Game_Files/2252.VGA 0cb960a584687ec64da0241c15fe6557 ./Essential_Game_Files/2261.VGA 395cd6d9d7e10e45929344c1d2171f51 ./Essential_Game_Files/2262.VGA 53e52e94b0256b968ff87e285c787804 ./Essential_Game_Files/2271.VGA 4b91a65435425e08e5aec48c124d672f ./Essential_Game_Files/2272.VGA 82ba12c23bbf34cf69f000a876e1347f ./Essential_Game_Files/2281.VGA 3c8103092f09ac2da548256143f10c75 ./Essential_Game_Files/2282.VGA f85961c60c6a9260dcb9d1b6461d2257 ./Essential_Game_Files/2291.VGA 11a3c497cda55d1c7ba3ed616d8eb17d ./Essential_Game_Files/2292.VGA e889c6dc9e4cead3a2527c0232b50cd4 ./Essential_Game_Files/2301.VGA c71ddf8137ea8033dec8ba91746f9c86 ./Essential_Game_Files/2302.VGA c9179570006769e13b55faa9f85d062f ./Essential_Game_Files/2311.VGA 13f73e64b06ff9699f18486be4799a0c ./Essential_Game_Files/2312.VGA 351f215213ca37127114a8ead93dc143 ./Essential_Game_Files/2331.VGA bfd9efa445d5d1d99d0e658cfea040f8 ./Essential_Game_Files/2332.VGA 641f9bb60ad62328bafda1e61a4a9493 ./Essential_Game_Files/3081.VGA 586bd630d6d33e2fcec944b7177f0317 ./Essential_Game_Files/3082.VGA 469d45b820d841cc896fc3496cdd96dc ./Essential_Game_Files/3091.VGA a85b8268dc5753c1cd821c266ff6a74f ./Essential_Game_Files/3092.VGA 854556ee6e2027687c570a7c6afdcbbf ./Essential_Game_Files/3101.VGA 9ea6b3c7ce56aadcf86f1926e5c9b3e0 ./Essential_Game_Files/3102.VGA 2548c35a794702194e91405d317bf478 ./Essential_Game_Files/3111.VGA 51552f158c3bb62ccb9ddfd1f0ff2327 ./Essential_Game_Files/3112.VGA f604de01409a18359053aca51778bbd2 ./Essential_Game_Files/3121.VGA 09c0751817996596d17944c411b2a6b6 ./Essential_Game_Files/3122.VGA 315ed5cd6409e5ad104831acdce4c870 ./Essential_Game_Files/3131.VGA 96e9d946dfa3dbc20fc40bf6c8f116a2 ./Essential_Game_Files/3132.VGA 3a7c86afdf6e76d0cb6e1c90ea056e79 ./Essential_Game_Files/3141.VGA 09eef60be0f9547424b86f75914fe99a ./Essential_Game_Files/3142.VGA fb3a76e829736bfdc5634b102440fe2a ./Essential_Game_Files/3151.VGA d9bcf154ec98dea1079390e9cdd0ced4 ./Essential_Game_Files/3152.VGA cc6c3fd714b9f507eaba29b463482c0d ./Essential_Game_Files/3161.VGA 0e3fe912b9fba729c6e70c9b8063afda ./Essential_Game_Files/3162.VGA cfc42f8f5a1760eaecd2a8ce518ef605 ./Essential_Game_Files/3171.VGA 5beb574fbb5e092ccc9778fc00b31733 ./Essential_Game_Files/3172.VGA fed6730618a4c98efb99b07d9fdb77df ./Essential_Game_Files/3181.VGA 0f591dc333891cdfef91737d964c3439 ./Essential_Game_Files/3182.VGA 5f358183d95b1dae608dd4b8213b46fc ./Essential_Game_Files/3191.VGA 51f56a4fa58e5b57b626f8a4b6b1eadd ./Essential_Game_Files/3192.VGA cc9e195f163eb32bde0bfea8ef99c744 ./Essential_Game_Files/3201.VGA 9d0f18393479cd6c5907598436fdeeaa ./Essential_Game_Files/3202.VGA bd2bc7335e61ed6d5a452430542a871a ./Essential_Game_Files/3211.VGA 13eff9f493356cd2687facc6172eca95 ./Essential_Game_Files/3212.VGA 4794ca9a6588dd9effba904e58f06a92 ./Essential_Game_Files/3221.VGA 33da9dca33f1f894046e26561c8104a6 ./Essential_Game_Files/3222.VGA e7d4d01abd11a1a7b6913696aea9fe32 ./Essential_Game_Files/3231.VGA d46406bc43e7a96f3d36c5ef6ac76594 ./Essential_Game_Files/3232.VGA 4d1f25a113f1193d5be94918b0b89d11 ./Essential_Game_Files/3241.VGA f8b77a428a76f77368c54a69baec3a93 ./Essential_Game_Files/3242.VGA ebedf64ff02c4ee75d5f66af9177c8ac ./Essential_Game_Files/3251.VGA 8ed0d4ed5ad93e41c730ff786b25e2ca ./Essential_Game_Files/3252.VGA bd974efc711841c9e5184ba0cc910973 ./Essential_Game_Files/3261.VGA f4104d2e8a88cf79181a7fee1236bc7b ./Essential_Game_Files/3262.VGA 10a8b55ef89c778b47ae6f8e9b83070d ./Essential_Game_Files/3271.VGA c1e07bf55bae6c675bb902f156a1c0a0 ./Essential_Game_Files/3272.VGA de77d1f526caedb63b67aa5e58319e4e ./Essential_Game_Files/3281.VGA 98f3f76926bfadb3d1adcbfdf1387be4 ./Essential_Game_Files/3282.VGA 40f2cf5e69e017c32e1f3c310559af4c ./Essential_Game_Files/3291.VGA 4582764bc765be9599f471c29edf1d3d ./Essential_Game_Files/3292.VGA 7c4cbdb31308305a3c6ceba62fb4e2e2 ./Essential_Game_Files/3301.VGA 70df5e0ed6f4b182095604c1aaa19df1 ./Essential_Game_Files/3302.VGA f1be13ed49dde47d1153a94c28bd8ca5 ./Essential_Game_Files/3311.VGA 26cfa5b4d84fec889c3c3a12829c3764 ./Essential_Game_Files/3312.VGA 969521951494ee79bbabd3674747046a ./Essential_Game_Files/3331.VGA aeb37c757f102ff4ca3d76db07eec04c ./Essential_Game_Files/3332.VGA 6aa0544fdfd9cc86ce6e72ca05d1433f ./Essential_Game_Files/Charisma.smk 31efba0e0f105ecdf77a8fe63db90ed3 ./Essential_Game_Files/Disk1.smk ecb26c965ca8b45e3a1856fc17a21b9e ./Essential_Game_Files/Disk2.smk b8f09cb0f9d811c32e5bdb07aac08584 ./Essential_Game_Files/Disk3.smk f2ce346f8f45c0d362f432ad5fe1b6dd ./Essential_Game_Files/Disk4.smk 24fe7ba975369c272088aa3b0c5bf348 ./Essential_Game_Files/GAME22 e445a0a7e554ebcb550a52ee6e74023e ./Essential_Game_Files/Nextdoor.smk c86a414aa0101d0838b6c5e20dd5e99c ./Essential_Game_Files/Omnitoy.smk 754e03f61a1186dd47b31ee7798fc704 ./Essential_Game_Files/Qtime.smk c4a0b8193335026c5b220257dea2c585 ./Essential_Game_Files/Run95.exe 7635d1e15ba1704b3cb1525c1eba0d6f ./Essential_Game_Files/SMACKW32.DLL 4157c16894c0413ca64e56a52aa46d50 ./Essential_Game_Files/TABLES01 d71b7918c74a999fa4c539ee8ef63003 ./Essential_Game_Files/TABLES02 ae33ef52caed416c1f29c2976736ac4f ./Essential_Game_Files/TABLES03 7edccf6dda9b1007a039a04980d06d88 ./Essential_Game_Files/TABLES04 5fdf13ec87decd2f48686e0a29cd880f ./Essential_Game_Files/TABLES05 660915b818d654b09a30d0ca8536e21a ./Essential_Game_Files/TABLES06 597d9304e3a1f354f39f81b6b538a395 ./Essential_Game_Files/TABLES07 243c717ab93de8c3064eda96d575f617 ./Essential_Game_Files/TABLES08 c0284a4c084db9bf4ce02c89f8842153 ./Essential_Game_Files/TABLES09 743ddf7cdd9488d74a840180fe71d468 ./Essential_Game_Files/TABLES10 0f1fdab8f4cc2dea3f29058250b82068 ./Essential_Game_Files/TABLES11 94b6a25599dfaaea64cb3a7a4a1c7589 ./Essential_Game_Files/TABLES12 773d8084c0b3a98b1c9b556768cbb564 ./Essential_Game_Files/TABLES13 4d7771240870c4a7e5b0f4b4a2e010f7 ./Essential_Game_Files/TABLES14 3718ba2c338b75bebe4709b939de7542 ./Essential_Game_Files/TABLES15 7de9a7487fe332e41041a39b10eac54d ./Essential_Game_Files/TABLES16 b9e5112e0462b7d69f218e64883193a9 ./Essential_Game_Files/TABLES17 a3a740286dfbb33f52d7a5cfb1ce51a7 ./Essential_Game_Files/TABLES18 dc5d78aa8377d0e85381a3768742f834 ./Essential_Game_Files/TABLES19 a528ec6eed4f050c492a1e89aa03f480 ./Essential_Game_Files/TABLES20 c521eb8fe621ddb1a1e112fc679ef1b4 ./Essential_Game_Files/TABLES21 6fc3c61399faee65d26451132ff94b94 ./Essential_Game_Files/TABLES22 41383b96f63ede313c7f698027a6fb5d ./Essential_Game_Files/TABLES23 b50f2a67685e05b792afd5edf894ebeb ./Essential_Game_Files/TABLES24 a7add5ae7548d332982c234a81bfb03f ./Essential_Game_Files/TABLES25 0bbfee8e69739111eb36b0d138da8ddf ./Essential_Game_Files/TBLLIST ae84d7898b6282127618069d9c586246 ./Essential_Game_Files/feeinbin.ico c1fa9f0e1726e9a95638b53b1d087468 ./Essential_Game_Files/icklfeeb.ico 71512fc98501a8071a26b683a31dde78 ./Essential_Game_Files/save.999 e00cead9fb77c8a6b48b9a8fe98af527 ./Essential_Game_Files/startup.wav unshield-1.5.1/test/v0/the-feeble-files-spanish.sh000077500000000000000000000016241415320644200217430ustar00rootroot00000000000000#!/bin/bash set -e cd `dirname $0` MD5_FILE=`pwd`/`basename $0 .sh`.md5 UNSHIELD=${UNSHIELD:-/var/tmp/unshield/bin/unshield} if [ \! -x ${UNSHIELD} ]; then echo "unshield executable not found at $UNSHIELD" >&2 exit 1 fi DIR=`mktemp -d` trap 'rm -rf ${DIR}' TERM INT EXIT cd ${DIR} URL="https://www.dropbox.com/s/1ng0z9kfxc7eb1e/unshield-the-feeble-files-spanish.zip?dl=1" curl -fsSL -o test.zip ${URL} unzip -q test.zip 'data*' set +e timeout 10 ${UNSHIELD} -O -d extract1 x data1.cab > log2 2>&1 CODE=$? if [ ${CODE} -ne 0 ]; then cat log2 >&2 echo "unshield failed with error $CODE" >&2 echo "See https://github.com/twogood/unshield/issues/27" >&2 exit 2 fi cd extract1 find . -type f | LC_ALL=C sort | xargs md5sum > ../md5 if ! diff -wu ${MD5_FILE} ../md5 >&2 ; then echo "MD5 sums diff" >&2 echo "See https://github.com/twogood/unshield/issues/27" >&2 exit 3 fi exit 0 unshield-1.5.1/test/v0/wireplay.md5000066400000000000000000000201721415320644200171030ustar00rootroot00000000000000596e93bd517f9d9056db083e1a445c63 ./Program_Executable_Files/CLIENT.EXE b7ef49b0dc87484a7dfd97cb67e47195 ./Program_Executable_Files/GAME.DAT 3c2937f573b9f5889727cd5818a7b37c ./Program_Executable_Files/HELP/ABOUT.HTM 9880b2b6081c754a264ec4ff75e84ac7 ./Program_Executable_Files/HELP/BIGRED.HTM 7f0329ee1840ef8ed654292a145bebc1 ./Program_Executable_Files/HELP/BRINST.HTM b14f65893801344852def3f75ceff4f0 ./Program_Executable_Files/HELP/BRRDEMO.HTM f74df3dcc0556b5a744db903530635d2 ./Program_Executable_Files/HELP/CLUBSOC.HTM 8a22ac5602edd904309aae4df407a158 ./Program_Executable_Files/HELP/COMANCHE.HTM 76f8f8921e5ed58121836b3d61be4ac2 ./Program_Executable_Files/HELP/COMMAND.HTM 463145d71702e2733c14f1f916c5332d ./Program_Executable_Files/HELP/DESC2DEM.HTM 191dd050b10c7d1e10ea6683d356def5 ./Program_Executable_Files/HELP/DESCENT.HTM 923b1e2791d03e83e1eebdeafb5e9451 ./Program_Executable_Files/HELP/DESCENT2.HTM 7b428da96eb62dedcfa4831be4b886e2 ./Program_Executable_Files/HELP/DOOM1666.HTM a8999012e87a8a00529905359452f89b ./Program_Executable_Files/HELP/DOOM19.HTM 14ce54b1f77b38f2b92c8fba0499aa81 ./Program_Executable_Files/HELP/DOOM2.HTM 22a42663824d6fb724960bb8b8594089 ./Program_Executable_Files/HELP/DOSHELP.HTM 4defdbf79a09988bb83f3c1ddefb3a41 ./Program_Executable_Files/HELP/DOSNEW.HTM a2ce6b14611732067d09edffc0796daa ./Program_Executable_Files/HELP/DUKE3D.HTM 6a907eb648b5cef907974fa88cfa0609 ./Program_Executable_Files/HELP/DUMMY.HTM 014487445e79cef96d24b5833074c52e ./Program_Executable_Files/HELP/EF2000.HTM 3f9283d47ce65f72abcab41b0516d23f ./Program_Executable_Files/HELP/EFINST.HTM 94c7dc53aeb52a59b8a47bc6638b1bc2 ./Program_Executable_Files/HELP/EURO96.HTM b086b0550b89886c5c21fb15051bf192 ./Program_Executable_Files/HELP/EXTREME.HTM 8697f3c42cc0c4f8513cb44c70ff51e1 ./Program_Executable_Files/HELP/FIRCON.IMG e3550453cb1b399c0bddecc0a57ca4b1 ./Program_Executable_Files/HELP/GAME0.HTM ab609af26e13d4b9e7abaab8c4ea3d5c ./Program_Executable_Files/HELP/GAMETEST.HTM 9b238951bcf412905869d93de78fea5a ./Program_Executable_Files/HELP/GENERAL.HTM 8cd56e7de3cd600edc68df08149b4cfa ./Program_Executable_Files/HELP/HAND1.IMG 7be093ead913ff28348fc47297f93688 ./Program_Executable_Files/HELP/HAND2.IMG 4fc377a78e97e56f6907b2b6fa4608df ./Program_Executable_Files/HELP/HANDCURS.IMG e7709ec7c8e398c83eea36715024cfa5 ./Program_Executable_Files/HELP/HELP.HTM 1db8a0787fa72fa3587b451372e0d2c7 ./Program_Executable_Files/HELP/HELP35.HTM bf963b7ecc1d7a920cca7cc32aa294c2 ./Program_Executable_Files/HELP/HELP36.HTM ae5a63ac93fb75b5be5b0d11f1c58ec2 ./Program_Executable_Files/HELP/HELP_10.HTM d909409d4a25e373968b1613df201005 ./Program_Executable_Files/HELP/HELP_11.HTM b1ca129c4c900a8920be3c2c6a482815 ./Program_Executable_Files/HELP/HELP_12.HTM 1eff62c4be4cea2841f52cc6a32ca39d ./Program_Executable_Files/HELP/HELP_13.HTM 1fc55c91fdd87321c2ef8e5c223dfd62 ./Program_Executable_Files/HELP/HELP_14.HTM bbecf18f02490fe4b3005c72ba426f96 ./Program_Executable_Files/HELP/HELP_2.HTM 9dd3468c18461cc67e8dd99cc84638c5 ./Program_Executable_Files/HELP/HELP_3.HTM 063ccdc42a2b1587763484bde2ae8f77 ./Program_Executable_Files/HELP/HELP_3A.HTM dcdf3be39e46104e21b09418fe47a5d4 ./Program_Executable_Files/HELP/HELP_4.HTM 39585902b1296b78b5af9f41843366ee ./Program_Executable_Files/HELP/HELP_4A.HTM 1cade7e5d5d88ea3e274f50282aa8f7f ./Program_Executable_Files/HELP/HELP_5.HTM 3a42d43855b5b5fe359fb1195422aa1a ./Program_Executable_Files/HELP/HELP_6.HTM c6ef44048c86cad34ff36f57e683baf9 ./Program_Executable_Files/HELP/HELP_6A.HTM 458be696aee2a6c918efd6123df28a10 ./Program_Executable_Files/HELP/HELP_6B.HTM 191d75ae2e28e58fe4974df7b4156273 ./Program_Executable_Files/HELP/HELP_6C.HTM d44e064c9ee3941d38f30999ac133797 ./Program_Executable_Files/HELP/HELP_6D.HTM 8ef96c25a1ac1e3d624d2ce99d5c5cb0 ./Program_Executable_Files/HELP/HELP_7.HTM b2f58a64fbf6f4656c3dfe4bd2013665 ./Program_Executable_Files/HELP/HELP_7A.HTM 0e67a6f3e0e27f1fc25b5f920fea69c0 ./Program_Executable_Files/HELP/HELP_7B.HTM f0f2990440fceb30eb053e72781409b0 ./Program_Executable_Files/HELP/HELP_7C.HTM 87a448f01235e4214032a4f0d14eac60 ./Program_Executable_Files/HELP/HELP_7D.HTM 6d751202eb9dd7dca209d0afa5ab5ac6 ./Program_Executable_Files/HELP/HELP_7E.HTM d475add6ba4d2907a594bba09ceb48da ./Program_Executable_Files/HELP/HELP_8.HTM 9ece5f2ea55cd083ce8155a734d04817 ./Program_Executable_Files/HELP/HELP_9.HTM 982db919ca7c9494056d3f02d75cd8b1 ./Program_Executable_Files/HELP/HELP_9A.HTM aaf5a0c62d7ef6458d5471ee87766b19 ./Program_Executable_Files/HELP/HELP_9AA.HT aaf5a0c62d7ef6458d5471ee87766b19 ./Program_Executable_Files/HELP/HELP_9AA.HTM ff5e0a17ddef735b37f82e76c8f1f9aa ./Program_Executable_Files/HELP/HELP_9B.HTM c681509bdfaedcb5118a4632b3e9e974 ./Program_Executable_Files/HELP/HELP_9C.HTM 3d188e186bfdb97631e96bf63d231fb2 ./Program_Executable_Files/HELP/HELP_9D.HTM 3a15d091cec2a5f6a54ce93a798b30a2 ./Program_Executable_Files/HELP/HELP_9E.HTM 1c6bc3ecb9a12c587ec690196875d0db ./Program_Executable_Files/HELP/HELP_9F.HTM 40a1e53d2464e73138ada299d583f12a ./Program_Executable_Files/HELP/HELP_9G.HTM 147d6fb6fa0b38ad02a53eb0cc25a01e ./Program_Executable_Files/HELP/HELP_9H.HTM a5a17b695104caa76df3b75bed5b9444 ./Program_Executable_Files/HELP/HELP_9J.HTM 26a2689b8fadcdca9ee5b7e87d1ef31e ./Program_Executable_Files/HELP/HELP_9K.HTM ecebeeda0e0d6d072870a4d740e04f6f ./Program_Executable_Files/HELP/IGICON.IMG d02f2d21cea8528f55059561040c633f ./Program_Executable_Files/HELP/INLOCK.IMG d3a40fcc32b7e71080f2af2949dcddc8 ./Program_Executable_Files/HELP/NASCAR2.HTM a48ac1d03486e8bab54a728fcbe335b2 ./Program_Executable_Files/HELP/NETMECH.HTM 257d7dcd16f715da5dfada89fd4963fa ./Program_Executable_Files/HELP/OFFLINE.IMG 1de08313c99ca991ef7b5ecdd4dddf9b ./Program_Executable_Files/HELP/OUTLOCK.IMG cd86dfa2c129577020ebf537d85d5df7 ./Program_Executable_Files/HELP/PAGEABLE.IMG 17c627f77fdabb20f9b62d9ce4478cd7 ./Program_Executable_Files/HELP/POINTER1.IMG 5226c2dfd554935259070ba27f3a5979 ./Program_Executable_Files/HELP/POINTER2.IMG 61346266968fbcb1e4a436bd344b41ed ./Program_Executable_Files/HELP/REDALERT.HTM 33c753c67c8b69d21444a200cc86dec6 ./Program_Executable_Files/HELP/REDNECK.HTM e1216b38e9f8b76c17ae170dc67666f5 ./Program_Executable_Files/HELP/SHADOWSW.HTM 257db161d6726e3ed364c8cb9ae8ff83 ./Program_Executable_Files/HELP/TERMINAL.HTM f6d039a634c2f8e1d88a73d8b88f0308 ./Program_Executable_Files/HELP/ULTIDOOM.HTM 199ffc6c3a250279fb5528367a81149e ./Program_Executable_Files/HELP/VPOOL.HTM 30f5028f06b5c9d0bdff8c7e9c78c0ab ./Program_Executable_Files/HELP/VSNOOKER.HTM 71e05df263430a89116ce7d897e11b25 ./Program_Executable_Files/HELP/WAR2DEMO.HTM 227ccc1c11592c0f35ac9cb15074311c ./Program_Executable_Files/HELP/WARCRAF2.HTM b80196f5414e9253b4ab7550657c781f ./Program_Executable_Files/HELP/WIREAPI.HTM b89989c6d74e52ee1beb3bf18f194726 ./Program_Executable_Files/HELP/WIRECOMM.HTM 491e367a7900888b96defa7ff592bfc9 ./Program_Executable_Files/HELP/WIREDOOM.HTM 5bd772d47f1d13794e7810422e62dad3 ./Program_Executable_Files/HELP/WIREDP.HTM 50ccb10071ba7b4a95c472b1666415bb ./Program_Executable_Files/HELP/WIREIP.HTM 69b3c48830a176f781b7af805160f7eb ./Program_Executable_Files/HELP/WIREIPX.HTM cf2dceb995d1c075f79d26435142083e ./Program_Executable_Files/HELP/WPDRVRS.HTM 5184100495b9f83c3fb32767d160524b ./Program_Executable_Files/LAUNCHER.INI fe62f30206b08e17d00a6e68c1f42692 ./Program_Executable_Files/MODEM.DAT c7d807185a6f4bbe10c143dec7156c4b ./Program_Executable_Files/PSTUB.EXE 74f7bfff760eb090d9e497142b84ccb2 ./Program_Executable_Files/Readme.txt 479e2b6aaea1723043a97f4a7b5a17ec ./Program_Executable_Files/USERS.INI 886faf562d08664ce941cce3bfb7769e ./Program_Executable_Files/V20.RES cb43a12a08b8bd9754483482115ed619 ./Program_Executable_Files/WIRECOMM.EXE 5141cef0ebfa2d204baa01986615c906 ./Program_Executable_Files/WIREDOOM.EXE 664bcc356a9d0068538df71baa45205e ./Program_Executable_Files/WIREIPX.EXE 2aaa0afb9213c9fccaea0bf7b44d6254 ./Program_Executable_Files/WIREPLAY.BAT 0fff40618a359f26515427b30c9aae8a ./Program_Executable_Files/WIREPLAY.CFG eecde17e712b9bf274f70254f49dbcb4 ./Program_Executable_Files/WIREPLAY.INI 34f1efa56118a6220822205f0b5f2080 ./Program_Executable_Files/WIREPLAY.PAL db5ea5dd885a508e7273b10c8f60bb86 ./Program_Executable_Files/WPGAME.EXE unshield-1.5.1/test/v0/wireplay.sh000077500000000000000000000014561415320644200170370ustar00rootroot00000000000000#!/bin/bash set -e cd "$(dirname "$0")" MD5_FILE=$(pwd)/$(basename "$0" .sh).md5 UNSHIELD=${UNSHIELD:-/var/tmp/unshield/bin/unshield} if [ \! -x "${UNSHIELD}" ]; then echo "unshield executable not found at $UNSHIELD" >&2 exit 1 fi DIR=$(mktemp -d) trap 'rm -rf ${DIR}' TERM INT EXIT cd "${DIR}" URL="https://www.dropbox.com/s/ac3418ds94j5542/dpcb1197-Wireplay.zip?dl=1" curl -sSL -o test.zip "${URL}" unzip -q test.zip set +e timeout 10 "${UNSHIELD}" -O -d extract x dpcb1197-Wireplay/DOS/data1.cab > log 2>&1 CODE=$? if [ ${CODE} -ne 0 ]; then cat log >&2 echo "unshield failed with error $CODE" >&2 exit 3 fi cd extract find . -type f -print0 | LC_ALL=C sort -z | xargs -0 md5sum > ../md5 if ! diff -wu "${MD5_FILE}" ../md5 >&2 ; then echo "MD5 sums diff" >&2 exit 4 fi exit 0 unshield-1.5.1/test/v5/000077500000000000000000000000001415320644200146435ustar00rootroot00000000000000unshield-1.5.1/test/v5/CVE-2015-1386/000077500000000000000000000000001415320644200162445ustar00rootroot00000000000000unshield-1.5.1/test/v5/CVE-2015-1386/CVE-2015-1386.sh000077500000000000000000000014621415320644200202070ustar00rootroot00000000000000#!/bin/bash if [ "$(uname)" != "Linux" ] ; then echo "This test can only run on Linux " exit 0 fi set -e cd `dirname $0` MD5_FILE=`pwd`/`basename $0 .sh`.md5 CAB_FILE=`pwd`/data1.cab UNSHIELD=${UNSHIELD:-/var/tmp/unshield/bin/unshield} if [ \! -x ${UNSHIELD} ]; then echo "unshield executable not found at $UNSHIELD" >&2 exit 1 fi DIR=`mktemp -d` #trap 'rm -rf ${DIR}' TERM INT EXIT cd ${DIR} set +e rm -f /tmp/moo timeout 10 ${UNSHIELD} -d extract1 x "$CAB_FILE" > log1 2>&1 CODE=$? if [ -e /tmp/moo ]; then cat log1 >&2 echo "unshield vulnerable to CVE-2015-1386" >&2 echo "See https://github.com/twogood/unshield/issues/42" >&2 exit 2 fi if [ ${CODE} -ne 1 ]; then cat log1 >&2 echo "unshield should have failed with error 1 but was $CODE" >&2 exit 3 fi exit 0 unshield-1.5.1/test/v5/CVE-2015-1386/data1.cab000066400000000000000000000010101415320644200176750ustar00rootroot00000000000000ISc(R^8wd ?Ȁ8wd Wwd Wwd pNG?NWcqcz'3K =YuProgram FilesBovine FilesBovine FilesCompactProgram FilesMainStartupBovine FilesProgram Files>hX. 9)C2 $+u 9FeN 9FeN../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../tmp/moounshield-1.5.1/valgrind.sh000077500000000000000000000001511415320644200154740ustar00rootroot00000000000000#!/bin/sh libtool --mode=execute valgrind --num-callers=10 --leak-check=yes `dirname $0`/src/unshield $@ unshield-1.5.1/win32_msvc/000077500000000000000000000000001415320644200153245ustar00rootroot00000000000000unshield-1.5.1/win32_msvc/dirent.h000066400000000000000000000531541415320644200167720ustar00rootroot00000000000000/* * Dirent interface for Microsoft Visual Studio * Version 1.21 * * Copyright (C) 2006-2012 Toni Ronkko * This file is part of dirent. Dirent may be freely distributed * under the MIT license. For all details and documentation, see * https://github.com/tronkko/dirent */ #ifndef DIRENT_H #define DIRENT_H /* * Include windows.h without Windows Sockets 1.1 to prevent conflicts with * Windows Sockets 2.0. */ #ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN #endif #include #include #include #include #include #include #include #include #include #include /* Indicates that d_type field is available in dirent structure */ #define _DIRENT_HAVE_D_TYPE /* Indicates that d_namlen field is available in dirent structure */ #define _DIRENT_HAVE_D_NAMLEN /* Entries missing from MSVC 6.0 */ #if !defined(FILE_ATTRIBUTE_DEVICE) # define FILE_ATTRIBUTE_DEVICE 0x40 #endif /* File type and permission flags for stat(), general mask */ #if !defined(S_IFMT) # define S_IFMT _S_IFMT #endif /* Directory bit */ #if !defined(S_IFDIR) # define S_IFDIR _S_IFDIR #endif /* Character device bit */ #if !defined(S_IFCHR) # define S_IFCHR _S_IFCHR #endif /* Pipe bit */ #if !defined(S_IFFIFO) # define S_IFFIFO _S_IFFIFO #endif /* Regular file bit */ #if !defined(S_IFREG) # define S_IFREG _S_IFREG #endif /* Read permission */ #if !defined(S_IREAD) # define S_IREAD _S_IREAD #endif /* Write permission */ #if !defined(S_IWRITE) # define S_IWRITE _S_IWRITE #endif /* Execute permission */ #if !defined(S_IEXEC) # define S_IEXEC _S_IEXEC #endif /* Pipe */ #if !defined(S_IFIFO) # define S_IFIFO _S_IFIFO #endif /* Block device */ #if !defined(S_IFBLK) # define S_IFBLK 0 #endif /* Link */ #if !defined(S_IFLNK) # define S_IFLNK 0 #endif /* Socket */ #if !defined(S_IFSOCK) # define S_IFSOCK 0 #endif /* Read user permission */ #if !defined(S_IRUSR) # define S_IRUSR S_IREAD #endif /* Write user permission */ #if !defined(S_IWUSR) # define S_IWUSR S_IWRITE #endif /* Execute user permission */ #if !defined(S_IXUSR) # define S_IXUSR 0 #endif /* Read group permission */ #if !defined(S_IRGRP) # define S_IRGRP 0 #endif /* Write group permission */ #if !defined(S_IWGRP) # define S_IWGRP 0 #endif /* Execute group permission */ #if !defined(S_IXGRP) # define S_IXGRP 0 #endif /* Read others permission */ #if !defined(S_IROTH) # define S_IROTH 0 #endif /* Write others permission */ #if !defined(S_IWOTH) # define S_IWOTH 0 #endif /* Execute others permission */ #if !defined(S_IXOTH) # define S_IXOTH 0 #endif /* Maximum length of file name */ #if !defined(PATH_MAX) # define PATH_MAX MAX_PATH #endif #if !defined(FILENAME_MAX) # define FILENAME_MAX MAX_PATH #endif #if !defined(NAME_MAX) # define NAME_MAX FILENAME_MAX #endif /* File type flags for d_type */ #define DT_UNKNOWN 0 #define DT_REG S_IFREG #define DT_DIR S_IFDIR #define DT_FIFO S_IFIFO #define DT_SOCK S_IFSOCK #define DT_CHR S_IFCHR #define DT_BLK S_IFBLK #define DT_LNK S_IFLNK /* Macros for converting between st_mode and d_type */ #define IFTODT(mode) ((mode) & S_IFMT) #define DTTOIF(type) (type) /* * File type macros. Note that block devices, sockets and links cannot be * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are * only defined for compatibility. These macros should always return false * on Windows. */ #if !defined(S_ISFIFO) # define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO) #endif #if !defined(S_ISDIR) # define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) #endif #if !defined(S_ISREG) # define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) #endif #if !defined(S_ISLNK) # define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) #endif #if !defined(S_ISSOCK) # define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) #endif #if !defined(S_ISCHR) # define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) #endif #if !defined(S_ISBLK) # define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) #endif /* Return the exact length of d_namlen without zero terminator */ #define _D_EXACT_NAMLEN(p) ((p)->d_namlen) /* Return number of bytes needed to store d_namlen */ #define _D_ALLOC_NAMLEN(p) (PATH_MAX) #ifdef __cplusplus extern "C" { #endif /* Wide-character version */ struct _wdirent { /* Always zero */ long d_ino; /* Structure size */ unsigned short d_reclen; /* Length of name without \0 */ size_t d_namlen; /* File type */ int d_type; /* File name */ wchar_t d_name[PATH_MAX]; }; typedef struct _wdirent _wdirent; struct _WDIR { /* Current directory entry */ struct _wdirent ent; /* Private file data */ WIN32_FIND_DATAW data; /* True if data is valid */ int cached; /* Win32 search handle */ HANDLE handle; /* Initial directory name */ wchar_t *patt; }; typedef struct _WDIR _WDIR; static _WDIR *_wopendir (const wchar_t *dirname); static struct _wdirent *_wreaddir (_WDIR *dirp); static int _wclosedir (_WDIR *dirp); static void _wrewinddir (_WDIR* dirp); /* For compatibility with Symbian */ #define wdirent _wdirent #define WDIR _WDIR #define wopendir _wopendir #define wreaddir _wreaddir #define wclosedir _wclosedir #define wrewinddir _wrewinddir /* Multi-byte character versions */ struct dirent { /* Always zero */ long d_ino; /* Structure size */ unsigned short d_reclen; /* Length of name without \0 */ size_t d_namlen; /* File type */ int d_type; /* File name */ char d_name[PATH_MAX]; }; typedef struct dirent dirent; struct DIR { struct dirent ent; struct _WDIR *wdirp; }; typedef struct DIR DIR; static DIR *opendir (const char *dirname); static struct dirent *readdir (DIR *dirp); static int closedir (DIR *dirp); static void rewinddir (DIR* dirp); /* Internal utility functions */ static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp); static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp); static int dirent_mbstowcs_s( size_t *pReturnValue, wchar_t *wcstr, size_t sizeInWords, const char *mbstr, size_t count); static int dirent_wcstombs_s( size_t *pReturnValue, char *mbstr, size_t sizeInBytes, const wchar_t *wcstr, size_t count); static void dirent_set_errno (int error); /* * Open directory stream DIRNAME for read and return a pointer to the * internal working area that is used to retrieve individual directory * entries. */ static _WDIR* _wopendir( const wchar_t *dirname) { _WDIR *dirp = NULL; int error; /* Must have directory name */ if (dirname == NULL || dirname[0] == '\0') { dirent_set_errno (ENOENT); return NULL; } /* Allocate new _WDIR structure */ dirp = (_WDIR*) malloc (sizeof (struct _WDIR)); if (dirp != NULL) { DWORD n; /* Reset _WDIR structure */ dirp->handle = INVALID_HANDLE_VALUE; dirp->patt = NULL; dirp->cached = 0; /* Compute the length of full path plus zero terminator * * Note that on WinRT there's no way to convert relative paths * into absolute paths, so just assume its an absolute path. */ # if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) n = wcslen(dirname); # else n = GetFullPathNameW (dirname, 0, NULL, NULL); # endif /* Allocate room for absolute directory name and search pattern */ dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16); if (dirp->patt) { /* * Convert relative directory name to an absolute one. This * allows rewinddir() to function correctly even when current * working directory is changed between opendir() and rewinddir(). * * Note that on WinRT there's no way to convert relative paths * into absolute paths, so just assume its an absolute path. */ # if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) wcsncpy_s(dirp->patt, n+1, dirname, n); # else n = GetFullPathNameW (dirname, n, dirp->patt, NULL); # endif if (n > 0) { wchar_t *p; /* Append search pattern \* to the directory name */ p = dirp->patt + n; if (dirp->patt < p) { switch (p[-1]) { case '\\': case '/': case ':': /* Directory ends in path separator, e.g. c:\temp\ */ /*NOP*/; break; default: /* Directory name doesn't end in path separator */ *p++ = '\\'; } } *p++ = '*'; *p = '\0'; /* Open directory stream and retrieve the first entry */ if (dirent_first (dirp)) { /* Directory stream opened successfully */ error = 0; } else { /* Cannot retrieve first entry */ error = 1; dirent_set_errno (ENOENT); } } else { /* Cannot retrieve full path name */ dirent_set_errno (ENOENT); error = 1; } } else { /* Cannot allocate memory for search pattern */ error = 1; } } else { /* Cannot allocate _WDIR structure */ error = 1; } /* Clean up in case of error */ if (error && dirp) { _wclosedir (dirp); dirp = NULL; } return dirp; } /* * Read next directory entry. The directory entry is returned in dirent * structure in the d_name field. Individual directory entries returned by * this function include regular files, sub-directories, pseudo-directories * "." and ".." as well as volume labels, hidden files and system files. */ static struct _wdirent* _wreaddir( _WDIR *dirp) { WIN32_FIND_DATAW *datap; struct _wdirent *entp; /* Read next directory entry */ datap = dirent_next (dirp); if (datap) { size_t n; DWORD attr; /* Pointer to directory entry to return */ entp = &dirp->ent; /* * Copy file name as wide-character string. If the file name is too * long to fit in to the destination buffer, then truncate file name * to PATH_MAX characters and zero-terminate the buffer. */ n = 0; while (n + 1 < PATH_MAX && datap->cFileName[n] != 0) { entp->d_name[n] = datap->cFileName[n]; n++; } dirp->ent.d_name[n] = 0; /* Length of file name excluding zero terminator */ entp->d_namlen = n; /* File type */ attr = datap->dwFileAttributes; if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { entp->d_type = DT_CHR; } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { entp->d_type = DT_DIR; } else { entp->d_type = DT_REG; } /* Reset dummy fields */ entp->d_ino = 0; entp->d_reclen = sizeof (struct _wdirent); } else { /* Last directory entry read */ entp = NULL; } return entp; } /* * Close directory stream opened by opendir() function. This invalidates the * DIR structure as well as any directory entry read previously by * _wreaddir(). */ static int _wclosedir( _WDIR *dirp) { int ok; if (dirp) { /* Release search handle */ if (dirp->handle != INVALID_HANDLE_VALUE) { FindClose (dirp->handle); dirp->handle = INVALID_HANDLE_VALUE; } /* Release search pattern */ if (dirp->patt) { free (dirp->patt); dirp->patt = NULL; } /* Release directory structure */ free (dirp); ok = /*success*/0; } else { /* Invalid directory stream */ dirent_set_errno (EBADF); ok = /*failure*/-1; } return ok; } /* * Rewind directory stream such that _wreaddir() returns the very first * file name again. */ static void _wrewinddir( _WDIR* dirp) { if (dirp) { /* Release existing search handle */ if (dirp->handle != INVALID_HANDLE_VALUE) { FindClose (dirp->handle); } /* Open new search handle */ dirent_first (dirp); } } /* Get first directory entry (internal) */ static WIN32_FIND_DATAW* dirent_first( _WDIR *dirp) { WIN32_FIND_DATAW *datap; /* Open directory and retrieve the first entry */ dirp->handle = FindFirstFileExW( dirp->patt, FindExInfoStandard, &dirp->data, FindExSearchNameMatch, NULL, 0); if (dirp->handle != INVALID_HANDLE_VALUE) { /* a directory entry is now waiting in memory */ datap = &dirp->data; dirp->cached = 1; } else { /* Failed to re-open directory: no directory entry in memory */ dirp->cached = 0; datap = NULL; } return datap; } /* Get next directory entry (internal) */ static WIN32_FIND_DATAW* dirent_next( _WDIR *dirp) { WIN32_FIND_DATAW *p; /* Get next directory entry */ if (dirp->cached != 0) { /* A valid directory entry already in memory */ p = &dirp->data; dirp->cached = 0; } else if (dirp->handle != INVALID_HANDLE_VALUE) { /* Get the next directory entry from stream */ if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) { /* Got a file */ p = &dirp->data; } else { /* The very last entry has been processed or an error occured */ FindClose (dirp->handle); dirp->handle = INVALID_HANDLE_VALUE; p = NULL; } } else { /* End of directory stream reached */ p = NULL; } return p; } /* * Open directory stream using plain old C-string. */ static DIR* opendir( const char *dirname) { struct DIR *dirp; int error; /* Must have directory name */ if (dirname == NULL || dirname[0] == '\0') { dirent_set_errno (ENOENT); return NULL; } /* Allocate memory for DIR structure */ dirp = (DIR*) malloc (sizeof (struct DIR)); if (dirp) { wchar_t wname[PATH_MAX]; size_t n; /* Convert directory name to wide-character string */ error = dirent_mbstowcs_s (&n, wname, PATH_MAX, dirname, PATH_MAX); if (!error) { /* Open directory stream using wide-character name */ dirp->wdirp = _wopendir (wname); if (dirp->wdirp) { /* Directory stream opened */ error = 0; } else { /* Failed to open directory stream */ error = 1; } } else { /* * Cannot convert file name to wide-character string. This * occurs if the string contains invalid multi-byte sequences or * the output buffer is too small to contain the resulting * string. */ error = 1; } } else { /* Cannot allocate DIR structure */ error = 1; } /* Clean up in case of error */ if (error && dirp) { free (dirp); dirp = NULL; } return dirp; } /* * Read next directory entry. * * When working with text consoles, please note that file names returned by * readdir() are represented in the default ANSI code page while any output to * console is typically formatted on another code page. Thus, non-ASCII * characters in file names will not usually display correctly on console. The * problem can be fixed in two ways: (1) change the character set of console * to 1252 using chcp utility and use Lucida Console font, or (2) use * _cprintf function when writing to console. The _cprinf() will re-encode * ANSI strings to the console code page so many non-ASCII characters will * display correcly. */ static struct dirent* readdir( DIR *dirp) { WIN32_FIND_DATAW *datap; struct dirent *entp; /* Read next directory entry */ datap = dirent_next (dirp->wdirp); if (datap) { size_t n; int error; /* Attempt to convert file name to multi-byte string */ error = dirent_wcstombs_s( &n, dirp->ent.d_name, PATH_MAX, datap->cFileName, PATH_MAX); /* * If the file name cannot be represented by a multi-byte string, * then attempt to use old 8+3 file name. This allows traditional * Unix-code to access some file names despite of unicode * characters, although file names may seem unfamiliar to the user. * * Be ware that the code below cannot come up with a short file * name unless the file system provides one. At least * VirtualBox shared folders fail to do this. */ if (error && datap->cAlternateFileName[0] != '\0') { error = dirent_wcstombs_s( &n, dirp->ent.d_name, PATH_MAX, datap->cAlternateFileName, PATH_MAX); } if (!error) { DWORD attr; /* Initialize directory entry for return */ entp = &dirp->ent; /* Length of file name excluding zero terminator */ entp->d_namlen = n - 1; /* File attributes */ attr = datap->dwFileAttributes; if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { entp->d_type = DT_CHR; } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { entp->d_type = DT_DIR; } else { entp->d_type = DT_REG; } /* Reset dummy fields */ entp->d_ino = 0; entp->d_reclen = sizeof (struct dirent); } else { /* * Cannot convert file name to multi-byte string so construct * an errornous directory entry and return that. Note that * we cannot return NULL as that would stop the processing * of directory entries completely. */ entp = &dirp->ent; entp->d_name[0] = '?'; entp->d_name[1] = '\0'; entp->d_namlen = 1; entp->d_type = DT_UNKNOWN; entp->d_ino = 0; entp->d_reclen = 0; } } else { /* No more directory entries */ entp = NULL; } return entp; } /* * Close directory stream. */ static int closedir( DIR *dirp) { int ok; if (dirp) { /* Close wide-character directory stream */ ok = _wclosedir (dirp->wdirp); dirp->wdirp = NULL; /* Release multi-byte character version */ free (dirp); } else { /* Invalid directory stream */ dirent_set_errno (EBADF); ok = /*failure*/-1; } return ok; } /* * Rewind directory stream to beginning. */ static void rewinddir( DIR* dirp) { /* Rewind wide-character string directory stream */ _wrewinddir (dirp->wdirp); } /* Convert multi-byte string to wide character string */ static int dirent_mbstowcs_s( size_t *pReturnValue, wchar_t *wcstr, size_t sizeInWords, const char *mbstr, size_t count) { int error; #if defined(_MSC_VER) && _MSC_VER >= 1400 /* Microsoft Visual Studio 2005 or later */ error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count); #else /* Older Visual Studio or non-Microsoft compiler */ size_t n; /* Convert to wide-character string (or count characters) */ n = mbstowcs (wcstr, mbstr, sizeInWords); if (!wcstr || n < count) { /* Zero-terminate output buffer */ if (wcstr && sizeInWords) { if (n >= sizeInWords) { n = sizeInWords - 1; } wcstr[n] = 0; } /* Length of resuting multi-byte string WITH zero terminator */ if (pReturnValue) { *pReturnValue = n + 1; } /* Success */ error = 0; } else { /* Could not convert string */ error = 1; } #endif return error; } /* Convert wide-character string to multi-byte string */ static int dirent_wcstombs_s( size_t *pReturnValue, char *mbstr, size_t sizeInBytes, /* max size of mbstr */ const wchar_t *wcstr, size_t count) { int error; #if defined(_MSC_VER) && _MSC_VER >= 1400 /* Microsoft Visual Studio 2005 or later */ error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count); #else /* Older Visual Studio or non-Microsoft compiler */ size_t n; /* Convert to multi-byte string (or count the number of bytes needed) */ n = wcstombs (mbstr, wcstr, sizeInBytes); if (!mbstr || n < count) { /* Zero-terminate output buffer */ if (mbstr && sizeInBytes) { if (n >= sizeInBytes) { n = sizeInBytes - 1; } mbstr[n] = '\0'; } /* Length of resulting multi-bytes string WITH zero-terminator */ if (pReturnValue) { *pReturnValue = n + 1; } /* Success */ error = 0; } else { /* Cannot convert string */ error = 1; } #endif return error; } /* Set errno variable */ static void dirent_set_errno( int error) { #if defined(_MSC_VER) && _MSC_VER >= 1400 /* Microsoft Visual Studio 2005 and later */ _set_errno (error); #else /* Non-Microsoft compiler or older Microsoft compiler */ errno = error; #endif } #ifdef __cplusplus } #endif #endif /*DIRENT_H*/ unshield-1.5.1/win32_msvc/getopt.h000066400000000000000000000265431415320644200170110ustar00rootroot00000000000000/* -*- indent-tabs-mode: nil -*- * * ya_getopt - Yet another getopt * https://github.com/kubo/ya_getopt * * Copyright 2015 Kubo Takehiro * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of the authors. * */ #ifndef YA_GETOPT_H #define YA_GETOPT_H 1 #if defined(__cplusplus) extern "C" { #endif #include #include #include #include #define ya_no_argument 0 #define ya_required_argument 1 #define ya_optional_argument 2 struct option { const char *name; int has_arg; int *flag; int val; }; // error: ‘ya_getopt’ defined but not used [-Werror=unused-function] ///static int ya_getopt(int argc, char * const argv[], const char *optstring); static int ya_getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex); ///static int ya_getopt_long_only(int argc, char * const argv[], const char *optstring, /// const struct option *longopts, int *longindex); #ifndef YA_GETOPT_NO_COMPAT_MACRO ///#define getopt ya_getopt #define getopt_long ya_getopt_long ///#define getopt_long_only ya_getopt_long_only #define optarg ya_optarg #define optind ya_optind #define opterr ya_opterr #define optopt ya_optopt #define no_argument ya_no_argument #define required_argument ya_required_argument #define optional_argument ya_optional_argument #endif // =============================================================================== char *ya_optarg = NULL; int ya_optind = 1; int ya_opterr = 1; int ya_optopt = '?'; static char *ya_optnext = NULL; static int posixly_correct = -1; static int handle_nonopt_argv = 0; static void ya_getopt_error(const char *optstring, const char *format, ...); static void check_gnu_extension(const char *optstring); static int ya_getopt_internal(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex, int long_only); static int ya_getopt_shortopts(int argc, char * const argv[], const char *optstring, int long_only); static int ya_getopt_longopts(int argc, char * const argv[], char *arg, const char *optstring, const struct option *longopts, int *longindex, int *long_only_flag); static void ya_getopt_error(const char *optstring, const char *format, ...) { if (ya_opterr && optstring[0] != ':') { va_list ap; va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap); } } static void check_gnu_extension(const char *optstring) { if (optstring[0] == '+' || getenv("POSIXLY_CORRECT") != NULL) { posixly_correct = 1; } else { posixly_correct = 0; } if (optstring[0] == '-') { handle_nonopt_argv = 1; } else { handle_nonopt_argv = 0; } } static int is_option(const char *arg) { return arg[0] == '-' && arg[1] != '\0'; } // ================================================================== ///static int ya_getopt(int argc, char * const argv[], const char *optstring) ///{ /// return ya_getopt_internal(argc, argv, optstring, NULL, NULL, 0); ///} static int ya_getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex) { return ya_getopt_internal(argc, argv, optstring, longopts, longindex, 0); } ///static int ya_getopt_long_only(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex) ///{ /// return ya_getopt_internal(argc, argv, optstring, longopts, longindex, 1); ///} // ================================================================== static int ya_getopt_internal(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex, int long_only) { static int start, end; if (ya_optopt == '?') { ya_optopt = 0; } if (posixly_correct == -1) { check_gnu_extension(optstring); } if (ya_optind == 0) { check_gnu_extension(optstring); ya_optind = 1; ya_optnext = NULL; } switch (optstring[0]) { case '+': case '-': optstring++; } if (ya_optnext == NULL && start != 0) { int last_pos = ya_optind - 1; ya_optind -= end - start; if (ya_optind <= 0) { ya_optind = 1; } while (start < end--) { int i; char *arg = argv[end]; for (i = end; i < last_pos; i++) { ((char **)argv)[i] = argv[i + 1]; } ((char const **)argv)[i] = arg; last_pos--; } start = 0; } if (ya_optind >= argc) { ya_optarg = NULL; return -1; } if (ya_optnext == NULL) { const char *arg = argv[ya_optind]; if (!is_option(arg)) { if (handle_nonopt_argv) { ya_optarg = argv[ya_optind++]; start = 0; return 1; } else if (posixly_correct) { ya_optarg = NULL; return -1; } else { int i; start = ya_optind; for (i = ya_optind + 1; i < argc; i++) { if (is_option(argv[i])) { end = i; break; } } if (i == argc) { ya_optarg = NULL; return -1; } ya_optind = i; arg = argv[ya_optind]; } } if (strcmp(arg, "--") == 0) { ya_optind++; return -1; } if (longopts != NULL && arg[1] == '-') { return ya_getopt_longopts(argc, argv, argv[ya_optind] + 2, optstring, longopts, longindex, NULL); } } if (ya_optnext == NULL) { ya_optnext = argv[ya_optind] + 1; } if (long_only) { int long_only_flag = 0; int rv = ya_getopt_longopts(argc, argv, ya_optnext, optstring, longopts, longindex, &long_only_flag); if (!long_only_flag) { ya_optnext = NULL; return rv; } } return ya_getopt_shortopts(argc, argv, optstring, long_only); } static int ya_getopt_shortopts(int argc, char * const argv[], const char *optstring, int long_only) { int opt = *ya_optnext; const char *os = strchr(optstring, opt); if (os == NULL) { ya_optarg = NULL; if (long_only) { ya_getopt_error(optstring, "%s: unrecognized option '-%s'\n", argv[0], ya_optnext); ya_optind++; ya_optnext = NULL; } else { ya_optopt = opt; ya_getopt_error(optstring, "%s: invalid option -- '%c'\n", argv[0], opt); if (*(++ya_optnext) == 0) { ya_optind++; ya_optnext = NULL; } } return '?'; } if (os[1] == ':') { if (ya_optnext[1] == 0) { ya_optind++; ya_optnext = NULL; if (os[2] == ':') { /* optional argument */ ya_optarg = NULL; } else { if (ya_optind == argc) { ya_optarg = NULL; ya_optopt = opt; ya_getopt_error(optstring, "%s: option requires an argument -- '%c'\n", argv[0], opt); if (optstring[0] == ':') { return ':'; } else { return '?'; } } ya_optarg = argv[ya_optind]; ya_optind++; } } else { ya_optarg = ya_optnext + 1; ya_optind++; } ya_optnext = NULL; } else { ya_optarg = NULL; if (ya_optnext[1] == 0) { ya_optnext = NULL; ya_optind++; } else { ya_optnext++; } } return opt; } static int ya_getopt_longopts(int argc, char * const argv[], char *arg, const char *optstring, const struct option *longopts, int *longindex, int *long_only_flag) { char *val = NULL; const struct option *opt; size_t namelen; int idx; for (idx = 0; longopts[idx].name != NULL; idx++) { opt = &longopts[idx]; namelen = strlen(opt->name); if (strncmp(arg, opt->name, namelen) == 0) { switch (arg[namelen]) { case '\0': switch (opt->has_arg) { case ya_required_argument: ya_optind++; if (ya_optind == argc) { ya_optarg = NULL; ya_optopt = opt->val; ya_getopt_error(optstring, "%s: option '--%s' requires an argument\n", argv[0], opt->name); if (optstring[0] == ':') { return ':'; } else { return '?'; } } val = argv[ya_optind]; break; } goto found; case '=': if (opt->has_arg == ya_no_argument) { const char *hyphens = (argv[ya_optind][1] == '-') ? "--" : "-"; ya_optind++; ya_optarg = NULL; ya_optopt = opt->val; ya_getopt_error(optstring, "%s: option '%s%s' doesn't allow an argument\n", argv[0], hyphens, opt->name); return '?'; } val = arg + namelen + 1; goto found; } } } if (long_only_flag) { *long_only_flag = 1; } else { ya_getopt_error(optstring, "%s: unrecognized option '%s'\n", argv[0], argv[ya_optind]); ya_optind++; } return '?'; found: ya_optarg = val; ya_optind++; if (opt->flag) { *opt->flag = opt->val; } if (longindex) { *longindex = idx; } return opt->flag ? 0 : opt->val; } #if defined(__cplusplus) } #endif #endif unshield-1.5.1/win32_msvc/unistd.h000066400000000000000000000023751415320644200170120ustar00rootroot00000000000000#ifndef _UNISTD_H #define _UNISTD_H 1 /* This file intended to serve as a drop-in replacement for * unistd.h on Windows * Please add functionality as neeeded */ #include #include #include /* for getpid() and the exec..() family */ #include /* for _getcwd() and _chdir() */ #define srandom srand #define random rand /* Values for the second argument to access. These may be OR'd together. */ #define R_OK 4 /* Test for read permission. */ #define W_OK 2 /* Test for write permission. */ //#define X_OK 1 /* execute permission - unsupported in windows*/ #define F_OK 0 /* Test for existence. */ #define access _access #define dup2 _dup2 #define execve _execve #define ftruncate _chsize #define unlink _unlink #define fileno _fileno #define getcwd _getcwd #define chdir _chdir #define isatty _isatty #define lseek _lseek /* read, write, and close are NOT being #defined here, because while there are file handle specific versions for Windows, they probably don't work for sockets. You need to look at your app and consider whether to call e.g. closesocket(). */ #define ssize_t int #define STDIN_FILENO 0 #define STDOUT_FILENO 1 #define STDERR_FILENO 2 #endif /* unistd.h */